1 /* 2 * "RTT as Real Time Clock" driver for AT91SAM9 SoC family 3 * 4 * (C) 2007 Michel Benoit 5 * 6 * Based on rtc-at91rm9200.c by Rick Bronson 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 */ 13 14 #include <linux/module.h> 15 #include <linux/kernel.h> 16 #include <linux/platform_device.h> 17 #include <linux/time.h> 18 #include <linux/rtc.h> 19 #include <linux/interrupt.h> 20 #include <linux/ioctl.h> 21 22 #include <mach/board.h> 23 #include <mach/at91_rtt.h> 24 25 26 /* 27 * This driver uses two configurable hardware resources that live in the 28 * AT91SAM9 backup power domain (intended to be powered at all times) 29 * to implement the Real Time Clock interfaces 30 * 31 * - A "Real-time Timer" (RTT) counts up in seconds from a base time. 32 * We can't assign the counter value (CRTV) ... but we can reset it. 33 * 34 * - One of the "General Purpose Backup Registers" (GPBRs) holds the 35 * base time, normally an offset from the beginning of the POSIX 36 * epoch (1970-Jan-1 00:00:00 UTC). Some systems also include the 37 * local timezone's offset. 38 * 39 * The RTC's value is the RTT counter plus that offset. The RTC's alarm 40 * is likewise a base (ALMV) plus that offset. 41 * 42 * Not all RTTs will be used as RTCs; some systems have multiple RTTs to 43 * choose from, or a "real" RTC module. All systems have multiple GPBR 44 * registers available, likewise usable for more than "RTC" support. 45 */ 46 47 /* 48 * We store ALARM_DISABLED in ALMV to record that no alarm is set. 49 * It's also the reset value for that field. 50 */ 51 #define ALARM_DISABLED ((u32)~0) 52 53 54 struct sam9_rtc { 55 void __iomem *rtt; 56 struct rtc_device *rtcdev; 57 u32 imr; 58 }; 59 60 #define rtt_readl(rtc, field) \ 61 __raw_readl((rtc)->rtt + AT91_RTT_ ## field) 62 #define rtt_writel(rtc, field, val) \ 63 __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) 64 65 #define gpbr_readl(rtc) \ 66 at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) 67 #define gpbr_writel(rtc, val) \ 68 at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) 69 70 /* 71 * Read current time and date in RTC 72 */ 73 static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) 74 { 75 struct sam9_rtc *rtc = dev_get_drvdata(dev); 76 u32 secs, secs2; 77 u32 offset; 78 79 /* read current time offset */ 80 offset = gpbr_readl(rtc); 81 if (offset == 0) 82 return -EILSEQ; 83 84 /* reread the counter to help sync the two clock domains */ 85 secs = rtt_readl(rtc, VR); 86 secs2 = rtt_readl(rtc, VR); 87 if (secs != secs2) 88 secs = rtt_readl(rtc, VR); 89 90 rtc_time_to_tm(offset + secs, tm); 91 92 dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime", 93 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, 94 tm->tm_hour, tm->tm_min, tm->tm_sec); 95 96 return 0; 97 } 98 99 /* 100 * Set current time and date in RTC 101 */ 102 static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) 103 { 104 struct sam9_rtc *rtc = dev_get_drvdata(dev); 105 int err; 106 u32 offset, alarm, mr; 107 unsigned long secs; 108 109 dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime", 110 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, 111 tm->tm_hour, tm->tm_min, tm->tm_sec); 112 113 err = rtc_tm_to_time(tm, &secs); 114 if (err != 0) 115 return err; 116 117 mr = rtt_readl(rtc, MR); 118 119 /* disable interrupts */ 120 rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); 121 122 /* read current time offset */ 123 offset = gpbr_readl(rtc); 124 125 /* store the new base time in a battery backup register */ 126 secs += 1; 127 gpbr_writel(rtc, secs); 128 129 /* adjust the alarm time for the new base */ 130 alarm = rtt_readl(rtc, AR); 131 if (alarm != ALARM_DISABLED) { 132 if (offset > secs) { 133 /* time jumped backwards, increase time until alarm */ 134 alarm += (offset - secs); 135 } else if ((alarm + offset) > secs) { 136 /* time jumped forwards, decrease time until alarm */ 137 alarm -= (secs - offset); 138 } else { 139 /* time jumped past the alarm, disable alarm */ 140 alarm = ALARM_DISABLED; 141 mr &= ~AT91_RTT_ALMIEN; 142 } 143 rtt_writel(rtc, AR, alarm); 144 } 145 146 /* reset the timer, and re-enable interrupts */ 147 rtt_writel(rtc, MR, mr | AT91_RTT_RTTRST); 148 149 return 0; 150 } 151 152 static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) 153 { 154 struct sam9_rtc *rtc = dev_get_drvdata(dev); 155 struct rtc_time *tm = &alrm->time; 156 u32 alarm = rtt_readl(rtc, AR); 157 u32 offset; 158 159 offset = gpbr_readl(rtc); 160 if (offset == 0) 161 return -EILSEQ; 162 163 memset(alrm, 0, sizeof(alrm)); 164 if (alarm != ALARM_DISABLED && offset != 0) { 165 rtc_time_to_tm(offset + alarm, tm); 166 167 dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm", 168 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, 169 tm->tm_hour, tm->tm_min, tm->tm_sec); 170 171 if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN) 172 alrm->enabled = 1; 173 } 174 175 return 0; 176 } 177 178 static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) 179 { 180 struct sam9_rtc *rtc = dev_get_drvdata(dev); 181 struct rtc_time *tm = &alrm->time; 182 unsigned long secs; 183 u32 offset; 184 u32 mr; 185 int err; 186 187 err = rtc_tm_to_time(tm, &secs); 188 if (err != 0) 189 return err; 190 191 offset = gpbr_readl(rtc); 192 if (offset == 0) { 193 /* time is not set */ 194 return -EILSEQ; 195 } 196 mr = rtt_readl(rtc, MR); 197 rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); 198 199 /* alarm in the past? finish and leave disabled */ 200 if (secs <= offset) { 201 rtt_writel(rtc, AR, ALARM_DISABLED); 202 return 0; 203 } 204 205 /* else set alarm and maybe enable it */ 206 rtt_writel(rtc, AR, secs - offset); 207 if (alrm->enabled) 208 rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); 209 210 dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm", 211 tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, 212 tm->tm_min, tm->tm_sec); 213 214 return 0; 215 } 216 217 /* 218 * Handle commands from user-space 219 */ 220 static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, 221 unsigned long arg) 222 { 223 struct sam9_rtc *rtc = dev_get_drvdata(dev); 224 int ret = 0; 225 u32 mr = rtt_readl(rtc, MR); 226 227 dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); 228 229 switch (cmd) { 230 case RTC_AIE_OFF: /* alarm off */ 231 rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); 232 break; 233 case RTC_AIE_ON: /* alarm on */ 234 rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); 235 break; 236 case RTC_UIE_OFF: /* update off */ 237 rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); 238 break; 239 case RTC_UIE_ON: /* update on */ 240 rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN); 241 break; 242 default: 243 ret = -ENOIOCTLCMD; 244 break; 245 } 246 247 return ret; 248 } 249 250 /* 251 * Provide additional RTC information in /proc/driver/rtc 252 */ 253 static int at91_rtc_proc(struct device *dev, struct seq_file *seq) 254 { 255 struct sam9_rtc *rtc = dev_get_drvdata(dev); 256 u32 mr = mr = rtt_readl(rtc, MR); 257 258 seq_printf(seq, "update_IRQ\t: %s\n", 259 (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); 260 return 0; 261 } 262 263 /* 264 * IRQ handler for the RTC 265 */ 266 static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) 267 { 268 struct sam9_rtc *rtc = _rtc; 269 u32 sr, mr; 270 unsigned long events = 0; 271 272 /* Shared interrupt may be for another device. Note: reading 273 * SR clears it, so we must only read it in this irq handler! 274 */ 275 mr = rtt_readl(rtc, MR) & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); 276 sr = rtt_readl(rtc, SR) & (mr >> 16); 277 if (!sr) 278 return IRQ_NONE; 279 280 /* alarm status */ 281 if (sr & AT91_RTT_ALMS) 282 events |= (RTC_AF | RTC_IRQF); 283 284 /* timer update/increment */ 285 if (sr & AT91_RTT_RTTINC) 286 events |= (RTC_UF | RTC_IRQF); 287 288 rtc_update_irq(rtc->rtcdev, 1, events); 289 290 pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, 291 events >> 8, events & 0x000000FF); 292 293 return IRQ_HANDLED; 294 } 295 296 static const struct rtc_class_ops at91_rtc_ops = { 297 .ioctl = at91_rtc_ioctl, 298 .read_time = at91_rtc_readtime, 299 .set_time = at91_rtc_settime, 300 .read_alarm = at91_rtc_readalarm, 301 .set_alarm = at91_rtc_setalarm, 302 .proc = at91_rtc_proc, 303 }; 304 305 /* 306 * Initialize and install RTC driver 307 */ 308 static int __init at91_rtc_probe(struct platform_device *pdev) 309 { 310 struct resource *r; 311 struct sam9_rtc *rtc; 312 int ret; 313 u32 mr; 314 315 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 316 if (!r) 317 return -ENODEV; 318 319 rtc = kzalloc(sizeof *rtc, GFP_KERNEL); 320 if (!rtc) 321 return -ENOMEM; 322 323 /* platform setup code should have handled this; sigh */ 324 if (!device_can_wakeup(&pdev->dev)) 325 device_init_wakeup(&pdev->dev, 1); 326 327 platform_set_drvdata(pdev, rtc); 328 rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS); 329 rtc->rtt += r->start; 330 331 mr = rtt_readl(rtc, MR); 332 333 /* unless RTT is counting at 1 Hz, re-initialize it */ 334 if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) { 335 mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES); 336 gpbr_writel(rtc, 0); 337 } 338 339 /* disable all interrupts (same as on shutdown path) */ 340 mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); 341 rtt_writel(rtc, MR, mr); 342 343 rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, 344 &at91_rtc_ops, THIS_MODULE); 345 if (IS_ERR(rtc->rtcdev)) { 346 ret = PTR_ERR(rtc->rtcdev); 347 goto fail; 348 } 349 350 /* register irq handler after we know what name we'll use */ 351 ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, 352 IRQF_DISABLED | IRQF_SHARED, 353 rtc->rtcdev->dev.bus_id, rtc); 354 if (ret) { 355 dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); 356 rtc_device_unregister(rtc->rtcdev); 357 goto fail; 358 } 359 360 /* NOTE: sam9260 rev A silicon has a ROM bug which resets the 361 * RTT on at least some reboots. If you have that chip, you must 362 * initialize the time from some external source like a GPS, wall 363 * clock, discrete RTC, etc 364 */ 365 366 if (gpbr_readl(rtc) == 0) 367 dev_warn(&pdev->dev, "%s: SET TIME!\n", 368 rtc->rtcdev->dev.bus_id); 369 370 return 0; 371 372 fail: 373 platform_set_drvdata(pdev, NULL); 374 kfree(rtc); 375 return ret; 376 } 377 378 /* 379 * Disable and remove the RTC driver 380 */ 381 static int __exit at91_rtc_remove(struct platform_device *pdev) 382 { 383 struct sam9_rtc *rtc = platform_get_drvdata(pdev); 384 u32 mr = rtt_readl(rtc, MR); 385 386 /* disable all interrupts */ 387 rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); 388 free_irq(AT91_ID_SYS, rtc); 389 390 rtc_device_unregister(rtc->rtcdev); 391 392 platform_set_drvdata(pdev, NULL); 393 kfree(rtc); 394 return 0; 395 } 396 397 static void at91_rtc_shutdown(struct platform_device *pdev) 398 { 399 struct sam9_rtc *rtc = platform_get_drvdata(pdev); 400 u32 mr = rtt_readl(rtc, MR); 401 402 rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); 403 rtt_writel(rtc, MR, mr & ~rtc->imr); 404 } 405 406 #ifdef CONFIG_PM 407 408 /* AT91SAM9 RTC Power management control */ 409 410 static int at91_rtc_suspend(struct platform_device *pdev, 411 pm_message_t state) 412 { 413 struct sam9_rtc *rtc = platform_get_drvdata(pdev); 414 u32 mr = rtt_readl(rtc, MR); 415 416 /* 417 * This IRQ is shared with DBGU and other hardware which isn't 418 * necessarily a wakeup event source. 419 */ 420 rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); 421 if (rtc->imr) { 422 if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { 423 enable_irq_wake(AT91_ID_SYS); 424 /* don't let RTTINC cause wakeups */ 425 if (mr & AT91_RTT_RTTINCIEN) 426 rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); 427 } else 428 rtt_writel(rtc, MR, mr & ~rtc->imr); 429 } 430 431 return 0; 432 } 433 434 static int at91_rtc_resume(struct platform_device *pdev) 435 { 436 struct sam9_rtc *rtc = platform_get_drvdata(pdev); 437 u32 mr; 438 439 if (rtc->imr) { 440 if (device_may_wakeup(&pdev->dev)) 441 disable_irq_wake(AT91_ID_SYS); 442 mr = rtt_readl(rtc, MR); 443 rtt_writel(rtc, MR, mr | rtc->imr); 444 } 445 446 return 0; 447 } 448 #else 449 #define at91_rtc_suspend NULL 450 #define at91_rtc_resume NULL 451 #endif 452 453 static struct platform_driver at91_rtc_driver = { 454 .driver.name = "rtc-at91sam9", 455 .driver.owner = THIS_MODULE, 456 .remove = __exit_p(at91_rtc_remove), 457 .shutdown = at91_rtc_shutdown, 458 .suspend = at91_rtc_suspend, 459 .resume = at91_rtc_resume, 460 }; 461 462 /* Chips can have more than one RTT module, and they can be used for more 463 * than just RTCs. So we can't just register as "the" RTT driver. 464 * 465 * A normal approach in such cases is to create a library to allocate and 466 * free the modules. Here we just use bus_find_device() as like such a 467 * library, binding directly ... no runtime "library" footprint is needed. 468 */ 469 static int __init at91_rtc_match(struct device *dev, void *v) 470 { 471 struct platform_device *pdev = to_platform_device(dev); 472 int ret; 473 474 /* continue searching if this isn't the RTT we need */ 475 if (strcmp("at91_rtt", pdev->name) != 0 476 || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) 477 goto fail; 478 479 /* else we found it ... but fail unless we can bind to the RTC driver */ 480 if (dev->driver) { 481 dev_dbg(dev, "busy, can't use as RTC!\n"); 482 goto fail; 483 } 484 dev->driver = &at91_rtc_driver.driver; 485 if (device_attach(dev) == 0) { 486 dev_dbg(dev, "can't attach RTC!\n"); 487 goto fail; 488 } 489 ret = at91_rtc_probe(pdev); 490 if (ret == 0) 491 return true; 492 493 dev_dbg(dev, "RTC probe err %d!\n", ret); 494 fail: 495 return false; 496 } 497 498 static int __init at91_rtc_init(void) 499 { 500 int status; 501 struct device *rtc; 502 503 status = platform_driver_register(&at91_rtc_driver); 504 if (status) 505 return status; 506 rtc = bus_find_device(&platform_bus_type, NULL, 507 NULL, at91_rtc_match); 508 if (!rtc) 509 platform_driver_unregister(&at91_rtc_driver); 510 return rtc ? 0 : -ENODEV; 511 } 512 module_init(at91_rtc_init); 513 514 static void __exit at91_rtc_exit(void) 515 { 516 platform_driver_unregister(&at91_rtc_driver); 517 } 518 module_exit(at91_rtc_exit); 519 520 521 MODULE_AUTHOR("Michel Benoit"); 522 MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); 523 MODULE_LICENSE("GPL"); 524