1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019 MediaTek Inc.
4 * Author: Ran Bi <ran.bi@mediatek.com>
7 #include <linux/delay.h>
8 #include <linux/init.h>
10 #include <linux/irqdomain.h>
11 #include <linux/module.h>
12 #include <linux/of_address.h>
13 #include <linux/of_irq.h>
14 #include <linux/platform_device.h>
15 #include <linux/rtc.h>
17 #define MT2712_BBPU 0x0000
18 #define MT2712_BBPU_CLRPKY BIT(4)
19 #define MT2712_BBPU_RELOAD BIT(5)
20 #define MT2712_BBPU_CBUSY BIT(6)
21 #define MT2712_BBPU_KEY (0x43 << 8)
23 #define MT2712_IRQ_STA 0x0004
24 #define MT2712_IRQ_STA_AL BIT(0)
25 #define MT2712_IRQ_STA_TC BIT(1)
27 #define MT2712_IRQ_EN 0x0008
28 #define MT2712_IRQ_EN_AL BIT(0)
29 #define MT2712_IRQ_EN_TC BIT(1)
30 #define MT2712_IRQ_EN_ONESHOT BIT(2)
32 #define MT2712_CII_EN 0x000c
34 #define MT2712_AL_MASK 0x0010
35 #define MT2712_AL_MASK_DOW BIT(4)
37 #define MT2712_TC_SEC 0x0014
38 #define MT2712_TC_MIN 0x0018
39 #define MT2712_TC_HOU 0x001c
40 #define MT2712_TC_DOM 0x0020
41 #define MT2712_TC_DOW 0x0024
42 #define MT2712_TC_MTH 0x0028
43 #define MT2712_TC_YEA 0x002c
45 #define MT2712_AL_SEC 0x0030
46 #define MT2712_AL_MIN 0x0034
47 #define MT2712_AL_HOU 0x0038
48 #define MT2712_AL_DOM 0x003c
49 #define MT2712_AL_DOW 0x0040
50 #define MT2712_AL_MTH 0x0044
51 #define MT2712_AL_YEA 0x0048
53 #define MT2712_SEC_MASK 0x003f
54 #define MT2712_MIN_MASK 0x003f
55 #define MT2712_HOU_MASK 0x001f
56 #define MT2712_DOM_MASK 0x001f
57 #define MT2712_DOW_MASK 0x0007
58 #define MT2712_MTH_MASK 0x000f
59 #define MT2712_YEA_MASK 0x007f
61 #define MT2712_POWERKEY1 0x004c
62 #define MT2712_POWERKEY2 0x0050
63 #define MT2712_POWERKEY1_KEY 0xa357
64 #define MT2712_POWERKEY2_KEY 0x67d2
66 #define MT2712_CON0 0x005c
67 #define MT2712_CON1 0x0060
69 #define MT2712_PROT 0x0070
70 #define MT2712_PROT_UNLOCK1 0x9136
71 #define MT2712_PROT_UNLOCK2 0x586a
73 #define MT2712_WRTGR 0x0078
75 #define MT2712_RTC_TIMESTAMP_END_2127 4985971199LL
78 struct rtc_device
*rtc
;
85 static inline u32
mt2712_readl(struct mt2712_rtc
*mt2712_rtc
, u32 reg
)
87 return readl(mt2712_rtc
->base
+ reg
);
90 static inline void mt2712_writel(struct mt2712_rtc
*mt2712_rtc
,
93 writel(val
, mt2712_rtc
->base
+ reg
);
96 static void mt2712_rtc_write_trigger(struct mt2712_rtc
*mt2712_rtc
)
98 unsigned long timeout
= jiffies
+ HZ
/ 10;
100 mt2712_writel(mt2712_rtc
, MT2712_WRTGR
, 1);
102 if (!(mt2712_readl(mt2712_rtc
, MT2712_BBPU
)
103 & MT2712_BBPU_CBUSY
))
106 if (time_after(jiffies
, timeout
)) {
107 dev_err(&mt2712_rtc
->rtc
->dev
,
108 "%s time out!\n", __func__
);
115 static void mt2712_rtc_writeif_unlock(struct mt2712_rtc
*mt2712_rtc
)
117 mt2712_writel(mt2712_rtc
, MT2712_PROT
, MT2712_PROT_UNLOCK1
);
118 mt2712_rtc_write_trigger(mt2712_rtc
);
119 mt2712_writel(mt2712_rtc
, MT2712_PROT
, MT2712_PROT_UNLOCK2
);
120 mt2712_rtc_write_trigger(mt2712_rtc
);
123 static irqreturn_t
rtc_irq_handler_thread(int irq
, void *data
)
125 struct mt2712_rtc
*mt2712_rtc
= data
;
128 /* Clear interrupt */
129 irqsta
= mt2712_readl(mt2712_rtc
, MT2712_IRQ_STA
);
130 if (irqsta
& MT2712_IRQ_STA_AL
) {
131 rtc_update_irq(mt2712_rtc
->rtc
, 1, RTC_IRQF
| RTC_AF
);
138 static void __mt2712_rtc_read_time(struct mt2712_rtc
*mt2712_rtc
,
139 struct rtc_time
*tm
, int *sec
)
141 tm
->tm_sec
= mt2712_readl(mt2712_rtc
, MT2712_TC_SEC
)
143 tm
->tm_min
= mt2712_readl(mt2712_rtc
, MT2712_TC_MIN
)
145 tm
->tm_hour
= mt2712_readl(mt2712_rtc
, MT2712_TC_HOU
)
147 tm
->tm_mday
= mt2712_readl(mt2712_rtc
, MT2712_TC_DOM
)
149 tm
->tm_mon
= (mt2712_readl(mt2712_rtc
, MT2712_TC_MTH
) - 1)
151 tm
->tm_year
= (mt2712_readl(mt2712_rtc
, MT2712_TC_YEA
) + 100)
154 *sec
= mt2712_readl(mt2712_rtc
, MT2712_TC_SEC
) & MT2712_SEC_MASK
;
157 static int mt2712_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
159 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
162 if (mt2712_rtc
->powerlost
)
166 __mt2712_rtc_read_time(mt2712_rtc
, tm
, &sec
);
167 } while (sec
< tm
->tm_sec
); /* SEC has carried */
172 static int mt2712_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
174 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
176 mt2712_writel(mt2712_rtc
, MT2712_TC_SEC
, tm
->tm_sec
& MT2712_SEC_MASK
);
177 mt2712_writel(mt2712_rtc
, MT2712_TC_MIN
, tm
->tm_min
& MT2712_MIN_MASK
);
178 mt2712_writel(mt2712_rtc
, MT2712_TC_HOU
, tm
->tm_hour
& MT2712_HOU_MASK
);
179 mt2712_writel(mt2712_rtc
, MT2712_TC_DOM
, tm
->tm_mday
& MT2712_DOM_MASK
);
180 mt2712_writel(mt2712_rtc
, MT2712_TC_MTH
,
181 (tm
->tm_mon
+ 1) & MT2712_MTH_MASK
);
182 mt2712_writel(mt2712_rtc
, MT2712_TC_YEA
,
183 (tm
->tm_year
- 100) & MT2712_YEA_MASK
);
185 mt2712_rtc_write_trigger(mt2712_rtc
);
187 if (mt2712_rtc
->powerlost
)
188 mt2712_rtc
->powerlost
= false;
193 static int mt2712_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alm
)
195 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
196 struct rtc_time
*tm
= &alm
->time
;
199 irqen
= mt2712_readl(mt2712_rtc
, MT2712_IRQ_EN
);
200 alm
->enabled
= !!(irqen
& MT2712_IRQ_EN_AL
);
202 tm
->tm_sec
= mt2712_readl(mt2712_rtc
, MT2712_AL_SEC
) & MT2712_SEC_MASK
;
203 tm
->tm_min
= mt2712_readl(mt2712_rtc
, MT2712_AL_MIN
) & MT2712_MIN_MASK
;
204 tm
->tm_hour
= mt2712_readl(mt2712_rtc
, MT2712_AL_HOU
) & MT2712_HOU_MASK
;
205 tm
->tm_mday
= mt2712_readl(mt2712_rtc
, MT2712_AL_DOM
) & MT2712_DOM_MASK
;
206 tm
->tm_mon
= (mt2712_readl(mt2712_rtc
, MT2712_AL_MTH
) - 1)
208 tm
->tm_year
= (mt2712_readl(mt2712_rtc
, MT2712_AL_YEA
) + 100)
214 static int mt2712_rtc_alarm_irq_enable(struct device
*dev
,
215 unsigned int enabled
)
217 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
220 irqen
= mt2712_readl(mt2712_rtc
, MT2712_IRQ_EN
);
222 irqen
|= MT2712_IRQ_EN_AL
;
224 irqen
&= ~MT2712_IRQ_EN_AL
;
225 mt2712_writel(mt2712_rtc
, MT2712_IRQ_EN
, irqen
);
226 mt2712_rtc_write_trigger(mt2712_rtc
);
231 static int mt2712_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alm
)
233 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
234 struct rtc_time
*tm
= &alm
->time
;
236 dev_dbg(&mt2712_rtc
->rtc
->dev
, "set al time: %ptR, alm en: %d\n",
239 mt2712_writel(mt2712_rtc
, MT2712_AL_SEC
,
240 (mt2712_readl(mt2712_rtc
, MT2712_AL_SEC
)
241 & ~(MT2712_SEC_MASK
)) | (tm
->tm_sec
& MT2712_SEC_MASK
));
242 mt2712_writel(mt2712_rtc
, MT2712_AL_MIN
,
243 (mt2712_readl(mt2712_rtc
, MT2712_AL_MIN
)
244 & ~(MT2712_MIN_MASK
)) | (tm
->tm_min
& MT2712_MIN_MASK
));
245 mt2712_writel(mt2712_rtc
, MT2712_AL_HOU
,
246 (mt2712_readl(mt2712_rtc
, MT2712_AL_HOU
)
247 & ~(MT2712_HOU_MASK
)) | (tm
->tm_hour
& MT2712_HOU_MASK
));
248 mt2712_writel(mt2712_rtc
, MT2712_AL_DOM
,
249 (mt2712_readl(mt2712_rtc
, MT2712_AL_DOM
)
250 & ~(MT2712_DOM_MASK
)) | (tm
->tm_mday
& MT2712_DOM_MASK
));
251 mt2712_writel(mt2712_rtc
, MT2712_AL_MTH
,
252 (mt2712_readl(mt2712_rtc
, MT2712_AL_MTH
)
253 & ~(MT2712_MTH_MASK
))
254 | ((tm
->tm_mon
+ 1) & MT2712_MTH_MASK
));
255 mt2712_writel(mt2712_rtc
, MT2712_AL_YEA
,
256 (mt2712_readl(mt2712_rtc
, MT2712_AL_YEA
)
257 & ~(MT2712_YEA_MASK
))
258 | ((tm
->tm_year
- 100) & MT2712_YEA_MASK
));
260 /* mask day of week */
261 mt2712_writel(mt2712_rtc
, MT2712_AL_MASK
, MT2712_AL_MASK_DOW
);
262 mt2712_rtc_write_trigger(mt2712_rtc
);
264 mt2712_rtc_alarm_irq_enable(dev
, alm
->enabled
);
269 /* Init RTC register */
270 static void mt2712_rtc_hw_init(struct mt2712_rtc
*mt2712_rtc
)
274 mt2712_writel(mt2712_rtc
, MT2712_BBPU
,
275 MT2712_BBPU_KEY
| MT2712_BBPU_RELOAD
);
277 mt2712_writel(mt2712_rtc
, MT2712_CII_EN
, 0);
278 mt2712_writel(mt2712_rtc
, MT2712_AL_MASK
, 0);
279 /* necessary before set MT2712_POWERKEY */
280 mt2712_writel(mt2712_rtc
, MT2712_CON0
, 0x4848);
281 mt2712_writel(mt2712_rtc
, MT2712_CON1
, 0x0048);
283 mt2712_rtc_write_trigger(mt2712_rtc
);
285 p1
= mt2712_readl(mt2712_rtc
, MT2712_POWERKEY1
);
286 p2
= mt2712_readl(mt2712_rtc
, MT2712_POWERKEY2
);
287 if (p1
!= MT2712_POWERKEY1_KEY
|| p2
!= MT2712_POWERKEY2_KEY
) {
288 mt2712_rtc
->powerlost
= true;
289 dev_dbg(&mt2712_rtc
->rtc
->dev
,
290 "powerkey not set (lost power)\n");
292 mt2712_rtc
->powerlost
= false;
295 /* RTC need POWERKEY1/2 match, then goto normal work mode */
296 mt2712_writel(mt2712_rtc
, MT2712_POWERKEY1
, MT2712_POWERKEY1_KEY
);
297 mt2712_writel(mt2712_rtc
, MT2712_POWERKEY2
, MT2712_POWERKEY2_KEY
);
298 mt2712_rtc_write_trigger(mt2712_rtc
);
300 mt2712_rtc_writeif_unlock(mt2712_rtc
);
303 static const struct rtc_class_ops mt2712_rtc_ops
= {
304 .read_time
= mt2712_rtc_read_time
,
305 .set_time
= mt2712_rtc_set_time
,
306 .read_alarm
= mt2712_rtc_read_alarm
,
307 .set_alarm
= mt2712_rtc_set_alarm
,
308 .alarm_irq_enable
= mt2712_rtc_alarm_irq_enable
,
311 static int mt2712_rtc_probe(struct platform_device
*pdev
)
313 struct mt2712_rtc
*mt2712_rtc
;
316 mt2712_rtc
= devm_kzalloc(&pdev
->dev
,
317 sizeof(struct mt2712_rtc
), GFP_KERNEL
);
321 mt2712_rtc
->base
= devm_platform_ioremap_resource(pdev
, 0);
322 if (IS_ERR(mt2712_rtc
->base
))
323 return PTR_ERR(mt2712_rtc
->base
);
326 mt2712_rtc_hw_init(mt2712_rtc
);
328 mt2712_rtc
->irq
= platform_get_irq(pdev
, 0);
329 if (mt2712_rtc
->irq
< 0)
330 return mt2712_rtc
->irq
;
332 platform_set_drvdata(pdev
, mt2712_rtc
);
334 mt2712_rtc
->rtc
= devm_rtc_allocate_device(&pdev
->dev
);
335 if (IS_ERR(mt2712_rtc
->rtc
))
336 return PTR_ERR(mt2712_rtc
->rtc
);
338 ret
= devm_request_threaded_irq(&pdev
->dev
, mt2712_rtc
->irq
, NULL
,
339 rtc_irq_handler_thread
,
340 IRQF_ONESHOT
| IRQF_TRIGGER_LOW
,
341 dev_name(&mt2712_rtc
->rtc
->dev
),
344 dev_err(&pdev
->dev
, "Failed to request alarm IRQ: %d: %d\n",
345 mt2712_rtc
->irq
, ret
);
349 device_init_wakeup(&pdev
->dev
, true);
351 mt2712_rtc
->rtc
->ops
= &mt2712_rtc_ops
;
352 mt2712_rtc
->rtc
->range_min
= RTC_TIMESTAMP_BEGIN_2000
;
353 mt2712_rtc
->rtc
->range_max
= MT2712_RTC_TIMESTAMP_END_2127
;
355 return rtc_register_device(mt2712_rtc
->rtc
);
358 #ifdef CONFIG_PM_SLEEP
359 static int mt2712_rtc_suspend(struct device
*dev
)
362 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
364 if (device_may_wakeup(dev
)) {
365 wake_status
= enable_irq_wake(mt2712_rtc
->irq
);
367 mt2712_rtc
->irq_wake_enabled
= true;
373 static int mt2712_rtc_resume(struct device
*dev
)
376 struct mt2712_rtc
*mt2712_rtc
= dev_get_drvdata(dev
);
378 if (device_may_wakeup(dev
) && mt2712_rtc
->irq_wake_enabled
) {
379 wake_status
= disable_irq_wake(mt2712_rtc
->irq
);
381 mt2712_rtc
->irq_wake_enabled
= false;
387 static SIMPLE_DEV_PM_OPS(mt2712_pm_ops
, mt2712_rtc_suspend
,
391 static const struct of_device_id mt2712_rtc_of_match
[] = {
392 { .compatible
= "mediatek,mt2712-rtc", },
396 MODULE_DEVICE_TABLE(of
, mt2712_rtc_of_match
);
398 static struct platform_driver mt2712_rtc_driver
= {
400 .name
= "mt2712-rtc",
401 .of_match_table
= mt2712_rtc_of_match
,
402 #ifdef CONFIG_PM_SLEEP
403 .pm
= &mt2712_pm_ops
,
406 .probe
= mt2712_rtc_probe
,
409 module_platform_driver(mt2712_rtc_driver
);
411 MODULE_DESCRIPTION("MediaTek MT2712 SoC based RTC Driver");
412 MODULE_AUTHOR("Ran Bi <ran.bi@mediatek.com>");
413 MODULE_LICENSE("GPL");