1 // SPDX-License-Identifier: GPL-2.0-or-later
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>
9 #include <linux/kernel.h>
10 #include <linux/string.h>
11 #include <linux/slab.h>
12 #include "amd_sfh_pcie.h"
13 #include "amd_sfh_hid_desc.h"
14 #include "amd_sfh_hid_report_desc.h"
16 #define AMD_SFH_FW_MULTIPLIER (1000)
17 #define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41
18 #define HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM 0x51
19 #define HID_DEFAULT_REPORT_INTERVAL 0x50
20 #define HID_DEFAULT_MIN_VALUE 0X7F
21 #define HID_DEFAULT_MAX_VALUE 0x80
22 #define HID_DEFAULT_SENSITIVITY 0x7F
23 #define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM 0x01
25 #define HID_USAGE_SENSOR_STATE_READY_ENUM 0x02
26 #define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM 0x05
27 #define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM 0x04
29 int get_report_descriptor(int sensor_idx
, u8
*rep_desc
)
32 case accel_idx
: /* accel */
33 memset(rep_desc
, 0, sizeof(accel3_report_descriptor
));
34 memcpy(rep_desc
, accel3_report_descriptor
,
35 sizeof(accel3_report_descriptor
));
37 case gyro_idx
: /* gyro */
38 memset(rep_desc
, 0, sizeof(gyro3_report_descriptor
));
39 memcpy(rep_desc
, gyro3_report_descriptor
,
40 sizeof(gyro3_report_descriptor
));
42 case mag_idx
: /* Magnetometer */
43 memset(rep_desc
, 0, sizeof(comp3_report_descriptor
));
44 memcpy(rep_desc
, comp3_report_descriptor
,
45 sizeof(comp3_report_descriptor
));
47 case als_idx
: /* ambient light sensor */
48 memset(rep_desc
, 0, sizeof(als_report_descriptor
));
49 memcpy(rep_desc
, als_report_descriptor
,
50 sizeof(als_report_descriptor
));
58 u32
get_descr_sz(int sensor_idx
, int descriptor_name
)
62 switch (descriptor_name
) {
64 return sizeof(accel3_report_descriptor
);
66 return sizeof(struct accel3_input_report
);
68 return sizeof(struct accel3_feature_report
);
72 switch (descriptor_name
) {
74 return sizeof(gyro3_report_descriptor
);
76 return sizeof(struct gyro_input_report
);
78 return sizeof(struct gyro_feature_report
);
82 switch (descriptor_name
) {
84 return sizeof(comp3_report_descriptor
);
86 return sizeof(struct magno_input_report
);
88 return sizeof(struct magno_feature_report
);
92 switch (descriptor_name
) {
94 return sizeof(als_report_descriptor
);
96 return sizeof(struct als_input_report
);
98 return sizeof(struct als_feature_report
);
107 static void get_common_features(struct common_feature_property
*common
, int report_id
)
109 common
->report_id
= report_id
;
110 common
->connection_type
= HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM
;
111 common
->report_state
= HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM
;
112 common
->power_state
= HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM
;
113 common
->sensor_state
= HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM
;
114 common
->report_interval
= HID_DEFAULT_REPORT_INTERVAL
;
117 u8
get_feature_report(int sensor_idx
, int report_id
, u8
*feature_report
)
119 struct accel3_feature_report acc_feature
;
120 struct gyro_feature_report gyro_feature
;
121 struct magno_feature_report magno_feature
;
122 struct als_feature_report als_feature
;
128 switch (sensor_idx
) {
129 case accel_idx
: /* accel */
130 get_common_features(&acc_feature
.common_property
, report_id
);
131 acc_feature
.accel_change_sesnitivity
= HID_DEFAULT_SENSITIVITY
;
132 acc_feature
.accel_sensitivity_min
= HID_DEFAULT_MIN_VALUE
;
133 acc_feature
.accel_sensitivity_max
= HID_DEFAULT_MAX_VALUE
;
134 memcpy(feature_report
, &acc_feature
, sizeof(acc_feature
));
135 report_size
= sizeof(acc_feature
);
137 case gyro_idx
: /* gyro */
138 get_common_features(&gyro_feature
.common_property
, report_id
);
139 gyro_feature
.gyro_change_sesnitivity
= HID_DEFAULT_SENSITIVITY
;
140 gyro_feature
.gyro_sensitivity_min
= HID_DEFAULT_MIN_VALUE
;
141 gyro_feature
.gyro_sensitivity_max
= HID_DEFAULT_MAX_VALUE
;
142 memcpy(feature_report
, &gyro_feature
, sizeof(gyro_feature
));
143 report_size
= sizeof(gyro_feature
);
145 case mag_idx
: /* Magnetometer */
146 get_common_features(&magno_feature
.common_property
, report_id
);
147 magno_feature
.magno_headingchange_sensitivity
= HID_DEFAULT_SENSITIVITY
;
148 magno_feature
.heading_min
= HID_DEFAULT_MIN_VALUE
;
149 magno_feature
.heading_max
= HID_DEFAULT_MAX_VALUE
;
150 magno_feature
.flux_change_sensitivity
= HID_DEFAULT_MIN_VALUE
;
151 magno_feature
.flux_min
= HID_DEFAULT_MIN_VALUE
;
152 magno_feature
.flux_max
= HID_DEFAULT_MAX_VALUE
;
153 memcpy(feature_report
, &magno_feature
, sizeof(magno_feature
));
154 report_size
= sizeof(magno_feature
);
156 case als_idx
: /* ambient light sensor */
157 get_common_features(&als_feature
.common_property
, report_id
);
158 als_feature
.als_change_sesnitivity
= HID_DEFAULT_SENSITIVITY
;
159 als_feature
.als_sensitivity_min
= HID_DEFAULT_MIN_VALUE
;
160 als_feature
.als_sensitivity_max
= HID_DEFAULT_MAX_VALUE
;
161 memcpy(feature_report
, &als_feature
, sizeof(als_feature
));
162 report_size
= sizeof(als_feature
);
170 static void get_common_inputs(struct common_input_property
*common
, int report_id
)
172 common
->report_id
= report_id
;
173 common
->sensor_state
= HID_USAGE_SENSOR_STATE_READY_ENUM
;
174 common
->event_type
= HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM
;
177 u8
get_input_report(int sensor_idx
, int report_id
, u8
*input_report
, u32
*sensor_virt_addr
)
179 struct accel3_input_report acc_input
;
180 struct gyro_input_report gyro_input
;
181 struct magno_input_report magno_input
;
182 struct als_input_report als_input
;
185 if (!sensor_virt_addr
|| !input_report
)
188 switch (sensor_idx
) {
189 case accel_idx
: /* accel */
190 get_common_inputs(&acc_input
.common_property
, report_id
);
191 acc_input
.in_accel_x_value
= (int)sensor_virt_addr
[0] / AMD_SFH_FW_MULTIPLIER
;
192 acc_input
.in_accel_y_value
= (int)sensor_virt_addr
[1] / AMD_SFH_FW_MULTIPLIER
;
193 acc_input
.in_accel_z_value
= (int)sensor_virt_addr
[2] / AMD_SFH_FW_MULTIPLIER
;
194 memcpy(input_report
, &acc_input
, sizeof(acc_input
));
195 report_size
= sizeof(acc_input
);
197 case gyro_idx
: /* gyro */
198 get_common_inputs(&gyro_input
.common_property
, report_id
);
199 gyro_input
.in_angel_x_value
= (int)sensor_virt_addr
[0] / AMD_SFH_FW_MULTIPLIER
;
200 gyro_input
.in_angel_y_value
= (int)sensor_virt_addr
[1] / AMD_SFH_FW_MULTIPLIER
;
201 gyro_input
.in_angel_z_value
= (int)sensor_virt_addr
[2] / AMD_SFH_FW_MULTIPLIER
;
202 memcpy(input_report
, &gyro_input
, sizeof(gyro_input
));
203 report_size
= sizeof(gyro_input
);
205 case mag_idx
: /* Magnetometer */
206 get_common_inputs(&magno_input
.common_property
, report_id
);
207 magno_input
.in_magno_x
= (int)sensor_virt_addr
[0] / AMD_SFH_FW_MULTIPLIER
;
208 magno_input
.in_magno_y
= (int)sensor_virt_addr
[1] / AMD_SFH_FW_MULTIPLIER
;
209 magno_input
.in_magno_z
= (int)sensor_virt_addr
[2] / AMD_SFH_FW_MULTIPLIER
;
210 magno_input
.in_magno_accuracy
= (u16
)sensor_virt_addr
[3] / AMD_SFH_FW_MULTIPLIER
;
211 memcpy(input_report
, &magno_input
, sizeof(magno_input
));
212 report_size
= sizeof(magno_input
);
214 case als_idx
: /* Als */
215 get_common_inputs(&als_input
.common_property
, report_id
);
216 als_input
.illuminance_value
= (int)sensor_virt_addr
[0] / AMD_SFH_FW_MULTIPLIER
;
217 report_size
= sizeof(als_input
);
218 memcpy(input_report
, &als_input
, sizeof(als_input
));