hid-sensor-custom-intel-hinge.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * HID Sensors Driver
  4. * Copyright (c) 2020, Intel Corporation.
  5. */
  6. #include <linux/hid-sensor-hub.h>
  7. #include <linux/iio/buffer.h>
  8. #include <linux/iio/iio.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/module.h>
  11. #include <linux/mod_devicetable.h>
  12. #include "../common/hid-sensors/hid-sensor-trigger.h"
  13. enum hinge_channel {
  14. CHANNEL_SCAN_INDEX_HINGE_ANGLE,
  15. CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
  16. CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
  17. CHANNEL_SCAN_INDEX_MAX,
  18. };
  19. #define CHANNEL_SCAN_INDEX_TIMESTAMP CHANNEL_SCAN_INDEX_MAX
  20. static const u32 hinge_addresses[CHANNEL_SCAN_INDEX_MAX] = {
  21. HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
  22. HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2),
  23. HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3)
  24. };
  25. static const char *const hinge_labels[CHANNEL_SCAN_INDEX_MAX] = { "hinge",
  26. "screen",
  27. "keyboard" };
  28. struct hinge_state {
  29. struct iio_dev *indio_dev;
  30. struct hid_sensor_hub_attribute_info hinge[CHANNEL_SCAN_INDEX_MAX];
  31. struct hid_sensor_hub_callbacks callbacks;
  32. struct hid_sensor_common common_attributes;
  33. const char *labels[CHANNEL_SCAN_INDEX_MAX];
  34. struct {
  35. u32 hinge_val[3];
  36. u64 timestamp __aligned(8);
  37. } scan;
  38. int scale_pre_decml;
  39. int scale_post_decml;
  40. int scale_precision;
  41. int value_offset;
  42. u64 timestamp;
  43. };
  44. static const u32 hinge_sensitivity_addresses[] = {
  45. HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1),
  46. };
  47. /* Channel definitions */
  48. static const struct iio_chan_spec hinge_channels[] = {
  49. {
  50. .type = IIO_ANGL,
  51. .indexed = 1,
  52. .channel = 0,
  53. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  54. .info_mask_shared_by_type =
  55. BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
  56. BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
  57. .scan_index = CHANNEL_SCAN_INDEX_HINGE_ANGLE,
  58. .scan_type = {
  59. .sign = 's',
  60. .storagebits = 32,
  61. },
  62. }, {
  63. .type = IIO_ANGL,
  64. .indexed = 1,
  65. .channel = 1,
  66. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  67. .info_mask_shared_by_type =
  68. BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
  69. BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
  70. .scan_index = CHANNEL_SCAN_INDEX_SCREEN_ANGLE,
  71. .scan_type = {
  72. .sign = 's',
  73. .storagebits = 32,
  74. },
  75. }, {
  76. .type = IIO_ANGL,
  77. .indexed = 1,
  78. .channel = 2,
  79. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  80. .info_mask_shared_by_type =
  81. BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE) |
  82. BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS),
  83. .scan_index = CHANNEL_SCAN_INDEX_KEYBOARD_ANGLE,
  84. .scan_type = {
  85. .sign = 's',
  86. .storagebits = 32,
  87. },
  88. },
  89. IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
  90. };
  91. /* Adjust channel real bits based on report descriptor */
  92. static void hinge_adjust_channel_realbits(struct iio_chan_spec *channels,
  93. int channel, int size)
  94. {
  95. channels[channel].scan_type.realbits = size * 8;
  96. }
  97. /* Channel read_raw handler */
  98. static int hinge_read_raw(struct iio_dev *indio_dev,
  99. struct iio_chan_spec const *chan, int *val, int *val2,
  100. long mask)
  101. {
  102. struct hinge_state *st = iio_priv(indio_dev);
  103. struct hid_sensor_hub_device *hsdev;
  104. int report_id;
  105. s32 min;
  106. hsdev = st->common_attributes.hsdev;
  107. switch (mask) {
  108. case IIO_CHAN_INFO_RAW:
  109. hid_sensor_power_state(&st->common_attributes, true);
  110. report_id = st->hinge[chan->scan_index].report_id;
  111. min = st->hinge[chan->scan_index].logical_minimum;
  112. if (report_id < 0) {
  113. hid_sensor_power_state(&st->common_attributes, false);
  114. return -EINVAL;
  115. }
  116. *val = sensor_hub_input_attr_get_raw_value(st->common_attributes.hsdev,
  117. hsdev->usage,
  118. hinge_addresses[chan->scan_index],
  119. report_id,
  120. SENSOR_HUB_SYNC, min < 0);
  121. hid_sensor_power_state(&st->common_attributes, false);
  122. return IIO_VAL_INT;
  123. case IIO_CHAN_INFO_SCALE:
  124. *val = st->scale_pre_decml;
  125. *val2 = st->scale_post_decml;
  126. return st->scale_precision;
  127. case IIO_CHAN_INFO_OFFSET:
  128. *val = st->value_offset;
  129. return IIO_VAL_INT;
  130. case IIO_CHAN_INFO_SAMP_FREQ:
  131. return hid_sensor_read_samp_freq_value(&st->common_attributes,
  132. val, val2);
  133. case IIO_CHAN_INFO_HYSTERESIS:
  134. return hid_sensor_read_raw_hyst_value(&st->common_attributes,
  135. val, val2);
  136. default:
  137. return -EINVAL;
  138. }
  139. }
  140. /* Channel write_raw handler */
  141. static int hinge_write_raw(struct iio_dev *indio_dev,
  142. struct iio_chan_spec const *chan, int val, int val2,
  143. long mask)
  144. {
  145. struct hinge_state *st = iio_priv(indio_dev);
  146. switch (mask) {
  147. case IIO_CHAN_INFO_SAMP_FREQ:
  148. return hid_sensor_write_samp_freq_value(&st->common_attributes,
  149. val, val2);
  150. case IIO_CHAN_INFO_HYSTERESIS:
  151. return hid_sensor_write_raw_hyst_value(&st->common_attributes,
  152. val, val2);
  153. default:
  154. return -EINVAL;
  155. }
  156. }
  157. static int hinge_read_label(struct iio_dev *indio_dev,
  158. struct iio_chan_spec const *chan, char *label)
  159. {
  160. struct hinge_state *st = iio_priv(indio_dev);
  161. return sprintf(label, "%s\n", st->labels[chan->channel]);
  162. }
  163. static const struct iio_info hinge_info = {
  164. .read_raw = hinge_read_raw,
  165. .write_raw = hinge_write_raw,
  166. .read_label = hinge_read_label,
  167. };
  168. /*
  169. * Callback handler to send event after all samples are received
  170. * and captured.
  171. */
  172. static int hinge_proc_event(struct hid_sensor_hub_device *hsdev,
  173. unsigned int usage_id, void *priv)
  174. {
  175. struct iio_dev *indio_dev = platform_get_drvdata(priv);
  176. struct hinge_state *st = iio_priv(indio_dev);
  177. if (atomic_read(&st->common_attributes.data_ready)) {
  178. if (!st->timestamp)
  179. st->timestamp = iio_get_time_ns(indio_dev);
  180. iio_push_to_buffers_with_timestamp(indio_dev, &st->scan,
  181. st->timestamp);
  182. st->timestamp = 0;
  183. }
  184. return 0;
  185. }
  186. /* Capture samples in local storage */
  187. static int hinge_capture_sample(struct hid_sensor_hub_device *hsdev,
  188. unsigned int usage_id, size_t raw_len,
  189. char *raw_data, void *priv)
  190. {
  191. struct iio_dev *indio_dev = platform_get_drvdata(priv);
  192. struct hinge_state *st = iio_priv(indio_dev);
  193. int offset;
  194. switch (usage_id) {
  195. case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1):
  196. case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(2):
  197. case HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(3):
  198. offset = usage_id - HID_USAGE_SENSOR_DATA_FIELD_CUSTOM_VALUE(1);
  199. st->scan.hinge_val[offset] = *(u32 *)raw_data;
  200. return 0;
  201. case HID_USAGE_SENSOR_TIME_TIMESTAMP:
  202. st->timestamp = hid_sensor_convert_timestamp(&st->common_attributes,
  203. *(int64_t *)raw_data);
  204. return 0;
  205. default:
  206. return -EINVAL;
  207. }
  208. }
  209. /* Parse report which is specific to an usage id */
  210. static int hinge_parse_report(struct platform_device *pdev,
  211. struct hid_sensor_hub_device *hsdev,
  212. struct iio_chan_spec *channels,
  213. unsigned int usage_id, struct hinge_state *st)
  214. {
  215. int ret;
  216. int i;
  217. for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; ++i) {
  218. ret = sensor_hub_input_get_attribute_info(hsdev,
  219. HID_INPUT_REPORT,
  220. usage_id,
  221. hinge_addresses[i],
  222. &st->hinge[i]);
  223. if (ret < 0)
  224. return ret;
  225. hinge_adjust_channel_realbits(channels, i, st->hinge[i].size);
  226. }
  227. st->scale_precision = hid_sensor_format_scale(HID_USAGE_SENSOR_HINGE,
  228. &st->hinge[CHANNEL_SCAN_INDEX_HINGE_ANGLE],
  229. &st->scale_pre_decml, &st->scale_post_decml);
  230. return ret;
  231. }
  232. /* Function to initialize the processing for usage id */
  233. static int hid_hinge_probe(struct platform_device *pdev)
  234. {
  235. struct hinge_state *st;
  236. struct iio_dev *indio_dev;
  237. struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
  238. int ret;
  239. int i;
  240. indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
  241. if (!indio_dev)
  242. return -ENOMEM;
  243. platform_set_drvdata(pdev, indio_dev);
  244. st = iio_priv(indio_dev);
  245. st->common_attributes.hsdev = hsdev;
  246. st->common_attributes.pdev = pdev;
  247. st->indio_dev = indio_dev;
  248. for (i = 0; i < CHANNEL_SCAN_INDEX_MAX; i++)
  249. st->labels[i] = hinge_labels[i];
  250. ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage,
  251. &st->common_attributes,
  252. hinge_sensitivity_addresses,
  253. ARRAY_SIZE(hinge_sensitivity_addresses));
  254. if (ret) {
  255. dev_err(&pdev->dev, "failed to setup common attributes\n");
  256. return ret;
  257. }
  258. indio_dev->num_channels = ARRAY_SIZE(hinge_channels);
  259. indio_dev->channels = devm_kmemdup(&indio_dev->dev, hinge_channels,
  260. sizeof(hinge_channels), GFP_KERNEL);
  261. if (!indio_dev->channels)
  262. return -ENOMEM;
  263. ret = hinge_parse_report(pdev, hsdev,
  264. (struct iio_chan_spec *)indio_dev->channels,
  265. hsdev->usage, st);
  266. if (ret) {
  267. dev_err(&pdev->dev, "failed to setup attributes\n");
  268. return ret;
  269. }
  270. indio_dev->info = &hinge_info;
  271. indio_dev->name = "hinge";
  272. indio_dev->modes = INDIO_DIRECT_MODE;
  273. atomic_set(&st->common_attributes.data_ready, 0);
  274. ret = hid_sensor_setup_trigger(indio_dev, indio_dev->name,
  275. &st->common_attributes);
  276. if (ret < 0) {
  277. dev_err(&pdev->dev, "trigger setup failed\n");
  278. return ret;
  279. }
  280. st->callbacks.send_event = hinge_proc_event;
  281. st->callbacks.capture_sample = hinge_capture_sample;
  282. st->callbacks.pdev = pdev;
  283. ret = sensor_hub_register_callback(hsdev, hsdev->usage, &st->callbacks);
  284. if (ret < 0) {
  285. dev_err(&pdev->dev, "callback reg failed\n");
  286. goto error_remove_trigger;
  287. }
  288. ret = iio_device_register(indio_dev);
  289. if (ret) {
  290. dev_err(&pdev->dev, "device register failed\n");
  291. goto error_remove_callback;
  292. }
  293. return ret;
  294. error_remove_callback:
  295. sensor_hub_remove_callback(hsdev, hsdev->usage);
  296. error_remove_trigger:
  297. hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
  298. return ret;
  299. }
  300. /* Function to deinitialize the processing for usage id */
  301. static int hid_hinge_remove(struct platform_device *pdev)
  302. {
  303. struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
  304. struct iio_dev *indio_dev = platform_get_drvdata(pdev);
  305. struct hinge_state *st = iio_priv(indio_dev);
  306. iio_device_unregister(indio_dev);
  307. sensor_hub_remove_callback(hsdev, hsdev->usage);
  308. hid_sensor_remove_trigger(indio_dev, &st->common_attributes);
  309. return 0;
  310. }
  311. static const struct platform_device_id hid_hinge_ids[] = {
  312. {
  313. /* Format: HID-SENSOR-INT-usage_id_in_hex_lowercase */
  314. .name = "HID-SENSOR-INT-020b",
  315. },
  316. { /* sentinel */ }
  317. };
  318. MODULE_DEVICE_TABLE(platform, hid_hinge_ids);
  319. static struct platform_driver hid_hinge_platform_driver = {
  320. .id_table = hid_hinge_ids,
  321. .driver = {
  322. .name = KBUILD_MODNAME,
  323. .pm = &hid_sensor_pm_ops,
  324. },
  325. .probe = hid_hinge_probe,
  326. .remove = hid_hinge_remove,
  327. };
  328. module_platform_driver(hid_hinge_platform_driver);
  329. MODULE_DESCRIPTION("HID Sensor INTEL Hinge");
  330. MODULE_AUTHOR("Ye Xiang <[email protected]>");
  331. MODULE_LICENSE("GPL");
  332. MODULE_IMPORT_NS(IIO_HID);