rtc-hid-sensor-time.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * HID Sensor Time Driver
  4. * Copyright (c) 2012, Alexander Holler.
  5. */
  6. #include <linux/device.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/module.h>
  9. #include <linux/hid-sensor-hub.h>
  10. #include <linux/iio/iio.h>
  11. #include <linux/rtc.h>
  12. enum hid_time_channel {
  13. CHANNEL_SCAN_INDEX_YEAR,
  14. CHANNEL_SCAN_INDEX_MONTH,
  15. CHANNEL_SCAN_INDEX_DAY,
  16. CHANNEL_SCAN_INDEX_HOUR,
  17. CHANNEL_SCAN_INDEX_MINUTE,
  18. CHANNEL_SCAN_INDEX_SECOND,
  19. TIME_RTC_CHANNEL_MAX,
  20. };
  21. struct hid_time_state {
  22. struct hid_sensor_hub_callbacks callbacks;
  23. struct hid_sensor_common common_attributes;
  24. struct hid_sensor_hub_attribute_info info[TIME_RTC_CHANNEL_MAX];
  25. struct rtc_time last_time;
  26. spinlock_t lock_last_time;
  27. struct completion comp_last_time;
  28. struct rtc_time time_buf;
  29. struct rtc_device *rtc;
  30. };
  31. static const u32 hid_time_addresses[TIME_RTC_CHANNEL_MAX] = {
  32. HID_USAGE_SENSOR_TIME_YEAR,
  33. HID_USAGE_SENSOR_TIME_MONTH,
  34. HID_USAGE_SENSOR_TIME_DAY,
  35. HID_USAGE_SENSOR_TIME_HOUR,
  36. HID_USAGE_SENSOR_TIME_MINUTE,
  37. HID_USAGE_SENSOR_TIME_SECOND,
  38. };
  39. /* Channel names for verbose error messages */
  40. static const char * const hid_time_channel_names[TIME_RTC_CHANNEL_MAX] = {
  41. "year", "month", "day", "hour", "minute", "second",
  42. };
  43. /* Callback handler to send event after all samples are received and captured */
  44. static int hid_time_proc_event(struct hid_sensor_hub_device *hsdev,
  45. unsigned usage_id, void *priv)
  46. {
  47. unsigned long flags;
  48. struct hid_time_state *time_state = platform_get_drvdata(priv);
  49. spin_lock_irqsave(&time_state->lock_last_time, flags);
  50. time_state->last_time = time_state->time_buf;
  51. spin_unlock_irqrestore(&time_state->lock_last_time, flags);
  52. complete(&time_state->comp_last_time);
  53. return 0;
  54. }
  55. static u32 hid_time_value(size_t raw_len, char *raw_data)
  56. {
  57. switch (raw_len) {
  58. case 1:
  59. return *(u8 *)raw_data;
  60. case 2:
  61. return *(u16 *)raw_data;
  62. case 4:
  63. return *(u32 *)raw_data;
  64. default:
  65. return (u32)(~0U); /* 0xff... or -1 to denote an error */
  66. }
  67. }
  68. static int hid_time_capture_sample(struct hid_sensor_hub_device *hsdev,
  69. unsigned usage_id, size_t raw_len,
  70. char *raw_data, void *priv)
  71. {
  72. struct hid_time_state *time_state = platform_get_drvdata(priv);
  73. struct rtc_time *time_buf = &time_state->time_buf;
  74. switch (usage_id) {
  75. case HID_USAGE_SENSOR_TIME_YEAR:
  76. /*
  77. * The draft for HID-sensors (HUTRR39) currently doesn't define
  78. * the range for the year attribute. Therefor we support
  79. * 8 bit (0-99) and 16 or 32 bits (full) as size for the year.
  80. */
  81. if (raw_len == 1) {
  82. time_buf->tm_year = *(u8 *)raw_data;
  83. if (time_buf->tm_year < 70)
  84. /* assume we are in 1970...2069 */
  85. time_buf->tm_year += 100;
  86. } else
  87. time_buf->tm_year =
  88. (int)hid_time_value(raw_len, raw_data)-1900;
  89. break;
  90. case HID_USAGE_SENSOR_TIME_MONTH:
  91. /* sensors are sending the month as 1-12, we need 0-11 */
  92. time_buf->tm_mon = (int)hid_time_value(raw_len, raw_data)-1;
  93. break;
  94. case HID_USAGE_SENSOR_TIME_DAY:
  95. time_buf->tm_mday = (int)hid_time_value(raw_len, raw_data);
  96. break;
  97. case HID_USAGE_SENSOR_TIME_HOUR:
  98. time_buf->tm_hour = (int)hid_time_value(raw_len, raw_data);
  99. break;
  100. case HID_USAGE_SENSOR_TIME_MINUTE:
  101. time_buf->tm_min = (int)hid_time_value(raw_len, raw_data);
  102. break;
  103. case HID_USAGE_SENSOR_TIME_SECOND:
  104. time_buf->tm_sec = (int)hid_time_value(raw_len, raw_data);
  105. break;
  106. default:
  107. return -EINVAL;
  108. }
  109. return 0;
  110. }
  111. /* small helper, haven't found any other way */
  112. static const char *hid_time_attrib_name(u32 attrib_id)
  113. {
  114. static const char unknown[] = "unknown";
  115. unsigned i;
  116. for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) {
  117. if (hid_time_addresses[i] == attrib_id)
  118. return hid_time_channel_names[i];
  119. }
  120. return unknown; /* should never happen */
  121. }
  122. static int hid_time_parse_report(struct platform_device *pdev,
  123. struct hid_sensor_hub_device *hsdev,
  124. unsigned usage_id,
  125. struct hid_time_state *time_state)
  126. {
  127. int report_id, i;
  128. for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i)
  129. if (sensor_hub_input_get_attribute_info(hsdev,
  130. HID_INPUT_REPORT, usage_id,
  131. hid_time_addresses[i],
  132. &time_state->info[i]) < 0)
  133. return -EINVAL;
  134. /* Check the (needed) attributes for sanity */
  135. report_id = time_state->info[0].report_id;
  136. if (report_id < 0) {
  137. dev_err(&pdev->dev, "bad report ID!\n");
  138. return -EINVAL;
  139. }
  140. for (i = 0; i < TIME_RTC_CHANNEL_MAX; ++i) {
  141. if (time_state->info[i].report_id != report_id) {
  142. dev_err(&pdev->dev,
  143. "not all needed attributes inside the same report!\n");
  144. return -EINVAL;
  145. }
  146. if (time_state->info[i].size == 3 ||
  147. time_state->info[i].size > 4) {
  148. dev_err(&pdev->dev,
  149. "attribute '%s' not 8, 16 or 32 bits wide!\n",
  150. hid_time_attrib_name(
  151. time_state->info[i].attrib_id));
  152. return -EINVAL;
  153. }
  154. if (time_state->info[i].units !=
  155. HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED &&
  156. /* allow attribute seconds with unit seconds */
  157. !(time_state->info[i].attrib_id ==
  158. HID_USAGE_SENSOR_TIME_SECOND &&
  159. time_state->info[i].units ==
  160. HID_USAGE_SENSOR_UNITS_SECOND)) {
  161. dev_err(&pdev->dev,
  162. "attribute '%s' hasn't a unit of type 'none'!\n",
  163. hid_time_attrib_name(
  164. time_state->info[i].attrib_id));
  165. return -EINVAL;
  166. }
  167. if (time_state->info[i].unit_expo) {
  168. dev_err(&pdev->dev,
  169. "attribute '%s' hasn't a unit exponent of 1!\n",
  170. hid_time_attrib_name(
  171. time_state->info[i].attrib_id));
  172. return -EINVAL;
  173. }
  174. }
  175. return 0;
  176. }
  177. static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm)
  178. {
  179. unsigned long flags;
  180. struct hid_time_state *time_state = dev_get_drvdata(dev);
  181. int ret;
  182. reinit_completion(&time_state->comp_last_time);
  183. /* get a report with all values through requesting one value */
  184. sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev,
  185. HID_USAGE_SENSOR_TIME, hid_time_addresses[0],
  186. time_state->info[0].report_id, SENSOR_HUB_SYNC, false);
  187. /* wait for all values (event) */
  188. ret = wait_for_completion_killable_timeout(
  189. &time_state->comp_last_time, HZ*6);
  190. if (ret > 0) {
  191. /* no error */
  192. spin_lock_irqsave(&time_state->lock_last_time, flags);
  193. *tm = time_state->last_time;
  194. spin_unlock_irqrestore(&time_state->lock_last_time, flags);
  195. return 0;
  196. }
  197. if (!ret)
  198. return -EIO; /* timeouted */
  199. return ret; /* killed (-ERESTARTSYS) */
  200. }
  201. static const struct rtc_class_ops hid_time_rtc_ops = {
  202. .read_time = hid_rtc_read_time,
  203. };
  204. static int hid_time_probe(struct platform_device *pdev)
  205. {
  206. int ret = 0;
  207. struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
  208. struct hid_time_state *time_state = devm_kzalloc(&pdev->dev,
  209. sizeof(struct hid_time_state), GFP_KERNEL);
  210. if (time_state == NULL)
  211. return -ENOMEM;
  212. platform_set_drvdata(pdev, time_state);
  213. spin_lock_init(&time_state->lock_last_time);
  214. init_completion(&time_state->comp_last_time);
  215. time_state->common_attributes.hsdev = hsdev;
  216. time_state->common_attributes.pdev = pdev;
  217. ret = hid_sensor_parse_common_attributes(hsdev,
  218. HID_USAGE_SENSOR_TIME,
  219. &time_state->common_attributes);
  220. if (ret) {
  221. dev_err(&pdev->dev, "failed to setup common attributes!\n");
  222. return ret;
  223. }
  224. ret = hid_time_parse_report(pdev, hsdev, HID_USAGE_SENSOR_TIME,
  225. time_state);
  226. if (ret) {
  227. dev_err(&pdev->dev, "failed to setup attributes!\n");
  228. return ret;
  229. }
  230. time_state->callbacks.send_event = hid_time_proc_event;
  231. time_state->callbacks.capture_sample = hid_time_capture_sample;
  232. time_state->callbacks.pdev = pdev;
  233. ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_TIME,
  234. &time_state->callbacks);
  235. if (ret < 0) {
  236. dev_err(&pdev->dev, "register callback failed!\n");
  237. return ret;
  238. }
  239. ret = sensor_hub_device_open(hsdev);
  240. if (ret) {
  241. dev_err(&pdev->dev, "failed to open sensor hub device!\n");
  242. goto err_open;
  243. }
  244. /*
  245. * Enable HID input processing early in order to be able to read the
  246. * clock already in devm_rtc_device_register().
  247. */
  248. hid_device_io_start(hsdev->hdev);
  249. time_state->rtc = devm_rtc_device_register(&pdev->dev,
  250. "hid-sensor-time", &hid_time_rtc_ops,
  251. THIS_MODULE);
  252. if (IS_ERR(time_state->rtc)) {
  253. hid_device_io_stop(hsdev->hdev);
  254. ret = PTR_ERR(time_state->rtc);
  255. time_state->rtc = NULL;
  256. dev_err(&pdev->dev, "rtc device register failed!\n");
  257. goto err_rtc;
  258. }
  259. return ret;
  260. err_rtc:
  261. sensor_hub_device_close(hsdev);
  262. err_open:
  263. sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
  264. return ret;
  265. }
  266. static int hid_time_remove(struct platform_device *pdev)
  267. {
  268. struct hid_sensor_hub_device *hsdev = dev_get_platdata(&pdev->dev);
  269. sensor_hub_device_close(hsdev);
  270. sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
  271. return 0;
  272. }
  273. static const struct platform_device_id hid_time_ids[] = {
  274. {
  275. /* Format: HID-SENSOR-usage_id_in_hex_lowercase */
  276. .name = "HID-SENSOR-2000a0",
  277. },
  278. { /* sentinel */ }
  279. };
  280. MODULE_DEVICE_TABLE(platform, hid_time_ids);
  281. static struct platform_driver hid_time_platform_driver = {
  282. .id_table = hid_time_ids,
  283. .driver = {
  284. .name = KBUILD_MODNAME,
  285. },
  286. .probe = hid_time_probe,
  287. .remove = hid_time_remove,
  288. };
  289. module_platform_driver(hid_time_platform_driver);
  290. MODULE_DESCRIPTION("HID Sensor Time");
  291. MODULE_AUTHOR("Alexander Holler <holler@ahsoftware.de>");
  292. MODULE_LICENSE("GPL");