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