Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * An rtc driver for the Dallas DS1742
0004  *
0005  * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
0006  *
0007  * Copyright (C) 2006 Torsten Ertbjerg Rasmussen <tr@newtec.dk>
0008  *  - nvram size determined from resource
0009  *  - this ds1742 driver now supports ds1743.
0010  */
0011 
0012 #include <linux/bcd.h>
0013 #include <linux/kernel.h>
0014 #include <linux/gfp.h>
0015 #include <linux/delay.h>
0016 #include <linux/jiffies.h>
0017 #include <linux/rtc.h>
0018 #include <linux/of.h>
0019 #include <linux/of_device.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/io.h>
0022 #include <linux/module.h>
0023 
0024 #define RTC_SIZE        8
0025 
0026 #define RTC_CONTROL     0
0027 #define RTC_CENTURY     0
0028 #define RTC_SECONDS     1
0029 #define RTC_MINUTES     2
0030 #define RTC_HOURS       3
0031 #define RTC_DAY         4
0032 #define RTC_DATE        5
0033 #define RTC_MONTH       6
0034 #define RTC_YEAR        7
0035 
0036 #define RTC_CENTURY_MASK    0x3f
0037 #define RTC_SECONDS_MASK    0x7f
0038 #define RTC_DAY_MASK        0x07
0039 
0040 /* Bits in the Control/Century register */
0041 #define RTC_WRITE       0x80
0042 #define RTC_READ        0x40
0043 
0044 /* Bits in the Seconds register */
0045 #define RTC_STOP        0x80
0046 
0047 /* Bits in the Day register */
0048 #define RTC_BATT_FLAG       0x80
0049 
0050 struct rtc_plat_data {
0051     void __iomem *ioaddr_nvram;
0052     void __iomem *ioaddr_rtc;
0053     unsigned long last_jiffies;
0054 };
0055 
0056 static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
0057 {
0058     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0059     void __iomem *ioaddr = pdata->ioaddr_rtc;
0060     u8 century;
0061 
0062     century = bin2bcd((tm->tm_year + 1900) / 100);
0063 
0064     writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
0065 
0066     writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR);
0067     writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH);
0068     writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
0069     writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE);
0070     writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS);
0071     writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES);
0072     writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
0073 
0074     /* RTC_CENTURY and RTC_CONTROL share same register */
0075     writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
0076     writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
0077     return 0;
0078 }
0079 
0080 static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
0081 {
0082     struct rtc_plat_data *pdata = dev_get_drvdata(dev);
0083     void __iomem *ioaddr = pdata->ioaddr_rtc;
0084     unsigned int year, month, day, hour, minute, second, week;
0085     unsigned int century;
0086 
0087     /* give enough time to update RTC in case of continuous read */
0088     if (pdata->last_jiffies == jiffies)
0089         msleep(1);
0090     pdata->last_jiffies = jiffies;
0091     writeb(RTC_READ, ioaddr + RTC_CONTROL);
0092     second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK;
0093     minute = readb(ioaddr + RTC_MINUTES);
0094     hour = readb(ioaddr + RTC_HOURS);
0095     day = readb(ioaddr + RTC_DATE);
0096     week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK;
0097     month = readb(ioaddr + RTC_MONTH);
0098     year = readb(ioaddr + RTC_YEAR);
0099     century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
0100     writeb(0, ioaddr + RTC_CONTROL);
0101     tm->tm_sec = bcd2bin(second);
0102     tm->tm_min = bcd2bin(minute);
0103     tm->tm_hour = bcd2bin(hour);
0104     tm->tm_mday = bcd2bin(day);
0105     tm->tm_wday = bcd2bin(week);
0106     tm->tm_mon = bcd2bin(month) - 1;
0107     /* year is 1900 + tm->tm_year */
0108     tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
0109 
0110     return 0;
0111 }
0112 
0113 static const struct rtc_class_ops ds1742_rtc_ops = {
0114     .read_time  = ds1742_rtc_read_time,
0115     .set_time   = ds1742_rtc_set_time,
0116 };
0117 
0118 static int ds1742_nvram_read(void *priv, unsigned int pos, void *val,
0119                  size_t bytes)
0120 {
0121     struct rtc_plat_data *pdata = priv;
0122     void __iomem *ioaddr = pdata->ioaddr_nvram;
0123     u8 *buf = val;
0124 
0125     for (; bytes; bytes--)
0126         *buf++ = readb(ioaddr + pos++);
0127     return 0;
0128 }
0129 
0130 static int ds1742_nvram_write(void *priv, unsigned int pos, void *val,
0131                   size_t bytes)
0132 {
0133     struct rtc_plat_data *pdata = priv;
0134     void __iomem *ioaddr = pdata->ioaddr_nvram;
0135     u8 *buf = val;
0136 
0137     for (; bytes; bytes--)
0138         writeb(*buf++, ioaddr + pos++);
0139     return 0;
0140 }
0141 
0142 static int ds1742_rtc_probe(struct platform_device *pdev)
0143 {
0144     struct rtc_device *rtc;
0145     struct resource *res;
0146     unsigned int cen, sec;
0147     struct rtc_plat_data *pdata;
0148     void __iomem *ioaddr;
0149     int ret = 0;
0150     struct nvmem_config nvmem_cfg = {
0151         .name = "ds1742_nvram",
0152         .reg_read = ds1742_nvram_read,
0153         .reg_write = ds1742_nvram_write,
0154     };
0155 
0156 
0157     pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0158     if (!pdata)
0159         return -ENOMEM;
0160 
0161     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0162     ioaddr = devm_ioremap_resource(&pdev->dev, res);
0163     if (IS_ERR(ioaddr))
0164         return PTR_ERR(ioaddr);
0165 
0166     pdata->ioaddr_nvram = ioaddr;
0167     pdata->ioaddr_rtc = ioaddr + resource_size(res) - RTC_SIZE;
0168 
0169     nvmem_cfg.size = resource_size(res) - RTC_SIZE;
0170     nvmem_cfg.priv = pdata;
0171 
0172     /* turn RTC on if it was not on */
0173     ioaddr = pdata->ioaddr_rtc;
0174     sec = readb(ioaddr + RTC_SECONDS);
0175     if (sec & RTC_STOP) {
0176         sec &= RTC_SECONDS_MASK;
0177         cen = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
0178         writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
0179         writeb(sec, ioaddr + RTC_SECONDS);
0180         writeb(cen & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
0181     }
0182     if (!(readb(ioaddr + RTC_DAY) & RTC_BATT_FLAG))
0183         dev_warn(&pdev->dev, "voltage-low detected.\n");
0184 
0185     pdata->last_jiffies = jiffies;
0186     platform_set_drvdata(pdev, pdata);
0187 
0188     rtc = devm_rtc_allocate_device(&pdev->dev);
0189     if (IS_ERR(rtc))
0190         return PTR_ERR(rtc);
0191 
0192     rtc->ops = &ds1742_rtc_ops;
0193 
0194     ret = devm_rtc_register_device(rtc);
0195     if (ret)
0196         return ret;
0197 
0198     devm_rtc_nvmem_register(rtc, &nvmem_cfg);
0199 
0200     return 0;
0201 }
0202 
0203 static const struct of_device_id __maybe_unused ds1742_rtc_of_match[] = {
0204     { .compatible = "maxim,ds1742", },
0205     { }
0206 };
0207 MODULE_DEVICE_TABLE(of, ds1742_rtc_of_match);
0208 
0209 static struct platform_driver ds1742_rtc_driver = {
0210     .probe      = ds1742_rtc_probe,
0211     .driver     = {
0212         .name   = "rtc-ds1742",
0213         .of_match_table = of_match_ptr(ds1742_rtc_of_match),
0214     },
0215 };
0216 
0217 module_platform_driver(ds1742_rtc_driver);
0218 
0219 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
0220 MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
0221 MODULE_LICENSE("GPL");
0222 MODULE_ALIAS("platform:rtc-ds1742");