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