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