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