ef1f9be8b89383ee16d61b298545aa52d740ceba
[releases.git] / amd_sfh_hid_desc.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  AMD SFH Report Descriptor generator
4  *  Copyright 2020-2021 Advanced Micro Devices, Inc.
5  *  Authors: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@amd.com>
6  *           Sandeep Singh <sandeep.singh@amd.com>
7  *           Basavaraj Natikar <Basavaraj.Natikar@amd.com>
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/string.h>
12 #include <linux/slab.h>
13 #include "amd_sfh_pcie.h"
14 #include "amd_sfh_hid_desc.h"
15 #include "amd_sfh_hid_report_desc.h"
16 #include "amd_sfh_hid.h"
17
18 #define AMD_SFH_FW_MULTIPLIER (1000)
19 #define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM   0x41
20 #define HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM    0x51
21 #define HID_DEFAULT_REPORT_INTERVAL                             0x50
22 #define HID_DEFAULT_MIN_VALUE                                   0X7F
23 #define HID_DEFAULT_MAX_VALUE                                   0x80
24 #define HID_DEFAULT_SENSITIVITY                                 0x7F
25 #define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM  0x01
26 /* state enums */
27 #define HID_USAGE_SENSOR_STATE_READY_ENUM                             0x02
28 #define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM                      0x05
29 #define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM                      0x04
30 #define ILLUMINANCE_MASK                                        GENMASK(14, 0)
31
32 static int get_report_descriptor(int sensor_idx, u8 *rep_desc)
33 {
34         switch (sensor_idx) {
35         case accel_idx: /* accel */
36                 memset(rep_desc, 0, sizeof(accel3_report_descriptor));
37                 memcpy(rep_desc, accel3_report_descriptor,
38                        sizeof(accel3_report_descriptor));
39                 break;
40         case gyro_idx: /* gyro */
41                 memset(rep_desc, 0, sizeof(gyro3_report_descriptor));
42                 memcpy(rep_desc, gyro3_report_descriptor,
43                        sizeof(gyro3_report_descriptor));
44                 break;
45         case mag_idx: /* Magnetometer */
46                 memset(rep_desc, 0, sizeof(comp3_report_descriptor));
47                 memcpy(rep_desc, comp3_report_descriptor,
48                        sizeof(comp3_report_descriptor));
49                 break;
50         case als_idx: /* ambient light sensor */
51         case ACS_IDX: /* ambient color sensor */
52                 memset(rep_desc, 0, sizeof(als_report_descriptor));
53                 memcpy(rep_desc, als_report_descriptor,
54                        sizeof(als_report_descriptor));
55                 break;
56         case HPD_IDX: /* HPD sensor */
57                 memset(rep_desc, 0, sizeof(hpd_report_descriptor));
58                 memcpy(rep_desc, hpd_report_descriptor,
59                        sizeof(hpd_report_descriptor));
60                 break;
61         default:
62                 break;
63         }
64         return 0;
65 }
66
67 static u32 get_descr_sz(int sensor_idx, int descriptor_name)
68 {
69         switch (sensor_idx) {
70         case accel_idx:
71                 switch (descriptor_name) {
72                 case descr_size:
73                         return sizeof(accel3_report_descriptor);
74                 case input_size:
75                         return sizeof(struct accel3_input_report);
76                 case feature_size:
77                         return sizeof(struct accel3_feature_report);
78                 }
79                 break;
80         case gyro_idx:
81                 switch (descriptor_name) {
82                 case descr_size:
83                         return sizeof(gyro3_report_descriptor);
84                 case input_size:
85                         return sizeof(struct gyro_input_report);
86                 case feature_size:
87                         return sizeof(struct gyro_feature_report);
88                 }
89                 break;
90         case mag_idx:
91                 switch (descriptor_name) {
92                 case descr_size:
93                         return sizeof(comp3_report_descriptor);
94                 case input_size:
95                         return sizeof(struct magno_input_report);
96                 case feature_size:
97                         return sizeof(struct magno_feature_report);
98                 }
99                 break;
100         case als_idx:
101         case ACS_IDX: /* ambient color sensor */
102                 switch (descriptor_name) {
103                 case descr_size:
104                         return sizeof(als_report_descriptor);
105                 case input_size:
106                         return sizeof(struct als_input_report);
107                 case feature_size:
108                         return sizeof(struct als_feature_report);
109                 }
110                 break;
111         case HPD_IDX:
112                 switch (descriptor_name) {
113                 case descr_size:
114                         return sizeof(hpd_report_descriptor);
115                 case input_size:
116                         return sizeof(struct hpd_input_report);
117                 case feature_size:
118                         return sizeof(struct hpd_feature_report);
119                 }
120                 break;
121
122         default:
123                 break;
124         }
125         return 0;
126 }
127
128 static void get_common_features(struct common_feature_property *common, int report_id)
129 {
130         common->report_id = report_id;
131         common->connection_type = HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM;
132         common->report_state = HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM;
133         common->power_state = HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM;
134         common->sensor_state = HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM;
135         common->report_interval =  HID_DEFAULT_REPORT_INTERVAL;
136 }
137
138 static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
139 {
140         struct accel3_feature_report acc_feature;
141         struct gyro_feature_report gyro_feature;
142         struct magno_feature_report magno_feature;
143         struct hpd_feature_report hpd_feature;
144         struct als_feature_report als_feature;
145         u8 report_size = 0;
146
147         if (!feature_report)
148                 return report_size;
149
150         switch (sensor_idx) {
151         case accel_idx: /* accel */
152                 get_common_features(&acc_feature.common_property, report_id);
153                 acc_feature.accel_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
154                 acc_feature.accel_sensitivity_min = HID_DEFAULT_MIN_VALUE;
155                 acc_feature.accel_sensitivity_max = HID_DEFAULT_MAX_VALUE;
156                 memcpy(feature_report, &acc_feature, sizeof(acc_feature));
157                 report_size = sizeof(acc_feature);
158                 break;
159         case gyro_idx: /* gyro */
160                 get_common_features(&gyro_feature.common_property, report_id);
161                 gyro_feature.gyro_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
162                 gyro_feature.gyro_sensitivity_min = HID_DEFAULT_MIN_VALUE;
163                 gyro_feature.gyro_sensitivity_max = HID_DEFAULT_MAX_VALUE;
164                 memcpy(feature_report, &gyro_feature, sizeof(gyro_feature));
165                 report_size = sizeof(gyro_feature);
166                 break;
167         case mag_idx: /* Magnetometer */
168                 get_common_features(&magno_feature.common_property, report_id);
169                 magno_feature.magno_headingchange_sensitivity = HID_DEFAULT_SENSITIVITY;
170                 magno_feature.heading_min = HID_DEFAULT_MIN_VALUE;
171                 magno_feature.heading_max = HID_DEFAULT_MAX_VALUE;
172                 magno_feature.flux_change_sensitivity = HID_DEFAULT_MIN_VALUE;
173                 magno_feature.flux_min = HID_DEFAULT_MIN_VALUE;
174                 magno_feature.flux_max = HID_DEFAULT_MAX_VALUE;
175                 memcpy(feature_report, &magno_feature, sizeof(magno_feature));
176                 report_size = sizeof(magno_feature);
177                 break;
178         case als_idx:  /* ambient light sensor */
179         case ACS_IDX: /* ambient color sensor */
180                 get_common_features(&als_feature.common_property, report_id);
181                 als_feature.als_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
182                 als_feature.als_sensitivity_min = HID_DEFAULT_MIN_VALUE;
183                 als_feature.als_sensitivity_max = HID_DEFAULT_MAX_VALUE;
184                 memcpy(feature_report, &als_feature, sizeof(als_feature));
185                 report_size = sizeof(als_feature);
186                 break;
187         case HPD_IDX:  /* human presence detection sensor */
188                 get_common_features(&hpd_feature.common_property, report_id);
189                 memcpy(feature_report, &hpd_feature, sizeof(hpd_feature));
190                 report_size = sizeof(hpd_feature);
191                 break;
192
193         default:
194                 break;
195         }
196         return report_size;
197 }
198
199 static void get_common_inputs(struct common_input_property *common, int report_id)
200 {
201         common->report_id = report_id;
202         common->sensor_state = HID_USAGE_SENSOR_STATE_READY_ENUM;
203         common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
204 }
205
206 static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
207                            struct amd_input_data *in_data)
208 {
209         struct amd_mp2_dev *privdata = container_of(in_data, struct amd_mp2_dev, in_data);
210         u32 *sensor_virt_addr = in_data->sensor_virt_addr[current_index];
211         u8 *input_report = in_data->input_report[current_index];
212         u8 supported_input = privdata->mp2_acs & GENMASK(3, 0);
213         struct magno_input_report magno_input;
214         struct accel3_input_report acc_input;
215         struct gyro_input_report gyro_input;
216         struct hpd_input_report hpd_input;
217         struct als_input_report als_input;
218         struct hpd_status hpdstatus;
219         u8 report_size = 0;
220
221         if (!sensor_virt_addr || !input_report)
222                 return report_size;
223
224         switch (sensor_idx) {
225         case accel_idx: /* accel */
226                 get_common_inputs(&acc_input.common_property, report_id);
227                 acc_input.in_accel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
228                 acc_input.in_accel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
229                 acc_input.in_accel_z_value =  (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
230                 memcpy(input_report, &acc_input, sizeof(acc_input));
231                 report_size = sizeof(acc_input);
232                 break;
233         case gyro_idx: /* gyro */
234                 get_common_inputs(&gyro_input.common_property, report_id);
235                 gyro_input.in_angel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
236                 gyro_input.in_angel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
237                 gyro_input.in_angel_z_value =  (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
238                 memcpy(input_report, &gyro_input, sizeof(gyro_input));
239                 report_size = sizeof(gyro_input);
240                 break;
241         case mag_idx: /* Magnetometer */
242                 get_common_inputs(&magno_input.common_property, report_id);
243                 magno_input.in_magno_x = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
244                 magno_input.in_magno_y = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
245                 magno_input.in_magno_z = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
246                 magno_input.in_magno_accuracy = (u16)sensor_virt_addr[3] / AMD_SFH_FW_MULTIPLIER;
247                 memcpy(input_report, &magno_input, sizeof(magno_input));
248                 report_size = sizeof(magno_input);
249                 break;
250         case als_idx: /* Als */
251         case ACS_IDX: /* ambient color sensor */
252                 get_common_inputs(&als_input.common_property, report_id);
253                 /* For ALS ,V2 Platforms uses C2P_MSG5 register instead of DRAM access method */
254                 if (supported_input == V2_STATUS)
255                         als_input.illuminance_value =
256                                 readl(privdata->mmio + AMD_C2P_MSG(5)) & ILLUMINANCE_MASK;
257                 else
258                         als_input.illuminance_value =
259                                 (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
260
261                 if (sensor_idx == ACS_IDX) {
262                         als_input.light_color_temp = sensor_virt_addr[1];
263                         als_input.chromaticity_x_value = sensor_virt_addr[2];
264                         als_input.chromaticity_y_value = sensor_virt_addr[3];
265                 }
266
267                 report_size = sizeof(als_input);
268                 memcpy(input_report, &als_input, sizeof(als_input));
269                 break;
270         case HPD_IDX: /* hpd */
271                 get_common_inputs(&hpd_input.common_property, report_id);
272                 hpdstatus.val = readl(privdata->mmio + AMD_C2P_MSG(4));
273                 hpd_input.human_presence = hpdstatus.shpd.human_presence_actual;
274                 report_size = sizeof(hpd_input);
275                 memcpy(input_report, &hpd_input, sizeof(hpd_input));
276                 break;
277         default:
278                 break;
279         }
280         return report_size;
281 }
282
283 void amd_sfh_set_desc_ops(struct amd_mp2_ops *mp2_ops)
284 {
285         mp2_ops->get_rep_desc = get_report_descriptor;
286         mp2_ops->get_feat_rep = get_feature_report;
287         mp2_ops->get_in_rep = get_input_report;
288         mp2_ops->get_desc_sz = get_descr_sz;
289 }