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