linux/drivers/rtc/rtc-ds1286.c
<<
>>
Prefs
   1/*
   2 * DS1286 Real Time Clock interface for Linux
   3 *
   4 * Copyright (C) 1998, 1999, 2000 Ralf Baechle
   5 * Copyright (C) 2008 Thomas Bogendoerfer
   6 *
   7 * Based on code written by Paul Gortmaker.
   8 *
   9 * This program is free software; you can redistribute it and/or modify it
  10 * under the terms of the GNU General Public License as published by the
  11 * Free Software Foundation; either version 2 of the License, or (at your
  12 * option) any later version.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/rtc.h>
  17#include <linux/platform_device.h>
  18#include <linux/bcd.h>
  19#include <linux/ds1286.h>
  20#include <linux/io.h>
  21#include <linux/slab.h>
  22
  23#define DRV_VERSION             "1.0"
  24
  25struct ds1286_priv {
  26        struct rtc_device *rtc;
  27        u32 __iomem *rtcregs;
  28        spinlock_t lock;
  29};
  30
  31static inline u8 ds1286_rtc_read(struct ds1286_priv *priv, int reg)
  32{
  33        return __raw_readl(&priv->rtcregs[reg]) & 0xff;
  34}
  35
  36static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg)
  37{
  38        __raw_writel(data, &priv->rtcregs[reg]);
  39}
  40
  41
  42static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled)
  43{
  44        struct ds1286_priv *priv = dev_get_drvdata(dev);
  45        unsigned long flags;
  46        unsigned char val;
  47
  48        /* Allow or mask alarm interrupts */
  49        spin_lock_irqsave(&priv->lock, flags);
  50        val = ds1286_rtc_read(priv, RTC_CMD);
  51        if (enabled)
  52                val &=  ~RTC_TDM;
  53        else
  54                val |=  RTC_TDM;
  55        ds1286_rtc_write(priv, val, RTC_CMD);
  56        spin_unlock_irqrestore(&priv->lock, flags);
  57
  58        return 0;
  59}
  60
  61#ifdef CONFIG_RTC_INTF_DEV
  62
  63static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  64{
  65        struct ds1286_priv *priv = dev_get_drvdata(dev);
  66        unsigned long flags;
  67        unsigned char val;
  68
  69        switch (cmd) {
  70        case RTC_WIE_OFF:
  71                /* Mask watchdog int. enab. bit */
  72                spin_lock_irqsave(&priv->lock, flags);
  73                val = ds1286_rtc_read(priv, RTC_CMD);
  74                val |= RTC_WAM;
  75                ds1286_rtc_write(priv, val, RTC_CMD);
  76                spin_unlock_irqrestore(&priv->lock, flags);
  77                break;
  78        case RTC_WIE_ON:
  79                /* Allow watchdog interrupts.   */
  80                spin_lock_irqsave(&priv->lock, flags);
  81                val = ds1286_rtc_read(priv, RTC_CMD);
  82                val &= ~RTC_WAM;
  83                ds1286_rtc_write(priv, val, RTC_CMD);
  84                spin_unlock_irqrestore(&priv->lock, flags);
  85                break;
  86        default:
  87                return -ENOIOCTLCMD;
  88        }
  89        return 0;
  90}
  91
  92#else
  93#define ds1286_ioctl    NULL
  94#endif
  95
  96#ifdef CONFIG_PROC_FS
  97
  98static int ds1286_proc(struct device *dev, struct seq_file *seq)
  99{
 100        struct ds1286_priv *priv = dev_get_drvdata(dev);
 101        unsigned char month, cmd, amode;
 102        const char *s;
 103
 104        month = ds1286_rtc_read(priv, RTC_MONTH);
 105        seq_printf(seq,
 106                   "oscillator\t: %s\n"
 107                   "square_wave\t: %s\n",
 108                   (month & RTC_EOSC) ? "disabled" : "enabled",
 109                   (month & RTC_ESQW) ? "disabled" : "enabled");
 110
 111        amode = ((ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x80) >> 5) |
 112                ((ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x80) >> 6) |
 113                ((ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x80) >> 7);
 114        switch (amode) {
 115        case 7:
 116                s = "each minute";
 117                break;
 118        case 3:
 119                s = "minutes match";
 120                break;
 121        case 1:
 122                s = "hours and minutes match";
 123                break;
 124        case 0:
 125                s = "days, hours and minutes match";
 126                break;
 127        default:
 128                s = "invalid";
 129                break;
 130        }
 131        seq_printf(seq, "alarm_mode\t: %s\n", s);
 132
 133        cmd = ds1286_rtc_read(priv, RTC_CMD);
 134        seq_printf(seq,
 135                   "alarm_enable\t: %s\n"
 136                   "wdog_alarm\t: %s\n"
 137                   "alarm_mask\t: %s\n"
 138                   "wdog_alarm_mask\t: %s\n"
 139                   "interrupt_mode\t: %s\n"
 140                   "INTB_mode\t: %s_active\n"
 141                   "interrupt_pins\t: %s\n",
 142                   (cmd & RTC_TDF) ? "yes" : "no",
 143                   (cmd & RTC_WAF) ? "yes" : "no",
 144                   (cmd & RTC_TDM) ? "disabled" : "enabled",
 145                   (cmd & RTC_WAM) ? "disabled" : "enabled",
 146                   (cmd & RTC_PU_LVL) ? "pulse" : "level",
 147                   (cmd & RTC_IBH_LO) ? "low" : "high",
 148                   (cmd & RTC_IPSW) ? "unswapped" : "swapped");
 149        return 0;
 150}
 151
 152#else
 153#define ds1286_proc     NULL
 154#endif
 155
 156static int ds1286_read_time(struct device *dev, struct rtc_time *tm)
 157{
 158        struct ds1286_priv *priv = dev_get_drvdata(dev);
 159        unsigned char save_control;
 160        unsigned long flags;
 161        unsigned long uip_watchdog = jiffies;
 162
 163        /*
 164         * read RTC once any update in progress is done. The update
 165         * can take just over 2ms. We wait 10 to 20ms. There is no need to
 166         * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
 167         * If you need to know *exactly* when a second has started, enable
 168         * periodic update complete interrupts, (via ioctl) and then
 169         * immediately read /dev/rtc which will block until you get the IRQ.
 170         * Once the read clears, read the RTC time (again via ioctl). Easy.
 171         */
 172
 173        if (ds1286_rtc_read(priv, RTC_CMD) & RTC_TE)
 174                while (time_before(jiffies, uip_watchdog + 2*HZ/100))
 175                        barrier();
 176
 177        /*
 178         * Only the values that we read from the RTC are set. We leave
 179         * tm_wday, tm_yday and tm_isdst untouched. Even though the
 180         * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
 181         * by the RTC when initially set to a non-zero value.
 182         */
 183        spin_lock_irqsave(&priv->lock, flags);
 184        save_control = ds1286_rtc_read(priv, RTC_CMD);
 185        ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD);
 186
 187        tm->tm_sec = ds1286_rtc_read(priv, RTC_SECONDS);
 188        tm->tm_min = ds1286_rtc_read(priv, RTC_MINUTES);
 189        tm->tm_hour = ds1286_rtc_read(priv, RTC_HOURS) & 0x3f;
 190        tm->tm_mday = ds1286_rtc_read(priv, RTC_DATE);
 191        tm->tm_mon = ds1286_rtc_read(priv, RTC_MONTH) & 0x1f;
 192        tm->tm_year = ds1286_rtc_read(priv, RTC_YEAR);
 193
 194        ds1286_rtc_write(priv, save_control, RTC_CMD);
 195        spin_unlock_irqrestore(&priv->lock, flags);
 196
 197        tm->tm_sec = bcd2bin(tm->tm_sec);
 198        tm->tm_min = bcd2bin(tm->tm_min);
 199        tm->tm_hour = bcd2bin(tm->tm_hour);
 200        tm->tm_mday = bcd2bin(tm->tm_mday);
 201        tm->tm_mon = bcd2bin(tm->tm_mon);
 202        tm->tm_year = bcd2bin(tm->tm_year);
 203
 204        /*
 205         * Account for differences between how the RTC uses the values
 206         * and how they are defined in a struct rtc_time;
 207         */
 208        if (tm->tm_year < 45)
 209                tm->tm_year += 30;
 210        tm->tm_year += 40;
 211        if (tm->tm_year < 70)
 212                tm->tm_year += 100;
 213
 214        tm->tm_mon--;
 215
 216        return rtc_valid_tm(tm);
 217}
 218
 219static int ds1286_set_time(struct device *dev, struct rtc_time *tm)
 220{
 221        struct ds1286_priv *priv = dev_get_drvdata(dev);
 222        unsigned char mon, day, hrs, min, sec;
 223        unsigned char save_control;
 224        unsigned int yrs;
 225        unsigned long flags;
 226
 227        yrs = tm->tm_year + 1900;
 228        mon = tm->tm_mon + 1;   /* tm_mon starts at zero */
 229        day = tm->tm_mday;
 230        hrs = tm->tm_hour;
 231        min = tm->tm_min;
 232        sec = tm->tm_sec;
 233
 234        if (yrs < 1970)
 235                return -EINVAL;
 236
 237        yrs -= 1940;
 238        if (yrs > 255)    /* They are unsigned */
 239                return -EINVAL;
 240
 241        if (yrs >= 100)
 242                yrs -= 100;
 243
 244        sec = bin2bcd(sec);
 245        min = bin2bcd(min);
 246        hrs = bin2bcd(hrs);
 247        day = bin2bcd(day);
 248        mon = bin2bcd(mon);
 249        yrs = bin2bcd(yrs);
 250
 251        spin_lock_irqsave(&priv->lock, flags);
 252        save_control = ds1286_rtc_read(priv, RTC_CMD);
 253        ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD);
 254
 255        ds1286_rtc_write(priv, yrs, RTC_YEAR);
 256        ds1286_rtc_write(priv, mon, RTC_MONTH);
 257        ds1286_rtc_write(priv, day, RTC_DATE);
 258        ds1286_rtc_write(priv, hrs, RTC_HOURS);
 259        ds1286_rtc_write(priv, min, RTC_MINUTES);
 260        ds1286_rtc_write(priv, sec, RTC_SECONDS);
 261        ds1286_rtc_write(priv, 0, RTC_HUNDREDTH_SECOND);
 262
 263        ds1286_rtc_write(priv, save_control, RTC_CMD);
 264        spin_unlock_irqrestore(&priv->lock, flags);
 265        return 0;
 266}
 267
 268static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 269{
 270        struct ds1286_priv *priv = dev_get_drvdata(dev);
 271        unsigned long flags;
 272
 273        /*
 274         * Only the values that we read from the RTC are set. That
 275         * means only tm_wday, tm_hour, tm_min.
 276         */
 277        spin_lock_irqsave(&priv->lock, flags);
 278        alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f;
 279        alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM)  & 0x1f;
 280        alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM)    & 0x07;
 281        ds1286_rtc_read(priv, RTC_CMD);
 282        spin_unlock_irqrestore(&priv->lock, flags);
 283
 284        alm->time.tm_min = bcd2bin(alm->time.tm_min);
 285        alm->time.tm_hour = bcd2bin(alm->time.tm_hour);
 286        alm->time.tm_sec = 0;
 287        return 0;
 288}
 289
 290static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 291{
 292        struct ds1286_priv *priv = dev_get_drvdata(dev);
 293        unsigned char hrs, min, sec;
 294
 295        hrs = alm->time.tm_hour;
 296        min = alm->time.tm_min;
 297        sec = alm->time.tm_sec;
 298
 299        if (hrs >= 24)
 300                hrs = 0xff;
 301
 302        if (min >= 60)
 303                min = 0xff;
 304
 305        if (sec != 0)
 306                return -EINVAL;
 307
 308        min = bin2bcd(min);
 309        hrs = bin2bcd(hrs);
 310
 311        spin_lock(&priv->lock);
 312        ds1286_rtc_write(priv, hrs, RTC_HOURS_ALARM);
 313        ds1286_rtc_write(priv, min, RTC_MINUTES_ALARM);
 314        spin_unlock(&priv->lock);
 315
 316        return 0;
 317}
 318
 319static const struct rtc_class_ops ds1286_ops = {
 320        .ioctl          = ds1286_ioctl,
 321        .proc           = ds1286_proc,
 322        .read_time      = ds1286_read_time,
 323        .set_time       = ds1286_set_time,
 324        .read_alarm     = ds1286_read_alarm,
 325        .set_alarm      = ds1286_set_alarm,
 326        .alarm_irq_enable = ds1286_alarm_irq_enable,
 327};
 328
 329static int ds1286_probe(struct platform_device *pdev)
 330{
 331        struct rtc_device *rtc;
 332        struct resource *res;
 333        struct ds1286_priv *priv;
 334
 335        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 336        if (!res)
 337                return -ENODEV;
 338        priv = devm_kzalloc(&pdev->dev, sizeof(struct ds1286_priv), GFP_KERNEL);
 339        if (!priv)
 340                return -ENOMEM;
 341
 342        priv->rtcregs = devm_ioremap_resource(&pdev->dev, res);
 343        if (IS_ERR(priv->rtcregs))
 344                return PTR_ERR(priv->rtcregs);
 345
 346        spin_lock_init(&priv->lock);
 347        platform_set_drvdata(pdev, priv);
 348        rtc = devm_rtc_device_register(&pdev->dev, "ds1286", &ds1286_ops,
 349                                        THIS_MODULE);
 350        if (IS_ERR(rtc))
 351                return PTR_ERR(rtc);
 352        priv->rtc = rtc;
 353        return 0;
 354}
 355
 356static int ds1286_remove(struct platform_device *pdev)
 357{
 358        return 0;
 359}
 360
 361static struct platform_driver ds1286_platform_driver = {
 362        .driver         = {
 363                .name   = "rtc-ds1286",
 364                .owner  = THIS_MODULE,
 365        },
 366        .probe          = ds1286_probe,
 367        .remove         = ds1286_remove,
 368};
 369
 370module_platform_driver(ds1286_platform_driver);
 371
 372MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 373MODULE_DESCRIPTION("DS1286 RTC driver");
 374MODULE_LICENSE("GPL");
 375MODULE_VERSION(DRV_VERSION);
 376MODULE_ALIAS("platform:rtc-ds1286");
 377
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.