Lines Matching +full:at91rm9200 +full:- +full:rtc
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Real Time Clock interface for Linux on Atmel AT91RM9200
7 * Converted to RTC class model by Andrew Victor
10 * Based on s3c2410-rtc.c Simtec Electronics
12 * Based on sa1100-rtc.c by Nils Faerber
13 * Based on rtc.c by Paul Gortmaker
27 #include <linux/rtc.h>
126 * Register read back (of any RTC-register) needed to make sure in at91_rtc_write_idr()
127 * IDR-register write has reached the peripheral before updating in at91_rtc_write_idr()
132 * way to be certain would be to poll the IMR-register, which is in at91_rtc_write_idr()
146 if (at91_rtc_config->use_shadow_imr) { in at91_rtc_read_imr()
172 tm->tm_sec = bcd2bin(FIELD_GET(AT91_RTC_SEC, time)); in at91_rtc_decodetime()
173 tm->tm_min = bcd2bin(FIELD_GET(AT91_RTC_MIN, time)); in at91_rtc_decodetime()
174 tm->tm_hour = bcd2bin(FIELD_GET(AT91_RTC_HOUR, time)); in at91_rtc_decodetime()
178 * the year - so these will return an invalid value. in at91_rtc_decodetime()
180 tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ in at91_rtc_decodetime()
181 tm->tm_year += bcd2bin(FIELD_GET(AT91_RTC_YEAR, date)); /* year */ in at91_rtc_decodetime()
183 tm->tm_wday = bcd2bin(FIELD_GET(AT91_RTC_DAY, date)) - 1; /* day of the week [0-6], Sunday=0 */ in at91_rtc_decodetime()
184 tm->tm_mon = bcd2bin(FIELD_GET(AT91_RTC_MONTH, date)) - 1; in at91_rtc_decodetime()
185 tm->tm_mday = bcd2bin(FIELD_GET(AT91_RTC_DATE, date)); in at91_rtc_decodetime()
189 * Read current time and date in RTC
194 tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); in at91_rtc_readtime()
195 tm->tm_year = tm->tm_year - 1900; in at91_rtc_readtime()
203 * Set current time and date in RTC
222 FIELD_PREP(AT91_RTC_SEC, bin2bcd(tm->tm_sec)) in at91_rtc_settime()
223 | FIELD_PREP(AT91_RTC_MIN, bin2bcd(tm->tm_min)) in at91_rtc_settime()
224 | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(tm->tm_hour))); in at91_rtc_settime()
228 bin2bcd((tm->tm_year + 1900) / 100)) in at91_rtc_settime()
229 | FIELD_PREP(AT91_RTC_YEAR, bin2bcd(tm->tm_year % 100)) in at91_rtc_settime()
230 | FIELD_PREP(AT91_RTC_MONTH, bin2bcd(tm->tm_mon + 1)) in at91_rtc_settime()
231 | FIELD_PREP(AT91_RTC_DAY, bin2bcd(tm->tm_wday + 1)) in at91_rtc_settime()
232 | FIELD_PREP(AT91_RTC_DATE, bin2bcd(tm->tm_mday))); in at91_rtc_settime()
244 * Read alarm time and date in RTC
248 struct rtc_time *tm = &alrm->time; in at91_rtc_readalarm()
251 tm->tm_year = -1; in at91_rtc_readalarm()
253 alrm->enabled = (at91_rtc_read_imr() & AT91_RTC_ALARM) in at91_rtc_readalarm()
257 alrm->enabled ? "en" : "dis"); in at91_rtc_readalarm()
263 * Set alarm time and date in RTC
267 struct rtc_time tm = alrm->time; in at91_rtc_setalarm()
271 FIELD_PREP(AT91_RTC_SEC, bin2bcd(alrm->time.tm_sec)) in at91_rtc_setalarm()
272 | FIELD_PREP(AT91_RTC_MIN, bin2bcd(alrm->time.tm_min)) in at91_rtc_setalarm()
273 | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(alrm->time.tm_hour)) in at91_rtc_setalarm()
276 FIELD_PREP(AT91_RTC_MONTH, bin2bcd(alrm->time.tm_mon + 1)) in at91_rtc_setalarm()
277 | FIELD_PREP(AT91_RTC_DATE, bin2bcd(alrm->time.tm_mday)) in at91_rtc_setalarm()
280 if (alrm->enabled) { in at91_rtc_setalarm()
316 val = -val; in at91_rtc_readoffset()
332 return -ERANGE; in at91_rtc_setoffset()
333 if (offset < -AT91_RTC_CORR_DIVIDEND / 2) in at91_rtc_setoffset()
334 return -ERANGE; in at91_rtc_setoffset()
342 offset = -offset; in at91_rtc_setoffset()
365 mr |= FIELD_PREP(AT91_RTC_CORRECTION, corr - 1); in at91_rtc_setoffset()
373 * IRQ handler for the RTC
378 struct rtc_device *rtc = platform_get_drvdata(pdev); in at91_rtc_interrupt() local
398 rtc_update_irq(rtc, 1, events); in at91_rtc_interrupt()
400 dev_dbg(&pdev->dev, "%s(): num=%ld, events=0x%02lx\n", in at91_rtc_interrupt()
428 .compatible = "atmel,at91rm9200-rtc",
431 .compatible = "atmel,at91sam9x5-rtc",
434 .compatible = "atmel,sama5d4-rtc",
437 .compatible = "atmel,sama5d2-rtc",
440 .compatible = "microchip,sam9x60-rtc",
467 * Initialize and install RTC driver
471 struct rtc_device *rtc; in at91_rtc_probe() local
475 at91_rtc_config = of_device_get_match_data(&pdev->dev); in at91_rtc_probe()
477 return -ENODEV; in at91_rtc_probe()
481 dev_err(&pdev->dev, "no mmio resource defined\n"); in at91_rtc_probe()
482 return -ENXIO; in at91_rtc_probe()
487 return -ENXIO; in at91_rtc_probe()
489 at91_rtc_regs = devm_ioremap(&pdev->dev, regs->start, in at91_rtc_probe()
492 dev_err(&pdev->dev, "failed to map registers, aborting.\n"); in at91_rtc_probe()
493 return -ENOMEM; in at91_rtc_probe()
496 rtc = devm_rtc_allocate_device(&pdev->dev); in at91_rtc_probe()
497 if (IS_ERR(rtc)) in at91_rtc_probe()
498 return PTR_ERR(rtc); in at91_rtc_probe()
499 platform_set_drvdata(pdev, rtc); in at91_rtc_probe()
501 sclk = devm_clk_get(&pdev->dev, NULL); in at91_rtc_probe()
507 dev_err(&pdev->dev, "Could not enable slow clock\n"); in at91_rtc_probe()
519 ret = devm_request_irq(&pdev->dev, irq, at91_rtc_interrupt, in at91_rtc_probe()
523 dev_err(&pdev->dev, "IRQ %d already in use.\n", irq); in at91_rtc_probe()
528 * being wake-capable; if it didn't, do that here. in at91_rtc_probe()
530 if (!device_can_wakeup(&pdev->dev)) in at91_rtc_probe()
531 device_init_wakeup(&pdev->dev, 1); in at91_rtc_probe()
533 if (at91_rtc_config->has_correction) in at91_rtc_probe()
534 rtc->ops = &sama5d4_rtc_ops; in at91_rtc_probe()
536 rtc->ops = &at91_rtc_ops; in at91_rtc_probe()
538 rtc->range_min = RTC_TIMESTAMP_BEGIN_1900; in at91_rtc_probe()
539 rtc->range_max = RTC_TIMESTAMP_END_2099; in at91_rtc_probe()
540 ret = devm_rtc_register_device(rtc); in at91_rtc_probe()
549 dev_info(&pdev->dev, "AT91 Real Time Clock driver.\n"); in at91_rtc_probe()
559 * Disable and remove the RTC driver
581 /* AT91RM9200 RTC Power management control */
610 struct rtc_device *rtc = dev_get_drvdata(dev); in at91_rtc_resume() local
619 rtc_update_irq(rtc, 1, cached_events); in at91_rtc_resume()
655 MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200");