1 // SPDX-License-Identifier: GPL-2.0-only
3 * An rtc driver for the Dallas DS1742
5 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
7 * Copyright (C) 2006 Torsten Ertbjerg Rasmussen <tr@newtec.dk>
8 * - nvram size determined from resource
9 * - this ds1742 driver now supports ds1743.
12 #include <linux/bcd.h>
13 #include <linux/kernel.h>
14 #include <linux/gfp.h>
15 #include <linux/delay.h>
16 #include <linux/jiffies.h>
17 #include <linux/rtc.h>
19 #include <linux/of_device.h>
20 #include <linux/platform_device.h>
22 #include <linux/module.h>
36 #define RTC_CENTURY_MASK 0x3f
37 #define RTC_SECONDS_MASK 0x7f
38 #define RTC_DAY_MASK 0x07
40 /* Bits in the Control/Century register */
41 #define RTC_WRITE 0x80
44 /* Bits in the Seconds register */
47 /* Bits in the Day register */
48 #define RTC_BATT_FLAG 0x80
50 struct rtc_plat_data
{
51 void __iomem
*ioaddr_nvram
;
52 void __iomem
*ioaddr_rtc
;
53 unsigned long last_jiffies
;
56 static int ds1742_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
58 struct rtc_plat_data
*pdata
= dev_get_drvdata(dev
);
59 void __iomem
*ioaddr
= pdata
->ioaddr_rtc
;
62 century
= bin2bcd((tm
->tm_year
+ 1900) / 100);
64 writeb(RTC_WRITE
, ioaddr
+ RTC_CONTROL
);
66 writeb(bin2bcd(tm
->tm_year
% 100), ioaddr
+ RTC_YEAR
);
67 writeb(bin2bcd(tm
->tm_mon
+ 1), ioaddr
+ RTC_MONTH
);
68 writeb(bin2bcd(tm
->tm_wday
) & RTC_DAY_MASK
, ioaddr
+ RTC_DAY
);
69 writeb(bin2bcd(tm
->tm_mday
), ioaddr
+ RTC_DATE
);
70 writeb(bin2bcd(tm
->tm_hour
), ioaddr
+ RTC_HOURS
);
71 writeb(bin2bcd(tm
->tm_min
), ioaddr
+ RTC_MINUTES
);
72 writeb(bin2bcd(tm
->tm_sec
) & RTC_SECONDS_MASK
, ioaddr
+ RTC_SECONDS
);
74 /* RTC_CENTURY and RTC_CONTROL share same register */
75 writeb(RTC_WRITE
| (century
& RTC_CENTURY_MASK
), ioaddr
+ RTC_CENTURY
);
76 writeb(century
& RTC_CENTURY_MASK
, ioaddr
+ RTC_CONTROL
);
80 static int ds1742_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
82 struct rtc_plat_data
*pdata
= dev_get_drvdata(dev
);
83 void __iomem
*ioaddr
= pdata
->ioaddr_rtc
;
84 unsigned int year
, month
, day
, hour
, minute
, second
, week
;
87 /* give enough time to update RTC in case of continuous read */
88 if (pdata
->last_jiffies
== jiffies
)
90 pdata
->last_jiffies
= jiffies
;
91 writeb(RTC_READ
, ioaddr
+ RTC_CONTROL
);
92 second
= readb(ioaddr
+ RTC_SECONDS
) & RTC_SECONDS_MASK
;
93 minute
= readb(ioaddr
+ RTC_MINUTES
);
94 hour
= readb(ioaddr
+ RTC_HOURS
);
95 day
= readb(ioaddr
+ RTC_DATE
);
96 week
= readb(ioaddr
+ RTC_DAY
) & RTC_DAY_MASK
;
97 month
= readb(ioaddr
+ RTC_MONTH
);
98 year
= readb(ioaddr
+ RTC_YEAR
);
99 century
= readb(ioaddr
+ RTC_CENTURY
) & RTC_CENTURY_MASK
;
100 writeb(0, ioaddr
+ RTC_CONTROL
);
101 tm
->tm_sec
= bcd2bin(second
);
102 tm
->tm_min
= bcd2bin(minute
);
103 tm
->tm_hour
= bcd2bin(hour
);
104 tm
->tm_mday
= bcd2bin(day
);
105 tm
->tm_wday
= bcd2bin(week
);
106 tm
->tm_mon
= bcd2bin(month
) - 1;
107 /* year is 1900 + tm->tm_year */
108 tm
->tm_year
= bcd2bin(year
) + bcd2bin(century
) * 100 - 1900;
113 static const struct rtc_class_ops ds1742_rtc_ops
= {
114 .read_time
= ds1742_rtc_read_time
,
115 .set_time
= ds1742_rtc_set_time
,
118 static int ds1742_nvram_read(void *priv
, unsigned int pos
, void *val
,
121 struct rtc_plat_data
*pdata
= priv
;
122 void __iomem
*ioaddr
= pdata
->ioaddr_nvram
;
125 for (; bytes
; bytes
--)
126 *buf
++ = readb(ioaddr
+ pos
++);
130 static int ds1742_nvram_write(void *priv
, unsigned int pos
, void *val
,
133 struct rtc_plat_data
*pdata
= priv
;
134 void __iomem
*ioaddr
= pdata
->ioaddr_nvram
;
137 for (; bytes
; bytes
--)
138 writeb(*buf
++, ioaddr
+ pos
++);
142 static int ds1742_rtc_probe(struct platform_device
*pdev
)
144 struct rtc_device
*rtc
;
145 struct resource
*res
;
146 unsigned int cen
, sec
;
147 struct rtc_plat_data
*pdata
;
148 void __iomem
*ioaddr
;
150 struct nvmem_config nvmem_cfg
= {
151 .name
= "ds1742_nvram",
152 .reg_read
= ds1742_nvram_read
,
153 .reg_write
= ds1742_nvram_write
,
157 pdata
= devm_kzalloc(&pdev
->dev
, sizeof(*pdata
), GFP_KERNEL
);
161 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
162 ioaddr
= devm_ioremap_resource(&pdev
->dev
, res
);
164 return PTR_ERR(ioaddr
);
166 pdata
->ioaddr_nvram
= ioaddr
;
167 pdata
->ioaddr_rtc
= ioaddr
+ resource_size(res
) - RTC_SIZE
;
169 nvmem_cfg
.size
= resource_size(res
) - RTC_SIZE
;
170 nvmem_cfg
.priv
= pdata
;
172 /* turn RTC on if it was not on */
173 ioaddr
= pdata
->ioaddr_rtc
;
174 sec
= readb(ioaddr
+ RTC_SECONDS
);
175 if (sec
& RTC_STOP
) {
176 sec
&= RTC_SECONDS_MASK
;
177 cen
= readb(ioaddr
+ RTC_CENTURY
) & RTC_CENTURY_MASK
;
178 writeb(RTC_WRITE
, ioaddr
+ RTC_CONTROL
);
179 writeb(sec
, ioaddr
+ RTC_SECONDS
);
180 writeb(cen
& RTC_CENTURY_MASK
, ioaddr
+ RTC_CONTROL
);
182 if (!(readb(ioaddr
+ RTC_DAY
) & RTC_BATT_FLAG
))
183 dev_warn(&pdev
->dev
, "voltage-low detected.\n");
185 pdata
->last_jiffies
= jiffies
;
186 platform_set_drvdata(pdev
, pdata
);
188 rtc
= devm_rtc_allocate_device(&pdev
->dev
);
192 rtc
->ops
= &ds1742_rtc_ops
;
194 ret
= devm_rtc_register_device(rtc
);
198 devm_rtc_nvmem_register(rtc
, &nvmem_cfg
);
203 static const struct of_device_id __maybe_unused ds1742_rtc_of_match
[] = {
204 { .compatible
= "maxim,ds1742", },
207 MODULE_DEVICE_TABLE(of
, ds1742_rtc_of_match
);
209 static struct platform_driver ds1742_rtc_driver
= {
210 .probe
= ds1742_rtc_probe
,
212 .name
= "rtc-ds1742",
213 .of_match_table
= of_match_ptr(ds1742_rtc_of_match
),
217 module_platform_driver(ds1742_rtc_driver
);
219 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
220 MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
221 MODULE_LICENSE("GPL");
222 MODULE_ALIAS("platform:rtc-ds1742");