• Home
  • Raw
  • Download

Lines Matching +full:rzn1 +full:- +full:rtc

1 // SPDX-License-Identifier: GPL-2.0+
6 * - 2014 Renesas Electronics Europe Limited
7 * - 2022 Schneider Electric
10 * - Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com>
11 * - Miquel Raynal <miquel.raynal@bootlin.com>
21 #include <linux/rtc.h>
67 static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm) in rzn1_rtc_get_time_snapshot() argument
69 tm->tm_sec = readl(rtc->base + RZN1_RTC_SECC); in rzn1_rtc_get_time_snapshot()
70 tm->tm_min = readl(rtc->base + RZN1_RTC_MINC); in rzn1_rtc_get_time_snapshot()
71 tm->tm_hour = readl(rtc->base + RZN1_RTC_HOURC); in rzn1_rtc_get_time_snapshot()
72 tm->tm_wday = readl(rtc->base + RZN1_RTC_WEEKC); in rzn1_rtc_get_time_snapshot()
73 tm->tm_mday = readl(rtc->base + RZN1_RTC_DAYC); in rzn1_rtc_get_time_snapshot()
74 tm->tm_mon = readl(rtc->base + RZN1_RTC_MONTHC); in rzn1_rtc_get_time_snapshot()
75 tm->tm_year = readl(rtc->base + RZN1_RTC_YEARC); in rzn1_rtc_get_time_snapshot()
87 /* day of the week, 1970-01-01 was a Thursday */ in rzn1_rtc_tm_to_wday()
93 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_read_time() local
97 * The RTC was not started or is stopped and thus does not carry the in rzn1_rtc_read_time()
100 val = readl(rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_read_time()
102 return -EINVAL; in rzn1_rtc_read_time()
104 rzn1_rtc_get_time_snapshot(rtc, tm); in rzn1_rtc_read_time()
105 secs = readl(rtc->base + RZN1_RTC_SECC); in rzn1_rtc_read_time()
106 if (tm->tm_sec != secs) in rzn1_rtc_read_time()
107 rzn1_rtc_get_time_snapshot(rtc, tm); in rzn1_rtc_read_time()
109 tm->tm_sec = bcd2bin(tm->tm_sec); in rzn1_rtc_read_time()
110 tm->tm_min = bcd2bin(tm->tm_min); in rzn1_rtc_read_time()
111 tm->tm_hour = bcd2bin(tm->tm_hour); in rzn1_rtc_read_time()
112 tm->tm_wday = bcd2bin(tm->tm_wday); in rzn1_rtc_read_time()
113 tm->tm_mday = bcd2bin(tm->tm_mday); in rzn1_rtc_read_time()
114 tm->tm_mon = bcd2bin(tm->tm_mon) - 1; in rzn1_rtc_read_time()
115 tm->tm_year = bcd2bin(tm->tm_year) + 100; in rzn1_rtc_read_time()
122 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_set_time() local
126 tm->tm_sec = bin2bcd(tm->tm_sec); in rzn1_rtc_set_time()
127 tm->tm_min = bin2bcd(tm->tm_min); in rzn1_rtc_set_time()
128 tm->tm_hour = bin2bcd(tm->tm_hour); in rzn1_rtc_set_time()
129 tm->tm_wday = bin2bcd(rzn1_rtc_tm_to_wday(tm)); in rzn1_rtc_set_time()
130 tm->tm_mday = bin2bcd(tm->tm_mday); in rzn1_rtc_set_time()
131 tm->tm_mon = bin2bcd(tm->tm_mon + 1); in rzn1_rtc_set_time()
132 tm->tm_year = bin2bcd(tm->tm_year - 100); in rzn1_rtc_set_time()
134 val = readl(rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_set_time()
137 writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_set_time()
141 ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val, in rzn1_rtc_set_time()
147 writel(tm->tm_sec, rtc->base + RZN1_RTC_SEC); in rzn1_rtc_set_time()
148 writel(tm->tm_min, rtc->base + RZN1_RTC_MIN); in rzn1_rtc_set_time()
149 writel(tm->tm_hour, rtc->base + RZN1_RTC_HOUR); in rzn1_rtc_set_time()
150 writel(tm->tm_wday, rtc->base + RZN1_RTC_WEEK); in rzn1_rtc_set_time()
151 writel(tm->tm_mday, rtc->base + RZN1_RTC_DAY); in rzn1_rtc_set_time()
152 writel(tm->tm_mon, rtc->base + RZN1_RTC_MONTH); in rzn1_rtc_set_time()
153 writel(tm->tm_year, rtc->base + RZN1_RTC_YEAR); in rzn1_rtc_set_time()
154 writel(0, rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_set_time()
161 struct rzn1_rtc *rtc = dev_id; in rzn1_rtc_alarm_irq() local
163 rtc_update_irq(rtc->rtcdev, 1, RTC_AF | RTC_IRQF); in rzn1_rtc_alarm_irq()
170 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_alarm_irq_enable() local
171 u32 ctl1 = readl(rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_alarm_irq_enable()
178 writel(ctl1, rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_alarm_irq_enable()
185 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_read_alarm() local
186 struct rtc_time *tm = &alrm->time; in rzn1_rtc_read_alarm()
196 min = readl(rtc->base + RZN1_RTC_ALM); in rzn1_rtc_read_alarm()
197 hour = readl(rtc->base + RZN1_RTC_ALH); in rzn1_rtc_read_alarm()
198 wday = readl(rtc->base + RZN1_RTC_ALW); in rzn1_rtc_read_alarm()
200 tm->tm_sec = 0; in rzn1_rtc_read_alarm()
201 tm->tm_min = bcd2bin(min); in rzn1_rtc_read_alarm()
202 tm->tm_hour = bcd2bin(hour); in rzn1_rtc_read_alarm()
203 delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7; in rzn1_rtc_read_alarm()
204 tm->tm_wday = fls(wday) - 1; in rzn1_rtc_read_alarm()
211 ctl1 = readl(rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_read_alarm()
212 alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME); in rzn1_rtc_read_alarm()
219 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_set_alarm() local
220 struct rtc_time *tm = &alrm->time, tm_now; in rzn1_rtc_set_alarm()
230 farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max; in rzn1_rtc_set_alarm()
233 return -ERANGE; in rzn1_rtc_set_alarm()
236 days_ahead = tm->tm_mday - tm_now.tm_mday; in rzn1_rtc_set_alarm()
239 writel(bin2bcd(tm->tm_min), rtc->base + RZN1_RTC_ALM); in rzn1_rtc_set_alarm()
240 writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH); in rzn1_rtc_set_alarm()
241 writel(BIT(wday), rtc->base + RZN1_RTC_ALW); in rzn1_rtc_set_alarm()
243 rzn1_rtc_alarm_irq_enable(dev, alrm->enabled); in rzn1_rtc_set_alarm()
250 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_read_offset() local
255 val = readl(rtc->base + RZN1_RTC_SUBU); in rzn1_rtc_read_offset()
263 *offset = -(((~val) & 0x3F) + 1) * ppb_per_step; in rzn1_rtc_read_offset()
265 *offset = (val - 1) * ppb_per_step; in rzn1_rtc_read_offset()
272 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_set_offset() local
287 if (stepsh >= -0x3E && stepsh <= 0x3E) { in rzn1_rtc_set_offset()
291 } else if (stepsl >= -0x3E && stepsl <= 0x3E) { in rzn1_rtc_set_offset()
295 return -ERANGE; in rzn1_rtc_set_offset()
305 subu |= (~(-steps - 1)) & 0x3F; in rzn1_rtc_set_offset()
308 ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, ctl2, in rzn1_rtc_set_offset()
313 writel(subu, rtc->base + RZN1_RTC_SUBU); in rzn1_rtc_set_offset()
330 struct rzn1_rtc *rtc; in rzn1_rtc_probe() local
334 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in rzn1_rtc_probe()
335 if (!rtc) in rzn1_rtc_probe()
336 return -ENOMEM; in rzn1_rtc_probe()
338 platform_set_drvdata(pdev, rtc); in rzn1_rtc_probe()
340 rtc->base = devm_platform_ioremap_resource(pdev, 0); in rzn1_rtc_probe()
341 if (IS_ERR(rtc->base)) in rzn1_rtc_probe()
342 return dev_err_probe(&pdev->dev, PTR_ERR(rtc->base), "Missing reg\n"); in rzn1_rtc_probe()
348 rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev); in rzn1_rtc_probe()
349 if (IS_ERR(rtc->rtcdev)) in rzn1_rtc_probe()
350 return PTR_ERR(rtc->rtcdev); in rzn1_rtc_probe()
352 rtc->rtcdev->range_min = RTC_TIMESTAMP_BEGIN_2000; in rzn1_rtc_probe()
353 rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099; in rzn1_rtc_probe()
354 rtc->rtcdev->alarm_offset_max = 7 * 86400; in rzn1_rtc_probe()
355 rtc->rtcdev->ops = &rzn1_rtc_ops; in rzn1_rtc_probe()
356 set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features); in rzn1_rtc_probe()
357 clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features); in rzn1_rtc_probe()
359 ret = devm_pm_runtime_enable(&pdev->dev); in rzn1_rtc_probe()
362 ret = pm_runtime_resume_and_get(&pdev->dev); in rzn1_rtc_probe()
368 * Set 24-hour mode and possible oscillator offset compensation in SUBU mode. in rzn1_rtc_probe()
371 rtc->base + RZN1_RTC_CTL0); in rzn1_rtc_probe()
374 writel(0, rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_probe()
376 ret = devm_request_irq(&pdev->dev, alarm_irq, rzn1_rtc_alarm_irq, 0, in rzn1_rtc_probe()
377 dev_name(&pdev->dev), rtc); in rzn1_rtc_probe()
379 dev_err(&pdev->dev, "RTC timer interrupt not available\n"); in rzn1_rtc_probe()
383 ret = devm_rtc_register_device(rtc->rtcdev); in rzn1_rtc_probe()
390 pm_runtime_put(&pdev->dev); in rzn1_rtc_probe()
397 pm_runtime_put(&pdev->dev); in rzn1_rtc_remove()
401 { .compatible = "renesas,rzn1-rtc" },
410 .name = "rzn1-rtc",
418 MODULE_DESCRIPTION("RZ/N1 RTC driver");