1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * HID Sensors Driver 4 * Copyright (c) 2014, Intel Corporation. 5 */ 6 7 #include <linux/device.h> 8 #include <linux/platform_device.h> 9 #include <linux/module.h> 10 #include <linux/interrupt.h> 11 #include <linux/irq.h> 12 #include <linux/slab.h> 13 #include <linux/hid-sensor-hub.h> 14 #include <linux/iio/iio.h> 15 #include <linux/iio/sysfs.h> 16 #include <linux/iio/buffer.h> 17 #include "../common/hid-sensors/hid-sensor-trigger.h" 18 19 struct dev_rot_state { 20 struct hid_sensor_hub_callbacks callbacks; 21 struct hid_sensor_common common_attributes; 22 struct hid_sensor_hub_attribute_info quaternion; 23 struct { 24 s32 sampled_vals[4] __aligned(16); 25 u64 timestamp __aligned(8); 26 } scan; 27 int scale_pre_decml; 28 int scale_post_decml; 29 int scale_precision; 30 int value_offset; 31 s64 timestamp; 32 }; 33 34 /* Channel definitions */ 35 static const struct iio_chan_spec dev_rot_channels[] = { 36 { 37 .type = IIO_ROT, 38 .modified = 1, 39 .channel2 = IIO_MOD_QUATERNION, 40 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 41 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | 42 BIT(IIO_CHAN_INFO_OFFSET) | 43 BIT(IIO_CHAN_INFO_SCALE) | 44 BIT(IIO_CHAN_INFO_HYSTERESIS), 45 .scan_index = 0 46 }, 47 IIO_CHAN_SOFT_TIMESTAMP(1) 48 }; 49 50 /* Adjust channel real bits based on report descriptor */ 51 static void dev_rot_adjust_channel_bit_mask(struct iio_chan_spec *chan, 52 int size) 53 { 54 chan->scan_type.sign = 's'; 55 /* Real storage bits will change based on the report desc. */ 56 chan->scan_type.realbits = size * 8; 57 /* Maximum size of a sample to capture is u32 */ 58 chan->scan_type.storagebits = sizeof(u32) * 8; 59 chan->scan_type.repeat = 4; 60 } 61 62 /* Channel read_raw handler */ 63 static int dev_rot_read_raw(struct iio_dev *indio_dev, 64 struct iio_chan_spec const *chan, 65 int size, int *vals, int *val_len, 66 long mask) 67 { 68 struct dev_rot_state *rot_state = iio_priv(indio_dev); 69 int ret_type; 70 int i; 71 72 vals[0] = 0; 73 vals[1] = 0; 74 75 switch (mask) { 76 case IIO_CHAN_INFO_RAW: 77 if (size >= 4) { 78 for (i = 0; i < 4; ++i) 79 vals[i] = rot_state->scan.sampled_vals[i]; 80 ret_type = IIO_VAL_INT_MULTIPLE; 81 *val_len = 4; 82 } else 83 ret_type = -EINVAL; 84 break; 85 case IIO_CHAN_INFO_SCALE: 86 vals[0] = rot_state->scale_pre_decml; 87 vals[1] = rot_state->scale_post_decml; 88 return rot_state->scale_precision; 89 90 case IIO_CHAN_INFO_OFFSET: 91 *vals = rot_state->value_offset; 92 return IIO_VAL_INT; 93 94 case IIO_CHAN_INFO_SAMP_FREQ: 95 ret_type = hid_sensor_read_samp_freq_value( 96 &rot_state->common_attributes, &vals[0], &vals[1]); 97 break; 98 case IIO_CHAN_INFO_HYSTERESIS: 99 ret_type = hid_sensor_read_raw_hyst_value( 100 &rot_state->common_attributes, &vals[0], &vals[1]); 101 break; 102 default: 103 ret_type = -EINVAL; 104 break; 105 } 106 107 return ret_type; 108 } 109 110 /* Channel write_raw handler */ 111 static int dev_rot_write_raw(struct iio_dev *indio_dev, 112 struct iio_chan_spec const *chan, 113 int val, 114 int val2, 115 long mask) 116 { 117 struct dev_rot_state *rot_state = iio_priv(indio_dev); 118 int ret; 119 120 switch (mask) { 121 case IIO_CHAN_INFO_SAMP_FREQ: 122 ret = hid_sensor_write_samp_freq_value( 123 &rot_state->common_attributes, val, val2); 124 break; 125 case IIO_CHAN_INFO_HYSTERESIS: 126 ret = hid_sensor_write_raw_hyst_value( 127 &rot_state->common_attributes, val, val2); 128 break; 129 default: 130 ret = -EINVAL; 131 } 132 133 return ret; 134 } 135 136 static const struct iio_info dev_rot_info = { 137 .read_raw_multi = &dev_rot_read_raw, 138 .write_raw = &dev_rot_write_raw, 139 }; 140 141 /* Callback handler to send event after all samples are received and captured */ 142 static int dev_rot_proc_event(struct hid_sensor_hub_device *hsdev, 143 unsigned usage_id, 144 void *priv) 145 { 146 struct iio_dev *indio_dev = platform_get_drvdata(priv); 147 struct dev_rot_state *rot_state = iio_priv(indio_dev); 148 149 dev_dbg(&indio_dev->dev, "dev_rot_proc_event\n"); 150 if (atomic_read(&rot_state->common_attributes.data_ready)) { 151 if (!rot_state->timestamp) 152 rot_state->timestamp = iio_get_time_ns(indio_dev); 153 154 iio_push_to_buffers_with_timestamp(indio_dev, &rot_state->scan, 155 rot_state->timestamp); 156 157 rot_state->timestamp = 0; 158 } 159 160 return 0; 161 } 162 163 /* Capture samples in local storage */ 164 static int dev_rot_capture_sample(struct hid_sensor_hub_device *hsdev, 165 unsigned usage_id, 166 size_t raw_len, char *raw_data, 167 void *priv) 168 { 169 struct iio_dev *indio_dev = platform_get_drvdata(priv); 170 struct dev_rot_state *rot_state = iio_priv(indio_dev); 171 172 if (usage_id == HID_USAGE_SENSOR_ORIENT_QUATERNION) { 173 if (raw_len / 4 == sizeof(s16)) { 174 rot_state->scan.sampled_vals[0] = ((s16 *)raw_data)[0]; 175 rot_state->scan.sampled_vals[1] = ((s16 *)raw_data)[1]; 176 rot_state->scan.sampled_vals[2] = ((s16 *)raw_data)[2]; 177 rot_state->scan.sampled_vals[3] = ((s16 *)raw_data)[3]; 178 } else { 179 memcpy(&rot_state->scan.sampled_vals, raw_data, 180 sizeof(rot_state->scan.sampled_vals)); 181 } 182 183 dev_dbg(&indio_dev->dev, "Recd Quat len:%zu::%zu\n", raw_len, 184 sizeof(rot_state->scan.sampled_vals)); 185 } else if (usage_id == HID_USAGE_SENSOR_TIME_TIMESTAMP) { 186 rot_state->timestamp = hid_sensor_convert_timestamp(&rot_state->common_attributes, 187 *(s64 *)raw_data); 188 } 189 190 return 0; 191 } 192 193 /* Parse report which is specific to an usage id*/ 194 static int dev_rot_parse_report(struct platform_device *pdev, 195 struct hid_sensor_hub_device *hsdev, 196 struct iio_chan_spec *channels, 197 unsigned usage_id, 198 struct dev_rot_state *st) 199 { 200 int ret; 201 202 ret = sensor_hub_input_get_attribute_info(hsdev, 203 HID_INPUT_REPORT, 204 usage_id, 205 HID_USAGE_SENSOR_ORIENT_QUATERNION, 206 &st->quaternion); 207 if (ret) 208 return ret; 209 210 dev_rot_adjust_channel_bit_mask(&channels[0], 211 st->quaternion.size / 4); 212 213 dev_dbg(&pdev->dev, "dev_rot %x:%x\n", st->quaternion.index, 214 st->quaternion.report_id); 215 216 dev_dbg(&pdev->dev, "dev_rot: attrib size %d\n", 217 st->quaternion.size); 218 219 st->scale_precision = hid_sensor_format_scale( 220 hsdev->usage, 221 &st->quaternion, 222 &st->scale_pre_decml, &st->scale_post_decml); 223 224 /* Set Sensitivity field ids, when there is no individual modifier */ 225 if (st->common_attributes.sensitivity.index < 0) { 226 sensor_hub_input_get_attribute_info(hsdev, 227 HID_FEATURE_REPORT, usage_id, 228 HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | 229 HID_USAGE_SENSOR_DATA_ORIENTATION, 230 &st->common_attributes.sensitivity); 231 dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", 232 st->common_attributes.sensitivity.index, 233 st->common_attributes.sensitivity.report_id); 234 } 235 236 return 0; 237 } 238 239 /* Function to initialize the processing for usage id */ 240 static int hid_dev_rot_probe(struct platform_device *pdev) 241 { 242 int ret; 243 char *name; 244 struct iio_dev *indio_dev; 245 struct dev_rot_state *rot_state; 246 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; 247 248 indio_dev = devm_iio_device_alloc(&pdev->dev, 249 sizeof(struct dev_rot_state)); 250 if (indio_dev == NULL) 251 return -ENOMEM; 252 253 platform_set_drvdata(pdev, indio_dev); 254 255 rot_state = iio_priv(indio_dev); 256 rot_state->common_attributes.hsdev = hsdev; 257 rot_state->common_attributes.pdev = pdev; 258 259 switch (hsdev->usage) { 260 case HID_USAGE_SENSOR_DEVICE_ORIENTATION: 261 name = "dev_rotation"; 262 break; 263 case HID_USAGE_SENSOR_RELATIVE_ORIENTATION: 264 name = "relative_orientation"; 265 break; 266 case HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION: 267 name = "geomagnetic_orientation"; 268 break; 269 default: 270 return -EINVAL; 271 } 272 273 ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage, 274 &rot_state->common_attributes); 275 if (ret) { 276 dev_err(&pdev->dev, "failed to setup common attributes\n"); 277 return ret; 278 } 279 280 indio_dev->channels = devm_kmemdup(&pdev->dev, dev_rot_channels, 281 sizeof(dev_rot_channels), 282 GFP_KERNEL); 283 if (!indio_dev->channels) { 284 dev_err(&pdev->dev, "failed to duplicate channels\n"); 285 return -ENOMEM; 286 } 287 288 ret = dev_rot_parse_report(pdev, hsdev, 289 (struct iio_chan_spec *)indio_dev->channels, 290 hsdev->usage, rot_state); 291 if (ret) { 292 dev_err(&pdev->dev, "failed to setup attributes\n"); 293 return ret; 294 } 295 296 indio_dev->num_channels = ARRAY_SIZE(dev_rot_channels); 297 indio_dev->info = &dev_rot_info; 298 indio_dev->name = name; 299 indio_dev->modes = INDIO_DIRECT_MODE; 300 301 atomic_set(&rot_state->common_attributes.data_ready, 0); 302 303 ret = hid_sensor_setup_trigger(indio_dev, name, 304 &rot_state->common_attributes); 305 if (ret) { 306 dev_err(&pdev->dev, "trigger setup failed\n"); 307 return ret; 308 } 309 310 ret = iio_device_register(indio_dev); 311 if (ret) { 312 dev_err(&pdev->dev, "device register failed\n"); 313 goto error_remove_trigger; 314 } 315 316 rot_state->callbacks.send_event = dev_rot_proc_event; 317 rot_state->callbacks.capture_sample = dev_rot_capture_sample; 318 rot_state->callbacks.pdev = pdev; 319 ret = sensor_hub_register_callback(hsdev, hsdev->usage, 320 &rot_state->callbacks); 321 if (ret) { 322 dev_err(&pdev->dev, "callback reg failed\n"); 323 goto error_iio_unreg; 324 } 325 326 return 0; 327 328 error_iio_unreg: 329 iio_device_unregister(indio_dev); 330 error_remove_trigger: 331 hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes); 332 return ret; 333 } 334 335 /* Function to deinitialize the processing for usage id */ 336 static int hid_dev_rot_remove(struct platform_device *pdev) 337 { 338 struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; 339 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 340 struct dev_rot_state *rot_state = iio_priv(indio_dev); 341 342 sensor_hub_remove_callback(hsdev, hsdev->usage); 343 iio_device_unregister(indio_dev); 344 hid_sensor_remove_trigger(indio_dev, &rot_state->common_attributes); 345 346 return 0; 347 } 348 349 static const struct platform_device_id hid_dev_rot_ids[] = { 350 { 351 /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ 352 .name = "HID-SENSOR-20008a", 353 }, 354 { 355 /* Relative orientation(AG) sensor */ 356 .name = "HID-SENSOR-20008e", 357 }, 358 { 359 /* Geomagnetic orientation(AM) sensor */ 360 .name = "HID-SENSOR-2000c1", 361 }, 362 { /* sentinel */ } 363 }; 364 MODULE_DEVICE_TABLE(platform, hid_dev_rot_ids); 365 366 static struct platform_driver hid_dev_rot_platform_driver = { 367 .id_table = hid_dev_rot_ids, 368 .driver = { 369 .name = KBUILD_MODNAME, 370 .pm = &hid_sensor_pm_ops, 371 }, 372 .probe = hid_dev_rot_probe, 373 .remove = hid_dev_rot_remove, 374 }; 375 module_platform_driver(hid_dev_rot_platform_driver); 376 377 MODULE_DESCRIPTION("HID Sensor Device Rotation"); 378 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); 379 MODULE_LICENSE("GPL"); 380