linux/drivers/rtc/rtc-m48t59.c
<<
>>
Prefs
   1/*
   2 * ST M48T59 RTC driver
   3 *
   4 * Copyright (c) 2007 Wind River Systems, Inc.
   5 *
   6 * Author: Mark Zhan <rongkai.zhan@windriver.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/init.h>
  16#include <linux/io.h>
  17#include <linux/device.h>
  18#include <linux/platform_device.h>
  19#include <linux/rtc.h>
  20#include <linux/rtc/m48t59.h>
  21#include <linux/bcd.h>
  22#include <linux/slab.h>
  23
  24#ifndef NO_IRQ
  25#define NO_IRQ  (-1)
  26#endif
  27
  28#define M48T59_READ(reg) (pdata->read_byte(dev, pdata->offset + reg))
  29#define M48T59_WRITE(val, reg) \
  30        (pdata->write_byte(dev, pdata->offset + reg, val))
  31
  32#define M48T59_SET_BITS(mask, reg)      \
  33        M48T59_WRITE((M48T59_READ(reg) | (mask)), (reg))
  34#define M48T59_CLEAR_BITS(mask, reg)    \
  35        M48T59_WRITE((M48T59_READ(reg) & ~(mask)), (reg))
  36
  37struct m48t59_private {
  38        void __iomem *ioaddr;
  39        int irq;
  40        struct rtc_device *rtc;
  41        spinlock_t lock; /* serialize the NVRAM and RTC access */
  42};
  43
  44/*
  45 * This is the generic access method when the chip is memory-mapped
  46 */
  47static void
  48m48t59_mem_writeb(struct device *dev, u32 ofs, u8 val)
  49{
  50        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
  51
  52        writeb(val, m48t59->ioaddr+ofs);
  53}
  54
  55static u8
  56m48t59_mem_readb(struct device *dev, u32 ofs)
  57{
  58        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
  59
  60        return readb(m48t59->ioaddr+ofs);
  61}
  62
  63/*
  64 * NOTE: M48T59 only uses BCD mode
  65 */
  66static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
  67{
  68        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
  69        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
  70        unsigned long flags;
  71        u8 val;
  72
  73        spin_lock_irqsave(&m48t59->lock, flags);
  74        /* Issue the READ command */
  75        M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
  76
  77        tm->tm_year     = bcd2bin(M48T59_READ(M48T59_YEAR));
  78        /* tm_mon is 0-11 */
  79        tm->tm_mon      = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
  80        tm->tm_mday     = bcd2bin(M48T59_READ(M48T59_MDAY));
  81
  82        val = M48T59_READ(M48T59_WDAY);
  83        if ((pdata->type == M48T59RTC_TYPE_M48T59) &&
  84            (val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) {
  85                dev_dbg(dev, "Century bit is enabled\n");
  86                tm->tm_year += 100;     /* one century */
  87        }
  88#ifdef CONFIG_SPARC
  89        /* Sun SPARC machines count years since 1968 */
  90        tm->tm_year += 68;
  91#endif
  92
  93        tm->tm_wday     = bcd2bin(val & 0x07);
  94        tm->tm_hour     = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F);
  95        tm->tm_min      = bcd2bin(M48T59_READ(M48T59_MIN) & 0x7F);
  96        tm->tm_sec      = bcd2bin(M48T59_READ(M48T59_SEC) & 0x7F);
  97
  98        /* Clear the READ bit */
  99        M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
 100        spin_unlock_irqrestore(&m48t59->lock, flags);
 101
 102        dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n",
 103                tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
 104                tm->tm_hour, tm->tm_min, tm->tm_sec);
 105        return 0;
 106}
 107
 108static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
 109{
 110        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
 111        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
 112        unsigned long flags;
 113        u8 val = 0;
 114        int year = tm->tm_year;
 115
 116#ifdef CONFIG_SPARC
 117        /* Sun SPARC machines count years since 1968 */
 118        year -= 68;
 119#endif
 120
 121        dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n",
 122                year + 1900, tm->tm_mon, tm->tm_mday,
 123                tm->tm_hour, tm->tm_min, tm->tm_sec);
 124
 125        if (year < 0)
 126                return -EINVAL;
 127
 128        spin_lock_irqsave(&m48t59->lock, flags);
 129        /* Issue the WRITE command */
 130        M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
 131
 132        M48T59_WRITE((bin2bcd(tm->tm_sec) & 0x7F), M48T59_SEC);
 133        M48T59_WRITE((bin2bcd(tm->tm_min) & 0x7F), M48T59_MIN);
 134        M48T59_WRITE((bin2bcd(tm->tm_hour) & 0x3F), M48T59_HOUR);
 135        M48T59_WRITE((bin2bcd(tm->tm_mday) & 0x3F), M48T59_MDAY);
 136        /* tm_mon is 0-11 */
 137        M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
 138        M48T59_WRITE(bin2bcd(year % 100), M48T59_YEAR);
 139
 140        if (pdata->type == M48T59RTC_TYPE_M48T59 && (year / 100))
 141                val = (M48T59_WDAY_CEB | M48T59_WDAY_CB);
 142        val |= (bin2bcd(tm->tm_wday) & 0x07);
 143        M48T59_WRITE(val, M48T59_WDAY);
 144
 145        /* Clear the WRITE bit */
 146        M48T59_CLEAR_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
 147        spin_unlock_irqrestore(&m48t59->lock, flags);
 148        return 0;
 149}
 150
 151/*
 152 * Read alarm time and date in RTC
 153 */
 154static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
 155{
 156        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
 157        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
 158        struct rtc_time *tm = &alrm->time;
 159        unsigned long flags;
 160        u8 val;
 161
 162        /* If no irq, we don't support ALARM */
 163        if (m48t59->irq == NO_IRQ)
 164                return -EIO;
 165
 166        spin_lock_irqsave(&m48t59->lock, flags);
 167        /* Issue the READ command */
 168        M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
 169
 170        tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR));
 171#ifdef CONFIG_SPARC
 172        /* Sun SPARC machines count years since 1968 */
 173        tm->tm_year += 68;
 174#endif
 175        /* tm_mon is 0-11 */
 176        tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
 177
 178        val = M48T59_READ(M48T59_WDAY);
 179        if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB))
 180                tm->tm_year += 100;     /* one century */
 181
 182        tm->tm_mday = bcd2bin(M48T59_READ(M48T59_ALARM_DATE));
 183        tm->tm_hour = bcd2bin(M48T59_READ(M48T59_ALARM_HOUR));
 184        tm->tm_min = bcd2bin(M48T59_READ(M48T59_ALARM_MIN));
 185        tm->tm_sec = bcd2bin(M48T59_READ(M48T59_ALARM_SEC));
 186
 187        /* Clear the READ bit */
 188        M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
 189        spin_unlock_irqrestore(&m48t59->lock, flags);
 190
 191        dev_dbg(dev, "RTC read alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
 192                tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
 193                tm->tm_hour, tm->tm_min, tm->tm_sec);
 194        return rtc_valid_tm(tm);
 195}
 196
 197/*
 198 * Set alarm time and date in RTC
 199 */
 200static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 201{
 202        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
 203        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
 204        struct rtc_time *tm = &alrm->time;
 205        u8 mday, hour, min, sec;
 206        unsigned long flags;
 207        int year = tm->tm_year;
 208
 209#ifdef CONFIG_SPARC
 210        /* Sun SPARC machines count years since 1968 */
 211        year -= 68;
 212#endif
 213
 214        /* If no irq, we don't support ALARM */
 215        if (m48t59->irq == NO_IRQ)
 216                return -EIO;
 217
 218        if (year < 0)
 219                return -EINVAL;
 220
 221        /*
 222         * 0xff means "always match"
 223         */
 224        mday = tm->tm_mday;
 225        mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
 226        if (mday == 0xff)
 227                mday = M48T59_READ(M48T59_MDAY);
 228
 229        hour = tm->tm_hour;
 230        hour = (hour < 24) ? bin2bcd(hour) : 0x00;
 231
 232        min = tm->tm_min;
 233        min = (min < 60) ? bin2bcd(min) : 0x00;
 234
 235        sec = tm->tm_sec;
 236        sec = (sec < 60) ? bin2bcd(sec) : 0x00;
 237
 238        spin_lock_irqsave(&m48t59->lock, flags);
 239        /* Issue the WRITE command */
 240        M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
 241
 242        M48T59_WRITE(mday, M48T59_ALARM_DATE);
 243        M48T59_WRITE(hour, M48T59_ALARM_HOUR);
 244        M48T59_WRITE(min, M48T59_ALARM_MIN);
 245        M48T59_WRITE(sec, M48T59_ALARM_SEC);
 246
 247        /* Clear the WRITE bit */
 248        M48T59_CLEAR_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
 249        spin_unlock_irqrestore(&m48t59->lock, flags);
 250
 251        dev_dbg(dev, "RTC set alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
 252                year + 1900, tm->tm_mon, tm->tm_mday,
 253                tm->tm_hour, tm->tm_min, tm->tm_sec);
 254        return 0;
 255}
 256
 257/*
 258 * Handle commands from user-space
 259 */
 260static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 261{
 262        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
 263        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
 264        unsigned long flags;
 265
 266        spin_lock_irqsave(&m48t59->lock, flags);
 267        if (enabled)
 268                M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR);
 269        else
 270                M48T59_WRITE(0x00, M48T59_INTR);
 271        spin_unlock_irqrestore(&m48t59->lock, flags);
 272
 273        return 0;
 274}
 275
 276static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq)
 277{
 278        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
 279        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
 280        unsigned long flags;
 281        u8 val;
 282
 283        spin_lock_irqsave(&m48t59->lock, flags);
 284        val = M48T59_READ(M48T59_FLAGS);
 285        spin_unlock_irqrestore(&m48t59->lock, flags);
 286
 287        seq_printf(seq, "battery\t\t: %s\n",
 288                 (val & M48T59_FLAGS_BF) ? "low" : "normal");
 289        return 0;
 290}
 291
 292/*
 293 * IRQ handler for the RTC
 294 */
 295static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id)
 296{
 297        struct device *dev = (struct device *)dev_id;
 298        struct m48t59_plat_data *pdata = dev_get_platdata(dev);
 299        struct m48t59_private *m48t59 = dev_get_drvdata(dev);
 300        u8 event;
 301
 302        spin_lock(&m48t59->lock);
 303        event = M48T59_READ(M48T59_FLAGS);
 304        spin_unlock(&m48t59->lock);
 305
 306        if (event & M48T59_FLAGS_AF) {
 307                rtc_update_irq(m48t59->rtc, 1, (RTC_AF | RTC_IRQF));
 308                return IRQ_HANDLED;
 309        }
 310
 311        return IRQ_NONE;
 312}
 313
 314static const struct rtc_class_ops m48t59_rtc_ops = {
 315        .read_time      = m48t59_rtc_read_time,
 316        .set_time       = m48t59_rtc_set_time,
 317        .read_alarm     = m48t59_rtc_readalarm,
 318        .set_alarm      = m48t59_rtc_setalarm,
 319        .proc           = m48t59_rtc_proc,
 320        .alarm_irq_enable = m48t59_rtc_alarm_irq_enable,
 321};
 322
 323static const struct rtc_class_ops m48t02_rtc_ops = {
 324        .read_time      = m48t59_rtc_read_time,
 325        .set_time       = m48t59_rtc_set_time,
 326};
 327
 328static int m48t59_nvram_read(void *priv, unsigned int offset, void *val,
 329                             size_t size)
 330{
 331        struct platform_device *pdev = priv;
 332        struct device *dev = &pdev->dev;
 333        struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
 334        struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
 335        ssize_t cnt = 0;
 336        unsigned long flags;
 337        u8 *buf = val;
 338
 339        spin_lock_irqsave(&m48t59->lock, flags);
 340
 341        for (; cnt < size; cnt++)
 342                *buf++ = M48T59_READ(cnt);
 343
 344        spin_unlock_irqrestore(&m48t59->lock, flags);
 345
 346        return 0;
 347}
 348
 349static int m48t59_nvram_write(void *priv, unsigned int offset, void *val,
 350                              size_t size)
 351{
 352        struct platform_device *pdev = priv;
 353        struct device *dev = &pdev->dev;
 354        struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
 355        struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
 356        ssize_t cnt = 0;
 357        unsigned long flags;
 358        u8 *buf = val;
 359
 360        spin_lock_irqsave(&m48t59->lock, flags);
 361
 362        for (; cnt < size; cnt++)
 363                M48T59_WRITE(*buf++, cnt);
 364
 365        spin_unlock_irqrestore(&m48t59->lock, flags);
 366
 367        return 0;
 368}
 369
 370static int m48t59_rtc_probe(struct platform_device *pdev)
 371{
 372        struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev);
 373        struct m48t59_private *m48t59 = NULL;
 374        struct resource *res;
 375        int ret = -ENOMEM;
 376        const struct rtc_class_ops *ops;
 377        struct nvmem_config nvmem_cfg = {
 378                .name = "m48t59-",
 379                .word_size = 1,
 380                .stride = 1,
 381                .reg_read = m48t59_nvram_read,
 382                .reg_write = m48t59_nvram_write,
 383                .priv = pdev,
 384        };
 385
 386        /* This chip could be memory-mapped or I/O-mapped */
 387        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 388        if (!res) {
 389                res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 390                if (!res)
 391                        return -EINVAL;
 392        }
 393
 394        if (res->flags & IORESOURCE_IO) {
 395                /* If we are I/O-mapped, the platform should provide
 396                 * the operations accessing chip registers.
 397                 */
 398                if (!pdata || !pdata->write_byte || !pdata->read_byte)
 399                        return -EINVAL;
 400        } else if (res->flags & IORESOURCE_MEM) {
 401                /* we are memory-mapped */
 402                if (!pdata) {
 403                        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata),
 404                                                GFP_KERNEL);
 405                        if (!pdata)
 406                                return -ENOMEM;
 407                        /* Ensure we only kmalloc platform data once */
 408                        pdev->dev.platform_data = pdata;
 409                }
 410                if (!pdata->type)
 411                        pdata->type = M48T59RTC_TYPE_M48T59;
 412
 413                /* Try to use the generic memory read/write ops */
 414                if (!pdata->write_byte)
 415                        pdata->write_byte = m48t59_mem_writeb;
 416                if (!pdata->read_byte)
 417                        pdata->read_byte = m48t59_mem_readb;
 418        }
 419
 420        m48t59 = devm_kzalloc(&pdev->dev, sizeof(*m48t59), GFP_KERNEL);
 421        if (!m48t59)
 422                return -ENOMEM;
 423
 424        m48t59->ioaddr = pdata->ioaddr;
 425
 426        if (!m48t59->ioaddr) {
 427                /* ioaddr not mapped externally */
 428                m48t59->ioaddr = devm_ioremap(&pdev->dev, res->start,
 429                                                resource_size(res));
 430                if (!m48t59->ioaddr)
 431                        return ret;
 432        }
 433
 434        /* Try to get irq number. We also can work in
 435         * the mode without IRQ.
 436         */
 437        m48t59->irq = platform_get_irq(pdev, 0);
 438        if (m48t59->irq <= 0)
 439                m48t59->irq = NO_IRQ;
 440
 441        if (m48t59->irq != NO_IRQ) {
 442                ret = devm_request_irq(&pdev->dev, m48t59->irq,
 443                                m48t59_rtc_interrupt, IRQF_SHARED,
 444                                "rtc-m48t59", &pdev->dev);
 445                if (ret)
 446                        return ret;
 447        }
 448        switch (pdata->type) {
 449        case M48T59RTC_TYPE_M48T59:
 450                ops = &m48t59_rtc_ops;
 451                pdata->offset = 0x1ff0;
 452                break;
 453        case M48T59RTC_TYPE_M48T02:
 454                ops = &m48t02_rtc_ops;
 455                pdata->offset = 0x7f0;
 456                break;
 457        case M48T59RTC_TYPE_M48T08:
 458                ops = &m48t02_rtc_ops;
 459                pdata->offset = 0x1ff0;
 460                break;
 461        default:
 462                dev_err(&pdev->dev, "Unknown RTC type\n");
 463                return -ENODEV;
 464        }
 465
 466        spin_lock_init(&m48t59->lock);
 467        platform_set_drvdata(pdev, m48t59);
 468
 469        m48t59->rtc = devm_rtc_allocate_device(&pdev->dev);
 470        if (IS_ERR(m48t59->rtc))
 471                return PTR_ERR(m48t59->rtc);
 472
 473        m48t59->rtc->nvram_old_abi = true;
 474        m48t59->rtc->ops = ops;
 475
 476        nvmem_cfg.size = pdata->offset;
 477        ret = rtc_nvmem_register(m48t59->rtc, &nvmem_cfg);
 478        if (ret)
 479                return ret;
 480
 481        ret = rtc_register_device(m48t59->rtc);
 482        if (ret)
 483                return ret;
 484
 485        return 0;
 486}
 487
 488/* work with hotplug and coldplug */
 489MODULE_ALIAS("platform:rtc-m48t59");
 490
 491static struct platform_driver m48t59_rtc_driver = {
 492        .driver         = {
 493                .name   = "rtc-m48t59",
 494        },
 495        .probe          = m48t59_rtc_probe,
 496};
 497
 498module_platform_driver(m48t59_rtc_driver);
 499
 500MODULE_AUTHOR("Mark Zhan <rongkai.zhan@windriver.com>");
 501MODULE_DESCRIPTION("M48T59/M48T02/M48T08 RTC driver");
 502MODULE_LICENSE("GPL");
 503