1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 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> 7 */ 8 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" 15 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 24 /* state enums */ 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 28 29 int get_report_descriptor(int sensor_idx, u8 *rep_desc) 30 { 31 switch (sensor_idx) { 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)); 36 break; 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)); 41 break; 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)); 46 break; 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)); 51 break; 52 default: 53 break; 54 } 55 return 0; 56 } 57 58 u32 get_descr_sz(int sensor_idx, int descriptor_name) 59 { 60 switch (sensor_idx) { 61 case accel_idx: 62 switch (descriptor_name) { 63 case descr_size: 64 return sizeof(accel3_report_descriptor); 65 case input_size: 66 return sizeof(struct accel3_input_report); 67 case feature_size: 68 return sizeof(struct accel3_feature_report); 69 } 70 break; 71 case gyro_idx: 72 switch (descriptor_name) { 73 case descr_size: 74 return sizeof(gyro3_report_descriptor); 75 case input_size: 76 return sizeof(struct gyro_input_report); 77 case feature_size: 78 return sizeof(struct gyro_feature_report); 79 } 80 break; 81 case mag_idx: 82 switch (descriptor_name) { 83 case descr_size: 84 return sizeof(comp3_report_descriptor); 85 case input_size: 86 return sizeof(struct magno_input_report); 87 case feature_size: 88 return sizeof(struct magno_feature_report); 89 } 90 break; 91 case als_idx: 92 switch (descriptor_name) { 93 case descr_size: 94 return sizeof(als_report_descriptor); 95 case input_size: 96 return sizeof(struct als_input_report); 97 case feature_size: 98 return sizeof(struct als_feature_report); 99 } 100 break; 101 default: 102 break; 103 } 104 return 0; 105 } 106 107 static void get_common_features(struct common_feature_property *common, int report_id) 108 { 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; 115 } 116 117 u8 get_feature_report(int sensor_idx, int report_id, u8 *feature_report) 118 { 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; 123 u8 report_size = 0; 124 125 if (!feature_report) 126 return report_size; 127 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); 136 break; 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); 144 break; 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); 155 break; 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); 163 break; 164 default: 165 break; 166 } 167 return report_size; 168 } 169 170 static void get_common_inputs(struct common_input_property *common, int report_id) 171 { 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; 175 } 176 177 u8 get_input_report(int sensor_idx, int report_id, u8 *input_report, u32 *sensor_virt_addr) 178 { 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; 183 u8 report_size = 0; 184 185 if (!sensor_virt_addr || !input_report) 186 return report_size; 187 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); 196 break; 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); 204 break; 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); 213 break; 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)); 219 break; 220 default: 221 break; 222 } 223 return report_size; 224 } 225