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 <buserror@gmail.com>
11 * - Miquel Raynal <miquel.raynal@bootlin.com>
21 #include <linux/rtc.h>
63 static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm) in rzn1_rtc_get_time_snapshot() argument
67 val = readl(rtc->base + RZN1_RTC_TIMEC); in rzn1_rtc_get_time_snapshot()
68 tm->tm_sec = bcd2bin(val); in rzn1_rtc_get_time_snapshot()
69 tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT); in rzn1_rtc_get_time_snapshot()
70 tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT); in rzn1_rtc_get_time_snapshot()
72 val = readl(rtc->base + RZN1_RTC_CALC); in rzn1_rtc_get_time_snapshot()
73 tm->tm_wday = val & 0x0f; in rzn1_rtc_get_time_snapshot()
74 tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT); in rzn1_rtc_get_time_snapshot()
75 tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1; in rzn1_rtc_get_time_snapshot()
76 tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100; in rzn1_rtc_get_time_snapshot()
81 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_read_time() local
85 * The RTC was not started or is stopped and thus does not carry the in rzn1_rtc_read_time()
88 val = readl(rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_read_time()
90 return -EINVAL; in rzn1_rtc_read_time()
92 rzn1_rtc_get_time_snapshot(rtc, tm); in rzn1_rtc_read_time()
93 secs = readl(rtc->base + RZN1_RTC_SECC); in rzn1_rtc_read_time()
94 if (tm->tm_sec != bcd2bin(secs)) in rzn1_rtc_read_time()
95 rzn1_rtc_get_time_snapshot(rtc, tm); in rzn1_rtc_read_time()
102 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_set_time() local
106 val = readl(rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_set_time()
109 writel(RZN1_RTC_CTL2_WAIT, rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_set_time()
113 ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, val, in rzn1_rtc_set_time()
119 val = bin2bcd(tm->tm_sec); in rzn1_rtc_set_time()
120 val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT; in rzn1_rtc_set_time()
121 val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT; in rzn1_rtc_set_time()
122 writel(val, rtc->base + RZN1_RTC_TIME); in rzn1_rtc_set_time()
124 val = tm->tm_wday; in rzn1_rtc_set_time()
125 val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT; in rzn1_rtc_set_time()
126 val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT; in rzn1_rtc_set_time()
127 val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT; in rzn1_rtc_set_time()
128 writel(val, rtc->base + RZN1_RTC_CAL); in rzn1_rtc_set_time()
130 writel(0, rtc->base + RZN1_RTC_CTL2); in rzn1_rtc_set_time()
137 struct rzn1_rtc *rtc = dev_id; in rzn1_rtc_alarm_irq() local
139 rtc_update_irq(rtc->rtcdev, 1, RTC_AF | RTC_IRQF); in rzn1_rtc_alarm_irq()
146 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_alarm_irq_enable() local
147 u32 ctl1 = readl(rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_alarm_irq_enable()
154 writel(ctl1, rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_alarm_irq_enable()
161 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_read_alarm() local
162 struct rtc_time *tm = &alrm->time; in rzn1_rtc_read_alarm()
172 min = readl(rtc->base + RZN1_RTC_ALM); in rzn1_rtc_read_alarm()
173 hour = readl(rtc->base + RZN1_RTC_ALH); in rzn1_rtc_read_alarm()
174 wday = readl(rtc->base + RZN1_RTC_ALW); in rzn1_rtc_read_alarm()
176 tm->tm_sec = 0; in rzn1_rtc_read_alarm()
177 tm->tm_min = bcd2bin(min); in rzn1_rtc_read_alarm()
178 tm->tm_hour = bcd2bin(hour); in rzn1_rtc_read_alarm()
179 delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7; in rzn1_rtc_read_alarm()
180 tm->tm_wday = fls(wday) - 1; in rzn1_rtc_read_alarm()
187 ctl1 = readl(rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_read_alarm()
188 alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME); in rzn1_rtc_read_alarm()
195 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_set_alarm() local
196 struct rtc_time *tm = &alrm->time, tm_now; in rzn1_rtc_set_alarm()
206 farest = rtc_tm_to_time64(&tm_now) + rtc->rtcdev->alarm_offset_max; in rzn1_rtc_set_alarm()
209 return -ERANGE; in rzn1_rtc_set_alarm()
212 days_ahead = tm->tm_mday - tm_now.tm_mday; in rzn1_rtc_set_alarm()
215 writel(bin2bcd(tm->tm_min), rtc->base + RZN1_RTC_ALM); in rzn1_rtc_set_alarm()
216 writel(bin2bcd(tm->tm_hour), rtc->base + RZN1_RTC_ALH); in rzn1_rtc_set_alarm()
217 writel(BIT(wday), rtc->base + RZN1_RTC_ALW); in rzn1_rtc_set_alarm()
219 rzn1_rtc_alarm_irq_enable(dev, alrm->enabled); in rzn1_rtc_set_alarm()
226 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_read_offset() local
231 val = readl(rtc->base + RZN1_RTC_SUBU); in rzn1_rtc_read_offset()
239 *offset = -(((~val) & 0x3F) + 1) * ppb_per_step; in rzn1_rtc_read_offset()
241 *offset = (val - 1) * ppb_per_step; in rzn1_rtc_read_offset()
248 struct rzn1_rtc *rtc = dev_get_drvdata(dev); in rzn1_rtc_set_offset() local
263 if (stepsh >= -0x3E && stepsh <= 0x3E) { in rzn1_rtc_set_offset()
267 } else if (stepsl >= -0x3E && stepsl <= 0x3E) { in rzn1_rtc_set_offset()
271 return -ERANGE; in rzn1_rtc_set_offset()
281 subu |= (~(-steps - 1)) & 0x3F; in rzn1_rtc_set_offset()
284 ret = readl_poll_timeout(rtc->base + RZN1_RTC_CTL2, ctl2, in rzn1_rtc_set_offset()
289 writel(subu, rtc->base + RZN1_RTC_SUBU); in rzn1_rtc_set_offset()
306 struct rzn1_rtc *rtc; in rzn1_rtc_probe() local
310 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in rzn1_rtc_probe()
311 if (!rtc) in rzn1_rtc_probe()
312 return -ENOMEM; in rzn1_rtc_probe()
314 platform_set_drvdata(pdev, rtc); in rzn1_rtc_probe()
316 rtc->base = devm_platform_ioremap_resource(pdev, 0); in rzn1_rtc_probe()
317 if (IS_ERR(rtc->base)) in rzn1_rtc_probe()
318 return dev_err_probe(&pdev->dev, PTR_ERR(rtc->base), "Missing reg\n"); in rzn1_rtc_probe()
324 rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev); in rzn1_rtc_probe()
325 if (IS_ERR(rtc->rtcdev)) in rzn1_rtc_probe()
326 return PTR_ERR(rtc->rtcdev); in rzn1_rtc_probe()
328 rtc->rtcdev->range_min = RTC_TIMESTAMP_BEGIN_2000; in rzn1_rtc_probe()
329 rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099; in rzn1_rtc_probe()
330 rtc->rtcdev->alarm_offset_max = 7 * 86400; in rzn1_rtc_probe()
331 rtc->rtcdev->ops = &rzn1_rtc_ops; in rzn1_rtc_probe()
332 set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features); in rzn1_rtc_probe()
333 clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features); in rzn1_rtc_probe()
335 ret = devm_pm_runtime_enable(&pdev->dev); in rzn1_rtc_probe()
338 ret = pm_runtime_resume_and_get(&pdev->dev); in rzn1_rtc_probe()
344 * Set 24-hour mode and possible oscillator offset compensation in SUBU mode. in rzn1_rtc_probe()
347 rtc->base + RZN1_RTC_CTL0); in rzn1_rtc_probe()
350 writel(0, rtc->base + RZN1_RTC_CTL1); in rzn1_rtc_probe()
352 ret = devm_request_irq(&pdev->dev, alarm_irq, rzn1_rtc_alarm_irq, 0, in rzn1_rtc_probe()
353 dev_name(&pdev->dev), rtc); in rzn1_rtc_probe()
355 dev_err(&pdev->dev, "RTC timer interrupt not available\n"); in rzn1_rtc_probe()
359 ret = devm_rtc_register_device(rtc->rtcdev); in rzn1_rtc_probe()
366 pm_runtime_put(&pdev->dev); in rzn1_rtc_probe()
373 pm_runtime_put(&pdev->dev); in rzn1_rtc_remove()
377 { .compatible = "renesas,rzn1-rtc" },
386 .name = "rzn1-rtc",
394 MODULE_DESCRIPTION("RZ/N1 RTC driver");