1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * HID Sensors Driver 4 * Copyright (c) 2012, Intel Corporation. 5 */ 6 #include <linux/bitops.h> 7 #include <linux/device.h> 8 #include <linux/platform_device.h> 9 #include <linux/module.h> 10 #include <linux/mod_devicetable.h> 11 #include <linux/slab.h> 12 #include <linux/hid-sensor-hub.h> 13 #include <linux/iio/iio.h> 14 #include <linux/iio/buffer.h> 15 #include "../common/hid-sensors/hid-sensor-trigger.h" 16 17 enum { 18 CHANNEL_SCAN_INDEX_INTENSITY, 19 CHANNEL_SCAN_INDEX_ILLUM, 20 CHANNEL_SCAN_INDEX_COLOR_TEMP, 21 CHANNEL_SCAN_INDEX_CHROMATICITY_X, 22 CHANNEL_SCAN_INDEX_CHROMATICITY_Y, 23 CHANNEL_SCAN_INDEX_MAX 24 }; 25 26 #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX 27 28 struct als_state { 29 struct hid_sensor_hub_callbacks callbacks; 30 struct hid_sensor_common common_attributes; 31 struct hid_sensor_hub_attribute_info als[CHANNEL_SCAN_INDEX_MAX]; 32 struct iio_chan_spec channels[CHANNEL_SCAN_INDEX_MAX + 1]; 33 struct { 34 u32 illum[CHANNEL_SCAN_INDEX_MAX]; 35 aligned_s64 timestamp; 36 } scan; 37 int scale_pre_decml; 38 int scale_post_decml; 39 int scale_precision; 40 int value_offset; 41 int num_channels; 42 s64 timestamp; 43 unsigned long als_scan_mask[2]; 44 }; 45 46 /* The order of usage ids must match scan index starting from CHANNEL_SCAN_INDEX_INTENSITY */ 47 static const u32 als_usage_ids[] = { 48 HID_USAGE_SENSOR_LIGHT_ILLUM, 49 HID_USAGE_SENSOR_LIGHT_ILLUM, 50 HID_USAGE_SENSOR_LIGHT_COLOR_TEMPERATURE, 51 HID_USAGE_SENSOR_LIGHT_CHROMATICITY_X, 52 HID_USAGE_SENSOR_LIGHT_CHROMATICITY_Y, 53 }; 54 55 static const u32 als_sensitivity_addresses[] = { 56 HID_USAGE_SENSOR_DATA_LIGHT, 57 HID_USAGE_SENSOR_LIGHT_ILLUM, 58 }; 59 60 /* Channel definitions */ 61 static const struct iio_chan_spec als_channels[] = { 62 { 63 .type = IIO_INTENSITY, 64 .modified = 1, 65 .channel2 = IIO_MOD_LIGHT_BOTH, 66 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 67 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | 68 BIT(IIO_CHAN_INFO_SCALE) | 69 BIT(IIO_CHAN_INFO_SAMP_FREQ) | 70 BIT(IIO_CHAN_INFO_HYSTERESIS) | 71 BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), 72 .scan_index = CHANNEL_SCAN_INDEX_INTENSITY, 73 }, 74 { 75 .type = IIO_LIGHT, 76 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 77 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | 78 BIT(IIO_CHAN_INFO_SCALE) | 79 BIT(IIO_CHAN_INFO_SAMP_FREQ) | 80 BIT(IIO_CHAN_INFO_HYSTERESIS) | 81 BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), 82 .scan_index = CHANNEL_SCAN_INDEX_ILLUM, 83 }, 84 { 85 .type = IIO_COLORTEMP, 86 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 87 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | 88 BIT(IIO_CHAN_INFO_SCALE) | 89 BIT(IIO_CHAN_INFO_SAMP_FREQ) | 90 BIT(IIO_CHAN_INFO_HYSTERESIS) | 91 BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), 92 .scan_index = CHANNEL_SCAN_INDEX_COLOR_TEMP, 93 }, 94 { 95 .type = IIO_CHROMATICITY, 96 .modified = 1, 97 .channel2 = IIO_MOD_X, 98 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 99 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | 100 BIT(IIO_CHAN_INFO_SCALE) | 101 BIT(IIO_CHAN_INFO_SAMP_FREQ) | 102 BIT(IIO_CHAN_INFO_HYSTERESIS) | 103 BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), 104 .scan_index = CHANNEL_SCAN_INDEX_CHROMATICITY_X, 105 }, 106 { 107 .type = IIO_CHROMATICITY, 108 .modified = 1, 109 .channel2 = IIO_MOD_Y, 110 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 111 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | 112 BIT(IIO_CHAN_INFO_SCALE) | 113 BIT(IIO_CHAN_INFO_SAMP_FREQ) | 114 BIT(IIO_CHAN_INFO_HYSTERESIS) | 115 BIT(IIO_CHAN_INFO_HYSTERESIS_RELATIVE), 116 .scan_index = CHANNEL_SCAN_INDEX_CHROMATICITY_Y, 117 }, 118 IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP) 119 }; 120 121 /* Channel read_raw handler */ 122 static int als_read_raw(struct iio_dev *indio_dev, 123 struct iio_chan_spec const *chan, 124 int *val, int *val2, 125 long mask) 126 { 127 struct als_state *als_state = iio_priv(indio_dev); 128 struct hid_sensor_hub_device *hsdev = als_state->common_attributes.hsdev; 129 int report_id = -1; 130 u32 address; 131 int ret_type; 132 s32 min; 133 134 *val = 0; 135 *val2 = 0; 136 switch (mask) { 137 case IIO_CHAN_INFO_RAW: 138 switch (chan->scan_index) { 139 case CHANNEL_SCAN_INDEX_INTENSITY: 140 case CHANNEL_SCAN_INDEX_ILLUM: 141 report_id = als_state->als[chan->scan_index].report_id; 142 min = als_state->als[chan->scan_index].logical_minimum; 143 address = HID_USAGE_SENSOR_LIGHT_ILLUM; 144 break; 145 case CHANNEL_SCAN_INDEX_COLOR_TEMP: 146 report_id = als_state->als[chan->scan_index].report_id; 147 min = als_state->als[chan->scan_index].logical_minimum; 148 address = HID_USAGE_SENSOR_LIGHT_COLOR_TEMPERATURE; 149 break; 150 case CHANNEL_SCAN_INDEX_CHROMATICITY_X: 151 report_id = als_state->als[chan->scan_index].report_id; 152 min = als_state->als[chan->scan_index].logical_minimum; 153 address = HID_USAGE_SENSOR_LIGHT_CHROMATICITY_X; 154 break; 155 case CHANNEL_SCAN_INDEX_CHROMATICITY_Y: 156 report_id = als_state->als[chan->scan_index].report_id; 157 min = als_state->als[chan->scan_index].logical_minimum; 158 address = HID_USAGE_SENSOR_LIGHT_CHROMATICITY_Y; 159 break; 160 default: 161 report_id = -1; 162 break; 163 } 164 if (report_id >= 0) { 165 hid_sensor_power_state(&als_state->common_attributes, 166 true); 167 *val = sensor_hub_input_attr_get_raw_value( 168 hsdev, hsdev->usage, address, report_id, 169 SENSOR_HUB_SYNC, min < 0); 170 hid_sensor_power_state(&als_state->common_attributes, 171 false); 172 } else { 173 *val = 0; 174 return -EINVAL; 175 } 176 ret_type = IIO_VAL_INT; 177 break; 178 case IIO_CHAN_INFO_SCALE: 179 *val = als_state->scale_pre_decml; 180 *val2 = als_state->scale_post_decml; 181 ret_type = als_state->scale_precision; 182 break; 183 case IIO_CHAN_INFO_OFFSET: 184 *val = als_state->value_offset; 185 ret_type = IIO_VAL_INT; 186 break; 187 case IIO_CHAN_INFO_SAMP_FREQ: 188 ret_type = hid_sensor_read_samp_freq_value( 189 &als_state->common_attributes, val, val2); 190 break; 191 case IIO_CHAN_INFO_HYSTERESIS: 192 ret_type = hid_sensor_read_raw_hyst_value( 193 &als_state->common_attributes, val, val2); 194 break; 195 case IIO_CHAN_INFO_HYSTERESIS_RELATIVE: 196 ret_type = hid_sensor_read_raw_hyst_rel_value( 197 &als_state->common_attributes, val, val2); 198 break; 199 default: 200 ret_type = -EINVAL; 201 break; 202 } 203 204 return ret_type; 205 } 206 207 /* Channel write_raw handler */ 208 static int als_write_raw(struct iio_dev *indio_dev, 209 struct iio_chan_spec const *chan, 210 int val, 211 int val2, 212 long mask) 213 { 214 struct als_state *als_state = iio_priv(indio_dev); 215 int ret = 0; 216 217 switch (mask) { 218 case IIO_CHAN_INFO_SAMP_FREQ: 219 ret = hid_sensor_write_samp_freq_value( 220 &als_state->common_attributes, val, val2); 221 break; 222 case IIO_CHAN_INFO_HYSTERESIS: 223 ret = hid_sensor_write_raw_hyst_value( 224 &als_state->common_attributes, val, val2); 225 break; 226 case IIO_CHAN_INFO_HYSTERESIS_RELATIVE: 227 ret = hid_sensor_write_raw_hyst_rel_value( 228 &als_state->common_attributes, val, val2); 229 break; 230 default: 231 ret = -EINVAL; 232 } 233 234 return ret; 235 } 236 237 static const struct iio_info als_info = { 238 .read_raw = &als_read_raw, 239 .write_raw = &als_write_raw, 240 }; 241 242 /* Callback handler to send event after all samples are received and captured */ 243 static int als_proc_event(struct hid_sensor_hub_device *hsdev, 244 unsigned usage_id, 245 void *priv) 246 { 247 struct iio_dev *indio_dev = platform_get_drvdata(priv); 248 struct als_state *als_state = iio_priv(indio_dev); 249 250 dev_dbg(&indio_dev->dev, "als_proc_event\n"); 251 if (atomic_read(&als_state->common_attributes.data_ready)) { 252 if (!als_state->timestamp) 253 als_state->timestamp = iio_get_time_ns(indio_dev); 254 255 iio_push_to_buffers_with_ts(indio_dev, &als_state->scan, 256 sizeof(als_state->scan), 257 als_state->timestamp); 258 als_state->timestamp = 0; 259 } 260 261 return 0; 262 } 263 264 /* Capture samples in local storage */ 265 static int als_capture_sample(struct hid_sensor_hub_device *hsdev, 266 unsigned usage_id, 267 size_t raw_len, char *raw_data, 268 void *priv) 269 { 270 struct iio_dev *indio_dev = platform_get_drvdata(priv); 271 struct als_state *als_state = iio_priv(indio_dev); 272 int ret = -EINVAL; 273 u32 sample_data = *(u32 *)raw_data; 274 275 switch (usage_id) { 276 case HID_USAGE_SENSOR_LIGHT_ILLUM: 277 als_state->scan.illum[CHANNEL_SCAN_INDEX_INTENSITY] = sample_data; 278 als_state->scan.illum[CHANNEL_SCAN_INDEX_ILLUM] = sample_data; 279 ret = 0; 280 break; 281 case HID_USAGE_SENSOR_LIGHT_COLOR_TEMPERATURE: 282 als_state->scan.illum[CHANNEL_SCAN_INDEX_COLOR_TEMP] = sample_data; 283 ret = 0; 284 break; 285 case HID_USAGE_SENSOR_LIGHT_CHROMATICITY_X: 286 als_state->scan.illum[CHANNEL_SCAN_INDEX_CHROMATICITY_X] = sample_data; 287 ret = 0; 288 break; 289 case HID_USAGE_SENSOR_LIGHT_CHROMATICITY_Y: 290 als_state->scan.illum[CHANNEL_SCAN_INDEX_CHROMATICITY_Y] = sample_data; 291 ret = 0; 292 break; 293 case HID_USAGE_SENSOR_TIME_TIMESTAMP: 294 als_state->timestamp = hid_sensor_convert_timestamp(&als_state->common_attributes, 295 *(s64 *)raw_data); 296 ret = 0; 297 break; 298 default: 299 break; 300 } 301 302 return ret; 303 } 304 305 /* Parse report which is specific to an usage id*/ 306 static int als_parse_report(struct platform_device *pdev, 307 struct hid_sensor_hub_device *hsdev, 308 unsigned usage_id, 309 struct als_state *st) 310 { 311 struct iio_chan_spec *channels; 312 int ret, index = 0; 313 int i; 314 315 channels = st->channels; 316 317 for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; ++i) { 318 ret = sensor_hub_input_get_attribute_info(hsdev, 319 HID_INPUT_REPORT, 320 usage_id, 321 als_usage_ids[i], 322 &st->als[i]); 323 if (ret < 0) 324 continue; 325 326 channels[index] = als_channels[i]; 327 st->als_scan_mask[0] |= BIT(i); 328 channels[index].scan_type = (struct iio_scan_type) { 329 .format = 's', 330 .realbits = BYTES_TO_BITS(st->als[i].size), 331 .storagebits = BITS_PER_TYPE(u32), 332 }; 333 ++index; 334 335 dev_dbg(&pdev->dev, "als %x:%x\n", st->als[i].index, 336 st->als[i].report_id); 337 } 338 339 st->num_channels = index; 340 /* Return success even if one usage id is present */ 341 if (index) 342 ret = 0; 343 344 st->scale_precision = hid_sensor_format_scale(usage_id, 345 &st->als[CHANNEL_SCAN_INDEX_INTENSITY], 346 &st->scale_pre_decml, &st->scale_post_decml); 347 348 return ret; 349 } 350 351 /* Function to initialize the processing for usage id */ 352 static int hid_als_probe(struct platform_device *pdev) 353 { 354 struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); 355 int ret = 0; 356 static const char *name = "als"; 357 struct iio_dev *indio_dev; 358 struct als_state *als_state; 359 360 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state)); 361 if (!indio_dev) 362 return -ENOMEM; 363 platform_set_drvdata(pdev, indio_dev); 364 365 als_state = iio_priv(indio_dev); 366 als_state->common_attributes.hsdev = hsdev; 367 als_state->common_attributes.pdev = pdev; 368 369 ret = hid_sensor_parse_common_attributes(hsdev, 370 hsdev->usage, 371 &als_state->common_attributes, 372 als_sensitivity_addresses, 373 ARRAY_SIZE(als_sensitivity_addresses)); 374 if (ret) { 375 dev_err(&pdev->dev, "failed to setup common attributes\n"); 376 return ret; 377 } 378 379 ret = als_parse_report(pdev, hsdev, 380 hsdev->usage, 381 als_state); 382 if (ret) { 383 dev_err(&pdev->dev, "failed to setup attributes\n"); 384 return ret; 385 } 386 387 /* Add timestamp channel */ 388 als_state->channels[als_state->num_channels] = als_channels[CHANNEL_SCAN_INDEX_TIMESTAMP]; 389 390 /* +1 for adding timestamp channel */ 391 indio_dev->num_channels = als_state->num_channels + 1; 392 393 indio_dev->channels = als_state->channels; 394 indio_dev->available_scan_masks = als_state->als_scan_mask; 395 396 indio_dev->info = &als_info; 397 indio_dev->name = name; 398 indio_dev->modes = INDIO_DIRECT_MODE; 399 400 atomic_set(&als_state->common_attributes.data_ready, 0); 401 402 ret = hid_sensor_setup_trigger(indio_dev, name, 403 &als_state->common_attributes); 404 if (ret < 0) { 405 dev_err(&pdev->dev, "trigger setup failed\n"); 406 return ret; 407 } 408 409 ret = iio_device_register(indio_dev); 410 if (ret) { 411 dev_err(&pdev->dev, "device register failed\n"); 412 goto error_remove_trigger; 413 } 414 415 als_state->callbacks.send_event = als_proc_event; 416 als_state->callbacks.capture_sample = als_capture_sample; 417 als_state->callbacks.pdev = pdev; 418 ret = sensor_hub_register_callback(hsdev, hsdev->usage, &als_state->callbacks); 419 if (ret < 0) { 420 dev_err(&pdev->dev, "callback reg failed\n"); 421 goto error_iio_unreg; 422 } 423 424 return ret; 425 426 error_iio_unreg: 427 iio_device_unregister(indio_dev); 428 error_remove_trigger: 429 hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes); 430 return ret; 431 } 432 433 /* Function to deinitialize the processing for usage id */ 434 static void hid_als_remove(struct platform_device *pdev) 435 { 436 struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev); 437 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 438 struct als_state *als_state = iio_priv(indio_dev); 439 440 sensor_hub_remove_callback(hsdev, hsdev->usage); 441 iio_device_unregister(indio_dev); 442 hid_sensor_remove_trigger(indio_dev, &als_state->common_attributes); 443 } 444 445 static const struct platform_device_id hid_als_ids[] = { 446 { 447 /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ 448 .name = "HID-SENSOR-200041", 449 }, 450 { 451 /* Format: HID-SENSOR-custom_sensor_tag-usage_id_in_hex_lowercase */ 452 .name = "HID-SENSOR-LISS-0041", 453 }, 454 { } 455 }; 456 MODULE_DEVICE_TABLE(platform, hid_als_ids); 457 458 static struct platform_driver hid_als_platform_driver = { 459 .id_table = hid_als_ids, 460 .driver = { 461 .name = KBUILD_MODNAME, 462 .pm = &hid_sensor_pm_ops, 463 }, 464 .probe = hid_als_probe, 465 .remove = hid_als_remove, 466 }; 467 module_platform_driver(hid_als_platform_driver); 468 469 MODULE_DESCRIPTION("HID Sensor ALS"); 470 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); 471 MODULE_LICENSE("GPL"); 472 MODULE_IMPORT_NS("IIO_HID"); 473