linux/drivers/rtc/rtc-tx4939.c
<<
>>
Prefs
   1/*
   2 * TX4939 internal RTC driver
   3 * Based on RBTX49xx patch from CELF patch archive.
   4 *
   5 * This file is subject to the terms and conditions of the GNU General Public
   6 * License.  See the file "COPYING" in the main directory of this archive
   7 * for more details.
   8 *
   9 * (C) Copyright TOSHIBA CORPORATION 2005-2007
  10 */
  11#include <linux/rtc.h>
  12#include <linux/platform_device.h>
  13#include <linux/interrupt.h>
  14#include <linux/module.h>
  15#include <linux/io.h>
  16#include <linux/gfp.h>
  17
  18#define TX4939_RTCCTL_ALME      0x00000080
  19#define TX4939_RTCCTL_ALMD      0x00000040
  20#define TX4939_RTCCTL_BUSY      0x00000020
  21
  22#define TX4939_RTCCTL_COMMAND   0x00000007
  23#define TX4939_RTCCTL_COMMAND_NOP       0x00000000
  24#define TX4939_RTCCTL_COMMAND_GETTIME   0x00000001
  25#define TX4939_RTCCTL_COMMAND_SETTIME   0x00000002
  26#define TX4939_RTCCTL_COMMAND_GETALARM  0x00000003
  27#define TX4939_RTCCTL_COMMAND_SETALARM  0x00000004
  28
  29#define TX4939_RTCTBC_PM        0x00000080
  30#define TX4939_RTCTBC_COMP      0x0000007f
  31
  32#define TX4939_RTC_REG_RAMSIZE  0x00000100
  33#define TX4939_RTC_REG_RWBSIZE  0x00000006
  34
  35struct tx4939_rtc_reg {
  36        __u32 ctl;
  37        __u32 adr;
  38        __u32 dat;
  39        __u32 tbc;
  40};
  41
  42struct tx4939rtc_plat_data {
  43        struct rtc_device *rtc;
  44        struct tx4939_rtc_reg __iomem *rtcreg;
  45        spinlock_t lock;
  46};
  47
  48static struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev)
  49{
  50        return platform_get_drvdata(to_platform_device(dev));
  51}
  52
  53static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd)
  54{
  55        int i = 0;
  56
  57        __raw_writel(cmd, &rtcreg->ctl);
  58        /* This might take 30us (next 32.768KHz clock) */
  59        while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) {
  60                /* timeout on approx. 100us (@ GBUS200MHz) */
  61                if (i++ > 200 * 100)
  62                        return -EBUSY;
  63                cpu_relax();
  64        }
  65        return 0;
  66}
  67
  68static int tx4939_rtc_set_mmss(struct device *dev, unsigned long secs)
  69{
  70        struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
  71        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
  72        int i, ret;
  73        unsigned char buf[6];
  74
  75        buf[0] = 0;
  76        buf[1] = 0;
  77        buf[2] = secs;
  78        buf[3] = secs >> 8;
  79        buf[4] = secs >> 16;
  80        buf[5] = secs >> 24;
  81        spin_lock_irq(&pdata->lock);
  82        __raw_writel(0, &rtcreg->adr);
  83        for (i = 0; i < 6; i++)
  84                __raw_writel(buf[i], &rtcreg->dat);
  85        ret = tx4939_rtc_cmd(rtcreg,
  86                             TX4939_RTCCTL_COMMAND_SETTIME |
  87                             (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
  88        spin_unlock_irq(&pdata->lock);
  89        return ret;
  90}
  91
  92static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm)
  93{
  94        struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
  95        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
  96        int i, ret;
  97        unsigned long sec;
  98        unsigned char buf[6];
  99
 100        spin_lock_irq(&pdata->lock);
 101        ret = tx4939_rtc_cmd(rtcreg,
 102                             TX4939_RTCCTL_COMMAND_GETTIME |
 103                             (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
 104        if (ret) {
 105                spin_unlock_irq(&pdata->lock);
 106                return ret;
 107        }
 108        __raw_writel(2, &rtcreg->adr);
 109        for (i = 2; i < 6; i++)
 110                buf[i] = __raw_readl(&rtcreg->dat);
 111        spin_unlock_irq(&pdata->lock);
 112        sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
 113                (buf[3] << 8) | buf[2];
 114        rtc_time_to_tm(sec, tm);
 115        return 0;
 116}
 117
 118static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 119{
 120        struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
 121        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 122        int i, ret;
 123        unsigned long sec;
 124        unsigned char buf[6];
 125
 126        if (alrm->time.tm_sec < 0 ||
 127            alrm->time.tm_min < 0 ||
 128            alrm->time.tm_hour < 0 ||
 129            alrm->time.tm_mday < 0 ||
 130            alrm->time.tm_mon < 0 ||
 131            alrm->time.tm_year < 0)
 132                return -EINVAL;
 133        rtc_tm_to_time(&alrm->time, &sec);
 134        buf[0] = 0;
 135        buf[1] = 0;
 136        buf[2] = sec;
 137        buf[3] = sec >> 8;
 138        buf[4] = sec >> 16;
 139        buf[5] = sec >> 24;
 140        spin_lock_irq(&pdata->lock);
 141        __raw_writel(0, &rtcreg->adr);
 142        for (i = 0; i < 6; i++)
 143                __raw_writel(buf[i], &rtcreg->dat);
 144        ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM |
 145                             (alrm->enabled ? TX4939_RTCCTL_ALME : 0));
 146        spin_unlock_irq(&pdata->lock);
 147        return ret;
 148}
 149
 150static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 151{
 152        struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
 153        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 154        int i, ret;
 155        unsigned long sec;
 156        unsigned char buf[6];
 157        u32 ctl;
 158
 159        spin_lock_irq(&pdata->lock);
 160        ret = tx4939_rtc_cmd(rtcreg,
 161                             TX4939_RTCCTL_COMMAND_GETALARM |
 162                             (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME));
 163        if (ret) {
 164                spin_unlock_irq(&pdata->lock);
 165                return ret;
 166        }
 167        __raw_writel(2, &rtcreg->adr);
 168        for (i = 2; i < 6; i++)
 169                buf[i] = __raw_readl(&rtcreg->dat);
 170        ctl = __raw_readl(&rtcreg->ctl);
 171        alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0;
 172        alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0;
 173        spin_unlock_irq(&pdata->lock);
 174        sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) |
 175                (buf[3] << 8) | buf[2];
 176        rtc_time_to_tm(sec, &alrm->time);
 177        return rtc_valid_tm(&alrm->time);
 178}
 179
 180static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 181{
 182        struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev);
 183
 184        spin_lock_irq(&pdata->lock);
 185        tx4939_rtc_cmd(pdata->rtcreg,
 186                       TX4939_RTCCTL_COMMAND_NOP |
 187                       (enabled ? TX4939_RTCCTL_ALME : 0));
 188        spin_unlock_irq(&pdata->lock);
 189        return 0;
 190}
 191
 192static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id)
 193{
 194        struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev_id);
 195        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 196        unsigned long events = RTC_IRQF;
 197
 198        spin_lock(&pdata->lock);
 199        if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) {
 200                events |= RTC_AF;
 201                tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP);
 202        }
 203        spin_unlock(&pdata->lock);
 204        rtc_update_irq(pdata->rtc, 1, events);
 205
 206        return IRQ_HANDLED;
 207}
 208
 209static const struct rtc_class_ops tx4939_rtc_ops = {
 210        .read_time              = tx4939_rtc_read_time,
 211        .read_alarm             = tx4939_rtc_read_alarm,
 212        .set_alarm              = tx4939_rtc_set_alarm,
 213        .set_mmss               = tx4939_rtc_set_mmss,
 214        .alarm_irq_enable       = tx4939_rtc_alarm_irq_enable,
 215};
 216
 217static int tx4939_nvram_read(void *priv, unsigned int pos, void *val,
 218                             size_t bytes)
 219{
 220        struct tx4939rtc_plat_data *pdata = priv;
 221        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 222        u8 *buf = val;
 223
 224        spin_lock_irq(&pdata->lock);
 225        for (; bytes; bytes--) {
 226                __raw_writel(pos++, &rtcreg->adr);
 227                *buf++ = __raw_readl(&rtcreg->dat);
 228        }
 229        spin_unlock_irq(&pdata->lock);
 230        return 0;
 231}
 232
 233static int tx4939_nvram_write(void *priv, unsigned int pos, void *val,
 234                              size_t bytes)
 235{
 236        struct tx4939rtc_plat_data *pdata = priv;
 237        struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg;
 238        u8 *buf = val;
 239
 240        spin_lock_irq(&pdata->lock);
 241        for (; bytes; bytes--) {
 242                __raw_writel(pos++, &rtcreg->adr);
 243                __raw_writel(*buf++, &rtcreg->dat);
 244        }
 245        spin_unlock_irq(&pdata->lock);
 246        return 0;
 247}
 248
 249static int __init tx4939_rtc_probe(struct platform_device *pdev)
 250{
 251        struct rtc_device *rtc;
 252        struct tx4939rtc_plat_data *pdata;
 253        struct resource *res;
 254        int irq, ret;
 255        struct nvmem_config nvmem_cfg = {
 256                .name = "rv8803_nvram",
 257                .word_size = 4,
 258                .stride = 4,
 259                .size = TX4939_RTC_REG_RAMSIZE,
 260                .reg_read = tx4939_nvram_read,
 261                .reg_write = tx4939_nvram_write,
 262        };
 263
 264        irq = platform_get_irq(pdev, 0);
 265        if (irq < 0)
 266                return -ENODEV;
 267        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 268        if (!pdata)
 269                return -ENOMEM;
 270        platform_set_drvdata(pdev, pdata);
 271
 272        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 273        pdata->rtcreg = devm_ioremap_resource(&pdev->dev, res);
 274        if (IS_ERR(pdata->rtcreg))
 275                return PTR_ERR(pdata->rtcreg);
 276
 277        spin_lock_init(&pdata->lock);
 278        tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
 279        if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
 280                             0, pdev->name, &pdev->dev) < 0)
 281                return -EBUSY;
 282        rtc = devm_rtc_allocate_device(&pdev->dev);
 283        if (IS_ERR(rtc))
 284                return PTR_ERR(rtc);
 285
 286        rtc->ops = &tx4939_rtc_ops;
 287        rtc->nvram_old_abi = true;
 288
 289        pdata->rtc = rtc;
 290
 291        nvmem_cfg.priv = pdata;
 292        ret = rtc_nvmem_register(rtc, &nvmem_cfg);
 293        if (ret)
 294                return ret;
 295
 296        return rtc_register_device(rtc);
 297}
 298
 299static int __exit tx4939_rtc_remove(struct platform_device *pdev)
 300{
 301        struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev);
 302
 303        spin_lock_irq(&pdata->lock);
 304        tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
 305        spin_unlock_irq(&pdata->lock);
 306        return 0;
 307}
 308
 309static struct platform_driver tx4939_rtc_driver = {
 310        .remove         = __exit_p(tx4939_rtc_remove),
 311        .driver         = {
 312                .name   = "tx4939rtc",
 313        },
 314};
 315
 316module_platform_driver_probe(tx4939_rtc_driver, tx4939_rtc_probe);
 317
 318MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 319MODULE_DESCRIPTION("TX4939 internal RTC driver");
 320MODULE_LICENSE("GPL");
 321MODULE_ALIAS("platform:tx4939rtc");
 322