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