Lines Matching full:rtc
3 * SuperH On-Chip RTC Support
10 * Based on the old arch/sh/kernel/cpu/rtc.c by:
19 #include <linux/rtc.h>
30 #include <asm/rtc.h>
32 /* Default values for RZ/A RTC */
39 #define DRV_NAME "sh-rtc"
45 #define RSECCNT RTC_REG(1) /* RTC sec */
46 #define RMINCNT RTC_REG(2) /* RTC min */
47 #define RHRCNT RTC_REG(3) /* RTC hour */
48 #define RWKCNT RTC_REG(4) /* RTC week */
49 #define RDAYCNT RTC_REG(5) /* RTC day */
50 #define RMONCNT RTC_REG(6) /* RTC month */
51 #define RYRCNT RTC_REG(7) /* RTC year */
83 #define RCR2_RTCEN BIT(3) /* ENable RTC */
94 unsigned long capabilities; /* See asm/rtc.h for cap bits */
99 struct sh_rtc *rtc = dev_id; in sh_rtc_alarm() local
102 spin_lock(&rtc->lock); in sh_rtc_alarm()
104 tmp = readb(rtc->regbase + RCR1); in sh_rtc_alarm()
107 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_alarm()
110 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); in sh_rtc_alarm()
112 spin_unlock(&rtc->lock); in sh_rtc_alarm()
119 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_alarm_irq_enable() local
122 spin_lock_irq(&rtc->lock); in sh_rtc_alarm_irq_enable()
124 tmp = readb(rtc->regbase + RCR1); in sh_rtc_alarm_irq_enable()
131 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_alarm_irq_enable()
133 spin_unlock_irq(&rtc->lock); in sh_rtc_alarm_irq_enable()
140 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_read_time() local
143 if (!(readb(rtc->regbase + RCR2) & RCR2_RTCEN)) in sh_rtc_read_time()
149 spin_lock_irq(&rtc->lock); in sh_rtc_read_time()
151 tmp = readb(rtc->regbase + RCR1); in sh_rtc_read_time()
154 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_read_time()
156 sec128 = readb(rtc->regbase + R64CNT); in sh_rtc_read_time()
158 tm->tm_sec = bcd2bin(readb(rtc->regbase + RSECCNT)); in sh_rtc_read_time()
159 tm->tm_min = bcd2bin(readb(rtc->regbase + RMINCNT)); in sh_rtc_read_time()
160 tm->tm_hour = bcd2bin(readb(rtc->regbase + RHRCNT)); in sh_rtc_read_time()
161 tm->tm_wday = bcd2bin(readb(rtc->regbase + RWKCNT)); in sh_rtc_read_time()
162 tm->tm_mday = bcd2bin(readb(rtc->regbase + RDAYCNT)); in sh_rtc_read_time()
163 tm->tm_mon = bcd2bin(readb(rtc->regbase + RMONCNT)) - 1; in sh_rtc_read_time()
165 if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { in sh_rtc_read_time()
166 yr = readw(rtc->regbase + RYRCNT); in sh_rtc_read_time()
170 yr = readb(rtc->regbase + RYRCNT); in sh_rtc_read_time()
176 sec2 = readb(rtc->regbase + R64CNT); in sh_rtc_read_time()
177 cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF; in sh_rtc_read_time()
179 spin_unlock_irq(&rtc->lock); in sh_rtc_read_time()
196 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_set_time() local
200 spin_lock_irq(&rtc->lock); in sh_rtc_set_time()
202 /* Reset pre-scaler & stop RTC */ in sh_rtc_set_time()
203 tmp = readb(rtc->regbase + RCR2); in sh_rtc_set_time()
206 writeb(tmp, rtc->regbase + RCR2); in sh_rtc_set_time()
208 writeb(bin2bcd(tm->tm_sec), rtc->regbase + RSECCNT); in sh_rtc_set_time()
209 writeb(bin2bcd(tm->tm_min), rtc->regbase + RMINCNT); in sh_rtc_set_time()
210 writeb(bin2bcd(tm->tm_hour), rtc->regbase + RHRCNT); in sh_rtc_set_time()
211 writeb(bin2bcd(tm->tm_wday), rtc->regbase + RWKCNT); in sh_rtc_set_time()
212 writeb(bin2bcd(tm->tm_mday), rtc->regbase + RDAYCNT); in sh_rtc_set_time()
213 writeb(bin2bcd(tm->tm_mon + 1), rtc->regbase + RMONCNT); in sh_rtc_set_time()
215 if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { in sh_rtc_set_time()
218 writew(year, rtc->regbase + RYRCNT); in sh_rtc_set_time()
221 writeb(bin2bcd(year), rtc->regbase + RYRCNT); in sh_rtc_set_time()
224 /* Start RTC */ in sh_rtc_set_time()
225 tmp = readb(rtc->regbase + RCR2); in sh_rtc_set_time()
228 writeb(tmp, rtc->regbase + RCR2); in sh_rtc_set_time()
230 spin_unlock_irq(&rtc->lock); in sh_rtc_set_time()
235 static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off) in sh_rtc_read_alarm_value() argument
240 byte = readb(rtc->regbase + reg_off); in sh_rtc_read_alarm_value()
251 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_read_alarm() local
254 spin_lock_irq(&rtc->lock); in sh_rtc_read_alarm()
256 tm->tm_sec = sh_rtc_read_alarm_value(rtc, RSECAR); in sh_rtc_read_alarm()
257 tm->tm_min = sh_rtc_read_alarm_value(rtc, RMINAR); in sh_rtc_read_alarm()
258 tm->tm_hour = sh_rtc_read_alarm_value(rtc, RHRAR); in sh_rtc_read_alarm()
259 tm->tm_wday = sh_rtc_read_alarm_value(rtc, RWKAR); in sh_rtc_read_alarm()
260 tm->tm_mday = sh_rtc_read_alarm_value(rtc, RDAYAR); in sh_rtc_read_alarm()
261 tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR); in sh_rtc_read_alarm()
263 tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ in sh_rtc_read_alarm()
265 wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0; in sh_rtc_read_alarm()
267 spin_unlock_irq(&rtc->lock); in sh_rtc_read_alarm()
272 static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, in sh_rtc_write_alarm_value() argument
277 writeb(0, rtc->regbase + reg_off); in sh_rtc_write_alarm_value()
279 writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); in sh_rtc_write_alarm_value()
284 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_set_alarm() local
289 spin_lock_irq(&rtc->lock); in sh_rtc_set_alarm()
292 rcr1 = readb(rtc->regbase + RCR1); in sh_rtc_set_alarm()
294 writeb(rcr1, rtc->regbase + RCR1); in sh_rtc_set_alarm()
297 sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); in sh_rtc_set_alarm()
298 sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); in sh_rtc_set_alarm()
299 sh_rtc_write_alarm_value(rtc, tm->tm_hour, RHRAR); in sh_rtc_set_alarm()
300 sh_rtc_write_alarm_value(rtc, tm->tm_wday, RWKAR); in sh_rtc_set_alarm()
301 sh_rtc_write_alarm_value(rtc, tm->tm_mday, RDAYAR); in sh_rtc_set_alarm()
305 sh_rtc_write_alarm_value(rtc, mon, RMONAR); in sh_rtc_set_alarm()
309 writeb(rcr1, rtc->regbase + RCR1); in sh_rtc_set_alarm()
312 spin_unlock_irq(&rtc->lock); in sh_rtc_set_alarm()
327 struct sh_rtc *rtc; in sh_rtc_probe() local
334 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in sh_rtc_probe()
335 if (unlikely(!rtc)) in sh_rtc_probe()
338 spin_lock_init(&rtc->lock); in sh_rtc_probe()
347 rtc->alarm_irq = platform_get_irq(pdev, 2); in sh_rtc_probe()
349 rtc->alarm_irq = ret; in sh_rtc_probe()
364 rtc->regbase = devm_ioremap(&pdev->dev, req_res->start, regsize); in sh_rtc_probe()
365 if (!rtc->regbase) in sh_rtc_probe()
374 snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id); in sh_rtc_probe()
379 rtc->clk = devm_clk_get(&pdev->dev, clk_name); in sh_rtc_probe()
380 if (IS_ERR(rtc->clk)) { in sh_rtc_probe()
382 * No error handling for rtc->clk intentionally, not all in sh_rtc_probe()
383 * platforms will have a unique clock for the RTC, and in sh_rtc_probe()
387 rtc->clk = NULL; in sh_rtc_probe()
390 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); in sh_rtc_probe()
391 if (IS_ERR(rtc->rtc_dev)) in sh_rtc_probe()
392 return PTR_ERR(rtc->rtc_dev); in sh_rtc_probe()
394 clk_enable(rtc->clk); in sh_rtc_probe()
396 rtc->capabilities = RTC_DEF_CAPABILITIES; in sh_rtc_probe()
407 rtc->capabilities |= pinfo->capabilities; in sh_rtc_probe()
411 ret = devm_request_irq(&pdev->dev, rtc->alarm_irq, sh_rtc_alarm, 0, "sh-rtc", rtc); in sh_rtc_probe()
414 ret, rtc->alarm_irq); in sh_rtc_probe()
418 platform_set_drvdata(pdev, rtc); in sh_rtc_probe()
421 tmp = readb(rtc->regbase + RCR1); in sh_rtc_probe()
423 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_probe()
425 rtc->rtc_dev->ops = &sh_rtc_ops; in sh_rtc_probe()
427 if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { in sh_rtc_probe()
428 rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900; in sh_rtc_probe()
429 rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_9999; in sh_rtc_probe()
431 rtc->rtc_dev->range_min = mktime64(1999, 1, 1, 0, 0, 0); in sh_rtc_probe()
432 rtc->rtc_dev->range_max = mktime64(2098, 12, 31, 23, 59, 59); in sh_rtc_probe()
435 ret = devm_rtc_register_device(rtc->rtc_dev); in sh_rtc_probe()
443 clk_disable(rtc->clk); in sh_rtc_probe()
450 struct sh_rtc *rtc = platform_get_drvdata(pdev); in sh_rtc_remove() local
454 clk_disable(rtc->clk); in sh_rtc_remove()
459 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_suspend() local
462 irq_set_irq_wake(rtc->alarm_irq, 1); in sh_rtc_suspend()
469 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_resume() local
472 irq_set_irq_wake(rtc->alarm_irq, 0); in sh_rtc_resume()
480 { .compatible = "renesas,sh-rtc", },
502 MODULE_DESCRIPTION("SuperH on-chip RTC driver");