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