Lines Matching +full:omap +full:- +full:l13x

1 // SPDX-License-Identifier: GPL-2.0+
3 * TI OMAP Real Time Clock interface for Linux
23 #include <linux/pinctrl/pinconf-generic.h>
28 #include <linux/rtc/rtc-omap.h>
31 * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
32 * with century-range alarm matching, driven by the 32kHz clock.
34 * The main user-visible ways it differs from PC RTCs are by omitting
35 * "don't care" alarm fields and sub-second periodic IRQs, and having
38 * Board-specific wiring options include using split power mode with
41 * low power modes) for OMAP1 boards (OMAP-L138 has this built into
42 * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
157 return readb(rtc->base + reg); in rtc_read()
162 return readl(rtc->base + reg); in rtc_readl()
167 writeb(val, rtc->base + reg); in rtc_write()
172 writel(val, rtc->base + reg); in rtc_writel()
196 * We rely on the rtc framework to handle locking (rtc->ops_lock),
225 rtc->type->unlock(rtc); in rtc_irq()
227 rtc->type->lock(rtc); in rtc_irq()
235 rtc_update_irq(rtc->rtc, 1, events); in rtc_irq()
248 if (rtc->type->has_irqwakeen) in omap_rtc_alarm_irq_enable()
259 rtc->type->unlock(rtc); in omap_rtc_alarm_irq_enable()
261 if (rtc->type->has_irqwakeen) in omap_rtc_alarm_irq_enable()
263 rtc->type->lock(rtc); in omap_rtc_alarm_irq_enable()
272 tm->tm_sec = bin2bcd(tm->tm_sec); in tm2bcd()
273 tm->tm_min = bin2bcd(tm->tm_min); in tm2bcd()
274 tm->tm_hour = bin2bcd(tm->tm_hour); in tm2bcd()
275 tm->tm_mday = bin2bcd(tm->tm_mday); in tm2bcd()
277 tm->tm_mon = bin2bcd(tm->tm_mon + 1); in tm2bcd()
278 tm->tm_year = bin2bcd(tm->tm_year - 100); in tm2bcd()
283 tm->tm_sec = bcd2bin(tm->tm_sec); in bcd2tm()
284 tm->tm_min = bcd2bin(tm->tm_min); in bcd2tm()
285 tm->tm_hour = bcd2bin(tm->tm_hour); in bcd2tm()
286 tm->tm_mday = bcd2bin(tm->tm_mday); in bcd2tm()
287 tm->tm_mon = bcd2bin(tm->tm_mon) - 1; in bcd2tm()
289 tm->tm_year = bcd2bin(tm->tm_year) + 100; in bcd2tm()
294 tm->tm_sec = rtc_read(rtc, OMAP_RTC_SECONDS_REG); in omap_rtc_read_time_raw()
295 tm->tm_min = rtc_read(rtc, OMAP_RTC_MINUTES_REG); in omap_rtc_read_time_raw()
296 tm->tm_hour = rtc_read(rtc, OMAP_RTC_HOURS_REG); in omap_rtc_read_time_raw()
297 tm->tm_mday = rtc_read(rtc, OMAP_RTC_DAYS_REG); in omap_rtc_read_time_raw()
298 tm->tm_mon = rtc_read(rtc, OMAP_RTC_MONTHS_REG); in omap_rtc_read_time_raw()
299 tm->tm_year = rtc_read(rtc, OMAP_RTC_YEARS_REG); in omap_rtc_read_time_raw()
326 rtc->type->unlock(rtc); in omap_rtc_set_time()
327 rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year); in omap_rtc_set_time()
328 rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon); in omap_rtc_set_time()
329 rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday); in omap_rtc_set_time()
330 rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour); in omap_rtc_set_time()
331 rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min); in omap_rtc_set_time()
332 rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec); in omap_rtc_set_time()
333 rtc->type->lock(rtc); in omap_rtc_set_time()
348 alm->time.tm_sec = rtc_read(rtc, OMAP_RTC_ALARM_SECONDS_REG); in omap_rtc_read_alarm()
349 alm->time.tm_min = rtc_read(rtc, OMAP_RTC_ALARM_MINUTES_REG); in omap_rtc_read_alarm()
350 alm->time.tm_hour = rtc_read(rtc, OMAP_RTC_ALARM_HOURS_REG); in omap_rtc_read_alarm()
351 alm->time.tm_mday = rtc_read(rtc, OMAP_RTC_ALARM_DAYS_REG); in omap_rtc_read_alarm()
352 alm->time.tm_mon = rtc_read(rtc, OMAP_RTC_ALARM_MONTHS_REG); in omap_rtc_read_alarm()
353 alm->time.tm_year = rtc_read(rtc, OMAP_RTC_ALARM_YEARS_REG); in omap_rtc_read_alarm()
357 bcd2tm(&alm->time); in omap_rtc_read_alarm()
360 alm->enabled = !!(interrupts & OMAP_RTC_INTERRUPTS_IT_ALARM); in omap_rtc_read_alarm()
370 tm2bcd(&alm->time); in omap_rtc_set_alarm()
375 rtc->type->unlock(rtc); in omap_rtc_set_alarm()
376 rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year); in omap_rtc_set_alarm()
377 rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon); in omap_rtc_set_alarm()
378 rtc_write(rtc, OMAP_RTC_ALARM_DAYS_REG, alm->time.tm_mday); in omap_rtc_set_alarm()
379 rtc_write(rtc, OMAP_RTC_ALARM_HOURS_REG, alm->time.tm_hour); in omap_rtc_set_alarm()
380 rtc_write(rtc, OMAP_RTC_ALARM_MINUTES_REG, alm->time.tm_min); in omap_rtc_set_alarm()
381 rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec); in omap_rtc_set_alarm()
384 if (rtc->type->has_irqwakeen) in omap_rtc_set_alarm()
387 if (alm->enabled) { in omap_rtc_set_alarm()
395 if (rtc->type->has_irqwakeen) in omap_rtc_set_alarm()
397 rtc->type->lock(rtc); in omap_rtc_set_alarm()
419 rtc->type->unlock(rtc); in omap_rtc_power_off_program()
462 rtc->type->lock(rtc); in omap_rtc_power_off_program()
469 * omap_rtc_poweroff: RTC-controlled power off
475 * The one-second alarm offset is the shortest offset possible as the alarm
484 struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc; in omap_rtc_power_off()
487 omap_rtc_power_off_program(rtc->dev.parent); in omap_rtc_power_off()
490 omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc); in omap_rtc_power_off()
495 omap_rtc_power_off_rtc->type->lock(omap_rtc_power_off_rtc); in omap_rtc_power_off()
537 .name = "am3352-rtc",
540 .name = "da830-rtc",
550 .compatible = "ti,am3352-rtc",
553 .compatible = "ti,da830-rtc",
589 {"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
611 return -EINVAL; in rtc_pinconf_get()
615 return -EINVAL; in rtc_pinconf_get()
618 return -ENOTSUPP; in rtc_pinconf_get()
656 dev_err(&rtc->rtc->dev, "Property %u not supported\n", in rtc_pinconf_set()
658 return -ENOTSUPP; in rtc_pinconf_set()
662 rtc->type->unlock(rtc); in rtc_pinconf_set()
664 rtc->type->lock(rtc); in rtc_pinconf_set()
709 rtc->type->unlock(rtc); in omap_rtc_scratch_write()
713 rtc->type->lock(rtc); in omap_rtc_scratch_write()
722 .size = OMAP_RTC_KICK0_REG - OMAP_RTC_SCRATCH0_REG,
734 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in omap_rtc_probe()
736 return -ENOMEM; in omap_rtc_probe()
738 rtc->type = device_get_match_data(&pdev->dev); in omap_rtc_probe()
739 if (rtc->type) { in omap_rtc_probe()
740 rtc->is_pmic_controller = rtc->type->has_pmic_mode && in omap_rtc_probe()
741 of_device_is_system_power_controller(pdev->dev.of_node); in omap_rtc_probe()
744 rtc->type = (void *)id_entry->driver_data; in omap_rtc_probe()
747 rtc->irq_timer = platform_get_irq(pdev, 0); in omap_rtc_probe()
748 if (rtc->irq_timer < 0) in omap_rtc_probe()
749 return rtc->irq_timer; in omap_rtc_probe()
751 rtc->irq_alarm = platform_get_irq(pdev, 1); in omap_rtc_probe()
752 if (rtc->irq_alarm < 0) in omap_rtc_probe()
753 return rtc->irq_alarm; in omap_rtc_probe()
755 rtc->clk = devm_clk_get(&pdev->dev, "ext-clk"); in omap_rtc_probe()
756 if (!IS_ERR(rtc->clk)) in omap_rtc_probe()
757 rtc->has_ext_clk = true; in omap_rtc_probe()
759 rtc->clk = devm_clk_get(&pdev->dev, "int-clk"); in omap_rtc_probe()
761 if (!IS_ERR(rtc->clk)) in omap_rtc_probe()
762 clk_prepare_enable(rtc->clk); in omap_rtc_probe()
764 rtc->base = devm_platform_ioremap_resource(pdev, 0); in omap_rtc_probe()
765 if (IS_ERR(rtc->base)) { in omap_rtc_probe()
766 clk_disable_unprepare(rtc->clk); in omap_rtc_probe()
767 return PTR_ERR(rtc->base); in omap_rtc_probe()
773 pm_runtime_enable(&pdev->dev); in omap_rtc_probe()
774 pm_runtime_get_sync(&pdev->dev); in omap_rtc_probe()
776 rtc->type->unlock(rtc); in omap_rtc_probe()
786 if (rtc->type->has_32kclk_en) { in omap_rtc_probe()
796 if (rtc->type->has_pmic_mode) in omap_rtc_probe()
799 if (rtc->type->has_power_up_reset) { in omap_rtc_probe()
802 dev_info(&pdev->dev, "RTC power up reset detected\n"); in omap_rtc_probe()
811 dev_info(&pdev->dev, "already running\n"); in omap_rtc_probe()
818 * BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: in omap_rtc_probe()
820 * - Device wake-up capability setting should come through chip in omap_rtc_probe()
823 * being woken up by RTC alarm. For OMAP-L138, this capability in omap_rtc_probe()
826 * - Boards wired so RTC_ON_nOFF is used as the reset signal, in omap_rtc_probe()
829 * is write-only, and always reads as zero...) in omap_rtc_probe()
833 dev_info(&pdev->dev, "split power mode\n"); in omap_rtc_probe()
842 if (rtc->has_ext_clk) { in omap_rtc_probe()
849 rtc->type->lock(rtc); in omap_rtc_probe()
851 device_init_wakeup(&pdev->dev, true); in omap_rtc_probe()
853 rtc->rtc = devm_rtc_allocate_device(&pdev->dev); in omap_rtc_probe()
854 if (IS_ERR(rtc->rtc)) { in omap_rtc_probe()
855 ret = PTR_ERR(rtc->rtc); in omap_rtc_probe()
859 rtc->rtc->ops = &omap_rtc_ops; in omap_rtc_probe()
860 rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; in omap_rtc_probe()
861 rtc->rtc->range_max = RTC_TIMESTAMP_END_2099; in omap_rtc_probe()
865 ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0, in omap_rtc_probe()
866 dev_name(&rtc->rtc->dev), rtc); in omap_rtc_probe()
870 if (rtc->irq_timer != rtc->irq_alarm) { in omap_rtc_probe()
871 ret = devm_request_irq(&pdev->dev, rtc->irq_alarm, rtc_irq, 0, in omap_rtc_probe()
872 dev_name(&rtc->rtc->dev), rtc); in omap_rtc_probe()
878 rtc_pinctrl_desc.name = dev_name(&pdev->dev); in omap_rtc_probe()
880 rtc->pctldev = devm_pinctrl_register(&pdev->dev, &rtc_pinctrl_desc, rtc); in omap_rtc_probe()
881 if (IS_ERR(rtc->pctldev)) { in omap_rtc_probe()
882 dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); in omap_rtc_probe()
883 ret = PTR_ERR(rtc->pctldev); in omap_rtc_probe()
887 ret = devm_rtc_register_device(rtc->rtc); in omap_rtc_probe()
891 devm_rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config); in omap_rtc_probe()
893 if (rtc->is_pmic_controller) { in omap_rtc_probe()
903 clk_disable_unprepare(rtc->clk); in omap_rtc_probe()
904 device_init_wakeup(&pdev->dev, false); in omap_rtc_probe()
905 rtc->type->lock(rtc); in omap_rtc_probe()
906 pm_runtime_put_sync(&pdev->dev); in omap_rtc_probe()
907 pm_runtime_disable(&pdev->dev); in omap_rtc_probe()
923 device_init_wakeup(&pdev->dev, 0); in omap_rtc_remove()
925 if (!IS_ERR(rtc->clk)) in omap_rtc_remove()
926 clk_disable_unprepare(rtc->clk); in omap_rtc_remove()
928 rtc->type->unlock(rtc); in omap_rtc_remove()
932 if (rtc->has_ext_clk) { in omap_rtc_remove()
938 rtc->type->lock(rtc); in omap_rtc_remove()
941 pm_runtime_put_sync(&pdev->dev); in omap_rtc_remove()
942 pm_runtime_disable(&pdev->dev); in omap_rtc_remove()
949 rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_suspend()
951 rtc->type->unlock(rtc); in omap_rtc_suspend()
958 enable_irq_wake(rtc->irq_alarm); in omap_rtc_suspend()
961 rtc->type->lock(rtc); in omap_rtc_suspend()
963 rtc->is_suspending = true; in omap_rtc_suspend()
972 rtc->type->unlock(rtc); in omap_rtc_resume()
974 disable_irq_wake(rtc->irq_alarm); in omap_rtc_resume()
976 rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg); in omap_rtc_resume()
977 rtc->type->lock(rtc); in omap_rtc_resume()
979 rtc->is_suspending = false; in omap_rtc_resume()
988 if (rtc->is_suspending && !rtc->has_ext_clk) in omap_rtc_runtime_suspend()
989 return -EBUSY; in omap_rtc_runtime_suspend()
1008 rtc->type->unlock(rtc); in omap_rtc_shutdown()
1012 rtc->type->lock(rtc); in omap_rtc_shutdown()
1030 MODULE_DESCRIPTION("TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx RTC driver");