Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * AMD MP2 1.1 descriptor interfaces
0004  *
0005  * Copyright (c) 2022, Advanced Micro Devices, Inc.
0006  * All Rights Reserved.
0007  *
0008  * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
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 /* state enums */
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: /* accelerometer */
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: /* gyroscope */
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: /* magnetometer */
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: /* ambient light sensor */
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: /* HPD sensor */
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: /* accelerometer */
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: /* gyroscope */
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: /* magnetometer */
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:  /* ambient light sensor */
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:  /* human presence detection sensor */
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: /* accelerometer */
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: /* gyroscope */
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: /* magnetometer */
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 }