1 // SPDX-License-Identifier: GPL-2.0 2 // RTC driver for ChromeOS Embedded Controller. 3 // 4 // Copyright (C) 2017 Google, Inc. 5 // Author: Stephen Barber <smbarber@chromium.org> 6 7 #include <linux/kernel.h> 8 #include <linux/mod_devicetable.h> 9 #include <linux/module.h> 10 #include <linux/platform_data/cros_ec_commands.h> 11 #include <linux/platform_data/cros_ec_proto.h> 12 #include <linux/platform_device.h> 13 #include <linux/rtc.h> 14 #include <linux/slab.h> 15 16 #define DRV_NAME "cros-ec-rtc" 17 18 #define SECS_PER_DAY (24 * 60 * 60) 19 20 /** 21 * struct cros_ec_rtc - Driver data for EC RTC 22 * 23 * @cros_ec: Pointer to EC device 24 * @rtc: Pointer to RTC device 25 * @notifier: Notifier info for responding to EC events 26 * @saved_alarm: Alarm to restore when interrupts are reenabled 27 */ 28 struct cros_ec_rtc { 29 struct cros_ec_device *cros_ec; 30 struct rtc_device *rtc; 31 struct notifier_block notifier; 32 u32 saved_alarm; 33 }; 34 35 static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command, 36 u32 *response) 37 { 38 int ret; 39 struct { 40 struct cros_ec_command msg; 41 struct ec_response_rtc data; 42 } __packed msg; 43 44 memset(&msg, 0, sizeof(msg)); 45 msg.msg.command = command; 46 msg.msg.insize = sizeof(msg.data); 47 48 ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); 49 if (ret < 0) 50 return ret; 51 52 *response = msg.data.time; 53 54 return 0; 55 } 56 57 static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command, 58 u32 param) 59 { 60 int ret; 61 struct { 62 struct cros_ec_command msg; 63 struct ec_response_rtc data; 64 } __packed msg; 65 66 memset(&msg, 0, sizeof(msg)); 67 msg.msg.command = command; 68 msg.msg.outsize = sizeof(msg.data); 69 msg.data.time = param; 70 71 ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); 72 if (ret < 0) 73 return ret; 74 return 0; 75 } 76 77 /* Read the current time from the EC. */ 78 static int cros_ec_rtc_read_time(struct device *dev, struct rtc_time *tm) 79 { 80 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); 81 struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; 82 int ret; 83 u32 time; 84 85 ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, &time); 86 if (ret) { 87 dev_err(dev, "error getting time: %d\n", ret); 88 return ret; 89 } 90 91 rtc_time64_to_tm(time, tm); 92 93 return 0; 94 } 95 96 /* Set the current EC time. */ 97 static int cros_ec_rtc_set_time(struct device *dev, struct rtc_time *tm) 98 { 99 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); 100 struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; 101 int ret; 102 time64_t time = rtc_tm_to_time64(tm); 103 104 ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_VALUE, (u32)time); 105 if (ret < 0) { 106 dev_err(dev, "error setting time: %d\n", ret); 107 return ret; 108 } 109 110 return 0; 111 } 112 113 /* Read alarm time from RTC. */ 114 static int cros_ec_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 115 { 116 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); 117 struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; 118 int ret; 119 u32 current_time, alarm_offset; 120 121 /* 122 * The EC host command for getting the alarm is relative (i.e. 5 123 * seconds from now) whereas rtc_wkalrm is absolute. Get the current 124 * RTC time first so we can calculate the relative time. 125 */ 126 ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); 127 if (ret < 0) { 128 dev_err(dev, "error getting time: %d\n", ret); 129 return ret; 130 } 131 132 ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_ALARM, &alarm_offset); 133 if (ret < 0) { 134 dev_err(dev, "error getting alarm: %d\n", ret); 135 return ret; 136 } 137 138 rtc_time64_to_tm(current_time + alarm_offset, &alrm->time); 139 140 return 0; 141 } 142 143 /* Set the EC's RTC alarm. */ 144 static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 145 { 146 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); 147 struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; 148 int ret; 149 time64_t alarm_time; 150 u32 current_time, alarm_offset; 151 152 /* 153 * The EC host command for setting the alarm is relative 154 * (i.e. 5 seconds from now) whereas rtc_wkalrm is absolute. 155 * Get the current RTC time first so we can calculate the 156 * relative time. 157 */ 158 ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); 159 if (ret < 0) { 160 dev_err(dev, "error getting time: %d\n", ret); 161 return ret; 162 } 163 164 alarm_time = rtc_tm_to_time64(&alrm->time); 165 166 if (alarm_time < 0 || alarm_time > U32_MAX) 167 return -EINVAL; 168 169 if (!alrm->enabled) { 170 /* 171 * If the alarm is being disabled, send an alarm 172 * clear command. 173 */ 174 alarm_offset = EC_RTC_ALARM_CLEAR; 175 cros_ec_rtc->saved_alarm = (u32)alarm_time; 176 } else { 177 /* Don't set an alarm in the past. */ 178 if ((u32)alarm_time <= current_time) 179 return -ETIME; 180 181 alarm_offset = (u32)alarm_time - current_time; 182 } 183 184 ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset); 185 if (ret < 0) { 186 dev_err(dev, "error setting alarm in %u seconds: %d\n", 187 alarm_offset, ret); 188 /* 189 * The EC code returns -EINVAL if the alarm time is too 190 * far in the future. Convert it to the expected error code. 191 */ 192 if (ret == -EINVAL) 193 ret = -ERANGE; 194 return ret; 195 } 196 197 return 0; 198 } 199 200 static int cros_ec_rtc_alarm_irq_enable(struct device *dev, 201 unsigned int enabled) 202 { 203 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); 204 struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; 205 int ret; 206 u32 current_time, alarm_offset, alarm_value; 207 208 ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); 209 if (ret < 0) { 210 dev_err(dev, "error getting time: %d\n", ret); 211 return ret; 212 } 213 214 if (enabled) { 215 /* Restore saved alarm if it's still in the future. */ 216 if (cros_ec_rtc->saved_alarm < current_time) 217 alarm_offset = EC_RTC_ALARM_CLEAR; 218 else 219 alarm_offset = cros_ec_rtc->saved_alarm - current_time; 220 221 ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, 222 alarm_offset); 223 if (ret < 0) { 224 dev_err(dev, "error restoring alarm: %d\n", ret); 225 return ret; 226 } 227 } else { 228 /* Disable alarm, saving the old alarm value. */ 229 ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_ALARM, 230 &alarm_offset); 231 if (ret < 0) { 232 dev_err(dev, "error saving alarm: %d\n", ret); 233 return ret; 234 } 235 236 alarm_value = current_time + alarm_offset; 237 238 /* 239 * If the current EC alarm is already past, we don't want 240 * to set an alarm when we go through the alarm irq enable 241 * path. 242 */ 243 if (alarm_value < current_time) 244 cros_ec_rtc->saved_alarm = EC_RTC_ALARM_CLEAR; 245 else 246 cros_ec_rtc->saved_alarm = alarm_value; 247 248 alarm_offset = EC_RTC_ALARM_CLEAR; 249 ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, 250 alarm_offset); 251 if (ret < 0) { 252 dev_err(dev, "error disabling alarm: %d\n", ret); 253 return ret; 254 } 255 } 256 257 return 0; 258 } 259 260 static int cros_ec_rtc_event(struct notifier_block *nb, 261 unsigned long queued_during_suspend, 262 void *_notify) 263 { 264 struct cros_ec_rtc *cros_ec_rtc; 265 struct rtc_device *rtc; 266 struct cros_ec_device *cros_ec; 267 u32 host_event; 268 269 cros_ec_rtc = container_of(nb, struct cros_ec_rtc, notifier); 270 rtc = cros_ec_rtc->rtc; 271 cros_ec = cros_ec_rtc->cros_ec; 272 273 host_event = cros_ec_get_host_event(cros_ec); 274 if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC)) { 275 rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); 276 return NOTIFY_OK; 277 } else { 278 return NOTIFY_DONE; 279 } 280 } 281 282 static const struct rtc_class_ops cros_ec_rtc_ops = { 283 .read_time = cros_ec_rtc_read_time, 284 .set_time = cros_ec_rtc_set_time, 285 .read_alarm = cros_ec_rtc_read_alarm, 286 .set_alarm = cros_ec_rtc_set_alarm, 287 .alarm_irq_enable = cros_ec_rtc_alarm_irq_enable, 288 }; 289 290 #ifdef CONFIG_PM_SLEEP 291 static int cros_ec_rtc_suspend(struct device *dev) 292 { 293 struct platform_device *pdev = to_platform_device(dev); 294 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(&pdev->dev); 295 296 if (device_may_wakeup(dev)) 297 return enable_irq_wake(cros_ec_rtc->cros_ec->irq); 298 299 return 0; 300 } 301 302 static int cros_ec_rtc_resume(struct device *dev) 303 { 304 struct platform_device *pdev = to_platform_device(dev); 305 struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(&pdev->dev); 306 307 if (device_may_wakeup(dev)) 308 return disable_irq_wake(cros_ec_rtc->cros_ec->irq); 309 310 return 0; 311 } 312 #endif 313 314 static SIMPLE_DEV_PM_OPS(cros_ec_rtc_pm_ops, cros_ec_rtc_suspend, 315 cros_ec_rtc_resume); 316 317 static int cros_ec_rtc_probe(struct platform_device *pdev) 318 { 319 struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent); 320 struct cros_ec_device *cros_ec = ec_dev->ec_dev; 321 struct cros_ec_rtc *cros_ec_rtc; 322 struct rtc_time tm; 323 int ret; 324 325 cros_ec_rtc = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_rtc), 326 GFP_KERNEL); 327 if (!cros_ec_rtc) 328 return -ENOMEM; 329 330 platform_set_drvdata(pdev, cros_ec_rtc); 331 cros_ec_rtc->cros_ec = cros_ec; 332 333 /* Get initial time */ 334 ret = cros_ec_rtc_read_time(&pdev->dev, &tm); 335 if (ret) { 336 dev_err(&pdev->dev, "failed to read RTC time\n"); 337 return ret; 338 } 339 340 ret = device_init_wakeup(&pdev->dev, 1); 341 if (ret) { 342 dev_err(&pdev->dev, "failed to initialize wakeup\n"); 343 return ret; 344 } 345 346 cros_ec_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); 347 if (IS_ERR(cros_ec_rtc->rtc)) 348 return PTR_ERR(cros_ec_rtc->rtc); 349 350 cros_ec_rtc->rtc->ops = &cros_ec_rtc_ops; 351 cros_ec_rtc->rtc->range_max = U32_MAX; 352 353 /* 354 * The RTC on some older Chromebooks can only handle alarms less than 355 * 24 hours in the future. The only way to find out is to try to set an 356 * alarm further in the future. If that fails, assume that the RTC 357 * connected to the EC can only handle less than 24 hours of alarm 358 * window. 359 */ 360 ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, SECS_PER_DAY * 2); 361 if (ret == -EINVAL) 362 cros_ec_rtc->rtc->alarm_offset_max = SECS_PER_DAY - 1; 363 364 (void)cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, 365 EC_RTC_ALARM_CLEAR); 366 367 ret = devm_rtc_register_device(cros_ec_rtc->rtc); 368 if (ret) 369 return ret; 370 371 /* Get RTC events from the EC. */ 372 cros_ec_rtc->notifier.notifier_call = cros_ec_rtc_event; 373 ret = blocking_notifier_chain_register(&cros_ec->event_notifier, 374 &cros_ec_rtc->notifier); 375 if (ret) { 376 dev_err(&pdev->dev, "failed to register notifier\n"); 377 return ret; 378 } 379 380 return 0; 381 } 382 383 static void cros_ec_rtc_remove(struct platform_device *pdev) 384 { 385 struct cros_ec_rtc *cros_ec_rtc = platform_get_drvdata(pdev); 386 struct device *dev = &pdev->dev; 387 int ret; 388 389 ret = blocking_notifier_chain_unregister( 390 &cros_ec_rtc->cros_ec->event_notifier, 391 &cros_ec_rtc->notifier); 392 if (ret) 393 dev_err(dev, "failed to unregister notifier\n"); 394 } 395 396 static const struct platform_device_id cros_ec_rtc_id[] = { 397 { DRV_NAME, 0 }, 398 {} 399 }; 400 MODULE_DEVICE_TABLE(platform, cros_ec_rtc_id); 401 402 static struct platform_driver cros_ec_rtc_driver = { 403 .probe = cros_ec_rtc_probe, 404 .remove = cros_ec_rtc_remove, 405 .driver = { 406 .name = DRV_NAME, 407 .pm = &cros_ec_rtc_pm_ops, 408 }, 409 .id_table = cros_ec_rtc_id, 410 }; 411 412 module_platform_driver(cros_ec_rtc_driver); 413 414 MODULE_DESCRIPTION("RTC driver for Chrome OS ECs"); 415 MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>"); 416 MODULE_LICENSE("GPL v2"); 417