1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * DS1286 Real Time Clock interface for Linux |
4 | * |
5 | * Copyright (C) 1998, 1999, 2000 Ralf Baechle |
6 | * Copyright (C) 2008 Thomas Bogendoerfer |
7 | * |
8 | * Based on code written by Paul Gortmaker. |
9 | */ |
10 | |
11 | #include <linux/module.h> |
12 | #include <linux/rtc.h> |
13 | #include <linux/platform_device.h> |
14 | #include <linux/bcd.h> |
15 | #include <linux/rtc/ds1286.h> |
16 | #include <linux/io.h> |
17 | #include <linux/slab.h> |
18 | |
19 | struct ds1286_priv { |
20 | struct rtc_device *rtc; |
21 | u32 __iomem *rtcregs; |
22 | spinlock_t lock; |
23 | }; |
24 | |
25 | static inline u8 ds1286_rtc_read(struct ds1286_priv *priv, int reg) |
26 | { |
27 | return __raw_readl(addr: &priv->rtcregs[reg]) & 0xff; |
28 | } |
29 | |
30 | static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) |
31 | { |
32 | __raw_writel(val: data, addr: &priv->rtcregs[reg]); |
33 | } |
34 | |
35 | |
36 | static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled) |
37 | { |
38 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
39 | unsigned long flags; |
40 | unsigned char val; |
41 | |
42 | /* Allow or mask alarm interrupts */ |
43 | spin_lock_irqsave(&priv->lock, flags); |
44 | val = ds1286_rtc_read(priv, RTC_CMD); |
45 | if (enabled) |
46 | val &= ~RTC_TDM; |
47 | else |
48 | val |= RTC_TDM; |
49 | ds1286_rtc_write(priv, data: val, RTC_CMD); |
50 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
51 | |
52 | return 0; |
53 | } |
54 | |
55 | #ifdef CONFIG_RTC_INTF_DEV |
56 | |
57 | static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
58 | { |
59 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
60 | unsigned long flags; |
61 | unsigned char val; |
62 | |
63 | switch (cmd) { |
64 | case RTC_WIE_OFF: |
65 | /* Mask watchdog int. enab. bit */ |
66 | spin_lock_irqsave(&priv->lock, flags); |
67 | val = ds1286_rtc_read(priv, RTC_CMD); |
68 | val |= RTC_WAM; |
69 | ds1286_rtc_write(priv, data: val, RTC_CMD); |
70 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
71 | break; |
72 | case RTC_WIE_ON: |
73 | /* Allow watchdog interrupts. */ |
74 | spin_lock_irqsave(&priv->lock, flags); |
75 | val = ds1286_rtc_read(priv, RTC_CMD); |
76 | val &= ~RTC_WAM; |
77 | ds1286_rtc_write(priv, data: val, RTC_CMD); |
78 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
79 | break; |
80 | default: |
81 | return -ENOIOCTLCMD; |
82 | } |
83 | return 0; |
84 | } |
85 | |
86 | #else |
87 | #define ds1286_ioctl NULL |
88 | #endif |
89 | |
90 | #ifdef CONFIG_PROC_FS |
91 | |
92 | static int ds1286_proc(struct device *dev, struct seq_file *seq) |
93 | { |
94 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
95 | unsigned char month, cmd, amode; |
96 | const char *s; |
97 | |
98 | month = ds1286_rtc_read(priv, RTC_MONTH); |
99 | seq_printf(m: seq, |
100 | fmt: "oscillator\t: %s\n" |
101 | "square_wave\t: %s\n" , |
102 | (month & RTC_EOSC) ? "disabled" : "enabled" , |
103 | (month & RTC_ESQW) ? "disabled" : "enabled" ); |
104 | |
105 | amode = ((ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x80) >> 5) | |
106 | ((ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x80) >> 6) | |
107 | ((ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x80) >> 7); |
108 | switch (amode) { |
109 | case 7: |
110 | s = "each minute" ; |
111 | break; |
112 | case 3: |
113 | s = "minutes match" ; |
114 | break; |
115 | case 1: |
116 | s = "hours and minutes match" ; |
117 | break; |
118 | case 0: |
119 | s = "days, hours and minutes match" ; |
120 | break; |
121 | default: |
122 | s = "invalid" ; |
123 | break; |
124 | } |
125 | seq_printf(m: seq, fmt: "alarm_mode\t: %s\n" , s); |
126 | |
127 | cmd = ds1286_rtc_read(priv, RTC_CMD); |
128 | seq_printf(m: seq, |
129 | fmt: "alarm_enable\t: %s\n" |
130 | "wdog_alarm\t: %s\n" |
131 | "alarm_mask\t: %s\n" |
132 | "wdog_alarm_mask\t: %s\n" |
133 | "interrupt_mode\t: %s\n" |
134 | "INTB_mode\t: %s_active\n" |
135 | "interrupt_pins\t: %s\n" , |
136 | (cmd & RTC_TDF) ? "yes" : "no" , |
137 | (cmd & RTC_WAF) ? "yes" : "no" , |
138 | (cmd & RTC_TDM) ? "disabled" : "enabled" , |
139 | (cmd & RTC_WAM) ? "disabled" : "enabled" , |
140 | (cmd & RTC_PU_LVL) ? "pulse" : "level" , |
141 | (cmd & RTC_IBH_LO) ? "low" : "high" , |
142 | (cmd & RTC_IPSW) ? "unswapped" : "swapped" ); |
143 | return 0; |
144 | } |
145 | |
146 | #else |
147 | #define ds1286_proc NULL |
148 | #endif |
149 | |
150 | static int ds1286_read_time(struct device *dev, struct rtc_time *tm) |
151 | { |
152 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
153 | unsigned char save_control; |
154 | unsigned long flags; |
155 | unsigned long uip_watchdog = jiffies; |
156 | |
157 | /* |
158 | * read RTC once any update in progress is done. The update |
159 | * can take just over 2ms. We wait 10 to 20ms. There is no need to |
160 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. |
161 | * If you need to know *exactly* when a second has started, enable |
162 | * periodic update complete interrupts, (via ioctl) and then |
163 | * immediately read /dev/rtc which will block until you get the IRQ. |
164 | * Once the read clears, read the RTC time (again via ioctl). Easy. |
165 | */ |
166 | |
167 | if (ds1286_rtc_read(priv, RTC_CMD) & RTC_TE) |
168 | while (time_before(jiffies, uip_watchdog + 2*HZ/100)) |
169 | barrier(); |
170 | |
171 | /* |
172 | * Only the values that we read from the RTC are set. We leave |
173 | * tm_wday, tm_yday and tm_isdst untouched. Even though the |
174 | * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated |
175 | * by the RTC when initially set to a non-zero value. |
176 | */ |
177 | spin_lock_irqsave(&priv->lock, flags); |
178 | save_control = ds1286_rtc_read(priv, RTC_CMD); |
179 | ds1286_rtc_write(priv, data: (save_control|RTC_TE), RTC_CMD); |
180 | |
181 | tm->tm_sec = ds1286_rtc_read(priv, RTC_SECONDS); |
182 | tm->tm_min = ds1286_rtc_read(priv, RTC_MINUTES); |
183 | tm->tm_hour = ds1286_rtc_read(priv, RTC_HOURS) & 0x3f; |
184 | tm->tm_mday = ds1286_rtc_read(priv, RTC_DATE); |
185 | tm->tm_mon = ds1286_rtc_read(priv, RTC_MONTH) & 0x1f; |
186 | tm->tm_year = ds1286_rtc_read(priv, RTC_YEAR); |
187 | |
188 | ds1286_rtc_write(priv, data: save_control, RTC_CMD); |
189 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
190 | |
191 | tm->tm_sec = bcd2bin(tm->tm_sec); |
192 | tm->tm_min = bcd2bin(tm->tm_min); |
193 | tm->tm_hour = bcd2bin(tm->tm_hour); |
194 | tm->tm_mday = bcd2bin(tm->tm_mday); |
195 | tm->tm_mon = bcd2bin(tm->tm_mon); |
196 | tm->tm_year = bcd2bin(tm->tm_year); |
197 | |
198 | /* |
199 | * Account for differences between how the RTC uses the values |
200 | * and how they are defined in a struct rtc_time; |
201 | */ |
202 | if (tm->tm_year < 45) |
203 | tm->tm_year += 30; |
204 | tm->tm_year += 40; |
205 | if (tm->tm_year < 70) |
206 | tm->tm_year += 100; |
207 | |
208 | tm->tm_mon--; |
209 | |
210 | return 0; |
211 | } |
212 | |
213 | static int ds1286_set_time(struct device *dev, struct rtc_time *tm) |
214 | { |
215 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
216 | unsigned char mon, day, hrs, min, sec; |
217 | unsigned char save_control; |
218 | unsigned int yrs; |
219 | unsigned long flags; |
220 | |
221 | yrs = tm->tm_year + 1900; |
222 | mon = tm->tm_mon + 1; /* tm_mon starts at zero */ |
223 | day = tm->tm_mday; |
224 | hrs = tm->tm_hour; |
225 | min = tm->tm_min; |
226 | sec = tm->tm_sec; |
227 | |
228 | if (yrs < 1970) |
229 | return -EINVAL; |
230 | |
231 | yrs -= 1940; |
232 | if (yrs > 255) /* They are unsigned */ |
233 | return -EINVAL; |
234 | |
235 | if (yrs >= 100) |
236 | yrs -= 100; |
237 | |
238 | sec = bin2bcd(sec); |
239 | min = bin2bcd(min); |
240 | hrs = bin2bcd(hrs); |
241 | day = bin2bcd(day); |
242 | mon = bin2bcd(mon); |
243 | yrs = bin2bcd(yrs); |
244 | |
245 | spin_lock_irqsave(&priv->lock, flags); |
246 | save_control = ds1286_rtc_read(priv, RTC_CMD); |
247 | ds1286_rtc_write(priv, data: (save_control|RTC_TE), RTC_CMD); |
248 | |
249 | ds1286_rtc_write(priv, data: yrs, RTC_YEAR); |
250 | ds1286_rtc_write(priv, data: mon, RTC_MONTH); |
251 | ds1286_rtc_write(priv, data: day, RTC_DATE); |
252 | ds1286_rtc_write(priv, data: hrs, RTC_HOURS); |
253 | ds1286_rtc_write(priv, data: min, RTC_MINUTES); |
254 | ds1286_rtc_write(priv, data: sec, RTC_SECONDS); |
255 | ds1286_rtc_write(priv, data: 0, RTC_HUNDREDTH_SECOND); |
256 | |
257 | ds1286_rtc_write(priv, data: save_control, RTC_CMD); |
258 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
259 | return 0; |
260 | } |
261 | |
262 | static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm) |
263 | { |
264 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
265 | unsigned long flags; |
266 | |
267 | /* |
268 | * Only the values that we read from the RTC are set. That |
269 | * means only tm_wday, tm_hour, tm_min. |
270 | */ |
271 | spin_lock_irqsave(&priv->lock, flags); |
272 | alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f; |
273 | alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x1f; |
274 | alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x07; |
275 | ds1286_rtc_read(priv, RTC_CMD); |
276 | spin_unlock_irqrestore(lock: &priv->lock, flags); |
277 | |
278 | alm->time.tm_min = bcd2bin(alm->time.tm_min); |
279 | alm->time.tm_hour = bcd2bin(alm->time.tm_hour); |
280 | alm->time.tm_sec = 0; |
281 | return 0; |
282 | } |
283 | |
284 | static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) |
285 | { |
286 | struct ds1286_priv *priv = dev_get_drvdata(dev); |
287 | unsigned char hrs, min, sec; |
288 | |
289 | hrs = alm->time.tm_hour; |
290 | min = alm->time.tm_min; |
291 | sec = alm->time.tm_sec; |
292 | |
293 | if (hrs >= 24) |
294 | hrs = 0xff; |
295 | |
296 | if (min >= 60) |
297 | min = 0xff; |
298 | |
299 | if (sec != 0) |
300 | return -EINVAL; |
301 | |
302 | min = bin2bcd(min); |
303 | hrs = bin2bcd(hrs); |
304 | |
305 | spin_lock(lock: &priv->lock); |
306 | ds1286_rtc_write(priv, data: hrs, RTC_HOURS_ALARM); |
307 | ds1286_rtc_write(priv, data: min, RTC_MINUTES_ALARM); |
308 | spin_unlock(lock: &priv->lock); |
309 | |
310 | return 0; |
311 | } |
312 | |
313 | static const struct rtc_class_ops ds1286_ops = { |
314 | .ioctl = ds1286_ioctl, |
315 | .proc = ds1286_proc, |
316 | .read_time = ds1286_read_time, |
317 | .set_time = ds1286_set_time, |
318 | .read_alarm = ds1286_read_alarm, |
319 | .set_alarm = ds1286_set_alarm, |
320 | .alarm_irq_enable = ds1286_alarm_irq_enable, |
321 | }; |
322 | |
323 | static int ds1286_probe(struct platform_device *pdev) |
324 | { |
325 | struct rtc_device *rtc; |
326 | struct ds1286_priv *priv; |
327 | |
328 | priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct ds1286_priv), GFP_KERNEL); |
329 | if (!priv) |
330 | return -ENOMEM; |
331 | |
332 | priv->rtcregs = devm_platform_ioremap_resource(pdev, index: 0); |
333 | if (IS_ERR(ptr: priv->rtcregs)) |
334 | return PTR_ERR(ptr: priv->rtcregs); |
335 | |
336 | spin_lock_init(&priv->lock); |
337 | platform_set_drvdata(pdev, data: priv); |
338 | rtc = devm_rtc_device_register(dev: &pdev->dev, name: "ds1286" , ops: &ds1286_ops, |
339 | THIS_MODULE); |
340 | if (IS_ERR(ptr: rtc)) |
341 | return PTR_ERR(ptr: rtc); |
342 | priv->rtc = rtc; |
343 | return 0; |
344 | } |
345 | |
346 | static struct platform_driver ds1286_platform_driver = { |
347 | .driver = { |
348 | .name = "rtc-ds1286" , |
349 | }, |
350 | .probe = ds1286_probe, |
351 | }; |
352 | |
353 | module_platform_driver(ds1286_platform_driver); |
354 | |
355 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>" ); |
356 | MODULE_DESCRIPTION("DS1286 RTC driver" ); |
357 | MODULE_LICENSE("GPL" ); |
358 | MODULE_ALIAS("platform:rtc-ds1286" ); |
359 | |