^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * TI OMAP Real Time Clock interface for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2003 MontaVista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2006 David Brownell (new RTC framework)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2014 Johan Hovold <johan@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * with century-range alarm matching, driven by the 32kHz clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * The main user-visible ways it differs from PC RTCs are by omitting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * "don't care" alarm fields and sub-second periodic IRQs, and having
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * an autoadjust mechanism to calibrate to the true oscillator rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Board-specific wiring options include using split power mode with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * low power modes) for OMAP1 boards (OMAP-L138 has this built into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* RTC registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define OMAP_RTC_SECONDS_REG 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define OMAP_RTC_MINUTES_REG 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define OMAP_RTC_HOURS_REG 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define OMAP_RTC_DAYS_REG 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define OMAP_RTC_MONTHS_REG 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define OMAP_RTC_YEARS_REG 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define OMAP_RTC_WEEKS_REG 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define OMAP_RTC_ALARM_SECONDS_REG 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define OMAP_RTC_ALARM_MINUTES_REG 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define OMAP_RTC_ALARM_HOURS_REG 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define OMAP_RTC_ALARM_DAYS_REG 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define OMAP_RTC_ALARM_MONTHS_REG 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define OMAP_RTC_ALARM_YEARS_REG 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define OMAP_RTC_CTRL_REG 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define OMAP_RTC_STATUS_REG 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define OMAP_RTC_INTERRUPTS_REG 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define OMAP_RTC_COMP_LSB_REG 0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define OMAP_RTC_COMP_MSB_REG 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define OMAP_RTC_OSC_REG 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define OMAP_RTC_SCRATCH0_REG 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define OMAP_RTC_SCRATCH1_REG 0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define OMAP_RTC_SCRATCH2_REG 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define OMAP_RTC_KICK0_REG 0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define OMAP_RTC_KICK1_REG 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define OMAP_RTC_IRQWAKEEN 0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define OMAP_RTC_ALARM2_SECONDS_REG 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define OMAP_RTC_ALARM2_MINUTES_REG 0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define OMAP_RTC_ALARM2_HOURS_REG 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define OMAP_RTC_ALARM2_DAYS_REG 0x8c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define OMAP_RTC_ALARM2_MONTHS_REG 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define OMAP_RTC_ALARM2_YEARS_REG 0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define OMAP_RTC_PMIC_REG 0x98
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* OMAP_RTC_CTRL_REG bit fields: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define OMAP_RTC_CTRL_SPLIT BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define OMAP_RTC_CTRL_DISABLE BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define OMAP_RTC_CTRL_SET_32_COUNTER BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define OMAP_RTC_CTRL_TEST BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define OMAP_RTC_CTRL_MODE_12_24 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define OMAP_RTC_CTRL_AUTO_COMP BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define OMAP_RTC_CTRL_ROUND_30S BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define OMAP_RTC_CTRL_STOP BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* OMAP_RTC_STATUS_REG bit fields: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define OMAP_RTC_STATUS_POWER_UP BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define OMAP_RTC_STATUS_ALARM2 BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define OMAP_RTC_STATUS_ALARM BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define OMAP_RTC_STATUS_1D_EVENT BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define OMAP_RTC_STATUS_1H_EVENT BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define OMAP_RTC_STATUS_1M_EVENT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define OMAP_RTC_STATUS_1S_EVENT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define OMAP_RTC_STATUS_RUN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define OMAP_RTC_STATUS_BUSY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* OMAP_RTC_INTERRUPTS_REG bit fields: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define OMAP_RTC_INTERRUPTS_IT_ALARM2 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define OMAP_RTC_INTERRUPTS_IT_ALARM BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define OMAP_RTC_INTERRUPTS_IT_TIMER BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* OMAP_RTC_OSC_REG bit fields: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define OMAP_RTC_OSC_32KCLK_EN BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define OMAP_RTC_OSC_OSC32K_GZ_DISABLE BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* OMAP_RTC_IRQWAKEEN bit fields: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* OMAP_RTC_PMIC bit fields: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define OMAP_RTC_PMIC_POWER_EN_EN BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define OMAP_RTC_PMIC_EXT_WKUP_EN(x) BIT(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define OMAP_RTC_PMIC_EXT_WKUP_POL(x) BIT(4 + x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* OMAP_RTC_KICKER values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define KICK0_VALUE 0x83e70b13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define KICK1_VALUE 0x95a4f1e0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct omap_rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct omap_rtc_device_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) bool has_32kclk_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bool has_irqwakeen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bool has_pmic_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bool has_power_up_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) void (*lock)(struct omap_rtc *rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) void (*unlock)(struct omap_rtc *rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct omap_rtc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct rtc_device *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int irq_alarm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int irq_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u8 interrupts_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) bool is_pmic_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bool has_ext_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) bool is_suspending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) const struct omap_rtc_device_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct pinctrl_dev *pctldev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static inline u8 rtc_read(struct omap_rtc *rtc, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return readb(rtc->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static inline u32 rtc_readl(struct omap_rtc *rtc, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return readl(rtc->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static inline void rtc_write(struct omap_rtc *rtc, unsigned int reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) writeb(val, rtc->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) writel(val, rtc->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void am3352_rtc_unlock(struct omap_rtc *rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static void am3352_rtc_lock(struct omap_rtc *rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) rtc_writel(rtc, OMAP_RTC_KICK1_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void default_rtc_unlock(struct omap_rtc *rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void default_rtc_lock(struct omap_rtc *rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * We rely on the rtc framework to handle locking (rtc->ops_lock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * so the only other requirement is that register accesses which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * require BUSY to be clear are made with IRQs locally disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void rtc_wait_not_busy(struct omap_rtc *rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* BUSY may stay active for 1/32768 second (~30 usec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) for (count = 0; count < 50; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) status = rtc_read(rtc, OMAP_RTC_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (!(status & OMAP_RTC_STATUS_BUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* now we have ~15 usec to read/write various registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static irqreturn_t rtc_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct omap_rtc *rtc = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) unsigned long events = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u8 irq_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) irq_data = rtc_read(rtc, OMAP_RTC_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* alarm irq? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (irq_data & OMAP_RTC_STATUS_ALARM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) events |= RTC_IRQF | RTC_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* 1/sec periodic/update irq? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) events |= RTC_IRQF | RTC_UF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) rtc_update_irq(rtc->rtc, 1, events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u8 reg, irqwake_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (rtc->type->has_irqwakeen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (rtc->type->has_irqwakeen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* this hardware doesn't support "don't care" alarm fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void tm2bcd(struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) tm->tm_sec = bin2bcd(tm->tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) tm->tm_min = bin2bcd(tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) tm->tm_hour = bin2bcd(tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) tm->tm_mday = bin2bcd(tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) tm->tm_mon = bin2bcd(tm->tm_mon + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) tm->tm_year = bin2bcd(tm->tm_year - 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void bcd2tm(struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) tm->tm_sec = bcd2bin(tm->tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) tm->tm_min = bcd2bin(tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) tm->tm_hour = bcd2bin(tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) tm->tm_mday = bcd2bin(tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* epoch == 1900 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) tm->tm_year = bcd2bin(tm->tm_year) + 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void omap_rtc_read_time_raw(struct omap_rtc *rtc, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) tm->tm_sec = rtc_read(rtc, OMAP_RTC_SECONDS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) tm->tm_min = rtc_read(rtc, OMAP_RTC_MINUTES_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) tm->tm_hour = rtc_read(rtc, OMAP_RTC_HOURS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) tm->tm_mday = rtc_read(rtc, OMAP_RTC_DAYS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) tm->tm_mon = rtc_read(rtc, OMAP_RTC_MONTHS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) tm->tm_year = rtc_read(rtc, OMAP_RTC_YEARS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static int omap_rtc_read_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* we don't report wday/yday/isdst ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) omap_rtc_read_time_raw(rtc, tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) bcd2tm(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tm2bcd(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int omap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u8 interrupts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) alm->time.tm_sec = rtc_read(rtc, OMAP_RTC_ALARM_SECONDS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) alm->time.tm_min = rtc_read(rtc, OMAP_RTC_ALARM_MINUTES_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) alm->time.tm_hour = rtc_read(rtc, OMAP_RTC_ALARM_HOURS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) alm->time.tm_mday = rtc_read(rtc, OMAP_RTC_ALARM_DAYS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) alm->time.tm_mon = rtc_read(rtc, OMAP_RTC_ALARM_MONTHS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) alm->time.tm_year = rtc_read(rtc, OMAP_RTC_ALARM_YEARS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) bcd2tm(&alm->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) interrupts = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) alm->enabled = !!(interrupts & OMAP_RTC_INTERRUPTS_IT_ALARM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u8 reg, irqwake_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) tm2bcd(&alm->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) rtc_write(rtc, OMAP_RTC_ALARM_DAYS_REG, alm->time.tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) rtc_write(rtc, OMAP_RTC_ALARM_HOURS_REG, alm->time.tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) rtc_write(rtc, OMAP_RTC_ALARM_MINUTES_REG, alm->time.tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) rtc_write(rtc, OMAP_RTC_ALARM_SECONDS_REG, alm->time.tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (rtc->type->has_irqwakeen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) irqwake_reg = rtc_read(rtc, OMAP_RTC_IRQWAKEEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (alm->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) reg |= OMAP_RTC_INTERRUPTS_IT_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) irqwake_reg |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (rtc->type->has_irqwakeen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static struct omap_rtc *omap_rtc_power_off_rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * generates pmic_pwr_enable control, which can be used to control an external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * PMIC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) int omap_rtc_power_off_program(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct omap_rtc *rtc = omap_rtc_power_off_rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct rtc_time tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned long now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int seconds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* enable pmic_power_en control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Clear any existing ALARM2 event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* set alarm one second from now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) omap_rtc_read_time_raw(rtc, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) seconds = tm.tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) bcd2tm(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) now = rtc_tm_to_time64(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) rtc_time64_to_tm(now + 1, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) tm2bcd(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) rtc_wait_not_busy(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) rtc_write(rtc, OMAP_RTC_ALARM2_SECONDS_REG, tm.tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) rtc_write(rtc, OMAP_RTC_ALARM2_MINUTES_REG, tm.tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) rtc_write(rtc, OMAP_RTC_ALARM2_HOURS_REG, tm.tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) rtc_write(rtc, OMAP_RTC_ALARM2_DAYS_REG, tm.tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) rtc_write(rtc, OMAP_RTC_ALARM2_MONTHS_REG, tm.tm_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) rtc_write(rtc, OMAP_RTC_ALARM2_YEARS_REG, tm.tm_year);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * enable ALARM2 interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * NOTE: this fails on AM3352 if rtc_write (writeb) is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Retry in case roll over happened before alarm was armed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) val = rtc_read(rtc, OMAP_RTC_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!(val & OMAP_RTC_STATUS_ALARM2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) EXPORT_SYMBOL(omap_rtc_power_off_program);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * omap_rtc_poweroff: RTC-controlled power off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * The RTC can be used to control an external PMIC via the pmic_power_en pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * which can be configured to transition to OFF on ALARM2 events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * The one-second alarm offset is the shortest offset possible as the alarm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * registers must be set before the next timer update and the offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * calculation is too heavy for everything to be done within a single access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * period (~15 us).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * Called with local interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static void omap_rtc_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) omap_rtc_power_off_program(rtc->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Set PMIC power enable and EXT_WAKEUP in case PB power on is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) val = rtc_readl(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) val |= OMAP_RTC_PMIC_POWER_EN_EN | OMAP_RTC_PMIC_EXT_WKUP_POL(0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) OMAP_RTC_PMIC_EXT_WKUP_EN(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) omap_rtc_power_off_rtc->type->lock(omap_rtc_power_off_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * Wait for alarm to trigger (within one second) and external PMIC to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * power off the system. Add a 500 ms margin for external latencies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * (e.g. debounce circuits).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mdelay(1500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static const struct rtc_class_ops omap_rtc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .read_time = omap_rtc_read_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .set_time = omap_rtc_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .read_alarm = omap_rtc_read_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .set_alarm = omap_rtc_set_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .alarm_irq_enable = omap_rtc_alarm_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static const struct omap_rtc_device_type omap_rtc_default_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) .has_power_up_reset = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .lock = default_rtc_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .unlock = default_rtc_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static const struct omap_rtc_device_type omap_rtc_am3352_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .has_32kclk_en = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) .has_irqwakeen = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) .has_pmic_mode = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .lock = am3352_rtc_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .unlock = am3352_rtc_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static const struct omap_rtc_device_type omap_rtc_da830_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .lock = am3352_rtc_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .unlock = am3352_rtc_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static const struct platform_device_id omap_rtc_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .name = "omap_rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .driver_data = (kernel_ulong_t)&omap_rtc_default_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .name = "am3352-rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .driver_data = (kernel_ulong_t)&omap_rtc_am3352_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .name = "da830-rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .driver_data = (kernel_ulong_t)&omap_rtc_da830_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) MODULE_DEVICE_TABLE(platform, omap_rtc_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static const struct of_device_id omap_rtc_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .compatible = "ti,am3352-rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .data = &omap_rtc_am3352_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .compatible = "ti,da830-rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .data = &omap_rtc_da830_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* sentinel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) MODULE_DEVICE_TABLE(of, omap_rtc_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static const struct pinctrl_pin_desc rtc_pins_desc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) PINCTRL_PIN(0, "ext_wakeup0"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) PINCTRL_PIN(1, "ext_wakeup1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) PINCTRL_PIN(2, "ext_wakeup2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) PINCTRL_PIN(3, "ext_wakeup3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int rtc_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static const char *rtc_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) unsigned int group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static const struct pinctrl_ops rtc_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .get_groups_count = rtc_pinctrl_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .get_group_name = rtc_pinctrl_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .dt_free_map = pinconf_generic_dt_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #define PIN_CONFIG_ACTIVE_HIGH (PIN_CONFIG_END + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static const struct pinconf_generic_params rtc_params[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {"ti,active-high", PIN_CONFIG_ACTIVE_HIGH, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static const struct pin_config_item rtc_conf_items[ARRAY_SIZE(rtc_params)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) PCONFDUMP(PIN_CONFIG_ACTIVE_HIGH, "input active high", NULL, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) unsigned int pin, unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) unsigned int param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u16 arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) case PIN_CONFIG_INPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!(val & OMAP_RTC_PMIC_EXT_WKUP_EN(pin)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case PIN_CONFIG_ACTIVE_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (val & OMAP_RTC_PMIC_EXT_WKUP_POL(pin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static int rtc_pinconf_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned int pin, unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned int num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct omap_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) unsigned int param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u32 param_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* active low by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) param = pinconf_to_config_param(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) param_val = pinconf_to_config_argument(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case PIN_CONFIG_INPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (param_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) val |= OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) val &= ~OMAP_RTC_PMIC_EXT_WKUP_EN(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case PIN_CONFIG_ACTIVE_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) val &= ~OMAP_RTC_PMIC_EXT_WKUP_POL(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) dev_err(&rtc->rtc->dev, "Property %u not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) rtc_writel(rtc, OMAP_RTC_PMIC_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static const struct pinconf_ops rtc_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .pin_config_get = rtc_pinconf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .pin_config_set = rtc_pinconf_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct pinctrl_desc rtc_pinctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .pins = rtc_pins_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) .npins = ARRAY_SIZE(rtc_pins_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) .pctlops = &rtc_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) .confops = &rtc_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) .custom_params = rtc_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .num_custom_params = ARRAY_SIZE(rtc_params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .custom_conf_items = rtc_conf_items,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) static int omap_rtc_scratch_read(void *priv, unsigned int offset, void *_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct omap_rtc *rtc = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) u32 *val = _val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) for (i = 0; i < bytes / 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) val[i] = rtc_readl(rtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) OMAP_RTC_SCRATCH0_REG + offset + (i * 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int omap_rtc_scratch_write(void *priv, unsigned int offset, void *_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct omap_rtc *rtc = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u32 *val = _val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) for (i = 0; i < bytes / 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) rtc_writel(rtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) OMAP_RTC_SCRATCH0_REG + offset + (i * 4), val[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static struct nvmem_config omap_rtc_nvmem_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) .name = "omap_rtc_scratch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) .word_size = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .size = OMAP_RTC_KICK0_REG - OMAP_RTC_SCRATCH0_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .reg_read = omap_rtc_scratch_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) .reg_write = omap_rtc_scratch_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static int omap_rtc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct omap_rtc *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) u8 reg, mask, new_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) const struct platform_device_id *id_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) const struct of_device_id *of_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (!rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (of_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) rtc->type = of_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) of_device_is_system_power_controller(pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) id_entry = platform_get_device_id(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) rtc->type = (void *)id_entry->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) rtc->irq_timer = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (rtc->irq_timer <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) rtc->irq_alarm = platform_get_irq(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (rtc->irq_alarm <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) rtc->clk = devm_clk_get(&pdev->dev, "ext-clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!IS_ERR(rtc->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) rtc->has_ext_clk = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) rtc->clk = devm_clk_get(&pdev->dev, "int-clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!IS_ERR(rtc->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) clk_prepare_enable(rtc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) rtc->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (IS_ERR(rtc->base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) clk_disable_unprepare(rtc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return PTR_ERR(rtc->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) platform_set_drvdata(pdev, rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* Enable the clock/module so that we can access the registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pm_runtime_get_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* enable RTC functional clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (rtc->type->has_32kclk_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) rtc_writel(rtc, OMAP_RTC_OSC_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) reg | OMAP_RTC_OSC_32KCLK_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /* clear old status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) reg = rtc_read(rtc, OMAP_RTC_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) mask = OMAP_RTC_STATUS_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (rtc->type->has_pmic_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) mask |= OMAP_RTC_STATUS_ALARM2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (rtc->type->has_power_up_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) mask |= OMAP_RTC_STATUS_POWER_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (reg & OMAP_RTC_STATUS_POWER_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dev_info(&pdev->dev, "RTC power up reset detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (reg & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) rtc_write(rtc, OMAP_RTC_STATUS_REG, reg & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* On boards with split power, RTC_ON_NOFF won't reset the RTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) reg = rtc_read(rtc, OMAP_RTC_CTRL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (reg & OMAP_RTC_CTRL_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dev_info(&pdev->dev, "already running\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* force to 24 hour mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT | OMAP_RTC_CTRL_AUTO_COMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) new_ctrl |= OMAP_RTC_CTRL_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * - Device wake-up capability setting should come through chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * init logic. OMAP1 boards should initialize the "wakeup capable"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * flag in the platform device if the board is wired right for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * being woken up by RTC alarm. For OMAP-L138, this capability
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * is built into the SoC by the "Deep Sleep" capability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * - Boards wired so RTC_ON_nOFF is used as the reset signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * rather than nPWRON_RESET, should forcibly enable split
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * power mode. (Some chip errata report that RTC_CTRL_SPLIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * is write-only, and always reads as zero...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (new_ctrl & OMAP_RTC_CTRL_SPLIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev_info(&pdev->dev, "split power mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (reg != new_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * If we have the external clock then switch to it so we can keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * ticking across suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (rtc->has_ext_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) rtc_writel(rtc, OMAP_RTC_OSC_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) device_init_wakeup(&pdev->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (IS_ERR(rtc->rtc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ret = PTR_ERR(rtc->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) rtc->rtc->ops = &omap_rtc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) rtc->rtc->range_max = RTC_TIMESTAMP_END_2099;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) omap_rtc_nvmem_config.priv = rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* handle periodic and alarm irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) dev_name(&rtc->rtc->dev), rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (rtc->irq_timer != rtc->irq_alarm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) ret = devm_request_irq(&pdev->dev, rtc->irq_alarm, rtc_irq, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) dev_name(&rtc->rtc->dev), rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /* Support ext_wakeup pinconf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) rtc_pinctrl_desc.name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (IS_ERR(rtc->pctldev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ret = PTR_ERR(rtc->pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ret = rtc_register_device(rtc->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto err_deregister_pinctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (rtc->is_pmic_controller) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (!pm_power_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) omap_rtc_power_off_rtc = rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) pm_power_off = omap_rtc_power_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) err_deregister_pinctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) pinctrl_unregister(rtc->pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) clk_disable_unprepare(rtc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) device_init_wakeup(&pdev->dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) pm_runtime_put_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static int omap_rtc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct omap_rtc *rtc = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (pm_power_off == omap_rtc_power_off &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) omap_rtc_power_off_rtc == rtc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) pm_power_off = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) omap_rtc_power_off_rtc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) device_init_wakeup(&pdev->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (!IS_ERR(rtc->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) clk_disable_unprepare(rtc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* leave rtc running, but disable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (rtc->has_ext_clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) reg &= ~OMAP_RTC_OSC_SEL_32KCLK_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) rtc_write(rtc, OMAP_RTC_OSC_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* Disable the clock/module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) pm_runtime_put_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* Remove ext_wakeup pinconf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) pinctrl_unregister(rtc->pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static int __maybe_unused omap_rtc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * FIXME: the RTC alarm is not currently acting as a wakeup event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * source on some platforms, and in fact this enable() call is just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * saving a flag that's never used...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (device_may_wakeup(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) enable_irq_wake(rtc->irq_alarm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) rtc->is_suspending = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static int __maybe_unused omap_rtc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (device_may_wakeup(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) disable_irq_wake(rtc->irq_alarm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) rtc->is_suspending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static int __maybe_unused omap_rtc_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct omap_rtc *rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (rtc->is_suspending && !rtc->has_ext_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static const struct dev_pm_ops omap_rtc_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) SET_SYSTEM_SLEEP_PM_OPS(omap_rtc_suspend, omap_rtc_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) SET_RUNTIME_PM_OPS(omap_rtc_runtime_suspend, NULL, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static void omap_rtc_shutdown(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct omap_rtc *rtc = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * Keep the ALARM interrupt enabled to allow the system to power up on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * alarm events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) rtc->type->unlock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) mask = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) mask &= OMAP_RTC_INTERRUPTS_IT_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) rtc->type->lock(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static struct platform_driver omap_rtc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .probe = omap_rtc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .remove = omap_rtc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .shutdown = omap_rtc_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .name = "omap_rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .pm = &omap_rtc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .of_match_table = omap_rtc_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .id_table = omap_rtc_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) module_platform_driver(omap_rtc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) MODULE_ALIAS("platform:omap_rtc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) MODULE_AUTHOR("George G. Davis (and others)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) MODULE_LICENSE("GPL");