^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) * Copyright (c) 2019 MediaTek Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Ran Bi <ran.bi@mediatek.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define MT2712_BBPU 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define MT2712_BBPU_CLRPKY BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define MT2712_BBPU_RELOAD BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MT2712_BBPU_CBUSY BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define MT2712_BBPU_KEY (0x43 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define MT2712_IRQ_STA 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define MT2712_IRQ_STA_AL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define MT2712_IRQ_STA_TC BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MT2712_IRQ_EN 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MT2712_IRQ_EN_AL BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MT2712_IRQ_EN_TC BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MT2712_IRQ_EN_ONESHOT BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MT2712_CII_EN 0x000c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MT2712_AL_MASK 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MT2712_AL_MASK_DOW BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MT2712_TC_SEC 0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MT2712_TC_MIN 0x0018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MT2712_TC_HOU 0x001c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MT2712_TC_DOM 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MT2712_TC_DOW 0x0024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MT2712_TC_MTH 0x0028
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define MT2712_TC_YEA 0x002c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MT2712_AL_SEC 0x0030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MT2712_AL_MIN 0x0034
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MT2712_AL_HOU 0x0038
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MT2712_AL_DOM 0x003c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MT2712_AL_DOW 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MT2712_AL_MTH 0x0044
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MT2712_AL_YEA 0x0048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MT2712_SEC_MASK 0x003f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MT2712_MIN_MASK 0x003f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MT2712_HOU_MASK 0x001f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define MT2712_DOM_MASK 0x001f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define MT2712_DOW_MASK 0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MT2712_MTH_MASK 0x000f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MT2712_YEA_MASK 0x007f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define MT2712_POWERKEY1 0x004c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define MT2712_POWERKEY2 0x0050
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MT2712_POWERKEY1_KEY 0xa357
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MT2712_POWERKEY2_KEY 0x67d2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MT2712_CON0 0x005c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define MT2712_CON1 0x0060
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MT2712_PROT 0x0070
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MT2712_PROT_UNLOCK1 0x9136
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MT2712_PROT_UNLOCK2 0x586a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MT2712_WRTGR 0x0078
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define MT2712_RTC_TIMESTAMP_END_2127 4985971199LL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct mt2712_rtc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct rtc_device *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u8 irq_wake_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u8 powerlost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static inline u32 mt2712_readl(struct mt2712_rtc *mt2712_rtc, u32 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return readl(mt2712_rtc->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static inline void mt2712_writel(struct mt2712_rtc *mt2712_rtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u32 reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) writel(val, mt2712_rtc->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void mt2712_rtc_write_trigger(struct mt2712_rtc *mt2712_rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned long timeout = jiffies + HZ / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mt2712_writel(mt2712_rtc, MT2712_WRTGR, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!(mt2712_readl(mt2712_rtc, MT2712_BBPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) & MT2712_BBPU_CBUSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (time_after(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) dev_err(&mt2712_rtc->rtc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "%s time out!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void mt2712_rtc_writeif_unlock(struct mt2712_rtc *mt2712_rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static irqreturn_t rtc_irq_handler_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct mt2712_rtc *mt2712_rtc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u16 irqsta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Clear interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) irqsta = mt2712_readl(mt2712_rtc, MT2712_IRQ_STA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (irqsta & MT2712_IRQ_STA_AL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) rtc_update_irq(mt2712_rtc->rtc, 1, RTC_IRQF | RTC_AF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static void __mt2712_rtc_read_time(struct mt2712_rtc *mt2712_rtc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct rtc_time *tm, int *sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) & MT2712_SEC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_TC_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) & MT2712_MIN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_TC_HOU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) & MT2712_HOU_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_TC_DOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) & MT2712_DOM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_TC_MTH) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) & MT2712_MTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_TC_YEA) + 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) & MT2712_YEA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC) & MT2712_SEC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int mt2712_rtc_read_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (mt2712_rtc->powerlost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) __mt2712_rtc_read_time(mt2712_rtc, tm, &sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) } while (sec < tm->tm_sec); /* SEC has carried */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int mt2712_rtc_set_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mt2712_writel(mt2712_rtc, MT2712_TC_SEC, tm->tm_sec & MT2712_SEC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mt2712_writel(mt2712_rtc, MT2712_TC_MIN, tm->tm_min & MT2712_MIN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mt2712_writel(mt2712_rtc, MT2712_TC_HOU, tm->tm_hour & MT2712_HOU_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mt2712_writel(mt2712_rtc, MT2712_TC_DOM, tm->tm_mday & MT2712_DOM_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mt2712_writel(mt2712_rtc, MT2712_TC_MTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) (tm->tm_mon + 1) & MT2712_MTH_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) mt2712_writel(mt2712_rtc, MT2712_TC_YEA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) (tm->tm_year - 100) & MT2712_YEA_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (mt2712_rtc->powerlost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) mt2712_rtc->powerlost = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^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) static int mt2712_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct rtc_time *tm = &alm->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u16 irqen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) alm->enabled = !!(irqen & MT2712_IRQ_EN_AL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_AL_SEC) & MT2712_SEC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_AL_MIN) & MT2712_MIN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_AL_HOU) & MT2712_HOU_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_AL_DOM) & MT2712_DOM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_AL_MTH) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) & MT2712_MTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_AL_YEA) + 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) & MT2712_YEA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return 0;
^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 int mt2712_rtc_alarm_irq_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned int enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u16 irqen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) irqen |= MT2712_IRQ_EN_AL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) irqen &= ~MT2712_IRQ_EN_AL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) mt2712_writel(mt2712_rtc, MT2712_IRQ_EN, irqen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int mt2712_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct rtc_time *tm = &alm->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev_dbg(&mt2712_rtc->rtc->dev, "set al time: %ptR, alm en: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) tm, alm->enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mt2712_writel(mt2712_rtc, MT2712_AL_SEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) (mt2712_readl(mt2712_rtc, MT2712_AL_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) & ~(MT2712_SEC_MASK)) | (tm->tm_sec & MT2712_SEC_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mt2712_writel(mt2712_rtc, MT2712_AL_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) (mt2712_readl(mt2712_rtc, MT2712_AL_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) & ~(MT2712_MIN_MASK)) | (tm->tm_min & MT2712_MIN_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mt2712_writel(mt2712_rtc, MT2712_AL_HOU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (mt2712_readl(mt2712_rtc, MT2712_AL_HOU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) & ~(MT2712_HOU_MASK)) | (tm->tm_hour & MT2712_HOU_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mt2712_writel(mt2712_rtc, MT2712_AL_DOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) (mt2712_readl(mt2712_rtc, MT2712_AL_DOM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) & ~(MT2712_DOM_MASK)) | (tm->tm_mday & MT2712_DOM_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) mt2712_writel(mt2712_rtc, MT2712_AL_MTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) (mt2712_readl(mt2712_rtc, MT2712_AL_MTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) & ~(MT2712_MTH_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) | ((tm->tm_mon + 1) & MT2712_MTH_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mt2712_writel(mt2712_rtc, MT2712_AL_YEA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (mt2712_readl(mt2712_rtc, MT2712_AL_YEA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) & ~(MT2712_YEA_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) | ((tm->tm_year - 100) & MT2712_YEA_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* mask day of week */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) mt2712_writel(mt2712_rtc, MT2712_AL_MASK, MT2712_AL_MASK_DOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) mt2712_rtc_alarm_irq_enable(dev, alm->enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* Init RTC register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static void mt2712_rtc_hw_init(struct mt2712_rtc *mt2712_rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 p1, p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mt2712_writel(mt2712_rtc, MT2712_BBPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) MT2712_BBPU_KEY | MT2712_BBPU_RELOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mt2712_writel(mt2712_rtc, MT2712_CII_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mt2712_writel(mt2712_rtc, MT2712_AL_MASK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* necessary before set MT2712_POWERKEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mt2712_writel(mt2712_rtc, MT2712_CON0, 0x4848);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mt2712_writel(mt2712_rtc, MT2712_CON1, 0x0048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) p1 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) p2 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) mt2712_rtc->powerlost = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_dbg(&mt2712_rtc->rtc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) "powerkey not set (lost power)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mt2712_rtc->powerlost = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* RTC need POWERKEY1/2 match, then goto normal work mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) mt2712_writel(mt2712_rtc, MT2712_POWERKEY1, MT2712_POWERKEY1_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) mt2712_writel(mt2712_rtc, MT2712_POWERKEY2, MT2712_POWERKEY2_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) mt2712_rtc_write_trigger(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mt2712_rtc_writeif_unlock(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static const struct rtc_class_ops mt2712_rtc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .read_time = mt2712_rtc_read_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .set_time = mt2712_rtc_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .read_alarm = mt2712_rtc_read_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .set_alarm = mt2712_rtc_set_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .alarm_irq_enable = mt2712_rtc_alarm_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int mt2712_rtc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct mt2712_rtc *mt2712_rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) mt2712_rtc = devm_kzalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sizeof(struct mt2712_rtc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!mt2712_rtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mt2712_rtc->base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (IS_ERR(mt2712_rtc->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return PTR_ERR(mt2712_rtc->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* rtc hw init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mt2712_rtc_hw_init(mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mt2712_rtc->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (mt2712_rtc->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return mt2712_rtc->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) platform_set_drvdata(pdev, mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mt2712_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (IS_ERR(mt2712_rtc->rtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return PTR_ERR(mt2712_rtc->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = devm_request_threaded_irq(&pdev->dev, mt2712_rtc->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) rtc_irq_handler_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) IRQF_ONESHOT | IRQF_TRIGGER_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) dev_name(&mt2712_rtc->rtc->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mt2712_rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mt2712_rtc->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) device_init_wakeup(&pdev->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) mt2712_rtc->rtc->ops = &mt2712_rtc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return rtc_register_device(mt2712_rtc->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int mt2712_rtc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int wake_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (device_may_wakeup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) wake_status = enable_irq_wake(mt2712_rtc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!wake_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) mt2712_rtc->irq_wake_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int mt2712_rtc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int wake_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (device_may_wakeup(dev) && mt2712_rtc->irq_wake_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) wake_status = disable_irq_wake(mt2712_rtc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!wake_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mt2712_rtc->irq_wake_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static SIMPLE_DEV_PM_OPS(mt2712_pm_ops, mt2712_rtc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mt2712_rtc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static const struct of_device_id mt2712_rtc_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { .compatible = "mediatek,mt2712-rtc", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) MODULE_DEVICE_TABLE(of, mt2712_rtc_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static struct platform_driver mt2712_rtc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .name = "mt2712-rtc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .of_match_table = mt2712_rtc_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .pm = &mt2712_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .probe = mt2712_rtc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) module_platform_driver(mt2712_rtc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) MODULE_DESCRIPTION("MediaTek MT2712 SoC based RTC Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) MODULE_AUTHOR("Ran Bi <ran.bi@mediatek.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) MODULE_LICENSE("GPL");