Lines Matching +full:jz4740 +full:- +full:rtc

1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
5 * JZ4740 SoC RTC driver
16 #include <linux/rtc.h>
57 struct rtc_device *rtc; member
64 static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg) in jz4740_rtc_reg_read() argument
66 return readl(rtc->base + reg); in jz4740_rtc_reg_read()
69 static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc) in jz4740_rtc_wait_write_ready() argument
75 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); in jz4740_rtc_wait_write_ready()
76 } while (!(ctrl & JZ_RTC_CTRL_WRDY) && --timeout); in jz4740_rtc_wait_write_ready()
78 return timeout ? 0 : -EIO; in jz4740_rtc_wait_write_ready()
81 static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc) in jz4780_rtc_enable_write() argument
86 ret = jz4740_rtc_wait_write_ready(rtc); in jz4780_rtc_enable_write()
90 writel(JZ_RTC_WENR_MAGIC, rtc->base + JZ_REG_RTC_WENR); in jz4780_rtc_enable_write()
93 ctrl = readl(rtc->base + JZ_REG_RTC_WENR); in jz4780_rtc_enable_write()
94 } while (!(ctrl & JZ_RTC_WENR_WEN) && --timeout); in jz4780_rtc_enable_write()
96 return timeout ? 0 : -EIO; in jz4780_rtc_enable_write()
99 static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg, in jz4740_rtc_reg_write() argument
104 if (rtc->type >= ID_JZ4760) in jz4740_rtc_reg_write()
105 ret = jz4780_rtc_enable_write(rtc); in jz4740_rtc_reg_write()
107 ret = jz4740_rtc_wait_write_ready(rtc); in jz4740_rtc_reg_write()
109 writel(val, rtc->base + reg); in jz4740_rtc_reg_write()
114 static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask, in jz4740_rtc_ctrl_set_bits() argument
121 spin_lock_irqsave(&rtc->lock, flags); in jz4740_rtc_ctrl_set_bits()
123 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); in jz4740_rtc_ctrl_set_bits()
133 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl); in jz4740_rtc_ctrl_set_bits()
135 spin_unlock_irqrestore(&rtc->lock, flags); in jz4740_rtc_ctrl_set_bits()
142 struct jz4740_rtc *rtc = dev_get_drvdata(dev); in jz4740_rtc_read_time() local
146 if (jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD) != 0x12345678) in jz4740_rtc_read_time()
147 return -EINVAL; in jz4740_rtc_read_time()
153 secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); in jz4740_rtc_read_time()
154 secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); in jz4740_rtc_read_time()
156 while (secs != secs2 && --timeout) { in jz4740_rtc_read_time()
158 secs2 = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC); in jz4740_rtc_read_time()
162 return -EIO; in jz4740_rtc_read_time()
171 struct jz4740_rtc *rtc = dev_get_drvdata(dev); in jz4740_rtc_set_time() local
174 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, rtc_tm_to_time64(time)); in jz4740_rtc_set_time()
178 return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); in jz4740_rtc_set_time()
183 struct jz4740_rtc *rtc = dev_get_drvdata(dev); in jz4740_rtc_read_alarm() local
187 secs = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SEC_ALARM); in jz4740_rtc_read_alarm()
189 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); in jz4740_rtc_read_alarm()
191 alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE); in jz4740_rtc_read_alarm()
192 alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF); in jz4740_rtc_read_alarm()
194 rtc_time64_to_tm(secs, &alrm->time); in jz4740_rtc_read_alarm()
202 struct jz4740_rtc *rtc = dev_get_drvdata(dev); in jz4740_rtc_set_alarm() local
203 uint32_t secs = lower_32_bits(rtc_tm_to_time64(&alrm->time)); in jz4740_rtc_set_alarm()
205 ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); in jz4740_rtc_set_alarm()
207 ret = jz4740_rtc_ctrl_set_bits(rtc, in jz4740_rtc_set_alarm()
208 JZ_RTC_CTRL_AE | JZ_RTC_CTRL_AF_IRQ, alrm->enabled); in jz4740_rtc_set_alarm()
215 struct jz4740_rtc *rtc = dev_get_drvdata(dev); in jz4740_rtc_alarm_irq_enable() local
216 return jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_AF_IRQ, enable); in jz4740_rtc_alarm_irq_enable()
229 struct jz4740_rtc *rtc = data; in jz4740_rtc_irq() local
233 ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL); in jz4740_rtc_irq()
241 rtc_update_irq(rtc->rtc, 1, events); in jz4740_rtc_irq()
243 jz4740_rtc_ctrl_set_bits(rtc, JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF, false); in jz4740_rtc_irq()
250 struct jz4740_rtc *rtc = dev_get_drvdata(dev); in jz4740_rtc_poweroff() local
251 jz4740_rtc_reg_write(rtc, JZ_REG_RTC_HIBERNATE, 1); in jz4740_rtc_poweroff()
266 { .compatible = "ingenic,jz4740-rtc", .data = (void *)ID_JZ4740 },
267 { .compatible = "ingenic,jz4760-rtc", .data = (void *)ID_JZ4760 },
268 { .compatible = "ingenic,jz4780-rtc", .data = (void *)ID_JZ4780 },
273 static void jz4740_rtc_set_wakeup_params(struct jz4740_rtc *rtc, in jz4740_rtc_set_wakeup_params() argument
281 of_property_read_u32(np, "ingenic,reset-pin-assert-time-ms", in jz4740_rtc_set_wakeup_params()
283 of_property_read_u32(np, "ingenic,min-wakeup-pin-assert-time-ms", in jz4740_rtc_set_wakeup_params()
288 * Range is 0 to 2 sec if RTC is clocked at 32 kHz. in jz4740_rtc_set_wakeup_params()
295 jz4740_rtc_reg_write(rtc, JZ_REG_RTC_WAKEUP_FILTER, wakeup_ticks); in jz4740_rtc_set_wakeup_params()
298 * Set reset pin low-level assertion time after wakeup: 60 ms. in jz4740_rtc_set_wakeup_params()
299 * Range is 0 to 125 ms if RTC is clocked at 32 kHz. in jz4740_rtc_set_wakeup_params()
306 jz4740_rtc_reg_write(rtc, JZ_REG_RTC_RESET_COUNTER, reset_ticks); in jz4740_rtc_set_wakeup_params()
311 struct device *dev = &pdev->dev; in jz4740_rtc_probe()
312 struct device_node *np = dev->of_node; in jz4740_rtc_probe()
313 struct jz4740_rtc *rtc; in jz4740_rtc_probe() local
318 rtc = devm_kzalloc(dev, sizeof(*rtc), GFP_KERNEL); in jz4740_rtc_probe()
319 if (!rtc) in jz4740_rtc_probe()
320 return -ENOMEM; in jz4740_rtc_probe()
322 rtc->type = (enum jz4740_rtc_type)device_get_match_data(dev); in jz4740_rtc_probe()
328 rtc->base = devm_platform_ioremap_resource(pdev, 0); in jz4740_rtc_probe()
329 if (IS_ERR(rtc->base)) in jz4740_rtc_probe()
330 return PTR_ERR(rtc->base); in jz4740_rtc_probe()
332 clk = devm_clk_get(dev, "rtc"); in jz4740_rtc_probe()
334 dev_err(dev, "Failed to get RTC clock\n"); in jz4740_rtc_probe()
350 spin_lock_init(&rtc->lock); in jz4740_rtc_probe()
352 platform_set_drvdata(pdev, rtc); in jz4740_rtc_probe()
362 rtc->rtc = devm_rtc_allocate_device(dev); in jz4740_rtc_probe()
363 if (IS_ERR(rtc->rtc)) { in jz4740_rtc_probe()
364 ret = PTR_ERR(rtc->rtc); in jz4740_rtc_probe()
365 dev_err(dev, "Failed to allocate rtc device: %d\n", ret); in jz4740_rtc_probe()
369 rtc->rtc->ops = &jz4740_rtc_ops; in jz4740_rtc_probe()
370 rtc->rtc->range_max = U32_MAX; in jz4740_rtc_probe()
373 jz4740_rtc_set_wakeup_params(rtc, np, rate); in jz4740_rtc_probe()
376 jz4740_rtc_reg_write(rtc, JZ_REG_RTC_REGULATOR, rate - 1); in jz4740_rtc_probe()
378 ret = rtc_register_device(rtc->rtc); in jz4740_rtc_probe()
383 pdev->name, rtc); in jz4740_rtc_probe()
385 dev_err(dev, "Failed to request rtc irq: %d\n", ret); in jz4740_rtc_probe()
404 .name = "jz4740-rtc",
411 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
413 MODULE_DESCRIPTION("RTC driver for the JZ4740 SoC\n");
414 MODULE_ALIAS("platform:jz4740-rtc");