root/drivers/rtc/rtc-ds1553.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ds1553_rtc_set_time
  2. ds1553_rtc_read_time
  3. ds1553_rtc_update_alarm
  4. ds1553_rtc_set_alarm
  5. ds1553_rtc_read_alarm
  6. ds1553_rtc_interrupt
  7. ds1553_rtc_alarm_irq_enable
  8. ds1553_nvram_read
  9. ds1553_nvram_write
  10. ds1553_rtc_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * An rtc driver for the Dallas DS1553
   4  *
   5  * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
   6  */
   7 
   8 #include <linux/bcd.h>
   9 #include <linux/init.h>
  10 #include <linux/kernel.h>
  11 #include <linux/gfp.h>
  12 #include <linux/delay.h>
  13 #include <linux/jiffies.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/rtc.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/io.h>
  18 #include <linux/module.h>
  19 
  20 #define RTC_REG_SIZE            0x2000
  21 #define RTC_OFFSET              0x1ff0
  22 
  23 #define RTC_FLAGS               (RTC_OFFSET + 0)
  24 #define RTC_SECONDS_ALARM       (RTC_OFFSET + 2)
  25 #define RTC_MINUTES_ALARM       (RTC_OFFSET + 3)
  26 #define RTC_HOURS_ALARM         (RTC_OFFSET + 4)
  27 #define RTC_DATE_ALARM          (RTC_OFFSET + 5)
  28 #define RTC_INTERRUPTS          (RTC_OFFSET + 6)
  29 #define RTC_WATCHDOG            (RTC_OFFSET + 7)
  30 #define RTC_CONTROL             (RTC_OFFSET + 8)
  31 #define RTC_CENTURY             (RTC_OFFSET + 8)
  32 #define RTC_SECONDS             (RTC_OFFSET + 9)
  33 #define RTC_MINUTES             (RTC_OFFSET + 10)
  34 #define RTC_HOURS               (RTC_OFFSET + 11)
  35 #define RTC_DAY                 (RTC_OFFSET + 12)
  36 #define RTC_DATE                (RTC_OFFSET + 13)
  37 #define RTC_MONTH               (RTC_OFFSET + 14)
  38 #define RTC_YEAR                (RTC_OFFSET + 15)
  39 
  40 #define RTC_CENTURY_MASK        0x3f
  41 #define RTC_SECONDS_MASK        0x7f
  42 #define RTC_DAY_MASK            0x07
  43 
  44 /* Bits in the Control/Century register */
  45 #define RTC_WRITE               0x80
  46 #define RTC_READ                0x40
  47 
  48 /* Bits in the Seconds register */
  49 #define RTC_STOP                0x80
  50 
  51 /* Bits in the Flags register */
  52 #define RTC_FLAGS_AF            0x40
  53 #define RTC_FLAGS_BLF           0x10
  54 
  55 /* Bits in the Interrupts register */
  56 #define RTC_INTS_AE             0x80
  57 
  58 struct rtc_plat_data {
  59         struct rtc_device *rtc;
  60         void __iomem *ioaddr;
  61         unsigned long last_jiffies;
  62         int irq;
  63         unsigned int irqen;
  64         int alrm_sec;
  65         int alrm_min;
  66         int alrm_hour;
  67         int alrm_mday;
  68         spinlock_t lock;
  69 };
  70 
  71 static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
  72 {
  73         struct rtc_plat_data *pdata = dev_get_drvdata(dev);
  74         void __iomem *ioaddr = pdata->ioaddr;
  75         u8 century;
  76 
  77         century = bin2bcd((tm->tm_year + 1900) / 100);
  78 
  79         writeb(RTC_WRITE, pdata->ioaddr + RTC_CONTROL);
  80 
  81         writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR);
  82         writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH);
  83         writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
  84         writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE);
  85         writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS);
  86         writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES);
  87         writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
  88 
  89         /* RTC_CENTURY and RTC_CONTROL share same register */
  90         writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
  91         writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
  92         return 0;
  93 }
  94 
  95 static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm)
  96 {
  97         struct rtc_plat_data *pdata = dev_get_drvdata(dev);
  98         void __iomem *ioaddr = pdata->ioaddr;
  99         unsigned int year, month, day, hour, minute, second, week;
 100         unsigned int century;
 101 
 102         /* give enough time to update RTC in case of continuous read */
 103         if (pdata->last_jiffies == jiffies)
 104                 msleep(1);
 105         pdata->last_jiffies = jiffies;
 106         writeb(RTC_READ, ioaddr + RTC_CONTROL);
 107         second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK;
 108         minute = readb(ioaddr + RTC_MINUTES);
 109         hour = readb(ioaddr + RTC_HOURS);
 110         day = readb(ioaddr + RTC_DATE);
 111         week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK;
 112         month = readb(ioaddr + RTC_MONTH);
 113         year = readb(ioaddr + RTC_YEAR);
 114         century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
 115         writeb(0, ioaddr + RTC_CONTROL);
 116         tm->tm_sec = bcd2bin(second);
 117         tm->tm_min = bcd2bin(minute);
 118         tm->tm_hour = bcd2bin(hour);
 119         tm->tm_mday = bcd2bin(day);
 120         tm->tm_wday = bcd2bin(week);
 121         tm->tm_mon = bcd2bin(month) - 1;
 122         /* year is 1900 + tm->tm_year */
 123         tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
 124 
 125         return 0;
 126 }
 127 
 128 static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata)
 129 {
 130         void __iomem *ioaddr = pdata->ioaddr;
 131         unsigned long flags;
 132 
 133         spin_lock_irqsave(&pdata->lock, flags);
 134         writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
 135                0x80 : bin2bcd(pdata->alrm_mday),
 136                ioaddr + RTC_DATE_ALARM);
 137         writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
 138                0x80 : bin2bcd(pdata->alrm_hour),
 139                ioaddr + RTC_HOURS_ALARM);
 140         writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
 141                0x80 : bin2bcd(pdata->alrm_min),
 142                ioaddr + RTC_MINUTES_ALARM);
 143         writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
 144                0x80 : bin2bcd(pdata->alrm_sec),
 145                ioaddr + RTC_SECONDS_ALARM);
 146         writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS);
 147         readb(ioaddr + RTC_FLAGS);      /* clear interrupts */
 148         spin_unlock_irqrestore(&pdata->lock, flags);
 149 }
 150 
 151 static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 152 {
 153         struct rtc_plat_data *pdata = dev_get_drvdata(dev);
 154 
 155         if (pdata->irq <= 0)
 156                 return -EINVAL;
 157         pdata->alrm_mday = alrm->time.tm_mday;
 158         pdata->alrm_hour = alrm->time.tm_hour;
 159         pdata->alrm_min = alrm->time.tm_min;
 160         pdata->alrm_sec = alrm->time.tm_sec;
 161         if (alrm->enabled)
 162                 pdata->irqen |= RTC_AF;
 163         ds1553_rtc_update_alarm(pdata);
 164         return 0;
 165 }
 166 
 167 static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 168 {
 169         struct rtc_plat_data *pdata = dev_get_drvdata(dev);
 170 
 171         if (pdata->irq <= 0)
 172                 return -EINVAL;
 173         alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday;
 174         alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour;
 175         alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min;
 176         alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec;
 177         alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0;
 178         return 0;
 179 }
 180 
 181 static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
 182 {
 183         struct platform_device *pdev = dev_id;
 184         struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 185         void __iomem *ioaddr = pdata->ioaddr;
 186         unsigned long events = 0;
 187 
 188         spin_lock(&pdata->lock);
 189         /* read and clear interrupt */
 190         if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF) {
 191                 events = RTC_IRQF;
 192                 if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
 193                         events |= RTC_UF;
 194                 else
 195                         events |= RTC_AF;
 196                 rtc_update_irq(pdata->rtc, 1, events);
 197         }
 198         spin_unlock(&pdata->lock);
 199         return events ? IRQ_HANDLED : IRQ_NONE;
 200 }
 201 
 202 static int ds1553_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 203 {
 204         struct rtc_plat_data *pdata = dev_get_drvdata(dev);
 205 
 206         if (pdata->irq <= 0)
 207                 return -EINVAL;
 208         if (enabled)
 209                 pdata->irqen |= RTC_AF;
 210         else
 211                 pdata->irqen &= ~RTC_AF;
 212         ds1553_rtc_update_alarm(pdata);
 213         return 0;
 214 }
 215 
 216 static const struct rtc_class_ops ds1553_rtc_ops = {
 217         .read_time              = ds1553_rtc_read_time,
 218         .set_time               = ds1553_rtc_set_time,
 219         .read_alarm             = ds1553_rtc_read_alarm,
 220         .set_alarm              = ds1553_rtc_set_alarm,
 221         .alarm_irq_enable       = ds1553_rtc_alarm_irq_enable,
 222 };
 223 
 224 static int ds1553_nvram_read(void *priv, unsigned int pos, void *val,
 225                              size_t bytes)
 226 {
 227         struct platform_device *pdev = priv;
 228         struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 229         void __iomem *ioaddr = pdata->ioaddr;
 230         u8 *buf = val;
 231 
 232         for (; bytes; bytes--)
 233                 *buf++ = readb(ioaddr + pos++);
 234         return 0;
 235 }
 236 
 237 static int ds1553_nvram_write(void *priv, unsigned int pos, void *val,
 238                               size_t bytes)
 239 {
 240         struct platform_device *pdev = priv;
 241         struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 242         void __iomem *ioaddr = pdata->ioaddr;
 243         u8 *buf = val;
 244 
 245         for (; bytes; bytes--)
 246                 writeb(*buf++, ioaddr + pos++);
 247         return 0;
 248 }
 249 
 250 static int ds1553_rtc_probe(struct platform_device *pdev)
 251 {
 252         struct resource *res;
 253         unsigned int cen, sec;
 254         struct rtc_plat_data *pdata;
 255         void __iomem *ioaddr;
 256         int ret = 0;
 257         struct nvmem_config nvmem_cfg = {
 258                 .name = "ds1553_nvram",
 259                 .word_size = 1,
 260                 .stride = 1,
 261                 .size = RTC_OFFSET,
 262                 .reg_read = ds1553_nvram_read,
 263                 .reg_write = ds1553_nvram_write,
 264                 .priv = pdev,
 265         };
 266 
 267         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 268         if (!pdata)
 269                 return -ENOMEM;
 270 
 271         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 272         ioaddr = devm_ioremap_resource(&pdev->dev, res);
 273         if (IS_ERR(ioaddr))
 274                 return PTR_ERR(ioaddr);
 275         pdata->ioaddr = ioaddr;
 276         pdata->irq = platform_get_irq(pdev, 0);
 277 
 278         /* turn RTC on if it was not on */
 279         sec = readb(ioaddr + RTC_SECONDS);
 280         if (sec & RTC_STOP) {
 281                 sec &= RTC_SECONDS_MASK;
 282                 cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
 283                 writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
 284                 writeb(sec, ioaddr + RTC_SECONDS);
 285                 writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
 286         }
 287         if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF)
 288                 dev_warn(&pdev->dev, "voltage-low detected.\n");
 289 
 290         spin_lock_init(&pdata->lock);
 291         pdata->last_jiffies = jiffies;
 292         platform_set_drvdata(pdev, pdata);
 293 
 294         pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
 295         if (IS_ERR(pdata->rtc))
 296                 return PTR_ERR(pdata->rtc);
 297 
 298         pdata->rtc->ops = &ds1553_rtc_ops;
 299         pdata->rtc->nvram_old_abi = true;
 300 
 301         ret = rtc_register_device(pdata->rtc);
 302         if (ret)
 303                 return ret;
 304 
 305         if (pdata->irq > 0) {
 306                 writeb(0, ioaddr + RTC_INTERRUPTS);
 307                 if (devm_request_irq(&pdev->dev, pdata->irq,
 308                                 ds1553_rtc_interrupt,
 309                                 0, pdev->name, pdev) < 0) {
 310                         dev_warn(&pdev->dev, "interrupt not available.\n");
 311                         pdata->irq = 0;
 312                 }
 313         }
 314 
 315         if (rtc_nvmem_register(pdata->rtc, &nvmem_cfg))
 316                 dev_err(&pdev->dev, "unable to register nvmem\n");
 317 
 318         return 0;
 319 }
 320 
 321 /* work with hotplug and coldplug */
 322 MODULE_ALIAS("platform:rtc-ds1553");
 323 
 324 static struct platform_driver ds1553_rtc_driver = {
 325         .probe          = ds1553_rtc_probe,
 326         .driver         = {
 327                 .name   = "rtc-ds1553",
 328         },
 329 };
 330 
 331 module_platform_driver(ds1553_rtc_driver);
 332 
 333 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 334 MODULE_DESCRIPTION("Dallas DS1553 RTC driver");
 335 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */