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) for OMAP1 boards (OMAP-L138 has this built into
  38 * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
  39 */
  40
  41#define OMAP_RTC_BASE                   0xfffb4800
  42
  43/* RTC registers */
  44#define OMAP_RTC_SECONDS_REG            0x00
  45#define OMAP_RTC_MINUTES_REG            0x04
  46#define OMAP_RTC_HOURS_REG              0x08
  47#define OMAP_RTC_DAYS_REG               0x0C
  48#define OMAP_RTC_MONTHS_REG             0x10
  49#define OMAP_RTC_YEARS_REG              0x14
  50#define OMAP_RTC_WEEKS_REG              0x18
  51
  52#define OMAP_RTC_ALARM_SECONDS_REG      0x20
  53#define OMAP_RTC_ALARM_MINUTES_REG      0x24
  54#define OMAP_RTC_ALARM_HOURS_REG        0x28
  55#define OMAP_RTC_ALARM_DAYS_REG         0x2c
  56#define OMAP_RTC_ALARM_MONTHS_REG       0x30
  57#define OMAP_RTC_ALARM_YEARS_REG        0x34
  58
  59#define OMAP_RTC_CTRL_REG               0x40
  60#define OMAP_RTC_STATUS_REG             0x44
  61#define OMAP_RTC_INTERRUPTS_REG         0x48
  62
  63#define OMAP_RTC_COMP_LSB_REG           0x4c
  64#define OMAP_RTC_COMP_MSB_REG           0x50
  65#define OMAP_RTC_OSC_REG                0x54
  66
  67/* OMAP_RTC_CTRL_REG bit fields: */
  68#define OMAP_RTC_CTRL_SPLIT             (1<<7)
  69#define OMAP_RTC_CTRL_DISABLE           (1<<6)
  70#define OMAP_RTC_CTRL_SET_32_COUNTER    (1<<5)
  71#define OMAP_RTC_CTRL_TEST              (1<<4)
  72#define OMAP_RTC_CTRL_MODE_12_24        (1<<3)
  73#define OMAP_RTC_CTRL_AUTO_COMP         (1<<2)
  74#define OMAP_RTC_CTRL_ROUND_30S         (1<<1)
  75#define OMAP_RTC_CTRL_STOP              (1<<0)
  76
  77/* OMAP_RTC_STATUS_REG bit fields: */
  78#define OMAP_RTC_STATUS_POWER_UP        (1<<7)
  79#define OMAP_RTC_STATUS_ALARM           (1<<6)
  80#define OMAP_RTC_STATUS_1D_EVENT        (1<<5)
  81#define OMAP_RTC_STATUS_1H_EVENT        (1<<4)
  82#define OMAP_RTC_STATUS_1M_EVENT        (1<<3)
  83#define OMAP_RTC_STATUS_1S_EVENT        (1<<2)
  84#define OMAP_RTC_STATUS_RUN             (1<<1)
  85#define OMAP_RTC_STATUS_BUSY            (1<<0)
  86
  87/* OMAP_RTC_INTERRUPTS_REG bit fields: */
  88#define OMAP_RTC_INTERRUPTS_IT_ALARM    (1<<3)
  89#define OMAP_RTC_INTERRUPTS_IT_TIMER    (1<<2)
  90
  91static void __iomem     *rtc_base;
  92
  93#define rtc_read(addr)          __raw_readb(rtc_base + (addr))
  94#define rtc_write(val, addr)    __raw_writeb(val, rtc_base + (addr))
  95
  96
  97/* we rely on the rtc framework to handle locking (rtc->ops_lock),
  98 * so the only other requirement is that register accesses which
  99 * require BUSY to be clear are made with IRQs locally disabled
 100 */
 101static void rtc_wait_not_busy(void)
 102{
 103        int     count = 0;
 104        u8      status;
 105
 106        /* BUSY may stay active for 1/32768 second (~30 usec) */
 107        for (count = 0; count < 50; count++) {
 108                status = rtc_read(OMAP_RTC_STATUS_REG);
 109                if ((status & (u8)OMAP_RTC_STATUS_BUSY) == 0)
 110                        break;
 111                udelay(1);
 112        }
 113        /* now we have ~15 usec to read/write various registers */
 114}
 115
 116static irqreturn_t rtc_irq(int irq, void *rtc)
 117{
 118        unsigned long           events = 0;
 119        u8                      irq_data;
 120
 121        irq_data = rtc_read(OMAP_RTC_STATUS_REG);
 122
 123        /* alarm irq? */
 124        if (irq_data & OMAP_RTC_STATUS_ALARM) {
 125                rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
 126                events |= RTC_IRQF | RTC_AF;
 127        }
 128
 129        /* 1/sec periodic/update irq? */
 130        if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
 131                events |= RTC_IRQF | RTC_UF;
 132
 133        rtc_update_irq(rtc, 1, events);
 134
 135        return IRQ_HANDLED;
 136}
 137
 138static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 139{
 140        u8 reg;
 141
 142        local_irq_disable();
 143        rtc_wait_not_busy();
 144        reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
 145        if (enabled)
 146                reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
 147        else
 148                reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
 149        rtc_wait_not_busy();
 150        rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
 151        local_irq_enable();
 152
 153        return 0;
 154}
 155
 156/* this hardware doesn't support "don't care" alarm fields */
 157static int tm2bcd(struct rtc_time *tm)
 158{
 159        if (rtc_valid_tm(tm) != 0)
 160                return -EINVAL;
 161
 162        tm->tm_sec = bin2bcd(tm->tm_sec);
 163        tm->tm_min = bin2bcd(tm->tm_min);
 164        tm->tm_hour = bin2bcd(tm->tm_hour);
 165        tm->tm_mday = bin2bcd(tm->tm_mday);
 166
 167        tm->tm_mon = bin2bcd(tm->tm_mon + 1);
 168
 169        /* epoch == 1900 */
 170        if (tm->tm_year < 100 || tm->tm_year > 199)
 171                return -EINVAL;
 172        tm->tm_year = bin2bcd(tm->tm_year - 100);
 173
 174        return 0;
 175}
 176
 177static void bcd2tm(struct rtc_time *tm)
 178{
 179        tm->tm_sec = bcd2bin(tm->tm_sec);
 180        tm->tm_min = bcd2bin(tm->tm_min);
 181        tm->tm_hour = bcd2bin(tm->tm_hour);
 182        tm->tm_mday = bcd2bin(tm->tm_mday);
 183        tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
 184        /* epoch == 1900 */
 185        tm->tm_year = bcd2bin(tm->tm_year) + 100;
 186}
 187
 188
 189static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm)
 190{
 191        /* we don't report wday/yday/isdst ... */
 192        local_irq_disable();
 193        rtc_wait_not_busy();
 194
 195        tm->tm_sec = rtc_read(OMAP_RTC_SECONDS_REG);
 196        tm->tm_min = rtc_read(OMAP_RTC_MINUTES_REG);
 197        tm->tm_hour = rtc_read(OMAP_RTC_HOURS_REG);
 198        tm->tm_mday = rtc_read(OMAP_RTC_DAYS_REG);
 199        tm->tm_mon = rtc_read(OMAP_RTC_MONTHS_REG);
 200        tm->tm_year = rtc_read(OMAP_RTC_YEARS_REG);
 201
 202        local_irq_enable();
 203
 204        bcd2tm(tm);
 205        return 0;
 206}
 207
 208static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm)
 209{
 210        if (tm2bcd(tm) < 0)
 211                return -EINVAL;
 212        local_irq_disable();
 213        rtc_wait_not_busy();
 214
 215        rtc_write(tm->tm_year, OMAP_RTC_YEARS_REG);
 216        rtc_write(tm->tm_mon, OMAP_RTC_MONTHS_REG);
 217        rtc_write(tm->tm_mday, OMAP_RTC_DAYS_REG);
 218        rtc_write(tm->tm_hour, OMAP_RTC_HOURS_REG);
 219        rtc_write(tm->tm_min, OMAP_RTC_MINUTES_REG);
 220        rtc_write(tm->tm_sec, OMAP_RTC_SECONDS_REG);
 221
 222        local_irq_enable();
 223
 224        return 0;
 225}
 226
 227static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 228{
 229        local_irq_disable();
 230        rtc_wait_not_busy();
 231
 232        alm->time.tm_sec = rtc_read(OMAP_RTC_ALARM_SECONDS_REG);
 233        alm->time.tm_min = rtc_read(OMAP_RTC_ALARM_MINUTES_REG);
 234        alm->time.tm_hour = rtc_read(OMAP_RTC_ALARM_HOURS_REG);
 235        alm->time.tm_mday = rtc_read(OMAP_RTC_ALARM_DAYS_REG);
 236        alm->time.tm_mon = rtc_read(OMAP_RTC_ALARM_MONTHS_REG);
 237        alm->time.tm_year = rtc_read(OMAP_RTC_ALARM_YEARS_REG);
 238
 239        local_irq_enable();
 240
 241        bcd2tm(&alm->time);
 242        alm->enabled = !!(rtc_read(OMAP_RTC_INTERRUPTS_REG)
 243                        & OMAP_RTC_INTERRUPTS_IT_ALARM);
 244
 245        return 0;
 246}
 247
 248static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 249{
 250        u8 reg;
 251
 252        if (tm2bcd(&alm->time) < 0)
 253                return -EINVAL;
 254
 255        local_irq_disable();
 256        rtc_wait_not_busy();
 257
 258        rtc_write(alm->time.tm_year, OMAP_RTC_ALARM_YEARS_REG);
 259        rtc_write(alm->time.tm_mon, OMAP_RTC_ALARM_MONTHS_REG);
 260        rtc_write(alm->time.tm_mday, OMAP_RTC_ALARM_DAYS_REG);
 261        rtc_write(alm->time.tm_hour, OMAP_RTC_ALARM_HOURS_REG);
 262        rtc_write(alm->time.tm_min, OMAP_RTC_ALARM_MINUTES_REG);
 263        rtc_write(alm->time.tm_sec, OMAP_RTC_ALARM_SECONDS_REG);
 264
 265        reg = rtc_read(OMAP_RTC_INTERRUPTS_REG);
 266        if (alm->enabled)
 267                reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
 268        else
 269                reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
 270        rtc_write(reg, OMAP_RTC_INTERRUPTS_REG);
 271
 272        local_irq_enable();
 273
 274        return 0;
 275}
 276
 277static struct rtc_class_ops omap_rtc_ops = {
 278        .read_time      = omap_rtc_read_time,
 279        .set_time       = omap_rtc_set_time,
 280        .read_alarm     = omap_rtc_read_alarm,
 281        .set_alarm      = omap_rtc_set_alarm,
 282        .alarm_irq_enable = omap_rtc_alarm_irq_enable,
 283};
 284
 285static int omap_rtc_alarm;
 286static int omap_rtc_timer;
 287
 288static int __init omap_rtc_probe(struct platform_device *pdev)
 289{
 290        struct resource         *res, *mem;
 291        struct rtc_device       *rtc;
 292        u8                      reg, new_ctrl;
 293
 294        omap_rtc_timer = platform_get_irq(pdev, 0);
 295        if (omap_rtc_timer <= 0) {
 296                pr_debug("%s: no update irq?\n", pdev->name);
 297                return -ENOENT;
 298        }
 299
 300        omap_rtc_alarm = platform_get_irq(pdev, 1);
 301        if (omap_rtc_alarm <= 0) {
 302                pr_debug("%s: no alarm irq?\n", pdev->name);
 303                return -ENOENT;
 304        }
 305
 306        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 307        if (!res) {
 308                pr_debug("%s: RTC resource data missing\n", pdev->name);
 309                return -ENOENT;
 310        }
 311
 312        mem = request_mem_region(res->start, resource_size(res), pdev->name);
 313        if (!mem) {
 314                pr_debug("%s: RTC registers at %08x are not free\n",
 315                        pdev->name, res->start);
 316                return -EBUSY;
 317        }
 318
 319        rtc_base = ioremap(res->start, resource_size(res));
 320        if (!rtc_base) {
 321                pr_debug("%s: RTC registers can't be mapped\n", pdev->name);
 322                goto fail;
 323        }
 324
 325        rtc = rtc_device_register(pdev->name, &pdev->dev,
 326                        &omap_rtc_ops, THIS_MODULE);
 327        if (IS_ERR(rtc)) {
 328                pr_debug("%s: can't register RTC device, err %ld\n",
 329                        pdev->name, PTR_ERR(rtc));
 330                goto fail0;
 331        }
 332        platform_set_drvdata(pdev, rtc);
 333        dev_set_drvdata(&rtc->dev, mem);
 334
 335        /* clear pending irqs, and set 1/second periodic,
 336         * which we'll use instead of update irqs
 337         */
 338        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 339
 340        /* clear old status */
 341        reg = rtc_read(OMAP_RTC_STATUS_REG);
 342        if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
 343                pr_info("%s: RTC power up reset detected\n",
 344                        pdev->name);
 345                rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG);
 346        }
 347        if (reg & (u8) OMAP_RTC_STATUS_ALARM)
 348                rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
 349
 350        /* handle periodic and alarm irqs */
 351        if (request_irq(omap_rtc_timer, rtc_irq, 0,
 352                        dev_name(&rtc->dev), rtc)) {
 353                pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
 354                        pdev->name, omap_rtc_timer);
 355                goto fail1;
 356        }
 357        if ((omap_rtc_timer != omap_rtc_alarm) &&
 358                (request_irq(omap_rtc_alarm, rtc_irq, 0,
 359                        dev_name(&rtc->dev), rtc))) {
 360                pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
 361                        pdev->name, omap_rtc_alarm);
 362                goto fail2;
 363        }
 364
 365        /* On boards with split power, RTC_ON_NOFF won't reset the RTC */
 366        reg = rtc_read(OMAP_RTC_CTRL_REG);
 367        if (reg & (u8) OMAP_RTC_CTRL_STOP)
 368                pr_info("%s: already running\n", pdev->name);
 369
 370        /* force to 24 hour mode */
 371        new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP);
 372        new_ctrl |= OMAP_RTC_CTRL_STOP;
 373
 374        /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
 375         *
 376         *  - Device wake-up capability setting should come through chip
 377         *    init logic. OMAP1 boards should initialize the "wakeup capable"
 378         *    flag in the platform device if the board is wired right for
 379         *    being woken up by RTC alarm. For OMAP-L138, this capability
 380         *    is built into the SoC by the "Deep Sleep" capability.
 381         *
 382         *  - Boards wired so RTC_ON_nOFF is used as the reset signal,
 383         *    rather than nPWRON_RESET, should forcibly enable split
 384         *    power mode.  (Some chip errata report that RTC_CTRL_SPLIT
 385         *    is write-only, and always reads as zero...)
 386         */
 387
 388        if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
 389                pr_info("%s: split power mode\n", pdev->name);
 390
 391        if (reg != new_ctrl)
 392                rtc_write(new_ctrl, OMAP_RTC_CTRL_REG);
 393
 394        return 0;
 395
 396fail2:
 397        free_irq(omap_rtc_timer, rtc);
 398fail1:
 399        rtc_device_unregister(rtc);
 400fail0:
 401        iounmap(rtc_base);
 402fail:
 403        release_mem_region(mem->start, resource_size(mem));
 404        return -EIO;
 405}
 406
 407static int __exit omap_rtc_remove(struct platform_device *pdev)
 408{
 409        struct rtc_device       *rtc = platform_get_drvdata(pdev);
 410        struct resource         *mem = dev_get_drvdata(&rtc->dev);
 411
 412        device_init_wakeup(&pdev->dev, 0);
 413
 414        /* leave rtc running, but disable irqs */
 415        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 416
 417        free_irq(omap_rtc_timer, rtc);
 418
 419        if (omap_rtc_timer != omap_rtc_alarm)
 420                free_irq(omap_rtc_alarm, rtc);
 421
 422        rtc_device_unregister(rtc);
 423        iounmap(rtc_base);
 424        release_mem_region(mem->start, resource_size(mem));
 425        return 0;
 426}
 427
 428#ifdef CONFIG_PM
 429
 430static u8 irqstat;
 431
 432static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 433{
 434        irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
 435
 436        /* FIXME the RTC alarm is not currently acting as a wakeup event
 437         * source, and in fact this enable() call is just saving a flag
 438         * that's never used...
 439         */
 440        if (device_may_wakeup(&pdev->dev))
 441                enable_irq_wake(omap_rtc_alarm);
 442        else
 443                rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 444
 445        return 0;
 446}
 447
 448static int omap_rtc_resume(struct platform_device *pdev)
 449{
 450        if (device_may_wakeup(&pdev->dev))
 451                disable_irq_wake(omap_rtc_alarm);
 452        else
 453                rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
 454        return 0;
 455}
 456
 457#else
 458#define omap_rtc_suspend NULL
 459#define omap_rtc_resume  NULL
 460#endif
 461
 462static void omap_rtc_shutdown(struct platform_device *pdev)
 463{
 464        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 465}
 466
 467MODULE_ALIAS("platform:omap_rtc");
 468static struct platform_driver omap_rtc_driver = {
 469        .remove         = __exit_p(omap_rtc_remove),
 470        .suspend        = omap_rtc_suspend,
 471        .resume         = omap_rtc_resume,
 472        .shutdown       = omap_rtc_shutdown,
 473        .driver         = {
 474                .name   = "omap_rtc",
 475                .owner  = THIS_MODULE,
 476        },
 477};
 478
 479static int __init rtc_init(void)
 480{
 481        return platform_driver_probe(&omap_rtc_driver, omap_rtc_probe);
 482}
 483module_init(rtc_init);
 484
 485static void __exit rtc_exit(void)
 486{
 487        platform_driver_unregister(&omap_rtc_driver);
 488}
 489module_exit(rtc_exit);
 490
 491MODULE_AUTHOR("George G. Davis (and others)");
 492MODULE_LICENSE("GPL");
 493
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.