0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/hid-sensor-ids.h>
0012
0013 #include "amd_sfh_interface.h"
0014 #include "../hid_descriptor/amd_sfh_hid_desc.h"
0015 #include "../hid_descriptor/amd_sfh_hid_report_desc.h"
0016
0017 #define SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM 0x41
0018 #define SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM 0x51
0019 #define HID_DEFAULT_REPORT_INTERVAL 0x50
0020 #define HID_DEFAULT_MIN_VALUE 0X7F
0021 #define HID_DEFAULT_MAX_VALUE 0x80
0022 #define HID_DEFAULT_SENSITIVITY 0x7F
0023 #define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM 0x01
0024
0025 #define HID_USAGE_SENSOR_STATE_READY_ENUM 0x02
0026 #define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM 0x05
0027 #define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM 0x04
0028
0029 static int get_report_desc(int sensor_idx, u8 *rep_desc)
0030 {
0031 switch (sensor_idx) {
0032 case ACCEL_IDX:
0033 memset(rep_desc, 0, sizeof(accel3_report_descriptor));
0034 memcpy(rep_desc, accel3_report_descriptor,
0035 sizeof(accel3_report_descriptor));
0036 break;
0037 case GYRO_IDX:
0038 memset(rep_desc, 0, sizeof(gyro3_report_descriptor));
0039 memcpy(rep_desc, gyro3_report_descriptor,
0040 sizeof(gyro3_report_descriptor));
0041 break;
0042 case MAG_IDX:
0043 memset(rep_desc, 0, sizeof(comp3_report_descriptor));
0044 memcpy(rep_desc, comp3_report_descriptor,
0045 sizeof(comp3_report_descriptor));
0046 break;
0047 case ALS_IDX:
0048 memset(rep_desc, 0, sizeof(als_report_descriptor));
0049 memcpy(rep_desc, als_report_descriptor,
0050 sizeof(als_report_descriptor));
0051 break;
0052 case HPD_IDX:
0053 memset(rep_desc, 0, sizeof(hpd_report_descriptor));
0054 memcpy(rep_desc, hpd_report_descriptor,
0055 sizeof(hpd_report_descriptor));
0056 break;
0057 }
0058 return 0;
0059 }
0060
0061 static void get_common_features(struct common_feature_property *common, int report_id)
0062 {
0063 common->report_id = report_id;
0064 common->connection_type = HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM;
0065 common->report_state = SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM;
0066 common->power_state = SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM;
0067 common->sensor_state = HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM;
0068 common->report_interval = HID_DEFAULT_REPORT_INTERVAL;
0069 }
0070
0071 static u8 get_feature_rep(int sensor_idx, int report_id, u8 *feature_report)
0072 {
0073 struct magno_feature_report magno_feature;
0074 struct accel3_feature_report acc_feature;
0075 struct gyro_feature_report gyro_feature;
0076 struct hpd_feature_report hpd_feature;
0077 struct als_feature_report als_feature;
0078 u8 report_size = 0;
0079
0080 if (!feature_report)
0081 return report_size;
0082
0083 switch (sensor_idx) {
0084 case ACCEL_IDX:
0085 get_common_features(&acc_feature.common_property, report_id);
0086 acc_feature.accel_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
0087 acc_feature.accel_sensitivity_min = HID_DEFAULT_MIN_VALUE;
0088 acc_feature.accel_sensitivity_max = HID_DEFAULT_MAX_VALUE;
0089 memcpy(feature_report, &acc_feature, sizeof(acc_feature));
0090 report_size = sizeof(acc_feature);
0091 break;
0092 case GYRO_IDX:
0093 get_common_features(&gyro_feature.common_property, report_id);
0094 gyro_feature.gyro_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
0095 gyro_feature.gyro_sensitivity_min = HID_DEFAULT_MIN_VALUE;
0096 gyro_feature.gyro_sensitivity_max = HID_DEFAULT_MAX_VALUE;
0097 memcpy(feature_report, &gyro_feature, sizeof(gyro_feature));
0098 report_size = sizeof(gyro_feature);
0099 break;
0100 case MAG_IDX:
0101 get_common_features(&magno_feature.common_property, report_id);
0102 magno_feature.magno_headingchange_sensitivity = HID_DEFAULT_SENSITIVITY;
0103 magno_feature.heading_min = HID_DEFAULT_MIN_VALUE;
0104 magno_feature.heading_max = HID_DEFAULT_MAX_VALUE;
0105 magno_feature.flux_change_sensitivity = HID_DEFAULT_MIN_VALUE;
0106 magno_feature.flux_min = HID_DEFAULT_MIN_VALUE;
0107 magno_feature.flux_max = HID_DEFAULT_MAX_VALUE;
0108 memcpy(feature_report, &magno_feature, sizeof(magno_feature));
0109 report_size = sizeof(magno_feature);
0110 break;
0111 case ALS_IDX:
0112 get_common_features(&als_feature.common_property, report_id);
0113 als_feature.als_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
0114 als_feature.als_sensitivity_min = HID_DEFAULT_MIN_VALUE;
0115 als_feature.als_sensitivity_max = HID_DEFAULT_MAX_VALUE;
0116 memcpy(feature_report, &als_feature, sizeof(als_feature));
0117 report_size = sizeof(als_feature);
0118 break;
0119 case HPD_IDX:
0120 get_common_features(&hpd_feature.common_property, report_id);
0121 memcpy(feature_report, &hpd_feature, sizeof(hpd_feature));
0122 report_size = sizeof(hpd_feature);
0123 break;
0124 }
0125 return report_size;
0126 }
0127
0128 static void get_common_inputs(struct common_input_property *common, int report_id)
0129 {
0130 common->report_id = report_id;
0131 common->sensor_state = HID_USAGE_SENSOR_STATE_READY_ENUM;
0132 common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
0133 }
0134
0135 static int float_to_int(u32 float32)
0136 {
0137 int fraction, shift, mantissa, sign, exp, zeropre;
0138
0139 mantissa = float32 & GENMASK(22, 0);
0140 sign = (float32 & BIT(31)) ? -1 : 1;
0141 exp = (float32 & ~BIT(31)) >> 23;
0142
0143 if (!exp && !mantissa)
0144 return 0;
0145
0146 exp -= 127;
0147 if (exp < 0) {
0148 exp = -exp;
0149 zeropre = (((BIT(23) + mantissa) * 100) >> 23) >> exp;
0150 return zeropre >= 50 ? sign : 0;
0151 }
0152
0153 shift = 23 - exp;
0154 float32 = BIT(exp) + (mantissa >> shift);
0155 fraction = mantissa & GENMASK(shift - 1, 0);
0156
0157 return (((fraction * 100) >> shift) >= 50) ? sign * (float32 + 1) : sign * float32;
0158 }
0159
0160 static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id,
0161 struct amd_input_data *in_data)
0162 {
0163 struct amd_mp2_dev *mp2 = container_of(in_data, struct amd_mp2_dev, in_data);
0164 u8 *input_report = in_data->input_report[current_index];
0165 struct magno_input_report magno_input;
0166 struct accel3_input_report acc_input;
0167 struct gyro_input_report gyro_input;
0168 struct als_input_report als_input;
0169 struct hpd_input_report hpd_input;
0170 struct sfh_accel_data accel_data;
0171 struct sfh_gyro_data gyro_data;
0172 struct sfh_mag_data mag_data;
0173 struct sfh_als_data als_data;
0174 struct hpd_status hpdstatus;
0175 void __iomem *sensoraddr;
0176 u8 report_size = 0;
0177
0178 if (!input_report)
0179 return report_size;
0180
0181 switch (sensor_idx) {
0182 case ACCEL_IDX:
0183 sensoraddr = mp2->vsbase + (ACCEL_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
0184 OFFSET_SENSOR_DATA_DEFAULT;
0185 memcpy_fromio(&accel_data, sensoraddr, sizeof(struct sfh_accel_data));
0186 get_common_inputs(&acc_input.common_property, report_id);
0187 acc_input.in_accel_x_value = float_to_int(accel_data.acceldata.x) / 100;
0188 acc_input.in_accel_y_value = float_to_int(accel_data.acceldata.y) / 100;
0189 acc_input.in_accel_z_value = float_to_int(accel_data.acceldata.z) / 100;
0190 memcpy(input_report, &acc_input, sizeof(acc_input));
0191 report_size = sizeof(acc_input);
0192 break;
0193 case GYRO_IDX:
0194 sensoraddr = mp2->vsbase + (GYRO_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
0195 OFFSET_SENSOR_DATA_DEFAULT;
0196 memcpy_fromio(&gyro_data, sensoraddr, sizeof(struct sfh_gyro_data));
0197 get_common_inputs(&gyro_input.common_property, report_id);
0198 gyro_input.in_angel_x_value = float_to_int(gyro_data.gyrodata.x) / 1000;
0199 gyro_input.in_angel_y_value = float_to_int(gyro_data.gyrodata.y) / 1000;
0200 gyro_input.in_angel_z_value = float_to_int(gyro_data.gyrodata.z) / 1000;
0201 memcpy(input_report, &gyro_input, sizeof(gyro_input));
0202 report_size = sizeof(gyro_input);
0203 break;
0204 case MAG_IDX:
0205 sensoraddr = mp2->vsbase + (MAG_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
0206 OFFSET_SENSOR_DATA_DEFAULT;
0207 memcpy_fromio(&mag_data, sensoraddr, sizeof(struct sfh_mag_data));
0208 get_common_inputs(&magno_input.common_property, report_id);
0209 magno_input.in_magno_x = float_to_int(mag_data.magdata.x) / 100;
0210 magno_input.in_magno_y = float_to_int(mag_data.magdata.y) / 100;
0211 magno_input.in_magno_z = float_to_int(mag_data.magdata.z) / 100;
0212 magno_input.in_magno_accuracy = mag_data.accuracy / 100;
0213 memcpy(input_report, &magno_input, sizeof(magno_input));
0214 report_size = sizeof(magno_input);
0215 break;
0216 case ALS_IDX:
0217 sensoraddr = mp2->vsbase + (ALS_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) +
0218 OFFSET_SENSOR_DATA_DEFAULT;
0219 memcpy_fromio(&als_data, sensoraddr, sizeof(struct sfh_als_data));
0220 get_common_inputs(&als_input.common_property, report_id);
0221 als_input.illuminance_value = als_data.lux;
0222 report_size = sizeof(als_input);
0223 memcpy(input_report, &als_input, sizeof(als_input));
0224 break;
0225 case HPD_IDX:
0226 get_common_inputs(&hpd_input.common_property, report_id);
0227 hpdstatus.val = readl(mp2->mmio + AMD_C2P_MSG(4));
0228 hpd_input.human_presence = hpdstatus.shpd.presence;
0229 report_size = sizeof(hpd_input);
0230 memcpy(input_report, &hpd_input, sizeof(hpd_input));
0231 break;
0232 }
0233 return report_size;
0234 }
0235
0236 static u32 get_desc_size(int sensor_idx, int descriptor_name)
0237 {
0238 switch (sensor_idx) {
0239 case ACCEL_IDX:
0240 switch (descriptor_name) {
0241 case descr_size:
0242 return sizeof(accel3_report_descriptor);
0243 case input_size:
0244 return sizeof(struct accel3_input_report);
0245 case feature_size:
0246 return sizeof(struct accel3_feature_report);
0247 }
0248 break;
0249 case GYRO_IDX:
0250 switch (descriptor_name) {
0251 case descr_size:
0252 return sizeof(gyro3_report_descriptor);
0253 case input_size:
0254 return sizeof(struct gyro_input_report);
0255 case feature_size:
0256 return sizeof(struct gyro_feature_report);
0257 }
0258 break;
0259 case MAG_IDX:
0260 switch (descriptor_name) {
0261 case descr_size:
0262 return sizeof(comp3_report_descriptor);
0263 case input_size:
0264 return sizeof(struct magno_input_report);
0265 case feature_size:
0266 return sizeof(struct magno_feature_report);
0267 }
0268 break;
0269 case ALS_IDX:
0270 switch (descriptor_name) {
0271 case descr_size:
0272 return sizeof(als_report_descriptor);
0273 case input_size:
0274 return sizeof(struct als_input_report);
0275 case feature_size:
0276 return sizeof(struct als_feature_report);
0277 }
0278 break;
0279 case HPD_IDX:
0280 switch (descriptor_name) {
0281 case descr_size:
0282 return sizeof(hpd_report_descriptor);
0283 case input_size:
0284 return sizeof(struct hpd_input_report);
0285 case feature_size:
0286 return sizeof(struct hpd_feature_report);
0287 }
0288 break;
0289 }
0290
0291 return 0;
0292 }
0293
0294 void amd_sfh1_1_set_desc_ops(struct amd_mp2_ops *mp2_ops)
0295 {
0296 mp2_ops->get_rep_desc = get_report_desc;
0297 mp2_ops->get_feat_rep = get_feature_rep;
0298 mp2_ops->get_desc_sz = get_desc_size;
0299 mp2_ops->get_in_rep = get_input_rep;
0300 }