Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  AMD SFH Report Descriptor generator
0004  *  Copyright 2020-2021 Advanced Micro Devices, Inc.
0005  *  Authors: Nehal Bakulchandra Shah <Nehal-Bakulchandra.Shah@amd.com>
0006  *       Sandeep Singh <sandeep.singh@amd.com>
0007  *       Basavaraj Natikar <Basavaraj.Natikar@amd.com>
0008  */
0009 
0010 #include <linux/kernel.h>
0011 #include <linux/string.h>
0012 #include <linux/slab.h>
0013 #include "amd_sfh_pcie.h"
0014 #include "amd_sfh_hid_desc.h"
0015 #include "amd_sfh_hid_report_desc.h"
0016 #include "amd_sfh_hid.h"
0017 
0018 #define AMD_SFH_FW_MULTIPLIER (1000)
0019 #define HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM   0x41
0020 #define HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM    0x51
0021 #define HID_DEFAULT_REPORT_INTERVAL             0x50
0022 #define HID_DEFAULT_MIN_VALUE                   0X7F
0023 #define HID_DEFAULT_MAX_VALUE                   0x80
0024 #define HID_DEFAULT_SENSITIVITY                 0x7F
0025 #define HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM  0x01
0026 /* state enums */
0027 #define HID_USAGE_SENSOR_STATE_READY_ENUM                             0x02
0028 #define HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM                      0x05
0029 #define HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM                      0x04
0030 #define ILLUMINANCE_MASK                    GENMASK(14, 0)
0031 
0032 static int get_report_descriptor(int sensor_idx, u8 *rep_desc)
0033 {
0034     switch (sensor_idx) {
0035     case accel_idx: /* accel */
0036         memset(rep_desc, 0, sizeof(accel3_report_descriptor));
0037         memcpy(rep_desc, accel3_report_descriptor,
0038                sizeof(accel3_report_descriptor));
0039         break;
0040     case gyro_idx: /* gyro */
0041         memset(rep_desc, 0, sizeof(gyro3_report_descriptor));
0042         memcpy(rep_desc, gyro3_report_descriptor,
0043                sizeof(gyro3_report_descriptor));
0044         break;
0045     case mag_idx: /* Magnetometer */
0046         memset(rep_desc, 0, sizeof(comp3_report_descriptor));
0047         memcpy(rep_desc, comp3_report_descriptor,
0048                sizeof(comp3_report_descriptor));
0049         break;
0050     case als_idx: /* ambient light sensor */
0051         memset(rep_desc, 0, sizeof(als_report_descriptor));
0052         memcpy(rep_desc, als_report_descriptor,
0053                sizeof(als_report_descriptor));
0054         break;
0055     case HPD_IDX: /* HPD sensor */
0056         memset(rep_desc, 0, sizeof(hpd_report_descriptor));
0057         memcpy(rep_desc, hpd_report_descriptor,
0058                sizeof(hpd_report_descriptor));
0059         break;
0060     default:
0061         break;
0062     }
0063     return 0;
0064 }
0065 
0066 static u32 get_descr_sz(int sensor_idx, int descriptor_name)
0067 {
0068     switch (sensor_idx) {
0069     case accel_idx:
0070         switch (descriptor_name) {
0071         case descr_size:
0072             return sizeof(accel3_report_descriptor);
0073         case input_size:
0074             return sizeof(struct accel3_input_report);
0075         case feature_size:
0076             return sizeof(struct accel3_feature_report);
0077         }
0078         break;
0079     case gyro_idx:
0080         switch (descriptor_name) {
0081         case descr_size:
0082             return sizeof(gyro3_report_descriptor);
0083         case input_size:
0084             return sizeof(struct gyro_input_report);
0085         case feature_size:
0086             return sizeof(struct gyro_feature_report);
0087         }
0088         break;
0089     case mag_idx:
0090         switch (descriptor_name) {
0091         case descr_size:
0092             return sizeof(comp3_report_descriptor);
0093         case input_size:
0094             return sizeof(struct magno_input_report);
0095         case feature_size:
0096             return sizeof(struct magno_feature_report);
0097         }
0098         break;
0099     case als_idx:
0100         switch (descriptor_name) {
0101         case descr_size:
0102             return sizeof(als_report_descriptor);
0103         case input_size:
0104             return sizeof(struct als_input_report);
0105         case feature_size:
0106             return sizeof(struct als_feature_report);
0107         }
0108         break;
0109     case HPD_IDX:
0110         switch (descriptor_name) {
0111         case descr_size:
0112             return sizeof(hpd_report_descriptor);
0113         case input_size:
0114             return sizeof(struct hpd_input_report);
0115         case feature_size:
0116             return sizeof(struct hpd_feature_report);
0117         }
0118         break;
0119 
0120     default:
0121         break;
0122     }
0123     return 0;
0124 }
0125 
0126 static void get_common_features(struct common_feature_property *common, int report_id)
0127 {
0128     common->report_id = report_id;
0129     common->connection_type = HID_USAGE_SENSOR_PROPERTY_CONNECTION_TYPE_PC_INTEGRATED_ENUM;
0130     common->report_state = HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM;
0131     common->power_state = HID_USAGE_SENSOR_PROP_POWER_STATE_D0_FULL_POWER_ENUM;
0132     common->sensor_state = HID_USAGE_SENSOR_STATE_INITIALIZING_ENUM;
0133     common->report_interval =  HID_DEFAULT_REPORT_INTERVAL;
0134 }
0135 
0136 static u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report)
0137 {
0138     struct accel3_feature_report acc_feature;
0139     struct gyro_feature_report gyro_feature;
0140     struct magno_feature_report magno_feature;
0141     struct hpd_feature_report hpd_feature;
0142     struct als_feature_report als_feature;
0143     u8 report_size = 0;
0144 
0145     if (!feature_report)
0146         return report_size;
0147 
0148     switch (sensor_idx) {
0149     case accel_idx: /* accel */
0150         get_common_features(&acc_feature.common_property, report_id);
0151         acc_feature.accel_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
0152         acc_feature.accel_sensitivity_min = HID_DEFAULT_MIN_VALUE;
0153         acc_feature.accel_sensitivity_max = HID_DEFAULT_MAX_VALUE;
0154         memcpy(feature_report, &acc_feature, sizeof(acc_feature));
0155         report_size = sizeof(acc_feature);
0156         break;
0157     case gyro_idx: /* gyro */
0158         get_common_features(&gyro_feature.common_property, report_id);
0159         gyro_feature.gyro_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
0160         gyro_feature.gyro_sensitivity_min = HID_DEFAULT_MIN_VALUE;
0161         gyro_feature.gyro_sensitivity_max = HID_DEFAULT_MAX_VALUE;
0162         memcpy(feature_report, &gyro_feature, sizeof(gyro_feature));
0163         report_size = sizeof(gyro_feature);
0164         break;
0165     case mag_idx: /* Magnetometer */
0166         get_common_features(&magno_feature.common_property, report_id);
0167         magno_feature.magno_headingchange_sensitivity = HID_DEFAULT_SENSITIVITY;
0168         magno_feature.heading_min = HID_DEFAULT_MIN_VALUE;
0169         magno_feature.heading_max = HID_DEFAULT_MAX_VALUE;
0170         magno_feature.flux_change_sensitivity = HID_DEFAULT_MIN_VALUE;
0171         magno_feature.flux_min = HID_DEFAULT_MIN_VALUE;
0172         magno_feature.flux_max = HID_DEFAULT_MAX_VALUE;
0173         memcpy(feature_report, &magno_feature, sizeof(magno_feature));
0174         report_size = sizeof(magno_feature);
0175         break;
0176     case als_idx:  /* ambient light sensor */
0177         get_common_features(&als_feature.common_property, report_id);
0178         als_feature.als_change_sesnitivity = HID_DEFAULT_SENSITIVITY;
0179         als_feature.als_sensitivity_min = HID_DEFAULT_MIN_VALUE;
0180         als_feature.als_sensitivity_max = HID_DEFAULT_MAX_VALUE;
0181         memcpy(feature_report, &als_feature, sizeof(als_feature));
0182         report_size = sizeof(als_feature);
0183         break;
0184     case HPD_IDX:  /* human presence detection sensor */
0185         get_common_features(&hpd_feature.common_property, report_id);
0186         memcpy(feature_report, &hpd_feature, sizeof(hpd_feature));
0187         report_size = sizeof(hpd_feature);
0188         break;
0189 
0190     default:
0191         break;
0192     }
0193     return report_size;
0194 }
0195 
0196 static void get_common_inputs(struct common_input_property *common, int report_id)
0197 {
0198     common->report_id = report_id;
0199     common->sensor_state = HID_USAGE_SENSOR_STATE_READY_ENUM;
0200     common->event_type = HID_USAGE_SENSOR_EVENT_DATA_UPDATED_ENUM;
0201 }
0202 
0203 static u8 get_input_report(u8 current_index, int sensor_idx, int report_id,
0204                struct amd_input_data *in_data)
0205 {
0206     struct amd_mp2_dev *privdata = container_of(in_data, struct amd_mp2_dev, in_data);
0207     u32 *sensor_virt_addr = in_data->sensor_virt_addr[current_index];
0208     u8 *input_report = in_data->input_report[current_index];
0209     u8 supported_input = privdata->mp2_acs & GENMASK(3, 0);
0210     struct magno_input_report magno_input;
0211     struct accel3_input_report acc_input;
0212     struct gyro_input_report gyro_input;
0213     struct hpd_input_report hpd_input;
0214     struct als_input_report als_input;
0215     struct hpd_status hpdstatus;
0216     u8 report_size = 0;
0217 
0218     if (!sensor_virt_addr || !input_report)
0219         return report_size;
0220 
0221     switch (sensor_idx) {
0222     case accel_idx: /* accel */
0223         get_common_inputs(&acc_input.common_property, report_id);
0224         acc_input.in_accel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
0225         acc_input.in_accel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
0226         acc_input.in_accel_z_value =  (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
0227         memcpy(input_report, &acc_input, sizeof(acc_input));
0228         report_size = sizeof(acc_input);
0229         break;
0230     case gyro_idx: /* gyro */
0231         get_common_inputs(&gyro_input.common_property, report_id);
0232         gyro_input.in_angel_x_value = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
0233         gyro_input.in_angel_y_value = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
0234         gyro_input.in_angel_z_value =  (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
0235         memcpy(input_report, &gyro_input, sizeof(gyro_input));
0236         report_size = sizeof(gyro_input);
0237         break;
0238     case mag_idx: /* Magnetometer */
0239         get_common_inputs(&magno_input.common_property, report_id);
0240         magno_input.in_magno_x = (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
0241         magno_input.in_magno_y = (int)sensor_virt_addr[1] / AMD_SFH_FW_MULTIPLIER;
0242         magno_input.in_magno_z = (int)sensor_virt_addr[2] / AMD_SFH_FW_MULTIPLIER;
0243         magno_input.in_magno_accuracy = (u16)sensor_virt_addr[3] / AMD_SFH_FW_MULTIPLIER;
0244         memcpy(input_report, &magno_input, sizeof(magno_input));
0245         report_size = sizeof(magno_input);
0246         break;
0247     case als_idx: /* Als */
0248         get_common_inputs(&als_input.common_property, report_id);
0249         /* For ALS ,V2 Platforms uses C2P_MSG5 register instead of DRAM access method */
0250         if (supported_input == V2_STATUS)
0251             als_input.illuminance_value =
0252                 readl(privdata->mmio + AMD_C2P_MSG(5)) & ILLUMINANCE_MASK;
0253         else
0254             als_input.illuminance_value =
0255                 (int)sensor_virt_addr[0] / AMD_SFH_FW_MULTIPLIER;
0256         report_size = sizeof(als_input);
0257         memcpy(input_report, &als_input, sizeof(als_input));
0258         break;
0259     case HPD_IDX: /* hpd */
0260         get_common_inputs(&hpd_input.common_property, report_id);
0261         hpdstatus.val = readl(privdata->mmio + AMD_C2P_MSG(4));
0262         hpd_input.human_presence = hpdstatus.shpd.human_presence_actual;
0263         report_size = sizeof(hpd_input);
0264         memcpy(input_report, &hpd_input, sizeof(hpd_input));
0265         break;
0266     default:
0267         break;
0268     }
0269     return report_size;
0270 }
0271 
0272 void amd_sfh_set_desc_ops(struct amd_mp2_ops *mp2_ops)
0273 {
0274     mp2_ops->get_rep_desc = get_report_descriptor;
0275     mp2_ops->get_feat_rep = get_feature_report;
0276     mp2_ops->get_in_rep = get_input_report;
0277     mp2_ops->get_desc_sz = get_descr_sz;
0278 }