PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.c

https://github.com/andikleen/linux-misc
C | 224 lines | 204 code | 12 blank | 8 comment | 11 complexity | 98d0caac594b1790ec5fb2df8f47321f MD5 | raw file
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * AMD SFH Report Descriptor generator
  4. * Copyright 2020 Advanced Micro Devices, Inc.
  5. * Authors: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@amd.com>
  6. * Sandeep Singh <sandeep.singh@amd.com>
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/string.h>
  10. #include <linux/slab.h>
  11. #include "amd_sfh_pcie.h"
  12. #include "amd_sfh_hid_desc.h"
  13. #include "amd_sfh_hid_report_desc.h"
  14. #define AMD_SFH_FW_MULTIPLIER (1000)
  15. #define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41
  16. #define HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM 0x51
  17. #define HID_DEFAULT_REPORT_INTERVAL 0x50
  18. #define HID_DEFAULT_MIN_VALUE 0X7F
  19. #define HID_DEFAULT_MAX_VALUE 0x80
  20. #define HID_DEFAULT_SENSITIVITY 0x7F
  21. #define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM 0x01
  22. /* state enums */
  23. #define HID_USAGE_SENSOR_STATE_READY_ENUM 0x02
  24. #define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM 0x05
  25. #define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM 0x04
  26. int get_report_descriptor(int sensor_idx, u8 *rep_desc)
  27. {
  28. switch (sensor_idx) {
  29. case accel_idx: /* accel */
  30. memset(rep_desc, 0, sizeof(accel3_report_descriptor));
  31. memcpy(rep_desc, accel3_report_descriptor,
  32. sizeof(accel3_report_descriptor));
  33. break;
  34. case gyro_idx: /* gyro */
  35. memset(rep_desc, 0, sizeof(gyro3_report_descriptor));
  36. memcpy(rep_desc, gyro3_report_descriptor,
  37. sizeof(gyro3_report_descriptor));
  38. break;
  39. case mag_idx: /* Magnetometer */
  40. memset(rep_desc, 0, sizeof(comp3_report_descriptor));
  41. memcpy(rep_desc, comp3_report_descriptor,
  42. sizeof(comp3_report_descriptor));
  43. break;
  44. case als_idx: /* ambient light sensor */
  45. memset(rep_desc, 0, sizeof(als_report_descriptor));
  46. memcpy(rep_desc, als_report_descriptor,
  47. sizeof(als_report_descriptor));
  48. break;
  49. default:
  50. break;
  51. }
  52. return 0;
  53. }
  54. u32 get_descr_sz(int sensor_idx, int descriptor_name)
  55. {
  56. switch (sensor_idx) {
  57. case accel_idx:
  58. switch (descriptor_name) {
  59. case descr_size:
  60. return sizeof(accel3_report_descriptor);
  61. case input_size:
  62. return sizeof(struct accel3_input_report);
  63. case feature_size:
  64. return sizeof(struct accel3_feature_report);
  65. }
  66. break;
  67. case gyro_idx:
  68. switch (descriptor_name) {
  69. case descr_size:
  70. return sizeof(gyro3_report_descriptor);
  71. case input_size:
  72. return sizeof(struct gyro_input_report);
  73. case feature_size:
  74. return sizeof(struct gyro_feature_report);
  75. }
  76. break;
  77. case mag_idx:
  78. switch (descriptor_name) {
  79. case descr_size:
  80. return sizeof(comp3_report_descriptor);
  81. case input_size:
  82. return sizeof(struct magno_input_report);
  83. case feature_size:
  84. return sizeof(struct magno_feature_report);
  85. }
  86. break;
  87. case als_idx:
  88. switch (descriptor_name) {
  89. case descr_size:
  90. return sizeof(als_report_descriptor);
  91. case input_size:
  92. return sizeof(struct als_input_report);
  93. case feature_size:
  94. return sizeof(struct als_feature_report);
  95. }
  96. break;
  97. default:
  98. break;
  99. }
  100. return 0;
  101. }
  102. static void get_common_features(struct common_feature_property *common, int report_id)
  103. {
  104. common->report_id = report_id;
  105. common->connection_type = HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM;
  106. common->report_state = HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM;
  107. common->power_state = HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM;
  108. common->sensor_state = HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM;
  109. common->report_interval = HID_DEFAULT_REPORT_INTERVAL;
  110. }
  111. u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
  112. {
  113. struct accel3_feature_report acc_feature;
  114. struct gyro_feature_report gyro_feature;
  115. struct magno_feature_report magno_feature;
  116. struct als_feature_report als_feature;
  117. u8 report_size = 0;
  118. if (!feature_report)
  119. return report_size;
  120. switch (sensor_idx) {
  121. case accel_idx: /* accel */
  122. get_common_features(&acc_feature.common_property, report_id);
  123. acc_feature.accel_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
  124. acc_feature.accel_sensitivity_min = HID_DEFAULT_MIN_VALUE;
  125. acc_feature.accel_sensitivity_max = HID_DEFAULT_MAX_VALUE;
  126. memcpy(feature_report, &acc_feature, sizeof(acc_feature));
  127. report_size = sizeof(acc_feature);
  128. break;
  129. case gyro_idx: /* gyro */
  130. get_common_features(&gyro_feature.common_property, report_id);
  131. gyro_feature.gyro_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
  132. gyro_feature.gyro_sensitivity_min = HID_DEFAULT_MIN_VALUE;
  133. gyro_feature.gyro_sensitivity_max = HID_DEFAULT_MAX_VALUE;
  134. memcpy(feature_report, &gyro_feature, sizeof(gyro_feature));
  135. report_size = sizeof(gyro_feature);
  136. break;
  137. case mag_idx: /* Magnetometer */
  138. get_common_features(&magno_feature.common_property, report_id);
  139. magno_feature.magno_headingchange_sensitivity = HID_DEFAULT_SENSITIVITY;
  140. magno_feature.heading_min = HID_DEFAULT_MIN_VALUE;
  141. magno_feature.heading_max = HID_DEFAULT_MAX_VALUE;
  142. magno_feature.flux_change_sensitivity = HID_DEFAULT_MIN_VALUE;
  143. magno_feature.flux_min = HID_DEFAULT_MIN_VALUE;
  144. magno_feature.flux_max = HID_DEFAULT_MAX_VALUE;
  145. memcpy(feature_report, &magno_feature, sizeof(magno_feature));
  146. report_size = sizeof(magno_feature);
  147. break;
  148. case als_idx: /* ambient light sensor */
  149. get_common_features(&als_feature.common_property, report_id);
  150. als_feature.als_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
  151. als_feature.als_sensitivity_min = HID_DEFAULT_MIN_VALUE;
  152. als_feature.als_sensitivity_max = HID_DEFAULT_MAX_VALUE;
  153. memcpy(feature_report, &als_feature, sizeof(als_feature));
  154. report_size = sizeof(als_feature);
  155. break;
  156. default:
  157. break;
  158. }
  159. return report_size;
  160. }
  161. static void get_common_inputs(struct common_input_property *common, int report_id)
  162. {
  163. common->report_id = report_id;
  164. common->sensor_state = HID_USAGE_SENSOR_STATE_READY_ENUM;
  165. common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
  166. }
  167. u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr)
  168. {
  169. struct accel3_input_report acc_input;
  170. struct gyro_input_report gyro_input;
  171. struct magno_input_report magno_input;
  172. struct als_input_report als_input;
  173. u8 report_size = 0;
  174. if (!sensor_virt_addr || !input_report)
  175. return report_size;
  176. switch (sensor_idx) {
  177. case accel_idx: /* accel */
  178. get_common_inputs(&acc_input.common_property, report_id);
  179. acc_input.in_accel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
  180. acc_input.in_accel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
  181. acc_input.in_accel_z_value = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
  182. memcpy(input_report, &acc_input, sizeof(acc_input));
  183. report_size = sizeof(acc_input);
  184. break;
  185. case gyro_idx: /* gyro */
  186. get_common_inputs(&gyro_input.common_property, report_id);
  187. gyro_input.in_angel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
  188. gyro_input.in_angel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
  189. gyro_input.in_angel_z_value = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
  190. memcpy(input_report, &gyro_input, sizeof(gyro_input));
  191. report_size = sizeof(gyro_input);
  192. break;
  193. case mag_idx: /* Magnetometer */
  194. get_common_inputs(&magno_input.common_property, report_id);
  195. magno_input.in_magno_x = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
  196. magno_input.in_magno_y = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
  197. magno_input.in_magno_z = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
  198. magno_input.in_magno_accuracy = (u16)sensor_virt_addr[3] / AMD_SFH_FW_MULTIPLIER;
  199. memcpy(input_report, &magno_input, sizeof(magno_input));
  200. report_size = sizeof(magno_input);
  201. break;
  202. case als_idx: /* Als */
  203. get_common_inputs(&als_input.common_property, report_id);
  204. als_input.illuminance_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
  205. report_size = sizeof(als_input);
  206. memcpy(input_report, &als_input, sizeof(als_input));
  207. break;
  208. default:
  209. break;
  210. }
  211. return report_size;
  212. }