Lines Matching +full:ma35d1 +full:- +full:rtc

1 // SPDX-License-Identifier: GPL-2.0
3 * RTC driver for Nuvoton MA35D1
16 #include <linux/rtc.h>
18 /* MA35D1 RTC Control Registers */
62 return __raw_readl(p->rtc_reg + offset); in rtc_reg_read()
67 __raw_writel(value, p->rtc_reg + offset); in rtc_reg_write()
72 struct ma35_rtc *rtc = (struct ma35_rtc *)data; in ma35d1_rtc_interrupt() local
75 rtc_irq = rtc_reg_read(rtc, MA35_REG_RTC_INTSTS); in ma35d1_rtc_interrupt()
78 rtc_reg_write(rtc, MA35_REG_RTC_INTSTS, RTC_INTSTS_ALMIF); in ma35d1_rtc_interrupt()
82 rtc_update_irq(rtc->rtcdev, 1, events); in ma35d1_rtc_interrupt()
87 static int ma35d1_rtc_init(struct ma35_rtc *rtc, u32 ms_timeout) in ma35d1_rtc_init() argument
92 if (rtc_reg_read(rtc, MA35_REG_RTC_INIT) & RTC_INIT_ACTIVE) in ma35d1_rtc_init()
95 rtc_reg_write(rtc, MA35_REG_RTC_INIT, RTC_INIT_MAGIC_CODE); in ma35d1_rtc_init()
101 return -ETIMEDOUT; in ma35d1_rtc_init()
106 struct ma35_rtc *rtc = dev_get_drvdata(dev); in ma35d1_alarm_irq_enable() local
109 reg_ien = rtc_reg_read(rtc, MA35_REG_RTC_INTEN); in ma35d1_alarm_irq_enable()
112 rtc_reg_write(rtc, MA35_REG_RTC_INTEN, reg_ien | RTC_INTEN_ALMIEN); in ma35d1_alarm_irq_enable()
114 rtc_reg_write(rtc, MA35_REG_RTC_INTEN, reg_ien & ~RTC_INTEN_ALMIEN); in ma35d1_alarm_irq_enable()
121 struct ma35_rtc *rtc = dev_get_drvdata(dev); in ma35d1_rtc_read_time() local
125 time = rtc_reg_read(rtc, MA35_REG_RTC_TIME); in ma35d1_rtc_read_time()
126 cal = rtc_reg_read(rtc, MA35_REG_RTC_CAL); in ma35d1_rtc_read_time()
127 wday = rtc_reg_read(rtc, MA35_REG_RTC_WEEKDAY); in ma35d1_rtc_read_time()
128 } while (time != rtc_reg_read(rtc, MA35_REG_RTC_TIME) || in ma35d1_rtc_read_time()
129 cal != rtc_reg_read(rtc, MA35_REG_RTC_CAL)); in ma35d1_rtc_read_time()
131 tm->tm_mday = bcd2bin(cal >> 0); in ma35d1_rtc_read_time()
132 tm->tm_wday = wday; in ma35d1_rtc_read_time()
133 tm->tm_mon = bcd2bin(cal >> 8); in ma35d1_rtc_read_time()
134 tm->tm_mon = tm->tm_mon - 1; in ma35d1_rtc_read_time()
135 tm->tm_year = bcd2bin(cal >> 16) + 100; in ma35d1_rtc_read_time()
137 tm->tm_sec = bcd2bin(time >> 0); in ma35d1_rtc_read_time()
138 tm->tm_min = bcd2bin(time >> 8); in ma35d1_rtc_read_time()
139 tm->tm_hour = bcd2bin(time >> 16); in ma35d1_rtc_read_time()
146 struct ma35_rtc *rtc = dev_get_drvdata(dev); in ma35d1_rtc_set_time() local
149 val = bin2bcd(tm->tm_mday) << 0 | bin2bcd(tm->tm_mon + 1) << 8 | in ma35d1_rtc_set_time()
150 bin2bcd(tm->tm_year - 100) << 16; in ma35d1_rtc_set_time()
151 rtc_reg_write(rtc, MA35_REG_RTC_CAL, val); in ma35d1_rtc_set_time()
153 val = bin2bcd(tm->tm_sec) << 0 | bin2bcd(tm->tm_min) << 8 | in ma35d1_rtc_set_time()
154 bin2bcd(tm->tm_hour) << 16; in ma35d1_rtc_set_time()
155 rtc_reg_write(rtc, MA35_REG_RTC_TIME, val); in ma35d1_rtc_set_time()
157 val = tm->tm_wday; in ma35d1_rtc_set_time()
158 rtc_reg_write(rtc, MA35_REG_RTC_WEEKDAY, val); in ma35d1_rtc_set_time()
165 struct ma35_rtc *rtc = dev_get_drvdata(dev); in ma35d1_rtc_read_alarm() local
168 talm = rtc_reg_read(rtc, MA35_REG_RTC_TALM); in ma35d1_rtc_read_alarm()
169 calm = rtc_reg_read(rtc, MA35_REG_RTC_CALM); in ma35d1_rtc_read_alarm()
171 alrm->time.tm_mday = bcd2bin(calm >> 0); in ma35d1_rtc_read_alarm()
172 alrm->time.tm_mon = bcd2bin(calm >> 8); in ma35d1_rtc_read_alarm()
173 alrm->time.tm_mon = alrm->time.tm_mon - 1; in ma35d1_rtc_read_alarm()
175 alrm->time.tm_year = bcd2bin(calm >> 16) + 100; in ma35d1_rtc_read_alarm()
177 alrm->time.tm_sec = bcd2bin(talm >> 0); in ma35d1_rtc_read_alarm()
178 alrm->time.tm_min = bcd2bin(talm >> 8); in ma35d1_rtc_read_alarm()
179 alrm->time.tm_hour = bcd2bin(talm >> 16); in ma35d1_rtc_read_alarm()
181 return rtc_valid_tm(&alrm->time); in ma35d1_rtc_read_alarm()
186 struct ma35_rtc *rtc = dev_get_drvdata(dev); in ma35d1_rtc_set_alarm() local
189 val = bin2bcd(alrm->time.tm_mday) << 0 | bin2bcd(alrm->time.tm_mon + 1) << 8 | in ma35d1_rtc_set_alarm()
190 bin2bcd(alrm->time.tm_year - 100) << 16; in ma35d1_rtc_set_alarm()
191 rtc_reg_write(rtc, MA35_REG_RTC_CALM, val); in ma35d1_rtc_set_alarm()
193 val = bin2bcd(alrm->time.tm_sec) << 0 | bin2bcd(alrm->time.tm_min) << 8 | in ma35d1_rtc_set_alarm()
194 bin2bcd(alrm->time.tm_hour) << 16; in ma35d1_rtc_set_alarm()
195 rtc_reg_write(rtc, MA35_REG_RTC_TALM, val); in ma35d1_rtc_set_alarm()
197 ma35d1_alarm_irq_enable(dev, alrm->enabled); in ma35d1_rtc_set_alarm()
212 struct ma35_rtc *rtc; in ma35d1_rtc_probe() local
216 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in ma35d1_rtc_probe()
217 if (!rtc) in ma35d1_rtc_probe()
218 return -ENOMEM; in ma35d1_rtc_probe()
220 rtc->rtc_reg = devm_platform_ioremap_resource(pdev, 0); in ma35d1_rtc_probe()
221 if (IS_ERR(rtc->rtc_reg)) in ma35d1_rtc_probe()
222 return PTR_ERR(rtc->rtc_reg); in ma35d1_rtc_probe()
224 clk = of_clk_get(pdev->dev.of_node, 0); in ma35d1_rtc_probe()
226 return dev_err_probe(&pdev->dev, PTR_ERR(clk), "failed to find rtc clock\n"); in ma35d1_rtc_probe()
232 if (!(rtc_reg_read(rtc, MA35_REG_RTC_INIT) & RTC_INIT_ACTIVE)) { in ma35d1_rtc_probe()
233 ret = ma35d1_rtc_init(rtc, RTC_INIT_TIMEOUT); in ma35d1_rtc_probe()
235 return dev_err_probe(&pdev->dev, ret, "rtc init failed\n"); in ma35d1_rtc_probe()
238 rtc->irq_num = platform_get_irq(pdev, 0); in ma35d1_rtc_probe()
240 ret = devm_request_irq(&pdev->dev, rtc->irq_num, ma35d1_rtc_interrupt, in ma35d1_rtc_probe()
241 IRQF_NO_SUSPEND, "ma35d1rtc", rtc); in ma35d1_rtc_probe()
243 return dev_err_probe(&pdev->dev, ret, "Failed to request rtc irq\n"); in ma35d1_rtc_probe()
245 platform_set_drvdata(pdev, rtc); in ma35d1_rtc_probe()
247 device_init_wakeup(&pdev->dev, true); in ma35d1_rtc_probe()
249 rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev); in ma35d1_rtc_probe()
250 if (IS_ERR(rtc->rtcdev)) in ma35d1_rtc_probe()
251 return PTR_ERR(rtc->rtcdev); in ma35d1_rtc_probe()
253 rtc->rtcdev->ops = &ma35d1_rtc_ops; in ma35d1_rtc_probe()
254 rtc->rtcdev->range_min = RTC_TIMESTAMP_BEGIN_2000; in ma35d1_rtc_probe()
255 rtc->rtcdev->range_max = RTC_TIMESTAMP_END_2099; in ma35d1_rtc_probe()
257 ret = devm_rtc_register_device(rtc->rtcdev); in ma35d1_rtc_probe()
259 return dev_err_probe(&pdev->dev, ret, "Failed to register rtc device\n"); in ma35d1_rtc_probe()
266 struct ma35_rtc *rtc = platform_get_drvdata(pdev); in ma35d1_rtc_suspend() local
268 if (device_may_wakeup(&pdev->dev)) in ma35d1_rtc_suspend()
269 enable_irq_wake(rtc->irq_num); in ma35d1_rtc_suspend()
276 struct ma35_rtc *rtc = platform_get_drvdata(pdev); in ma35d1_rtc_resume() local
278 if (device_may_wakeup(&pdev->dev)) in ma35d1_rtc_resume()
279 disable_irq_wake(rtc->irq_num); in ma35d1_rtc_resume()
285 { .compatible = "nuvoton,ma35d1-rtc", },
295 .name = "rtc-ma35d1",
302 MODULE_AUTHOR("Ming-Jen Chen <mjchen@nuvoton.com>");
303 MODULE_DESCRIPTION("MA35D1 RTC driver");