linux/drivers/rtc/rtc-omap.c
<<
>>
Prefs
   1/*
   2 * TI OMAP1 Real Time Clock interface for Linux
   3 *
   4 * Copyright (C) 2003 MontaVista Software, Inc.
   5 * Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
   6 *
   7 * Copyright (C) 2006 David Brownell (new RTC framework)
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License
  11 * as published by the Free Software Foundation; either version
  12 * 2 of the License, or (at your option) any later version.
  13 */
  14
  15#include <linux/kernel.h>
  16#include <linux/init.h>
  17#include <linux/module.h>
  18#include <linux/ioport.h>
  19#include <linux/delay.h>
  20#include <linux/rtc.h>
  21#include <linux/bcd.h>
  22#include <linux/platform_device.h>
  23
  24#include <asm/io.h>
  25
  26
  27/* The OMAP1 RTC is a year/month/day/hours/minutes/seconds BCD clock
  28 * with century-range alarm matching, driven by the 32kHz clock.
  29 *
  30 * The main user-visible ways it differs from PC RTCs are by omitting
  31 * "don't care" alarm fields and sub-second periodic IRQs, and having
  32 * an autoadjust mechanism to calibrate to the true oscillator rate.
  33 *
  34 * Board-specific wiring options include using split power mode with
  35 * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset),
  36 * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from
  37 * low power modes).  See the BOARD-SPECIFIC CUSTOMIZATION comment.
  38 */
  39
  40#define OMAP_RTC_BASE                   0xfffb4800
  41
  42/* RTC registers */
  43#define OMAP_RTC_SECONDS_REG            0x00
  44#define OMAP_RTC_MINUTES_REG            0x04
  45#define OMAP_RTC_HOURS_REG              0x08
  46#define OMAP_RTC_DAYS_REG               0x0C
  47#define OMAP_RTC_MONTHS_REG             0x10
  48#define OMAP_RTC_YEARS_REG              0x14
  49#define OMAP_RTC_WEEKS_REG              0x18
  50
  51#define OMAP_RTC_ALARM_SECONDS_REG      0x20
  52#define OMAP_RTC_ALARM_MINUTES_REG      0x24
  53#define OMAP_RTC_ALARM_HOURS_REG        0x28
  54#define OMAP_RTC_ALARM_DAYS_REG         0x2c
  55#define OMAP_RTC_ALARM_MONTHS_REG       0x30
  56#define OMAP_RTC_ALARM_YEARS_REG        0x34
  57
  58#define OMAP_RTC_CTRL_REG               0x40
  59#define OMAP_RTC_STATUS_REG             0x44
  60#define OMAP_RTC_INTERRUPTS_REG         0x48
  61
  62#define OMAP_RTC_COMP_LSB_REG           0x4c
  63#define OMAP_RTC_COMP_MSB_REG           0x50
  64#define OMAP_RTC_OSC_REG                0x54
  65
  66/* OMAP_RTC_CTRL_REG bit fields: */
  67#define OMAP_RTC_CTRL_SPLIT             (1<<7)
  68#define OMAP_RTC_CTRL_DISABLE           (1<<6)
  69#define OMAP_RTC_CTRL_SET_32_COUNTER    (1<<5)
  70#define OMAP_RTC_CTRL_TEST              (1<<4)
  71#define OMAP_RTC_CTRL_MODE_12_24        (1<<3)
  72#define OMAP_RTC_CTRL_AUTO_COMP         (1<<2)
  73#define OMAP_RTC_CTRL_ROUND_30S         (1<<1)
  74#define OMAP_RTC_CTRL_STOP              (1<<0)
  75
  76/* OMAP_RTC_STATUS_REG bit fields: */
  77#define OMAP_RTC_STATUS_POWER_UP        (1<<7)
  78#define OMAP_RTC_STATUS_ALARM           (1<<6)
  79#define OMAP_RTC_STATUS_1D_EVENT        (1<<5)
  80#define OMAP_RTC_STATUS_1H_EVENT        (1<<4)
  81#define OMAP_RTC_STATUS_1M_EVENT        (1<<3)
  82#define OMAP_RTC_STATUS_1S_EVENT        (1<<2)
  83#define OMAP_RTC_STATUS_RUN             (1<<1)
  84#define OMAP_RTC_STATUS_BUSY            (1<<0)
  85
  86/* OMAP_RTC_INTERRUPTS_REG bit fields: */
  87#define OMAP_RTC_INTERRUPTS_IT_ALARM    (1<<3)
  88#define OMAP_RTC_INTERRUPTS_IT_TIMER    (1<<2)
  89
  90
  91#define rtc_read(addr)          omap_readb(OMAP_RTC_BASE + (addr))
  92#define rtc_write(val, addr)    omap_writeb(val, OMAP_RTC_BASE + (addr))
  93
  94
  95/* we rely on the rtc framework to handle locking (rtc->ops_lock),
  96 * so the only other requirement is that register accesses which
  97 * require BUSY to be clear are made with IRQs locally disabled
  98 */
  99static void rtc_wait_not_busy(void)
 100{
 101        int     count = 0;
 102        u8      status;
 103
 104        /* BUSY may stay active for 1/32768 second (~30 usec) */
 105        for (count = 0; count < 50; count++) {
 106                status = rtc_read(OMAP_RTC_STATUS_REG);
 107                if ((status & (u8)OMAP_RTC_STATUS_BUSY) == 0)
 108                        break;
 109                udelay(1);
 110        }
 111        /* now we have ~15 usec to read/write various registers */
 112}
 113
 114static irqreturn_t rtc_irq(int irq, void *rtc)
 115{
 116        unsigned long           events = 0;
 117        u8                      irq_data;
 118
 119        irq_data = rtc_read(OMAP_RTC_STATUS_REG);
 120
 121        /* alarm irq? */
 122        if (irq_data & OMAP_RTC_STATUS_ALARM) {
 123                rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
 124                events |= RTC_IRQF | RTC_AF;
 125        }
 126
 127        /* 1/sec periodic/update irq? */
 128        if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
 129                events |= RTC_IRQF | RTC_UF;
 130
 131        rtc_update_irq(rtc, 1, events);
 132
 133        return IRQ_HANDLED;
 134}
 135
 136#ifdef  CONFIG_RTC_INTF_DEV
 137
 138static int
 139omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 140{
 141        u8 reg;
 142
 143        switch (cmd) {
 144        case RTC_AIE_OFF:
 145        case RTC_AIE_ON:
 146        case RTC_UIE_OFF:
 147        case RTC_UIE_ON:
 148                break;
 149        default:
 150                return -ENOIOCTLCMD;
 151        }
 152
 153        local_irq_disable();
 154        rtc_wait_not_busy();
 155        reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
 156        switch (cmd) {
 157        /* AIE = Alarm Interrupt Enable */
 158        case RTC_AIE_OFF:
 159                reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
 160                break;
 161        case RTC_AIE_ON:
 162                reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
 163                break;
 164        /* UIE = Update Interrupt Enable (1/second) */
 165        case RTC_UIE_OFF:
 166                reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER;
 167                break;
 168        case RTC_UIE_ON:
 169                reg |= OMAP_RTC_INTERRUPTS_IT_TIMER;
 170                break;
 171        }
 172        rtc_wait_not_busy();
 173        rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
 174        local_irq_enable();
 175
 176        return 0;
 177}
 178
 179#else
 180#define omap_rtc_ioctl  NULL
 181#endif
 182
 183/* this hardware doesn't support "don't care" alarm fields */
 184static int tm2bcd(struct rtc_time *tm)
 185{
 186        if (rtc_valid_tm(tm) != 0)
 187                return -EINVAL;
 188
 189        tm->tm_sec = bin2bcd(tm->tm_sec);
 190        tm->tm_min = bin2bcd(tm->tm_min);
 191        tm->tm_hour = bin2bcd(tm->tm_hour);
 192        tm->tm_mday = bin2bcd(tm->tm_mday);
 193
 194        tm->tm_mon = bin2bcd(tm->tm_mon + 1);
 195
 196        /* epoch == 1900 */
 197        if (tm->tm_year < 100 || tm->tm_year > 199)
 198                return -EINVAL;
 199        tm->tm_year = bin2bcd(tm->tm_year - 100);
 200
 201        return 0;
 202}
 203
 204static void bcd2tm(struct rtc_time *tm)
 205{
 206        tm->tm_sec = bcd2bin(tm->tm_sec);
 207        tm->tm_min = bcd2bin(tm->tm_min);
 208        tm->tm_hour = bcd2bin(tm->tm_hour);
 209        tm->tm_mday = bcd2bin(tm->tm_mday);
 210        tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
 211        /* epoch == 1900 */
 212        tm->tm_year = bcd2bin(tm->tm_year) + 100;
 213}
 214
 215
 216static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm)
 217{
 218        /* we don't report wday/yday/isdst ... */
 219        local_irq_disable();
 220        rtc_wait_not_busy();
 221
 222        tm->tm_sec = rtc_read(OMAP_RTC_SECONDS_REG);
 223        tm->tm_min = rtc_read(OMAP_RTC_MINUTES_REG);
 224        tm->tm_hour = rtc_read(OMAP_RTC_HOURS_REG);
 225        tm->tm_mday = rtc_read(OMAP_RTC_DAYS_REG);
 226        tm->tm_mon = rtc_read(OMAP_RTC_MONTHS_REG);
 227        tm->tm_year = rtc_read(OMAP_RTC_YEARS_REG);
 228
 229        local_irq_enable();
 230
 231        bcd2tm(tm);
 232        return 0;
 233}
 234
 235static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm)
 236{
 237        if (tm2bcd(tm) < 0)
 238                return -EINVAL;
 239        local_irq_disable();
 240        rtc_wait_not_busy();
 241
 242        rtc_write(tm->tm_year, OMAP_RTC_YEARS_REG);
 243        rtc_write(tm->tm_mon, OMAP_RTC_MONTHS_REG);
 244        rtc_write(tm->tm_mday, OMAP_RTC_DAYS_REG);
 245        rtc_write(tm->tm_hour, OMAP_RTC_HOURS_REG);
 246        rtc_write(tm->tm_min, OMAP_RTC_MINUTES_REG);
 247        rtc_write(tm->tm_sec, OMAP_RTC_SECONDS_REG);
 248
 249        local_irq_enable();
 250
 251        return 0;
 252}
 253
 254static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 255{
 256        local_irq_disable();
 257        rtc_wait_not_busy();
 258
 259        alm->time.tm_sec = rtc_read(OMAP_RTC_ALARM_SECONDS_REG);
 260        alm->time.tm_min = rtc_read(OMAP_RTC_ALARM_MINUTES_REG);
 261        alm->time.tm_hour = rtc_read(OMAP_RTC_ALARM_HOURS_REG);
 262        alm->time.tm_mday = rtc_read(OMAP_RTC_ALARM_DAYS_REG);
 263        alm->time.tm_mon = rtc_read(OMAP_RTC_ALARM_MONTHS_REG);
 264        alm->time.tm_year = rtc_read(OMAP_RTC_ALARM_YEARS_REG);
 265
 266        local_irq_enable();
 267
 268        bcd2tm(&alm->time);
 269        alm->enabled = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
 270                        & OMAP_RTC_INTERRUPTS_IT_ALARM);
 271
 272        return 0;
 273}
 274
 275static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 276{
 277        u8 reg;
 278
 279        if (tm2bcd(&alm->time) < 0)
 280                return -EINVAL;
 281
 282        local_irq_disable();
 283        rtc_wait_not_busy();
 284
 285        rtc_write(alm->time.tm_year, OMAP_RTC_ALARM_YEARS_REG);
 286        rtc_write(alm->time.tm_mon, OMAP_RTC_ALARM_MONTHS_REG);
 287        rtc_write(alm->time.tm_mday, OMAP_RTC_ALARM_DAYS_REG);
 288        rtc_write(alm->time.tm_hour, OMAP_RTC_ALARM_HOURS_REG);
 289        rtc_write(alm->time.tm_min, OMAP_RTC_ALARM_MINUTES_REG);
 290        rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);
 291
 292        reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
 293        if (alm->enabled)
 294                reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
 295        else
 296                reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
 297        rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
 298
 299        local_irq_enable();
 300
 301        return 0;
 302}
 303
 304static struct rtc_class_ops omap_rtc_ops = {
 305        .ioctl          = omap_rtc_ioctl,
 306        .read_time      = omap_rtc_read_time,
 307        .set_time       = omap_rtc_set_time,
 308        .read_alarm     = omap_rtc_read_alarm,
 309        .set_alarm      = omap_rtc_set_alarm,
 310};
 311
 312static int omap_rtc_alarm;
 313static int omap_rtc_timer;
 314
 315static int __init omap_rtc_probe(struct platform_device *pdev)
 316{
 317        struct resource         *res, *mem;
 318        struct rtc_device       *rtc;
 319        u8                      reg, new_ctrl;
 320
 321        omap_rtc_timer = platform_get_irq(pdev, 0);
 322        if (omap_rtc_timer <= 0) {
 323                pr_debug("%s: no update irq?\n", pdev->name);
 324                return -ENOENT;
 325        }
 326
 327        omap_rtc_alarm = platform_get_irq(pdev, 1);
 328        if (omap_rtc_alarm <= 0) {
 329                pr_debug("%s: no alarm irq?\n", pdev->name);
 330                return -ENOENT;
 331        }
 332
 333        /* NOTE:  using static mapping for RTC registers */
 334        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 335        if (res && res->start != OMAP_RTC_BASE) {
 336                pr_debug("%s: RTC registers at %08x, expected %08x\n",
 337                        pdev->name, (unsigned) res->start, OMAP_RTC_BASE);
 338                return -ENOENT;
 339        }
 340
 341        if (res)
 342                mem = request_mem_region(res->start,
 343                                res->end - res->start + 1,
 344                                pdev->name);
 345        else
 346                mem = NULL;
 347        if (!mem) {
 348                pr_debug("%s: RTC registers at %08x are not free\n",
 349                        pdev->name, OMAP_RTC_BASE);
 350                return -EBUSY;
 351        }
 352
 353        rtc = rtc_device_register(pdev->name, &pdev->dev,
 354                        &omap_rtc_ops, THIS_MODULE);
 355        if (IS_ERR(rtc)) {
 356                pr_debug("%s: can't register RTC device, err %ld\n",
 357                        pdev->name, PTR_ERR(rtc));
 358                goto fail;
 359        }
 360        platform_set_drvdata(pdev, rtc);
 361        dev_set_drvdata(&rtc->dev, mem);
 362
 363        /* clear pending irqs, and set 1/second periodic,
 364         * which we'll use instead of update irqs
 365         */
 366        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 367
 368        /* clear old status */
 369        reg = rtc_read(OMAP_RTC_STATUS_REG);
 370        if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
 371                pr_info("%s: RTC power up reset detected\n",
 372                        pdev->name);
 373                rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG);
 374        }
 375        if (reg & (u8) OMAP_RTC_STATUS_ALARM)
 376                rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
 377
 378        /* handle periodic and alarm irqs */
 379        if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
 380                        dev_name(&rtc->dev), rtc)) {
 381                pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
 382                        pdev->name, omap_rtc_timer);
 383                goto fail0;
 384        }
 385        if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
 386                        dev_name(&rtc->dev), rtc)) {
 387                pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
 388                        pdev->name, omap_rtc_alarm);
 389                goto fail1;
 390        }
 391
 392        /* On boards with split power, RTC_ON_NOFF won't reset the RTC */
 393        reg = rtc_read(OMAP_RTC_CTRL_REG);
 394        if (reg & (u8) OMAP_RTC_CTRL_STOP)
 395                pr_info("%s: already running\n", pdev->name);
 396
 397        /* force to 24 hour mode */
 398        new_ctrl = reg & ~(OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP);
 399        new_ctrl |= OMAP_RTC_CTRL_STOP;
 400
 401        /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
 402         *
 403         *  - Boards wired so that RTC_WAKE_INT does something, and muxed
 404         *    right (W13_1610_RTC_WAKE_INT is the default after chip reset),
 405         *    should initialize the device wakeup flag appropriately.
 406         *
 407         *  - Boards wired so RTC_ON_nOFF is used as the reset signal,
 408         *    rather than nPWRON_RESET, should forcibly enable split
 409         *    power mode.  (Some chip errata report that RTC_CTRL_SPLIT
 410         *    is write-only, and always reads as zero...)
 411         */
 412        device_init_wakeup(&pdev->dev, 0);
 413
 414        if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
 415                pr_info("%s: split power mode\n", pdev->name);
 416
 417        if (reg != new_ctrl)
 418                rtc_write(new_ctrl, OMAP_RTC_CTRL_REG);
 419
 420        return 0;
 421
 422fail1:
 423        free_irq(omap_rtc_timer, NULL);
 424fail0:
 425        rtc_device_unregister(rtc);
 426fail:
 427        release_resource(mem);
 428        return -EIO;
 429}
 430
 431static int __exit omap_rtc_remove(struct platform_device *pdev)
 432{
 433        struct rtc_device       *rtc = platform_get_drvdata(pdev);;
 434
 435        device_init_wakeup(&pdev->dev, 0);
 436
 437        /* leave rtc running, but disable irqs */
 438        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 439
 440        free_irq(omap_rtc_timer, rtc);
 441        free_irq(omap_rtc_alarm, rtc);
 442
 443        release_resource(dev_get_drvdata(&rtc->dev));
 444        rtc_device_unregister(rtc);
 445        return 0;
 446}
 447
 448#ifdef CONFIG_PM
 449
 450static u8 irqstat;
 451
 452static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 453{
 454        irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
 455
 456        /* FIXME the RTC alarm is not currently acting as a wakeup event
 457         * source, and in fact this enable() call is just saving a flag
 458         * that's never used...
 459         */
 460        if (device_may_wakeup(&pdev->dev))
 461                enable_irq_wake(omap_rtc_alarm);
 462        else
 463                rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 464
 465        return 0;
 466}
 467
 468static int omap_rtc_resume(struct platform_device *pdev)
 469{
 470        if (device_may_wakeup(&pdev->dev))
 471                disable_irq_wake(omap_rtc_alarm);
 472        else
 473                rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
 474        return 0;
 475}
 476
 477#else
 478#define omap_rtc_suspend NULL
 479#define omap_rtc_resume  NULL
 480#endif
 481
 482static void omap_rtc_shutdown(struct platform_device *pdev)
 483{
 484        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 485}
 486
 487MODULE_ALIAS("platform:omap_rtc");
 488static struct platform_driver omap_rtc_driver = {
 489        .remove         = __exit_p(omap_rtc_remove),
 490        .suspend        = omap_rtc_suspend,
 491        .resume         = omap_rtc_resume,
 492        .shutdown       = omap_rtc_shutdown,
 493        .driver         = {
 494                .name   = "omap_rtc",
 495                .owner  = THIS_MODULE,
 496        },
 497};
 498
 499static int __init rtc_init(void)
 500{
 501        return platform_driver_probe(&omap_rtc_driver, omap_rtc_probe);
 502}
 503module_init(rtc_init);
 504
 505static void __exit rtc_exit(void)
 506{
 507        platform_driver_unregister(&omap_rtc_driver);
 508}
 509module_exit(rtc_exit);
 510
 511MODULE_AUTHOR("George G. Davis (and others)");
 512MODULE_LICENSE("GPL");
 513