hid-sensor-als.c 13 KB

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