1 /*
2  * Copyright (c) 2023 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT motorola_mc146818
8 
9 #include <errno.h>
10 #include <zephyr/device.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/init.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/spinlock.h>
15 #include <zephyr/devicetree.h>
16 #include <zephyr/drivers/rtc.h>
17 #include <zephyr/sys/sys_io.h>
18 
19 #define RTC_STD_INDEX (DT_INST_REG_ADDR_BY_IDX(0, 0))
20 #define RTC_STD_TARGET (DT_INST_REG_ADDR_BY_IDX(0, 1))
21 
22 /* Time indices in RTC RAM */
23 #define RTC_SEC		0x00
24 #define RTC_MIN		0x02
25 #define RTC_HOUR	0x04
26 
27 /* Day of week index in RTC RAM */
28 #define RTC_WDAY	0x06
29 
30 /* Day of month index in RTC RAM */
31 #define RTC_MDAY	0x07
32 
33 /* Month and year index in RTC RAM */
34 #define RTC_MONTH	0x08
35 #define RTC_YEAR	0x09
36 
37 /* Y2K Bugfix */
38 #define RTC_CENTURY	0x32
39 
40 /* Alarm time indices in RTC RAM */
41 #define RTC_ALARM_SEC	0x01
42 #define RTC_ALARM_MIN	0x03
43 #define RTC_ALARM_HOUR	0x05
44 
45 /* Registers A-D indeces in RTC RAM */
46 #define RTC_REG_A	0x0A
47 #define RTC_REG_B	0x0B
48 #define RTC_REG_C	0x0C
49 #define RTC_REG_D	0x0D
50 
51 #define RTC_UIP		RTC_REG_A
52 #define RTC_DATA	RTC_REG_B
53 #define RTC_FLAG	RTC_REG_C
54 
55 /* Alarm don't case state */
56 #define RTC_ALARM_DC	0xFF
57 
58 /* Update In Progress bit in REG_A */
59 #define RTC_UIP_BIT	BIT(7)
60 
61 /* Update Cycle Inhibit bit in REG_B */
62 #define RTC_UCI_BIT	BIT(7)
63 
64 /* Periodic Interrupt Enable bit in REG_B */
65 #define RTC_PIE_BIT	BIT(6)
66 
67 /* Alarm Interrupt Enable bit in REG_B */
68 #define RTC_AIE_BIT	BIT(5)
69 
70 /* Update-ended Interrupt Enable bit in REG_B */
71 #define RTC_UIE_BIT	BIT(4)
72 
73 /* Data mode bit in  REG_B */
74 #define RTC_DMODE_BIT	BIT(2)
75 
76 /* Hour Format bit in REG_B */
77 #define RTC_HFORMAT_BIT	BIT(1)
78 
79 /* Daylight Savings Enable Format bit in REG_B */
80 #define RTC_DSE_BIT	BIT(0)
81 
82 /* Interrupt Request Flag bit in REG_C */
83 #define RTC_IRF_BIT	BIT(7)
84 
85 /* Periodic Flag bit in REG_C */
86 #define RTC_PF_BIT	BIT(6)
87 
88 /* Alarm Flag bit in REG_C */
89 #define RTC_AF_BIT	BIT(5)
90 
91 /* Update-end Flag bit in REG_C */
92 #define RTC_UEF_BIT	BIT(4)
93 
94 /* VRT bit in REG_D */
95 #define RTC_VRT_BIT	BIT(7)
96 
97 /* Month day Alarm bits in REG_D */
98 #define RTC_MDAY_ALARM	BIT_MASK(5)
99 
100 /* Maximum and Minimum values of time */
101 #define MIN_SEC		0
102 #define MAX_SEC		59
103 #define MIN_MIN		0
104 #define MAX_MIN		59
105 #define MIN_HOUR	0
106 #define MAX_HOUR	23
107 #define MAX_WDAY	7
108 #define MIN_WDAY	1
109 #define MAX_MDAY	31
110 #define MIN_MDAY	1
111 #define MAX_MON		12
112 #define MIN_MON		1
113 #define MIN_YEAR_DIFF	0 /* YEAR - 1900 */
114 #define MAX_YEAR_DIFF	99 /* YEAR - 1999 */
115 
116 /* Input clock frequency mapped to divider bits */
117 #define RTC_IN_CLK_DIV_BITS_4194304 (0)
118 #define RTC_IN_CLK_DIV_BITS_1048576 (1 << 4)
119 #define RTC_IN_CLK_DIV_BITS_32768   (2 << 4)
120 
121 struct rtc_mc146818_data {
122 	struct k_spinlock lock;
123 	bool alarm_pending;
124 	rtc_alarm_callback cb;
125 	void *cb_data;
126 	rtc_update_callback update_cb;
127 	void *update_cb_data;
128 };
129 
rtc_read(int reg)130 static uint8_t rtc_read(int reg)
131 {
132 	uint8_t value;
133 
134 	sys_out8(reg, RTC_STD_INDEX);
135 	value = sys_in8(RTC_STD_TARGET);
136 
137 	return value;
138 }
139 
rtc_write(int reg,uint8_t value)140 static void rtc_write(int reg, uint8_t value)
141 {
142 	sys_out8(reg, RTC_STD_INDEX);
143 	sys_out8(value, RTC_STD_TARGET);
144 }
145 
rtc_mc146818_validate_time(const struct rtc_time * timeptr)146 static bool rtc_mc146818_validate_time(const struct rtc_time *timeptr)
147 {
148 	if (timeptr->tm_sec < MIN_SEC || timeptr->tm_sec > MAX_SEC) {
149 		return false;
150 	}
151 	if (timeptr->tm_min < MIN_MIN || timeptr->tm_min > MAX_MIN) {
152 		return false;
153 	}
154 	if (timeptr->tm_hour < MIN_HOUR || timeptr->tm_hour > MAX_HOUR) {
155 		return false;
156 	}
157 	if (timeptr->tm_wday + 1 < MIN_WDAY || timeptr->tm_wday + 1 > MAX_WDAY) {
158 		return false;
159 	}
160 	if (timeptr->tm_mday < MIN_MDAY || timeptr->tm_mday > MAX_MDAY) {
161 		return false;
162 	}
163 	if (timeptr->tm_mon + 1 < MIN_MON || timeptr->tm_mon + 1 > MAX_MON) {
164 		return false;
165 	}
166 	if (timeptr->tm_year - 70 < MIN_YEAR_DIFF || timeptr->tm_year - 70 > MAX_YEAR_DIFF) {
167 		return false;
168 	}
169 	return true;
170 }
171 
rtc_mc146818_set_time(const struct device * dev,const struct rtc_time * timeptr)172 static int rtc_mc146818_set_time(const struct device *dev, const struct rtc_time *timeptr)
173 {
174 	struct rtc_mc146818_data * const dev_data = dev->data;
175 	uint8_t value;
176 	int year;
177 	int cent;
178 	int ret;
179 
180 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
181 
182 	if (timeptr == NULL) {
183 		ret = -EINVAL;
184 		goto out;
185 	}
186 
187 	/* Check time valid */
188 	if (!rtc_mc146818_validate_time(timeptr)) {
189 		ret = -EINVAL;
190 		goto out;
191 	}
192 
193 	value = rtc_read(RTC_DATA);
194 	rtc_write(RTC_DATA, value | RTC_UCI_BIT);
195 
196 	year = (1900 + timeptr->tm_year) % 100;
197 	cent = (1900 + timeptr->tm_year) / 100;
198 
199 	rtc_write(RTC_SEC, (uint8_t)timeptr->tm_sec);
200 	rtc_write(RTC_MIN, (uint8_t)timeptr->tm_min);
201 	rtc_write(RTC_HOUR, (uint8_t)timeptr->tm_hour);
202 	rtc_write(RTC_WDAY, (uint8_t)timeptr->tm_wday);
203 	rtc_write(RTC_MDAY, (uint8_t)timeptr->tm_mday);
204 	rtc_write(RTC_MONTH, (uint8_t)timeptr->tm_mon + 1);
205 	rtc_write(RTC_YEAR, year);
206 	rtc_write(RTC_CENTURY, cent);
207 
208 	value &= (~RTC_UCI_BIT);
209 	rtc_write(RTC_DATA, value);
210 	ret = 0;
211 out:
212 	k_spin_unlock(&dev_data->lock, key);
213 	return ret;
214 }
215 
rtc_mc146818_get_time(const struct device * dev,struct rtc_time * timeptr)216 static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time  *timeptr)
217 {
218 	struct rtc_mc146818_data * const dev_data = dev->data;
219 	int ret;
220 	uint8_t cent;
221 	uint8_t year;
222 	uint8_t value;
223 
224 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
225 
226 	/* Validate arguments */
227 	if (timeptr == NULL) {
228 		ret = -EINVAL;
229 		goto out;
230 	}
231 
232 	if (!(rtc_read(RTC_REG_D) & RTC_VRT_BIT)) {
233 		ret = -ENODATA;
234 		goto out;
235 	}
236 
237 	while (rtc_read(RTC_UIP) & RTC_UIP_BIT) {
238 		continue;
239 	}
240 
241 	cent = rtc_read(RTC_CENTURY);
242 	year = rtc_read(RTC_YEAR);
243 	timeptr->tm_mon = rtc_read(RTC_MONTH) - 1;
244 	timeptr->tm_mday = rtc_read(RTC_MDAY);
245 	timeptr->tm_wday = rtc_read(RTC_WDAY) - 1;
246 	timeptr->tm_hour = rtc_read(RTC_HOUR);
247 	timeptr->tm_min = rtc_read(RTC_MIN);
248 	timeptr->tm_sec = rtc_read(RTC_SEC);
249 
250 	timeptr->tm_year = 100 * (int)cent + year - 1900;
251 
252 	timeptr->tm_nsec = 0;
253 	timeptr->tm_yday = 0;
254 	value = rtc_read(RTC_DATA);
255 
256 	/* Check time valid */
257 	if (!rtc_mc146818_validate_time(timeptr)) {
258 		ret = -ENODATA;
259 		goto out;
260 	}
261 	ret = 0;
262 out:
263 	k_spin_unlock(&dev_data->lock, key);
264 	return ret;
265 }
266 
267 #if defined(CONFIG_RTC_ALARM)
rtc_mc146818_validate_alarm(const struct rtc_time * timeptr,uint32_t mask)268 static bool rtc_mc146818_validate_alarm(const struct rtc_time *timeptr, uint32_t mask)
269 {
270 	if ((mask & RTC_ALARM_TIME_MASK_SECOND) &&
271 	    (timeptr->tm_sec < MIN_SEC || timeptr->tm_sec > MAX_SEC)) {
272 		return false;
273 	}
274 
275 	if ((mask & RTC_ALARM_TIME_MASK_MINUTE) &&
276 	    (timeptr->tm_min < MIN_MIN || timeptr->tm_min > MAX_MIN)) {
277 		return false;
278 	}
279 
280 	if ((mask & RTC_ALARM_TIME_MASK_HOUR) &&
281 	    (timeptr->tm_hour < MIN_HOUR || timeptr->tm_hour > MAX_HOUR)) {
282 		return false;
283 	}
284 
285 	return true;
286 }
287 
rtc_mc146818_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)288 static int rtc_mc146818_alarm_get_supported_fields(const struct device *dev, uint16_t id,
289 						   uint16_t *mask)
290 {
291 	ARG_UNUSED(dev);
292 
293 	if (id != 0) {
294 		return -EINVAL;
295 	}
296 
297 	(*mask) = (RTC_ALARM_TIME_MASK_SECOND
298 		   | RTC_ALARM_TIME_MASK_MINUTE
299 		   | RTC_ALARM_TIME_MASK_HOUR);
300 
301 	return 0;
302 }
303 
rtc_mc146818_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)304 static int rtc_mc146818_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
305 				       const struct rtc_time *timeptr)
306 {
307 	struct rtc_mc146818_data * const dev_data = dev->data;
308 	int ret;
309 
310 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
311 
312 	if (id != 0) {
313 		ret = -EINVAL;
314 		goto out;
315 	}
316 
317 	if ((mask > 0) && (timeptr == NULL)) {
318 		ret = -EINVAL;
319 		goto out;
320 	}
321 
322 	/* Check time valid */
323 	if (!rtc_mc146818_validate_alarm(timeptr, mask)) {
324 		ret = -EINVAL;
325 		goto out;
326 	}
327 
328 	if (mask & RTC_ALARM_TIME_MASK_SECOND) {
329 		rtc_write(RTC_ALARM_SEC, timeptr->tm_sec);
330 	} else {
331 		rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
332 	}
333 
334 	if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
335 		rtc_write(RTC_ALARM_MIN, timeptr->tm_min);
336 	} else {
337 		rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
338 	}
339 	if (mask & RTC_ALARM_TIME_MASK_HOUR) {
340 		rtc_write(RTC_ALARM_HOUR, timeptr->tm_hour);
341 	} else {
342 		rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
343 	}
344 
345 	rtc_write(RTC_DATA, rtc_read(RTC_DATA) | RTC_AIE_BIT);
346 	ret = 0;
347 out:
348 	k_spin_unlock(&dev_data->lock, key);
349 	return ret;
350 }
351 
rtc_mc146818_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)352 static int rtc_mc146818_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
353 				   struct rtc_time *timeptr)
354 {
355 	struct rtc_mc146818_data * const dev_data = dev->data;
356 	uint8_t value;
357 	int ret;
358 
359 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
360 
361 	if (id != 0) {
362 		ret = -EINVAL;
363 		goto out;
364 	}
365 
366 	if (timeptr == NULL) {
367 		ret = -EINVAL;
368 		goto out;
369 	}
370 
371 	(*mask) = 0;
372 
373 	value = rtc_read(RTC_ALARM_SEC);
374 	if (value <= MAX_SEC) {
375 		timeptr->tm_sec = value;
376 		(*mask) |= RTC_ALARM_TIME_MASK_SECOND;
377 	}
378 
379 	value = rtc_read(RTC_ALARM_MIN);
380 	if (value <= MAX_SEC) {
381 		timeptr->tm_min = value;
382 		(*mask) |= RTC_ALARM_TIME_MASK_MINUTE;
383 	}
384 
385 	value = rtc_read(RTC_ALARM_HOUR);
386 	if (value <= MAX_SEC) {
387 		timeptr->tm_hour = value;
388 		(*mask) |= RTC_ALARM_TIME_MASK_HOUR;
389 	}
390 
391 	ret = 0;
392 out:
393 	k_spin_unlock(&dev_data->lock, key);
394 	return ret;
395 }
396 
rtc_mc146818_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback callback,void * user_data)397 static int rtc_mc146818_alarm_set_callback(const struct device *dev, uint16_t id,
398 				       rtc_alarm_callback callback, void *user_data)
399 {
400 	struct rtc_mc146818_data * const dev_data = dev->data;
401 
402 	if (id != 0) {
403 		return -EINVAL;
404 	}
405 
406 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
407 
408 	dev_data->cb = callback;
409 	dev_data->cb_data = user_data;
410 
411 	if (callback != NULL) {
412 		/* Enable Alarm callback */
413 		rtc_write(RTC_DATA, (rtc_read(RTC_DATA) | RTC_AIE_BIT));
414 	} else {
415 		/* Disable Alarm callback */
416 		rtc_write(RTC_DATA, (rtc_read(RTC_DATA) & (~RTC_AIE_BIT)));
417 	}
418 
419 	k_spin_unlock(&dev_data->lock, key);
420 	return 0;
421 }
422 
rtc_mc146818_alarm_is_pending(const struct device * dev,uint16_t id)423 static int rtc_mc146818_alarm_is_pending(const struct device *dev, uint16_t id)
424 {
425 	struct rtc_mc146818_data * const dev_data = dev->data;
426 	int ret;
427 
428 	if (id != 0) {
429 		return -EINVAL;
430 	}
431 
432 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
433 
434 	ret = dev_data->alarm_pending ? 1 : 0;
435 	dev_data->alarm_pending = false;
436 
437 	k_spin_unlock(&dev_data->lock, key);
438 	return ret;
439 }
440 #endif /* CONFIG_RTC_ALARM */
441 
442 #if defined(CONFIG_RTC_UPDATE)
rtc_mc146818_update_set_callback(const struct device * dev,rtc_update_callback callback,void * user_data)443 static int rtc_mc146818_update_set_callback(const struct device *dev,
444 					rtc_update_callback callback, void *user_data)
445 {
446 	struct rtc_mc146818_data * const dev_data = dev->data;
447 
448 	k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
449 
450 	dev_data->update_cb = callback;
451 	dev_data->update_cb_data = user_data;
452 
453 	if (callback != NULL) {
454 		/* Enable update callback */
455 		rtc_write(RTC_DATA, (rtc_read(RTC_DATA) | RTC_UIE_BIT));
456 	} else {
457 		/* Disable update callback */
458 		rtc_write(RTC_DATA, (rtc_read(RTC_DATA) & (~RTC_UIE_BIT)));
459 	}
460 
461 
462 	k_spin_unlock(&dev_data->lock, key);
463 	return 0;
464 }
465 
466 #endif /* CONFIG_RTC_UPDATE */
467 
rtc_mc146818_isr(const struct device * dev)468 static void rtc_mc146818_isr(const struct device *dev)
469 {
470 	struct rtc_mc146818_data * const dev_data = dev->data;
471 	uint8_t regc;
472 
473 	ARG_UNUSED(dev_data);
474 
475 	/* Read register, which clears the register */
476 	regc = rtc_read(RTC_FLAG);
477 
478 #if defined(CONFIG_RTC_ALARM)
479 	if (regc & RTC_AF_BIT) {
480 		if (dev_data->cb) {
481 			dev_data->cb(dev, 0, dev_data->cb_data);
482 			dev_data->alarm_pending = false;
483 		} else {
484 			dev_data->alarm_pending = true;
485 		}
486 	}
487 #endif
488 
489 #if defined(CONFIG_RTC_UPDATE)
490 	if (regc & RTC_UEF_BIT) {
491 		if (dev_data->update_cb) {
492 			dev_data->update_cb(dev, dev_data->update_cb_data);
493 		}
494 	}
495 #endif
496 }
497 
498 struct rtc_driver_api rtc_mc146818_driver_api = {
499 	.set_time = rtc_mc146818_set_time,
500 	.get_time = rtc_mc146818_get_time,
501 #if defined(CONFIG_RTC_ALARM)
502 	.alarm_get_supported_fields = rtc_mc146818_alarm_get_supported_fields,
503 	.alarm_set_time = rtc_mc146818_alarm_set_time,
504 	.alarm_get_time = rtc_mc146818_alarm_get_time,
505 	.alarm_is_pending = rtc_mc146818_alarm_is_pending,
506 	.alarm_set_callback = rtc_mc146818_alarm_set_callback,
507 #endif /* CONFIG_RTC_ALARM */
508 
509 #if defined(CONFIG_RTC_UPDATE)
510 	.update_set_callback = rtc_mc146818_update_set_callback,
511 #endif /* CONFIG_RTC_UPDATE */
512 };
513 
514 #define RTC_MC146818_INIT_FN_DEFINE(n)						\
515 	static int rtc_mc146818_init##n(const struct device *dev)		\
516 	{									\
517 		rtc_write(RTC_REG_A,						\
518 			  _CONCAT(RTC_IN_CLK_DIV_BITS_,				\
519 				  DT_INST_PROP(n, clock_frequency)));		\
520 										\
521 		rtc_write(RTC_REG_B, RTC_DMODE_BIT | RTC_HFORMAT_BIT);		\
522 										\
523 		IRQ_CONNECT(DT_INST_IRQN(0),					\
524 				DT_INST_IRQ(0, priority),			\
525 				rtc_mc146818_isr, DEVICE_DT_INST_GET(n),	\
526 				DT_INST_IRQ(0, sense));				\
527 										\
528 		irq_enable(DT_INST_IRQN(0));					\
529 										\
530 		return 0;							\
531 	}
532 
533 #define RTC_MC146818_DEV_CFG(inst)						\
534 	struct rtc_mc146818_data rtc_mc146818_data##inst;			\
535 										\
536 	RTC_MC146818_INIT_FN_DEFINE(inst)					\
537 										\
538 	DEVICE_DT_INST_DEFINE(inst, &rtc_mc146818_init##inst, NULL,		\
539 			      &rtc_mc146818_data##inst, NULL, POST_KERNEL,	\
540 			      CONFIG_RTC_INIT_PRIORITY,				\
541 			      &rtc_mc146818_driver_api);			\
542 
543 DT_INST_FOREACH_STATUS_OKAY(RTC_MC146818_DEV_CFG)
544