xref: /linux/drivers/rtc/rtc-atcrtc100.c (revision d324e9a91502184e0ac201293a6ec0fbe10458ed)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Driver for Andes ATCRTC100 real time clock.
4  *
5  * Copyright (C) 2025 Andes Technology Corporation
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/delay.h>
10 #include <linux/interrupt.h>
11 #include <linux/math64.h>
12 #include <linux/module.h>
13 #include <linux/of.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_wakeirq.h>
16 #include <linux/regmap.h>
17 #include <linux/rtc.h>
18 #include <linux/workqueue.h>
19 
20 /* Register Offsets */
21 #define RTC_ID		0x00	/* ID and Revision Register */
22 #define RTC_RSV		0x04	/* Reserved Register */
23 #define RTC_CNT		0x10	/* Counter Register */
24 #define RTC_ALM		0x14	/* Alarm Register */
25 #define RTC_CR		0x18	/* Control Register */
26 #define RTC_STA		0x1C	/* Status Register */
27 #define RTC_TRIM	0x20	/* Digital Trimming Register */
28 
29 /* RTC_ID Register */
30 #define ID_MSK		GENMASK(31, 8)
31 #define ID_ATCRTC100	0x030110
32 
33 /* RTC_CNT and RTC_ALM Register Fields */
34 #define SEC_MSK		GENMASK(5, 0)
35 #define MIN_MSK		GENMASK(11, 6)
36 #define HOUR_MSK	GENMASK(16, 12)
37 #define DAY_MSK		GENMASK(31, 17)
38 #define RTC_SEC_GET(x)	FIELD_GET(SEC_MSK, x)
39 #define RTC_MIN_GET(x)	FIELD_GET(MIN_MSK, x)
40 #define RTC_HOUR_GET(x)	FIELD_GET(HOUR_MSK, x)
41 #define RTC_DAY_GET(x)	FIELD_GET(DAY_MSK, x)
42 #define RTC_SEC_SET(x)	FIELD_PREP(SEC_MSK, x)
43 #define RTC_MIN_SET(x)	FIELD_PREP(MIN_MSK, x)
44 #define RTC_HOUR_SET(x)	FIELD_PREP(HOUR_MSK, x)
45 #define RTC_DAY_SET(x)	FIELD_PREP(DAY_MSK, x)
46 
47 /* RTC_CR Register Bits */
48 #define RTC_EN		BIT(0)	/* RTC Enable */
49 #define ALARM_WAKEUP	BIT(1)	/* Alarm Wakeup Enable */
50 #define ALARM_INT	BIT(2)	/* Alarm Interrupt Enable */
51 #define DAY_INT		BIT(3)	/* Day Interrupt Enable */
52 #define HOUR_INT	BIT(4)	/* Hour Interrupt Enable */
53 #define MIN_INT		BIT(5)	/* Minute Interrupt Enable */
54 #define SEC_INT		BIT(6)	/* Second Periodic Interrupt Enable */
55 #define HSEC_INT	BIT(7)	/* Half-Second Periodic Interrupt Enable */
56 
57 /* RTC_STA Register Bits */
58 #define WRITE_DONE	BIT(16)	/* Register write completion status */
59 
60 /* Time conversion macro */
61 #define ATCRTC_TIME_TO_SEC(D, H, M, S)	\
62 	((time64_t)(D) * 86400 + (H) * 3600 + (M) * 60 + (S))
63 
64 /* Timeout for waiting for the write_done bit */
65 #define ATCRTC_TIMEOUT_US		1000000
66 #define ATCRTC_TIMEOUT_USLEEP_MIN	20
67 #define ATCRTC_TIMEOUT_USLEEP_MAX	30
68 
69 struct atcrtc_dev {
70 	struct rtc_device	*rtc_dev;
71 	struct regmap		*regmap;
72 	struct work_struct	rtc_work;
73 	unsigned int		alarm_irq;
74 	bool			alarm_en;
75 };
76 
77 static const struct regmap_config atcrtc_regmap_config = {
78 	.reg_bits = 32,
79 	.reg_stride = 4,
80 	.val_bits = 32,
81 	.max_register = RTC_TRIM,
82 	.cache_type = REGCACHE_NONE,
83 };
84 
85 /**
86  * atcrtc_check_write_done - Wait for RTC registers to be synchronized.
87  * @rtc: Pointer to the atcrtc_dev structure.
88  *
89  * The WriteDone bit in the status register indicates the synchronization
90  * progress of RTC register updates. This bit is cleared to zero whenever
91  * any RTC control register (Counter, Alarm, Control, etc.) is written.
92  * It returns to one only after all previous updates have been fully
93  * synchronized to the RTC clock domain. This function polls the WriteDone
94  * bit with a timeout to ensure the device is ready for the next operation.
95  *
96  * Return: 0 on success, or -EBUSY on timeout.
97  */
atcrtc_check_write_done(struct atcrtc_dev * rtc)98 static int atcrtc_check_write_done(struct atcrtc_dev *rtc)
99 {
100 	unsigned int val;
101 
102 	/*
103 	 * Using read_poll_timeout is more efficient than a manual loop
104 	 * with usleep_range.
105 	 */
106 	return regmap_read_poll_timeout(rtc->regmap, RTC_STA, val,
107 					val & WRITE_DONE,
108 					ATCRTC_TIMEOUT_USLEEP_MIN,
109 					ATCRTC_TIMEOUT_US);
110 }
111 
atcrtc_alarm_isr(int irq,void * dev)112 static irqreturn_t atcrtc_alarm_isr(int irq, void *dev)
113 {
114 	struct atcrtc_dev *rtc = dev;
115 	unsigned int status;
116 
117 	regmap_read(rtc->regmap, RTC_STA, &status);
118 	if (status & ALARM_INT) {
119 		regmap_write(rtc->regmap, RTC_STA, ALARM_INT);
120 		rtc->alarm_en = false;
121 		schedule_work(&rtc->rtc_work);
122 		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
123 		return IRQ_HANDLED;
124 	}
125 	return IRQ_NONE;
126 }
127 
atcrtc_alarm_irq_enable(struct device * dev,unsigned int enable)128 static int atcrtc_alarm_irq_enable(struct device *dev, unsigned int enable)
129 {
130 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
131 	unsigned int mask;
132 	int ret;
133 
134 	ret = atcrtc_check_write_done(rtc);
135 	if (ret)
136 		return ret;
137 
138 	mask = ALARM_WAKEUP | ALARM_INT;
139 	regmap_update_bits(rtc->regmap, RTC_CR, mask, enable ? mask : 0);
140 
141 	return 0;
142 }
143 
atcrtc_alarm_clear(struct work_struct * work)144 static void atcrtc_alarm_clear(struct work_struct *work)
145 {
146 	struct atcrtc_dev *rtc =
147 		container_of(work, struct atcrtc_dev, rtc_work);
148 	int ret;
149 
150 	rtc_lock(rtc->rtc_dev);
151 
152 	if (!rtc->alarm_en) {
153 		ret = atcrtc_check_write_done(rtc);
154 		if (ret)
155 			dev_info(&rtc->rtc_dev->dev,
156 				 "failed to sync before clearing alarm: %d\n",
157 				 ret);
158 		else
159 			regmap_update_bits(rtc->regmap, RTC_CR,
160 					   ALARM_WAKEUP | ALARM_INT, 0);
161 	}
162 	rtc_unlock(rtc->rtc_dev);
163 }
164 
atcrtc_read_time(struct device * dev,struct rtc_time * tm)165 static int atcrtc_read_time(struct device *dev, struct rtc_time *tm)
166 {
167 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
168 	time64_t time;
169 	unsigned int rtc_cnt;
170 
171 	if (!regmap_test_bits(rtc->regmap, RTC_CR, RTC_EN))
172 		return -EIO;
173 
174 	regmap_read(rtc->regmap, RTC_CNT, &rtc_cnt);
175 	time = ATCRTC_TIME_TO_SEC(RTC_DAY_GET(rtc_cnt),
176 				  RTC_HOUR_GET(rtc_cnt),
177 				  RTC_MIN_GET(rtc_cnt),
178 				  RTC_SEC_GET(rtc_cnt));
179 	rtc_time64_to_tm(time, tm);
180 
181 	return 0;
182 }
183 
atcrtc_set_time(struct device * dev,struct rtc_time * tm)184 static int atcrtc_set_time(struct device *dev, struct rtc_time *tm)
185 {
186 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
187 	time64_t time;
188 	unsigned int counter;
189 	unsigned int day;
190 	int ret;
191 
192 	time = rtc_tm_to_time64(tm);
193 	day = div_s64(time, 86400);
194 	counter = RTC_DAY_SET(day) |
195 		  RTC_HOUR_SET(tm->tm_hour) |
196 		  RTC_MIN_SET(tm->tm_min) |
197 		  RTC_SEC_SET(tm->tm_sec);
198 	ret = atcrtc_check_write_done(rtc);
199 	if (ret)
200 		return ret;
201 	regmap_write(rtc->regmap, RTC_CNT, counter);
202 
203 	ret = atcrtc_check_write_done(rtc);
204 	if (ret)
205 		return ret;
206 	regmap_update_bits(rtc->regmap, RTC_CR, RTC_EN, RTC_EN);
207 
208 	return 0;
209 }
210 
atcrtc_read_alarm(struct device * dev,struct rtc_wkalrm * wkalrm)211 static int atcrtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
212 {
213 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
214 	struct rtc_time *tm = &wkalrm->time;
215 	unsigned int rtc_alarm;
216 
217 	wkalrm->enabled = regmap_test_bits(rtc->regmap, RTC_CR, ALARM_INT);
218 	regmap_read(rtc->regmap, RTC_ALM, &rtc_alarm);
219 	tm->tm_hour = RTC_HOUR_GET(rtc_alarm);
220 	tm->tm_min = RTC_MIN_GET(rtc_alarm);
221 	tm->tm_sec = RTC_SEC_GET(rtc_alarm);
222 
223 	/* The RTC alarm does not support day/month/year fields */
224 	tm->tm_mday = -1;
225 	tm->tm_mon = -1;
226 	tm->tm_year = -1;
227 
228 	return 0;
229 }
230 
atcrtc_set_alarm(struct device * dev,struct rtc_wkalrm * wkalrm)231 static int atcrtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
232 {
233 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
234 	struct rtc_time *tm = &wkalrm->time;
235 	unsigned int rtc_alarm;
236 	int ret;
237 
238 	/* Disable alarm first before setting a new one */
239 	ret = atcrtc_alarm_irq_enable(dev, 0);
240 	if (ret)
241 		return ret;
242 
243 	rtc->alarm_en = false;
244 
245 	rtc_alarm = RTC_SEC_SET(tm->tm_sec) |
246 		    RTC_MIN_SET(tm->tm_min) |
247 		    RTC_HOUR_SET(tm->tm_hour);
248 
249 	ret = atcrtc_check_write_done(rtc);
250 	if (ret)
251 		return ret;
252 
253 	regmap_write(rtc->regmap, RTC_ALM, rtc_alarm);
254 
255 	rtc->alarm_en = wkalrm->enabled;
256 	ret = atcrtc_alarm_irq_enable(dev, wkalrm->enabled);
257 
258 	return ret;
259 }
260 
261 static const struct rtc_class_ops rtc_ops = {
262 	.read_time = atcrtc_read_time,
263 	.set_time = atcrtc_set_time,
264 	.read_alarm = atcrtc_read_alarm,
265 	.set_alarm = atcrtc_set_alarm,
266 	.alarm_irq_enable = atcrtc_alarm_irq_enable,
267 };
268 
atcrtc_probe(struct platform_device * pdev)269 static int atcrtc_probe(struct platform_device *pdev)
270 {
271 	struct atcrtc_dev *atcrtc_dev;
272 	void __iomem *reg_base;
273 	unsigned int rtc_id;
274 	int ret;
275 
276 	atcrtc_dev = devm_kzalloc(&pdev->dev, sizeof(*atcrtc_dev), GFP_KERNEL);
277 	if (!atcrtc_dev)
278 		return -ENOMEM;
279 	platform_set_drvdata(pdev, atcrtc_dev);
280 
281 	reg_base = devm_platform_ioremap_resource(pdev, 0);
282 	if (IS_ERR(reg_base))
283 		return dev_err_probe(&pdev->dev, PTR_ERR(reg_base),
284 				     "Failed to map I/O space\n");
285 
286 	atcrtc_dev->regmap = devm_regmap_init_mmio(&pdev->dev,
287 						   reg_base,
288 						   &atcrtc_regmap_config);
289 	if (IS_ERR(atcrtc_dev->regmap))
290 		return dev_err_probe(&pdev->dev, PTR_ERR(atcrtc_dev->regmap),
291 				     "Failed to initialize regmap\n");
292 
293 	regmap_read(atcrtc_dev->regmap, RTC_ID, &rtc_id);
294 	if (FIELD_GET(ID_MSK, rtc_id) != ID_ATCRTC100)
295 		return dev_err_probe(&pdev->dev, -ENODEV,
296 				     "Failed to initialize RTC: unsupported hardware ID 0x%x\n",
297 				     rtc_id);
298 
299 	ret = platform_get_irq(pdev, 1);
300 	if (ret < 0)
301 		return dev_err_probe(&pdev->dev, ret,
302 				     "Failed to get IRQ for alarm\n");
303 	atcrtc_dev->alarm_irq = ret;
304 
305 	ret = devm_request_irq(&pdev->dev,
306 			       atcrtc_dev->alarm_irq,
307 			       atcrtc_alarm_isr,
308 			       0,
309 			       "atcrtc_alarm",
310 			       atcrtc_dev);
311 	if (ret)
312 		return dev_err_probe(&pdev->dev, ret,
313 				     "Failed to request IRQ %d for alarm\n",
314 				     atcrtc_dev->alarm_irq);
315 
316 	atcrtc_dev->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
317 	if (IS_ERR(atcrtc_dev->rtc_dev))
318 		return dev_err_probe(&pdev->dev, PTR_ERR(atcrtc_dev->rtc_dev),
319 				     "Failed to allocate RTC device\n");
320 
321 	set_bit(RTC_FEATURE_ALARM, atcrtc_dev->rtc_dev->features);
322 	ret = device_init_wakeup(&pdev->dev, true);
323 	if (ret)
324 		return dev_err_probe(&pdev->dev, ret,
325 				     "Failed to initialize wake capability\n");
326 
327 	ret = dev_pm_set_wake_irq(&pdev->dev, atcrtc_dev->alarm_irq);
328 	if (ret) {
329 		device_init_wakeup(&pdev->dev, false);
330 		return dev_err_probe(&pdev->dev, ret,
331 				     "Failed to set wake IRQ\n");
332 	}
333 
334 	atcrtc_dev->rtc_dev->ops = &rtc_ops;
335 
336 	INIT_WORK(&atcrtc_dev->rtc_work, atcrtc_alarm_clear);
337 	return devm_rtc_register_device(atcrtc_dev->rtc_dev);
338 }
339 
atcrtc_resume(struct device * dev)340 static int atcrtc_resume(struct device *dev)
341 {
342 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
343 
344 	if (device_may_wakeup(dev))
345 		disable_irq_wake(rtc->alarm_irq);
346 
347 	return 0;
348 }
349 
atcrtc_suspend(struct device * dev)350 static int atcrtc_suspend(struct device *dev)
351 {
352 	struct atcrtc_dev *rtc = dev_get_drvdata(dev);
353 
354 	if (device_may_wakeup(dev))
355 		enable_irq_wake(rtc->alarm_irq);
356 
357 	return 0;
358 }
359 
360 static DEFINE_SIMPLE_DEV_PM_OPS(atcrtc_pm_ops, atcrtc_suspend, atcrtc_resume);
361 
362 static const struct of_device_id atcrtc_dt_match[] = {
363 	{ .compatible = "andestech,atcrtc100" },
364 	{ },
365 };
366 MODULE_DEVICE_TABLE(of, atcrtc_dt_match);
367 
368 static struct platform_driver atcrtc_platform_driver = {
369 	.driver = {
370 		.name = "atcrtc100",
371 		.of_match_table = atcrtc_dt_match,
372 		.pm = pm_sleep_ptr(&atcrtc_pm_ops),
373 	},
374 	.probe = atcrtc_probe,
375 };
376 
377 module_platform_driver(atcrtc_platform_driver);
378 
379 MODULE_AUTHOR("CL Wang <cl634@andestech.com>");
380 MODULE_DESCRIPTION("Andes ATCRTC100 driver");
381 MODULE_LICENSE("GPL");
382