1 // SPDX-License-Identifier: GPL-2.0+
5 #include <linux/init.h>
7 #include <linux/kernel.h>
8 #include <linux/mfd/syscon.h>
9 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_wakeirq.h>
13 #include <linux/regmap.h>
14 #include <linux/rtc.h>
16 #define BBNSM_CTRL 0x8
17 #define BBNSM_INT_EN 0x10
18 #define BBNSM_EVENTS 0x14
19 #define BBNSM_RTC_LS 0x40
20 #define BBNSM_RTC_MS 0x44
24 #define RTC_EN_MSK 0x3
25 #define TA_EN (0x2 << 2)
26 #define TA_DIS (0x1 << 2)
27 #define TA_EN_MSK (0x3 << 2)
28 #define RTC_INT_EN 0x2
29 #define TA_INT_EN (0x2 << 2)
31 #define BBNSM_EVENT_TA (0x2 << 2)
33 #define CNTR_TO_SECS_SH 15
36 struct rtc_device
*rtc
;
37 struct regmap
*regmap
;
42 static u32
bbnsm_read_counter(struct bbnsm_rtc
*bbnsm
)
45 unsigned int timeout
= 100;
52 regmap_read(bbnsm
->regmap
, BBNSM_RTC_MS
, &rtc_msb
);
54 regmap_read(bbnsm
->regmap
, BBNSM_RTC_LS
, &rtc_lsb
);
55 /* convert to seconds */
56 tmp
= (rtc_msb
<< 17) | (rtc_lsb
>> 15);
57 } while (tmp
!= time
&& --timeout
);
62 static int bbnsm_rtc_read_time(struct device
*dev
, struct rtc_time
*tm
)
64 struct bbnsm_rtc
*bbnsm
= dev_get_drvdata(dev
);
68 regmap_read(bbnsm
->regmap
, BBNSM_CTRL
, &val
);
69 if ((val
& RTC_EN_MSK
) != RTC_EN
)
72 time
= bbnsm_read_counter(bbnsm
);
73 rtc_time64_to_tm(time
, tm
);
78 static int bbnsm_rtc_set_time(struct device
*dev
, struct rtc_time
*tm
)
80 struct bbnsm_rtc
*bbnsm
= dev_get_drvdata(dev
);
81 unsigned long time
= rtc_tm_to_time64(tm
);
83 /* disable the RTC first */
84 regmap_update_bits(bbnsm
->regmap
, BBNSM_CTRL
, RTC_EN_MSK
, 0);
86 /* write the 32bit sec time to 47 bit timer counter, leaving 15 LSBs blank */
87 regmap_write(bbnsm
->regmap
, BBNSM_RTC_LS
, time
<< CNTR_TO_SECS_SH
);
88 regmap_write(bbnsm
->regmap
, BBNSM_RTC_MS
, time
>> (32 - CNTR_TO_SECS_SH
));
90 /* Enable the RTC again */
91 regmap_update_bits(bbnsm
->regmap
, BBNSM_CTRL
, RTC_EN_MSK
, RTC_EN
);
96 static int bbnsm_rtc_read_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
98 struct bbnsm_rtc
*bbnsm
= dev_get_drvdata(dev
);
99 u32 bbnsm_events
, bbnsm_ta
;
101 regmap_read(bbnsm
->regmap
, BBNSM_TA
, &bbnsm_ta
);
102 rtc_time64_to_tm(bbnsm_ta
, &alrm
->time
);
104 regmap_read(bbnsm
->regmap
, BBNSM_EVENTS
, &bbnsm_events
);
105 alrm
->pending
= (bbnsm_events
& BBNSM_EVENT_TA
) ? 1 : 0;
110 static int bbnsm_rtc_alarm_irq_enable(struct device
*dev
, unsigned int enable
)
112 struct bbnsm_rtc
*bbnsm
= dev_get_drvdata(dev
);
114 /* enable the alarm event */
115 regmap_update_bits(bbnsm
->regmap
, BBNSM_CTRL
, TA_EN_MSK
, enable
? TA_EN
: TA_DIS
);
116 /* enable the alarm interrupt */
117 regmap_update_bits(bbnsm
->regmap
, BBNSM_INT_EN
, TA_EN_MSK
, enable
? TA_EN
: TA_DIS
);
122 static int bbnsm_rtc_set_alarm(struct device
*dev
, struct rtc_wkalrm
*alrm
)
124 struct bbnsm_rtc
*bbnsm
= dev_get_drvdata(dev
);
125 unsigned long time
= rtc_tm_to_time64(&alrm
->time
);
127 /* disable the alarm */
128 regmap_update_bits(bbnsm
->regmap
, BBNSM_CTRL
, TA_EN
, TA_EN
);
130 /* write the seconds to TA */
131 regmap_write(bbnsm
->regmap
, BBNSM_TA
, time
);
133 return bbnsm_rtc_alarm_irq_enable(dev
, alrm
->enabled
);
136 static const struct rtc_class_ops bbnsm_rtc_ops
= {
137 .read_time
= bbnsm_rtc_read_time
,
138 .set_time
= bbnsm_rtc_set_time
,
139 .read_alarm
= bbnsm_rtc_read_alarm
,
140 .set_alarm
= bbnsm_rtc_set_alarm
,
141 .alarm_irq_enable
= bbnsm_rtc_alarm_irq_enable
,
144 static irqreturn_t
bbnsm_rtc_irq_handler(int irq
, void *dev_id
)
146 struct device
*dev
= dev_id
;
147 struct bbnsm_rtc
*bbnsm
= dev_get_drvdata(dev
);
150 regmap_read(bbnsm
->regmap
, BBNSM_EVENTS
, &val
);
151 if (val
& BBNSM_EVENT_TA
) {
152 bbnsm_rtc_alarm_irq_enable(dev
, false);
153 /* clear the alarm event */
154 regmap_write_bits(bbnsm
->regmap
, BBNSM_EVENTS
, TA_EN_MSK
, BBNSM_EVENT_TA
);
155 rtc_update_irq(bbnsm
->rtc
, 1, RTC_AF
| RTC_IRQF
);
163 static int bbnsm_rtc_probe(struct platform_device
*pdev
)
165 struct device_node
*np
= pdev
->dev
.of_node
;
166 struct bbnsm_rtc
*bbnsm
;
169 bbnsm
= devm_kzalloc(&pdev
->dev
, sizeof(*bbnsm
), GFP_KERNEL
);
173 bbnsm
->rtc
= devm_rtc_allocate_device(&pdev
->dev
);
174 if (IS_ERR(bbnsm
->rtc
))
175 return PTR_ERR(bbnsm
->rtc
);
177 bbnsm
->regmap
= syscon_node_to_regmap(np
->parent
);
178 if (IS_ERR(bbnsm
->regmap
)) {
179 dev_dbg(&pdev
->dev
, "bbnsm get regmap failed\n");
180 return PTR_ERR(bbnsm
->regmap
);
183 bbnsm
->irq
= platform_get_irq(pdev
, 0);
187 platform_set_drvdata(pdev
, bbnsm
);
189 /* clear all the pending events */
190 regmap_write(bbnsm
->regmap
, BBNSM_EVENTS
, 0x7A);
192 device_init_wakeup(&pdev
->dev
, true);
193 dev_pm_set_wake_irq(&pdev
->dev
, bbnsm
->irq
);
195 ret
= devm_request_irq(&pdev
->dev
, bbnsm
->irq
, bbnsm_rtc_irq_handler
,
196 IRQF_SHARED
, "rtc alarm", &pdev
->dev
);
198 dev_err(&pdev
->dev
, "failed to request irq %d: %d\n",
203 bbnsm
->rtc
->ops
= &bbnsm_rtc_ops
;
204 bbnsm
->rtc
->range_max
= U32_MAX
;
206 ret
= devm_rtc_register_device(bbnsm
->rtc
);
213 dev_pm_clear_wake_irq(&pdev
->dev
);
214 device_init_wakeup(&pdev
->dev
, false);
218 static void bbnsm_rtc_remove(struct platform_device
*pdev
)
220 dev_pm_clear_wake_irq(&pdev
->dev
);
221 device_init_wakeup(&pdev
->dev
, false);
224 static const struct of_device_id bbnsm_dt_ids
[] = {
225 { .compatible
= "nxp,imx93-bbnsm-rtc" },
228 MODULE_DEVICE_TABLE(of
, bbnsm_dt_ids
);
230 static struct platform_driver bbnsm_rtc_driver
= {
233 .of_match_table
= bbnsm_dt_ids
,
235 .probe
= bbnsm_rtc_probe
,
236 .remove
= bbnsm_rtc_remove
,
238 module_platform_driver(bbnsm_rtc_driver
);
240 MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>");
241 MODULE_DESCRIPTION("NXP BBNSM RTC Driver");
242 MODULE_LICENSE("GPL");