Lines Matching full:rtc

8  * Copyright (C) 2006 David Brownell (new RTC framework)
27 #include <linux/rtc.h>
28 #include <linux/rtc/rtc-omap.h>
31 * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
39 * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset),
40 * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from
45 /* RTC registers */
137 void (*lock)(struct omap_rtc *rtc);
138 void (*unlock)(struct omap_rtc *rtc);
142 struct rtc_device *rtc; member
155 static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg) in rtc_read() argument
157 return readb(rtc->base + reg); in rtc_read()
160 static inline u32 rtc_readl(struct omap_rtc *rtc, unsigned int reg) in rtc_readl() argument
162 return readl(rtc->base + reg); in rtc_readl()
165 static inline void rtc_write(struct omap_rtc *rtc, unsigned int reg, u8 val) in rtc_write() argument
167 writeb(val, rtc->base + reg); in rtc_write()
170 static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val) in rtc_writel() argument
172 writel(val, rtc->base + reg); in rtc_writel()
175 static void am3352_rtc_unlock(struct omap_rtc *rtc) in am3352_rtc_unlock() argument
177 rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); in am3352_rtc_unlock()
178 rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); in am3352_rtc_unlock()
181 static void am3352_rtc_lock(struct omap_rtc *rtc) in am3352_rtc_lock() argument
183 rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); in am3352_rtc_lock()
184 rtc_writel(rtc, OMAP_RTC_KICK1_REG, 0); in am3352_rtc_lock()
187 static void default_rtc_unlock(struct omap_rtc *rtc) in default_rtc_unlock() argument
191 static void default_rtc_lock(struct omap_rtc *rtc) in default_rtc_lock() argument
196 * We rely on the rtc framework to handle locking (rtc->ops_lock),
200 static void rtc_wait_not_busy(struct omap_rtc *rtc) in rtc_wait_not_busy() argument
207 status = rtc_read(rtc, OMAP_RTC_STATUS_REG); in rtc_wait_not_busy()
217 struct omap_rtc *rtc = dev_id; in rtc_irq() local
221 irq_data = rtc_read(rtc, OMAP_RTC_STATUS_REG); in rtc_irq()
225 rtc->type->unlock(rtc); in rtc_irq()
226 rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); in rtc_irq()
227 rtc->type->lock(rtc); in rtc_irq()
235 rtc_update_irq(rtc->rtc, 1, events); in rtc_irq()
242 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_alarm_irq_enable() local
246 rtc_wait_not_busy(rtc); in omap_rtc_alarm_irq_enable()
247 reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_alarm_irq_enable()
248 if (rtc->type->has_irqwakeen) in omap_rtc_alarm_irq_enable()
249 irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN); in omap_rtc_alarm_irq_enable()
258 rtc_wait_not_busy(rtc); in omap_rtc_alarm_irq_enable()
259 rtc->type->unlock(rtc); in omap_rtc_alarm_irq_enable()
260 rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); in omap_rtc_alarm_irq_enable()
261 if (rtc->type->has_irqwakeen) in omap_rtc_alarm_irq_enable()
262 rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); in omap_rtc_alarm_irq_enable()
263 rtc->type->lock(rtc); in omap_rtc_alarm_irq_enable()
292 static void omap_rtc_read_time_raw(struct omap_rtc *rtc, struct rtc_time *tm) in omap_rtc_read_time_raw() argument
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()
304 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_read_time() local
308 rtc_wait_not_busy(rtc); in omap_rtc_read_time()
309 omap_rtc_read_time_raw(rtc, tm); in omap_rtc_read_time()
319 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_set_time() local
324 rtc_wait_not_busy(rtc); in omap_rtc_set_time()
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()
342 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_read_alarm() local
346 rtc_wait_not_busy(rtc); in omap_rtc_read_alarm()
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()
359 interrupts = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_read_alarm()
367 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_set_alarm() local
373 rtc_wait_not_busy(rtc); 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()
383 reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_set_alarm()
384 if (rtc->type->has_irqwakeen) in omap_rtc_set_alarm()
385 irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN); in omap_rtc_set_alarm()
394 rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); in omap_rtc_set_alarm()
395 if (rtc->type->has_irqwakeen) in omap_rtc_set_alarm()
396 rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); in omap_rtc_set_alarm()
397 rtc->type->lock(rtc); in omap_rtc_set_alarm()
407 * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
413 struct omap_rtc *rtc = omap_rtc_power_off_rtc; in omap_rtc_power_off_program() local
419 rtc->type->unlock(rtc); in omap_rtc_power_off_program()
421 val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); in omap_rtc_power_off_program()
422 rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN); in omap_rtc_power_off_program()
426 rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2); in omap_rtc_power_off_program()
429 omap_rtc_read_time_raw(rtc, &tm); in omap_rtc_power_off_program()
437 rtc_wait_not_busy(rtc); in omap_rtc_power_off_program()
439 rtc_write(rtc, OMAP_RTC_ALARM2_SECONDS_REG, tm.tm_sec); in omap_rtc_power_off_program()
440 rtc_write(rtc, OMAP_RTC_ALARM2_MINUTES_REG, tm.tm_min); in omap_rtc_power_off_program()
441 rtc_write(rtc, OMAP_RTC_ALARM2_HOURS_REG, tm.tm_hour); in omap_rtc_power_off_program()
442 rtc_write(rtc, OMAP_RTC_ALARM2_DAYS_REG, tm.tm_mday); in omap_rtc_power_off_program()
443 rtc_write(rtc, OMAP_RTC_ALARM2_MONTHS_REG, tm.tm_mon); in omap_rtc_power_off_program()
444 rtc_write(rtc, OMAP_RTC_ALARM2_YEARS_REG, tm.tm_year); in omap_rtc_power_off_program()
451 val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_power_off_program()
452 rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, in omap_rtc_power_off_program()
456 if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) { in omap_rtc_power_off_program()
457 val = rtc_read(rtc, OMAP_RTC_STATUS_REG); 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
471 * The RTC can be used to control an external PMIC via the pmic_power_en pin,
484 struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc; in omap_rtc_power_off() local
487 omap_rtc_power_off_program(rtc->dev.parent); in omap_rtc_power_off()
537 .name = "am3352-rtc",
540 .name = "da830-rtc",
550 .compatible = "ti,am3352-rtc",
553 .compatible = "ti,da830-rtc",
601 struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev); in rtc_pinconf_get() local
606 val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); in rtc_pinconf_get()
630 struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev); in rtc_pinconf_set() local
636 val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); in rtc_pinconf_set()
656 dev_err(&rtc->rtc->dev, "Property %u not supported\n", in rtc_pinconf_set()
662 rtc->type->unlock(rtc); in rtc_pinconf_set()
663 rtc_writel(rtc, OMAP_RTC_PMIC_REG, val); in rtc_pinconf_set()
664 rtc->type->lock(rtc); in rtc_pinconf_set()
691 struct omap_rtc *rtc = priv; in omap_rtc_scratch_read() local
696 val[i] = rtc_readl(rtc, in omap_rtc_scratch_read()
705 struct omap_rtc *rtc = priv; in omap_rtc_scratch_write() local
709 rtc->type->unlock(rtc); in omap_rtc_scratch_write()
711 rtc_writel(rtc, in omap_rtc_scratch_write()
713 rtc->type->lock(rtc); in omap_rtc_scratch_write()
729 struct omap_rtc *rtc; in omap_rtc_probe() local
734 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); in omap_rtc_probe()
735 if (!rtc) 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()
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()
770 platform_set_drvdata(pdev, rtc); in omap_rtc_probe()
776 rtc->type->unlock(rtc); in omap_rtc_probe()
783 rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0); in omap_rtc_probe()
785 /* enable RTC functional clock */ in omap_rtc_probe()
786 if (rtc->type->has_32kclk_en) { in omap_rtc_probe()
787 reg = rtc_read(rtc, OMAP_RTC_OSC_REG); in omap_rtc_probe()
788 rtc_write(rtc, OMAP_RTC_OSC_REG, reg | OMAP_RTC_OSC_32KCLK_EN); in omap_rtc_probe()
792 reg = rtc_read(rtc, OMAP_RTC_STATUS_REG); 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()
806 rtc_write(rtc, OMAP_RTC_STATUS_REG, reg & mask); in omap_rtc_probe()
808 /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ in omap_rtc_probe()
809 reg = rtc_read(rtc, OMAP_RTC_CTRL_REG); in omap_rtc_probe()
823 * being woken up by RTC alarm. For OMAP-L138, this capability in omap_rtc_probe()
836 rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); in omap_rtc_probe()
842 if (rtc->has_ext_clk) { in omap_rtc_probe()
843 reg = rtc_read(rtc, OMAP_RTC_OSC_REG); in omap_rtc_probe()
846 rtc_write(rtc, OMAP_RTC_OSC_REG, reg); in omap_rtc_probe()
849 rtc->type->lock(rtc); 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()
862 omap_rtc_nvmem_config.priv = rtc; 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()
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()
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()
895 omap_rtc_power_off_rtc = rtc; in omap_rtc_probe()
903 clk_disable_unprepare(rtc->clk); in omap_rtc_probe()
905 rtc->type->lock(rtc); in omap_rtc_probe()
914 struct omap_rtc *rtc = platform_get_drvdata(pdev); in omap_rtc_remove() local
918 omap_rtc_power_off_rtc == rtc) { 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()
929 /* leave rtc running, but disable irqs */ in omap_rtc_remove()
930 rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); in omap_rtc_remove()
932 if (rtc->has_ext_clk) { in omap_rtc_remove()
933 reg = rtc_read(rtc, OMAP_RTC_OSC_REG); in omap_rtc_remove()
935 rtc_write(rtc, OMAP_RTC_OSC_REG, reg); in omap_rtc_remove()
938 rtc->type->lock(rtc); in omap_rtc_remove()
947 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_suspend() local
949 rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_suspend()
951 rtc->type->unlock(rtc); in omap_rtc_suspend()
953 * FIXME: the RTC alarm is not currently acting as a wakeup event in omap_rtc_suspend()
958 enable_irq_wake(rtc->irq_alarm); in omap_rtc_suspend()
960 rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); in omap_rtc_suspend()
961 rtc->type->lock(rtc); in omap_rtc_suspend()
963 rtc->is_suspending = true; in omap_rtc_suspend()
970 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_resume() local
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()
986 struct omap_rtc *rtc = dev_get_drvdata(dev); in omap_rtc_runtime_suspend() local
988 if (rtc->is_suspending && !rtc->has_ext_clk) in omap_rtc_runtime_suspend()
1001 struct omap_rtc *rtc = platform_get_drvdata(pdev); in omap_rtc_shutdown() local
1008 rtc->type->unlock(rtc); in omap_rtc_shutdown()
1009 mask = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); in omap_rtc_shutdown()
1011 rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, mask); 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");