Lines Matching full:rtc
2 * SuperH On-Chip RTC Support
8 * Based on the old arch/sh/kernel/cpu/rtc.c by:
21 #include <linux/rtc.h>
32 #include <asm/rtc.h>
34 /* Default values for RZ/A RTC */
41 #define DRV_NAME "sh-rtc"
47 #define RSECCNT RTC_REG(1) /* RTC sec */
48 #define RMINCNT RTC_REG(2) /* RTC min */
49 #define RHRCNT RTC_REG(3) /* RTC hour */
50 #define RWKCNT RTC_REG(4) /* RTC week */
51 #define RDAYCNT RTC_REG(5) /* RTC day */
52 #define RMONCNT RTC_REG(6) /* RTC month */
53 #define RYRCNT RTC_REG(7) /* RTC year */
94 #define RCR2_RTCEN 0x08 /* ENable RTC */
109 unsigned long capabilities; /* See asm/rtc.h for cap bits */
113 static int __sh_rtc_interrupt(struct sh_rtc *rtc) in __sh_rtc_interrupt() argument
117 tmp = readb(rtc->regbase + RCR1); in __sh_rtc_interrupt()
120 writeb(tmp, rtc->regbase + RCR1); in __sh_rtc_interrupt()
123 if (pending && rtc->periodic_freq & PF_OXS) in __sh_rtc_interrupt()
124 rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); in __sh_rtc_interrupt()
129 static int __sh_rtc_alarm(struct sh_rtc *rtc) in __sh_rtc_alarm() argument
133 tmp = readb(rtc->regbase + RCR1); in __sh_rtc_alarm()
136 writeb(tmp, rtc->regbase + RCR1); in __sh_rtc_alarm()
139 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); in __sh_rtc_alarm()
144 static int __sh_rtc_periodic(struct sh_rtc *rtc) in __sh_rtc_periodic() argument
148 tmp = readb(rtc->regbase + RCR2); in __sh_rtc_periodic()
151 writeb(tmp, rtc->regbase + RCR2); in __sh_rtc_periodic()
157 if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) in __sh_rtc_periodic()
158 rtc->periodic_freq &= ~PF_COUNT; in __sh_rtc_periodic()
160 if (rtc->periodic_freq & PF_HP) in __sh_rtc_periodic()
161 rtc->periodic_freq |= PF_COUNT; in __sh_rtc_periodic()
162 rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); in __sh_rtc_periodic()
170 struct sh_rtc *rtc = dev_id; in sh_rtc_interrupt() local
173 spin_lock(&rtc->lock); in sh_rtc_interrupt()
174 ret = __sh_rtc_interrupt(rtc); in sh_rtc_interrupt()
175 spin_unlock(&rtc->lock); in sh_rtc_interrupt()
182 struct sh_rtc *rtc = dev_id; in sh_rtc_alarm() local
185 spin_lock(&rtc->lock); in sh_rtc_alarm()
186 ret = __sh_rtc_alarm(rtc); in sh_rtc_alarm()
187 spin_unlock(&rtc->lock); in sh_rtc_alarm()
194 struct sh_rtc *rtc = dev_id; in sh_rtc_periodic() local
197 spin_lock(&rtc->lock); in sh_rtc_periodic()
198 ret = __sh_rtc_periodic(rtc); in sh_rtc_periodic()
199 spin_unlock(&rtc->lock); in sh_rtc_periodic()
206 struct sh_rtc *rtc = dev_id; in sh_rtc_shared() local
209 spin_lock(&rtc->lock); in sh_rtc_shared()
210 ret = __sh_rtc_interrupt(rtc); in sh_rtc_shared()
211 ret |= __sh_rtc_alarm(rtc); in sh_rtc_shared()
212 ret |= __sh_rtc_periodic(rtc); in sh_rtc_shared()
213 spin_unlock(&rtc->lock); in sh_rtc_shared()
220 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_setaie() local
223 spin_lock_irq(&rtc->lock); in sh_rtc_setaie()
225 tmp = readb(rtc->regbase + RCR1); in sh_rtc_setaie()
232 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_setaie()
234 spin_unlock_irq(&rtc->lock); in sh_rtc_setaie()
239 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_proc() local
242 tmp = readb(rtc->regbase + RCR1); in sh_rtc_proc()
245 tmp = readb(rtc->regbase + RCR2); in sh_rtc_proc()
254 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_setcie() local
257 spin_lock_irq(&rtc->lock); in sh_rtc_setcie()
259 tmp = readb(rtc->regbase + RCR1); in sh_rtc_setcie()
266 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_setcie()
268 spin_unlock_irq(&rtc->lock); in sh_rtc_setcie()
279 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_read_time() local
285 spin_lock_irq(&rtc->lock); in sh_rtc_read_time()
287 tmp = readb(rtc->regbase + RCR1); in sh_rtc_read_time()
290 writeb(tmp, rtc->regbase + RCR1); in sh_rtc_read_time()
292 sec128 = readb(rtc->regbase + R64CNT); in sh_rtc_read_time()
294 tm->tm_sec = bcd2bin(readb(rtc->regbase + RSECCNT)); in sh_rtc_read_time()
295 tm->tm_min = bcd2bin(readb(rtc->regbase + RMINCNT)); in sh_rtc_read_time()
296 tm->tm_hour = bcd2bin(readb(rtc->regbase + RHRCNT)); in sh_rtc_read_time()
297 tm->tm_wday = bcd2bin(readb(rtc->regbase + RWKCNT)); in sh_rtc_read_time()
298 tm->tm_mday = bcd2bin(readb(rtc->regbase + RDAYCNT)); in sh_rtc_read_time()
299 tm->tm_mon = bcd2bin(readb(rtc->regbase + RMONCNT)) - 1; in sh_rtc_read_time()
301 if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { in sh_rtc_read_time()
302 yr = readw(rtc->regbase + RYRCNT); in sh_rtc_read_time()
306 yr = readb(rtc->regbase + RYRCNT); in sh_rtc_read_time()
312 sec2 = readb(rtc->regbase + R64CNT); in sh_rtc_read_time()
313 cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF; in sh_rtc_read_time()
315 spin_unlock_irq(&rtc->lock); in sh_rtc_read_time()
324 if (!(rtc->periodic_freq & PF_OXS)) in sh_rtc_read_time()
338 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_set_time() local
342 spin_lock_irq(&rtc->lock); in sh_rtc_set_time()
344 /* Reset pre-scaler & stop RTC */ in sh_rtc_set_time()
345 tmp = readb(rtc->regbase + RCR2); in sh_rtc_set_time()
348 writeb(tmp, rtc->regbase + RCR2); in sh_rtc_set_time()
350 writeb(bin2bcd(tm->tm_sec), rtc->regbase + RSECCNT); in sh_rtc_set_time()
351 writeb(bin2bcd(tm->tm_min), rtc->regbase + RMINCNT); in sh_rtc_set_time()
352 writeb(bin2bcd(tm->tm_hour), rtc->regbase + RHRCNT); in sh_rtc_set_time()
353 writeb(bin2bcd(tm->tm_wday), rtc->regbase + RWKCNT); in sh_rtc_set_time()
354 writeb(bin2bcd(tm->tm_mday), rtc->regbase + RDAYCNT); in sh_rtc_set_time()
355 writeb(bin2bcd(tm->tm_mon + 1), rtc->regbase + RMONCNT); in sh_rtc_set_time()
357 if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { in sh_rtc_set_time()
360 writew(year, rtc->regbase + RYRCNT); in sh_rtc_set_time()
363 writeb(bin2bcd(year), rtc->regbase + RYRCNT); in sh_rtc_set_time()
366 /* Start RTC */ in sh_rtc_set_time()
367 tmp = readb(rtc->regbase + RCR2); in sh_rtc_set_time()
370 writeb(tmp, rtc->regbase + RCR2); in sh_rtc_set_time()
372 spin_unlock_irq(&rtc->lock); in sh_rtc_set_time()
377 static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off) in sh_rtc_read_alarm_value() argument
382 byte = readb(rtc->regbase + reg_off); in sh_rtc_read_alarm_value()
393 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_read_alarm() local
396 spin_lock_irq(&rtc->lock); in sh_rtc_read_alarm()
398 tm->tm_sec = sh_rtc_read_alarm_value(rtc, RSECAR); in sh_rtc_read_alarm()
399 tm->tm_min = sh_rtc_read_alarm_value(rtc, RMINAR); in sh_rtc_read_alarm()
400 tm->tm_hour = sh_rtc_read_alarm_value(rtc, RHRAR); in sh_rtc_read_alarm()
401 tm->tm_wday = sh_rtc_read_alarm_value(rtc, RWKAR); in sh_rtc_read_alarm()
402 tm->tm_mday = sh_rtc_read_alarm_value(rtc, RDAYAR); in sh_rtc_read_alarm()
403 tm->tm_mon = sh_rtc_read_alarm_value(rtc, RMONAR); in sh_rtc_read_alarm()
405 tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ in sh_rtc_read_alarm()
407 wkalrm->enabled = (readb(rtc->regbase + RCR1) & RCR1_AIE) ? 1 : 0; in sh_rtc_read_alarm()
409 spin_unlock_irq(&rtc->lock); in sh_rtc_read_alarm()
414 static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, in sh_rtc_write_alarm_value() argument
419 writeb(0, rtc->regbase + reg_off); in sh_rtc_write_alarm_value()
421 writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); in sh_rtc_write_alarm_value()
426 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_set_alarm() local
431 spin_lock_irq(&rtc->lock); in sh_rtc_set_alarm()
434 rcr1 = readb(rtc->regbase + RCR1); in sh_rtc_set_alarm()
436 writeb(rcr1, rtc->regbase + RCR1); in sh_rtc_set_alarm()
439 sh_rtc_write_alarm_value(rtc, tm->tm_sec, RSECAR); in sh_rtc_set_alarm()
440 sh_rtc_write_alarm_value(rtc, tm->tm_min, RMINAR); in sh_rtc_set_alarm()
441 sh_rtc_write_alarm_value(rtc, tm->tm_hour, RHRAR); in sh_rtc_set_alarm()
442 sh_rtc_write_alarm_value(rtc, tm->tm_wday, RWKAR); in sh_rtc_set_alarm()
443 sh_rtc_write_alarm_value(rtc, tm->tm_mday, RDAYAR); in sh_rtc_set_alarm()
447 sh_rtc_write_alarm_value(rtc, mon, RMONAR); in sh_rtc_set_alarm()
451 writeb(rcr1, rtc->regbase + RCR1); in sh_rtc_set_alarm()
454 spin_unlock_irq(&rtc->lock); in sh_rtc_set_alarm()
470 struct sh_rtc *rtc; in sh_rtc_probe() local
476 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in sh_rtc_probe()
477 if (unlikely(!rtc)) in sh_rtc_probe()
480 spin_lock_init(&rtc->lock); in sh_rtc_probe()
489 rtc->periodic_irq = ret; in sh_rtc_probe()
490 rtc->carry_irq = platform_get_irq(pdev, 1); in sh_rtc_probe()
491 rtc->alarm_irq = platform_get_irq(pdev, 2); in sh_rtc_probe()
501 rtc->regsize = resource_size(res); in sh_rtc_probe()
503 rtc->res = devm_request_mem_region(&pdev->dev, res->start, in sh_rtc_probe()
504 rtc->regsize, pdev->name); in sh_rtc_probe()
505 if (unlikely(!rtc->res)) in sh_rtc_probe()
508 rtc->regbase = devm_ioremap_nocache(&pdev->dev, rtc->res->start, in sh_rtc_probe()
509 rtc->regsize); in sh_rtc_probe()
510 if (unlikely(!rtc->regbase)) in sh_rtc_probe()
519 snprintf(clk_name, sizeof(clk_name), "rtc%d", clk_id); in sh_rtc_probe()
523 rtc->clk = devm_clk_get(&pdev->dev, clk_name); in sh_rtc_probe()
524 if (IS_ERR(rtc->clk)) { in sh_rtc_probe()
526 * No error handling for rtc->clk intentionally, not all in sh_rtc_probe()
527 * platforms will have a unique clock for the RTC, and in sh_rtc_probe()
531 rtc->clk = NULL; in sh_rtc_probe()
534 clk_enable(rtc->clk); in sh_rtc_probe()
536 rtc->capabilities = RTC_DEF_CAPABILITIES; in sh_rtc_probe()
547 rtc->capabilities |= pinfo->capabilities; in sh_rtc_probe()
551 if (rtc->carry_irq <= 0) { in sh_rtc_probe()
553 ret = devm_request_irq(&pdev->dev, rtc->periodic_irq, in sh_rtc_probe()
554 sh_rtc_shared, 0, "sh-rtc", rtc); in sh_rtc_probe()
558 rtc->periodic_irq); in sh_rtc_probe()
563 ret = devm_request_irq(&pdev->dev, rtc->periodic_irq, in sh_rtc_probe()
564 sh_rtc_periodic, 0, "sh-rtc period", rtc); in sh_rtc_probe()
568 ret, rtc->periodic_irq); in sh_rtc_probe()
572 ret = devm_request_irq(&pdev->dev, rtc->carry_irq, in sh_rtc_probe()
573 sh_rtc_interrupt, 0, "sh-rtc carry", rtc); in sh_rtc_probe()
577 ret, rtc->carry_irq); in sh_rtc_probe()
581 ret = devm_request_irq(&pdev->dev, rtc->alarm_irq, in sh_rtc_probe()
582 sh_rtc_alarm, 0, "sh-rtc alarm", rtc); in sh_rtc_probe()
586 ret, rtc->alarm_irq); in sh_rtc_probe()
591 platform_set_drvdata(pdev, rtc); in sh_rtc_probe()
597 rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "sh", in sh_rtc_probe()
599 if (IS_ERR(rtc->rtc_dev)) { in sh_rtc_probe()
600 ret = PTR_ERR(rtc->rtc_dev); in sh_rtc_probe()
604 rtc->rtc_dev->max_user_freq = 256; in sh_rtc_probe()
606 /* reset rtc to epoch 0 if time is invalid */ in sh_rtc_probe()
607 if (rtc_read_time(rtc->rtc_dev, &r) < 0) { in sh_rtc_probe()
609 rtc_set_time(rtc->rtc_dev, &r); in sh_rtc_probe()
616 clk_disable(rtc->clk); in sh_rtc_probe()
623 struct sh_rtc *rtc = platform_get_drvdata(pdev); in sh_rtc_remove() local
628 clk_disable(rtc->clk); in sh_rtc_remove()
635 struct sh_rtc *rtc = dev_get_drvdata(dev); in sh_rtc_set_irq_wake() local
637 irq_set_irq_wake(rtc->periodic_irq, enabled); in sh_rtc_set_irq_wake()
639 if (rtc->carry_irq > 0) { in sh_rtc_set_irq_wake()
640 irq_set_irq_wake(rtc->carry_irq, enabled); in sh_rtc_set_irq_wake()
641 irq_set_irq_wake(rtc->alarm_irq, enabled); in sh_rtc_set_irq_wake()
664 { .compatible = "renesas,sh-rtc", },
680 MODULE_DESCRIPTION("SuperH on-chip RTC driver");