Lines Matching +full:rtc +full:-

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Real-time clock driver for MPC5121
7 * Copyright 2011, Dmitry Eremin-Solenikov
12 #include <linux/rtc.h>
20 u8 set_time; /* RTC + 0x00 */
21 u8 hour_set; /* RTC + 0x01 */
22 u8 minute_set; /* RTC + 0x02 */
23 u8 second_set; /* RTC + 0x03 */
25 u8 set_date; /* RTC + 0x04 */
26 u8 month_set; /* RTC + 0x05 */
27 u8 weekday_set; /* RTC + 0x06 */
28 u8 date_set; /* RTC + 0x07 */
30 u8 write_sw; /* RTC + 0x08 */
31 u8 sw_set; /* RTC + 0x09 */
32 u16 year_set; /* RTC + 0x0a */
34 u8 alm_enable; /* RTC + 0x0c */
35 u8 alm_hour_set; /* RTC + 0x0d */
36 u8 alm_min_set; /* RTC + 0x0e */
37 u8 int_enable; /* RTC + 0x0f */
40 u8 hour; /* RTC + 0x11 */
41 u8 minute; /* RTC + 0x12 */
42 u8 second; /* RTC + 0x13 */
44 u8 month; /* RTC + 0x14 */
45 u8 wday_mday; /* RTC + 0x15 */
46 u16 year; /* RTC + 0x16 */
48 u8 int_alm; /* RTC + 0x18 */
49 u8 int_sw; /* RTC + 0x19 */
50 u8 alm_status; /* RTC + 0x1a */
51 u8 sw_minute; /* RTC + 0x1b */
53 u8 bus_error_1; /* RTC + 0x1c */
54 u8 int_day; /* RTC + 0x1d */
55 u8 int_min; /* RTC + 0x1e */
56 u8 int_sec; /* RTC + 0x1f */
61 * does not work on silicon rev 1.5 so use it for non-volatile
65 u32 target_time; /* RTC + 0x20 */
70 u32 actual_time; /* RTC + 0x24 */
71 u32 keep_alive; /* RTC + 0x28 */
78 struct rtc_device *rtc; member
90 out_8(&regs->second_set, tm->tm_sec); in mpc5121_rtc_update_smh()
91 out_8(&regs->minute_set, tm->tm_min); in mpc5121_rtc_update_smh()
92 out_8(&regs->hour_set, tm->tm_hour); in mpc5121_rtc_update_smh()
95 out_8(&regs->set_time, 0x1); in mpc5121_rtc_update_smh()
96 out_8(&regs->set_time, 0x3); in mpc5121_rtc_update_smh()
97 out_8(&regs->set_time, 0x1); in mpc5121_rtc_update_smh()
98 out_8(&regs->set_time, 0x0); in mpc5121_rtc_update_smh()
103 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5121_rtc_read_time() local
104 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_read_time()
110 now = in_be32(&regs->actual_time) + in_be32(&regs->target_time); in mpc5121_rtc_read_time()
125 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5121_rtc_set_time() local
126 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_set_time()
134 out_be32(&regs->target_time, now - in_be32(&regs->actual_time)); in mpc5121_rtc_set_time()
147 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5200_rtc_read_time() local
148 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5200_rtc_read_time()
151 tm->tm_sec = in_8(&regs->second); in mpc5200_rtc_read_time()
152 tm->tm_min = in_8(&regs->minute); in mpc5200_rtc_read_time()
155 if (in_8(&regs->hour) & 0x20) in mpc5200_rtc_read_time()
156 tm->tm_hour = (in_8(&regs->hour) >> 1) + in mpc5200_rtc_read_time()
157 (in_8(&regs->hour) & 1 ? 12 : 0); in mpc5200_rtc_read_time()
159 tm->tm_hour = in_8(&regs->hour); in mpc5200_rtc_read_time()
161 tmp = in_8(&regs->wday_mday); in mpc5200_rtc_read_time()
162 tm->tm_mday = tmp & 0x1f; in mpc5200_rtc_read_time()
163 tm->tm_mon = in_8(&regs->month) - 1; in mpc5200_rtc_read_time()
164 tm->tm_year = in_be16(&regs->year) - 1900; in mpc5200_rtc_read_time()
165 tm->tm_wday = (tmp >> 5) % 7; in mpc5200_rtc_read_time()
166 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); in mpc5200_rtc_read_time()
167 tm->tm_isdst = 0; in mpc5200_rtc_read_time()
174 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5200_rtc_set_time() local
175 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5200_rtc_set_time()
180 out_8(&regs->month_set, tm->tm_mon + 1); in mpc5200_rtc_set_time()
181 out_8(&regs->weekday_set, tm->tm_wday ? tm->tm_wday : 7); in mpc5200_rtc_set_time()
182 out_8(&regs->date_set, tm->tm_mday); in mpc5200_rtc_set_time()
183 out_be16(&regs->year_set, tm->tm_year + 1900); in mpc5200_rtc_set_time()
186 out_8(&regs->set_date, 0x1); in mpc5200_rtc_set_time()
187 out_8(&regs->set_date, 0x3); in mpc5200_rtc_set_time()
188 out_8(&regs->set_date, 0x1); in mpc5200_rtc_set_time()
189 out_8(&regs->set_date, 0x0); in mpc5200_rtc_set_time()
196 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5121_rtc_read_alarm() local
197 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_read_alarm()
199 *alarm = rtc->wkalarm; in mpc5121_rtc_read_alarm()
201 alarm->pending = in_8(&regs->alm_status); in mpc5121_rtc_read_alarm()
208 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5121_rtc_set_alarm() local
209 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_set_alarm()
211 alarm->time.tm_mday = -1; in mpc5121_rtc_set_alarm()
212 alarm->time.tm_mon = -1; in mpc5121_rtc_set_alarm()
213 alarm->time.tm_year = -1; in mpc5121_rtc_set_alarm()
215 out_8(&regs->alm_min_set, alarm->time.tm_min); in mpc5121_rtc_set_alarm()
216 out_8(&regs->alm_hour_set, alarm->time.tm_hour); in mpc5121_rtc_set_alarm()
218 out_8(&regs->alm_enable, alarm->enabled); in mpc5121_rtc_set_alarm()
220 rtc->wkalarm = *alarm; in mpc5121_rtc_set_alarm()
226 struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev); in mpc5121_rtc_handler() local
227 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_handler()
229 if (in_8(&regs->int_alm)) { in mpc5121_rtc_handler()
231 out_8(&regs->int_alm, 1); in mpc5121_rtc_handler()
232 out_8(&regs->alm_status, 1); in mpc5121_rtc_handler()
234 rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); in mpc5121_rtc_handler()
243 struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev); in mpc5121_rtc_handler_upd() local
244 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_handler_upd()
246 if (in_8(&regs->int_sec) && (in_8(&regs->int_enable) & 0x1)) { in mpc5121_rtc_handler_upd()
248 out_8(&regs->int_sec, 1); in mpc5121_rtc_handler_upd()
250 rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_UF); in mpc5121_rtc_handler_upd()
260 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); in mpc5121_rtc_alarm_irq_enable() local
261 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_alarm_irq_enable()
269 out_8(&regs->alm_enable, val); in mpc5121_rtc_alarm_irq_enable()
270 rtc->wkalarm.enabled = val; in mpc5121_rtc_alarm_irq_enable()
293 struct mpc5121_rtc_data *rtc; in mpc5121_rtc_probe() local
296 rtc = devm_kzalloc(&op->dev, sizeof(*rtc), GFP_KERNEL); in mpc5121_rtc_probe()
297 if (!rtc) in mpc5121_rtc_probe()
298 return -ENOMEM; in mpc5121_rtc_probe()
300 rtc->regs = devm_platform_ioremap_resource(op, 0); in mpc5121_rtc_probe()
301 if (IS_ERR(rtc->regs)) { in mpc5121_rtc_probe()
302 dev_err(&op->dev, "%s: couldn't map io space\n", __func__); in mpc5121_rtc_probe()
303 return PTR_ERR(rtc->regs); in mpc5121_rtc_probe()
306 device_init_wakeup(&op->dev, 1); in mpc5121_rtc_probe()
308 platform_set_drvdata(op, rtc); in mpc5121_rtc_probe()
310 rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); in mpc5121_rtc_probe()
311 err = devm_request_irq(&op->dev, rtc->irq, mpc5121_rtc_handler, 0, in mpc5121_rtc_probe()
312 "mpc5121-rtc", &op->dev); in mpc5121_rtc_probe()
314 dev_err(&op->dev, "%s: could not request irq: %i\n", in mpc5121_rtc_probe()
315 __func__, rtc->irq); in mpc5121_rtc_probe()
319 rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); in mpc5121_rtc_probe()
320 err = devm_request_irq(&op->dev, rtc->irq_periodic, in mpc5121_rtc_probe()
321 mpc5121_rtc_handler_upd, 0, "mpc5121-rtc_upd", in mpc5121_rtc_probe()
322 &op->dev); in mpc5121_rtc_probe()
324 dev_err(&op->dev, "%s: could not request irq: %i\n", in mpc5121_rtc_probe()
325 __func__, rtc->irq_periodic); in mpc5121_rtc_probe()
329 rtc->rtc = devm_rtc_allocate_device(&op->dev); in mpc5121_rtc_probe()
330 if (IS_ERR(rtc->rtc)) { in mpc5121_rtc_probe()
331 err = PTR_ERR(rtc->rtc); in mpc5121_rtc_probe()
335 rtc->rtc->ops = &mpc5200_rtc_ops; in mpc5121_rtc_probe()
336 set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtc->features); in mpc5121_rtc_probe()
337 clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtc->features); in mpc5121_rtc_probe()
338 rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; in mpc5121_rtc_probe()
339 rtc->rtc->range_max = 65733206399ULL; /* 4052-12-31 23:59:59 */ in mpc5121_rtc_probe()
341 if (of_device_is_compatible(op->dev.of_node, "fsl,mpc5121-rtc")) { in mpc5121_rtc_probe()
343 ka = in_be32(&rtc->regs->keep_alive); in mpc5121_rtc_probe()
345 dev_warn(&op->dev, in mpc5121_rtc_probe()
346 "mpc5121-rtc: Battery or oscillator failure!\n"); in mpc5121_rtc_probe()
347 out_be32(&rtc->regs->keep_alive, ka); in mpc5121_rtc_probe()
349 rtc->rtc->ops = &mpc5121_rtc_ops; in mpc5121_rtc_probe()
355 rtc->rtc->range_min = 0; in mpc5121_rtc_probe()
356 rtc->rtc->range_max = U32_MAX; in mpc5121_rtc_probe()
359 err = devm_rtc_register_device(rtc->rtc); in mpc5121_rtc_probe()
366 irq_dispose_mapping(rtc->irq_periodic); in mpc5121_rtc_probe()
368 irq_dispose_mapping(rtc->irq); in mpc5121_rtc_probe()
375 struct mpc5121_rtc_data *rtc = platform_get_drvdata(op); in mpc5121_rtc_remove() local
376 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; in mpc5121_rtc_remove()
379 out_8(&regs->alm_enable, 0); in mpc5121_rtc_remove()
380 out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1); in mpc5121_rtc_remove()
382 irq_dispose_mapping(rtc->irq); in mpc5121_rtc_remove()
383 irq_dispose_mapping(rtc->irq_periodic); in mpc5121_rtc_remove()
388 { .compatible = "fsl,mpc5121-rtc", },
389 { .compatible = "fsl,mpc5200-rtc", },
397 .name = "mpc5121-rtc",
406 MODULE_DESCRIPTION("Freescale MPC5121 built-in RTC driver");