1 /*
2  * SPDX-License-Identifier: Apache-2.0
3  *
4  * Copyright (c) 2024 Gergo Vari <work@gergovari.com>
5  */
6 
7 /* TODO: implement user mode? */
8 /* TODO: implement aging offset with calibration */
9 /* TODO: handle century bit, external storage? */
10 
11 #include <zephyr/drivers/mfd/ds3231.h>
12 #include <zephyr/drivers/rtc/rtc_ds3231.h>
13 
14 #include <zephyr/drivers/rtc.h>
15 #include <zephyr/pm/device.h>
16 #include <zephyr/sys/util.h>
17 
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(RTC_DS3231, CONFIG_RTC_LOG_LEVEL);
20 
21 #include <zephyr/drivers/gpio.h>
22 
23 #define DT_DRV_COMPAT maxim_ds3231_rtc
24 
25 #ifdef CONFIG_RTC_ALARM
26 #define ALARM_COUNT 2
27 struct rtc_ds3231_alarm {
28 	rtc_alarm_callback cb;
29 	void *user_data;
30 };
31 #endif
32 
33 #ifdef CONFIG_RTC_UPDATE
34 struct rtc_ds3231_update {
35 	rtc_update_callback cb;
36 	void *user_data;
37 };
38 #endif
39 
40 struct rtc_ds3231_data {
41 #ifdef CONFIG_RTC_ALARM
42 	struct rtc_ds3231_alarm alarms[ALARM_COUNT];
43 #endif
44 #ifdef CONFIG_RTC_UPDATE
45 	struct rtc_ds3231_update update;
46 #endif
47 	struct k_sem lock;
48 	struct gpio_callback isw_cb_data;
49 	struct k_work work;
50 	const struct device *dev;
51 };
52 
53 struct rtc_ds3231_conf {
54 	const struct device *mfd;
55 	struct gpio_dt_spec freq_32k_gpios;
56 	struct gpio_dt_spec isw_gpios;
57 };
58 
rtc_ds3231_modify_register(const struct device * dev,uint8_t reg,uint8_t * buf,const uint8_t bitmask)59 static int rtc_ds3231_modify_register(const struct device *dev, uint8_t reg, uint8_t *buf,
60 				      const uint8_t bitmask)
61 {
62 	int err;
63 	const struct rtc_ds3231_conf *config = dev->config;
64 
65 	if (bitmask != 255) {
66 		uint8_t og_buf = 0;
67 
68 		err = mfd_ds3231_i2c_get_registers(config->mfd, reg, &og_buf, 1);
69 		if (err != 0) {
70 			return err;
71 		}
72 		og_buf &= ~bitmask;
73 		*buf &= bitmask;
74 		og_buf |= *buf;
75 		*buf = og_buf;
76 	}
77 	if (err != 0) {
78 		return err;
79 	}
80 	err = mfd_ds3231_i2c_set_registers(config->mfd, reg, buf, 1);
81 	return err;
82 }
83 
84 enum rtc_ds3231_freq {
85 	FREQ_1000,
86 	FREQ_1024,
87 	FREQ_4096,
88 	FREQ_8192
89 };
90 struct rtc_ds3231_ctrl {
91 	bool en_osc;
92 
93 	bool conv;
94 
95 	enum rtc_ds3231_freq sqw_freq;
96 
97 	bool intctrl;
98 	bool en_alarm_1;
99 	bool en_alarm_2;
100 };
rtc_ds3231_ctrl_to_buf(const struct rtc_ds3231_ctrl * ctrl,uint8_t * buf)101 static int rtc_ds3231_ctrl_to_buf(const struct rtc_ds3231_ctrl *ctrl, uint8_t *buf)
102 {
103 	if (ctrl->en_alarm_1) {
104 		*buf |= DS3231_BITS_CTRL_ALARM_1_EN;
105 	}
106 
107 	if (ctrl->en_alarm_2) {
108 		*buf |= DS3231_BITS_CTRL_ALARM_2_EN;
109 	}
110 
111 	switch (ctrl->sqw_freq) {
112 	case FREQ_1000:
113 		break;
114 	case FREQ_1024:
115 		*buf |= DS3231_BITS_CTRL_RS1;
116 		break;
117 	case FREQ_4096:
118 		*buf |= DS3231_BITS_CTRL_RS2;
119 		break;
120 	case FREQ_8192:
121 		*buf |= DS3231_BITS_CTRL_RS1;
122 		*buf |= DS3231_BITS_CTRL_RS2;
123 		break;
124 	}
125 	if (ctrl->intctrl) {
126 		*buf |= DS3231_BITS_CTRL_INTCTRL;
127 	} else { /* enable sqw */
128 		*buf |= DS3231_BITS_CTRL_BBSQW;
129 	}
130 
131 	if (ctrl->conv) {
132 		*buf |= DS3231_BITS_CTRL_CONV;
133 	}
134 
135 	if (!ctrl->en_osc) { /* active low */
136 		*buf |= DS3231_BITS_CTRL_EOSC;
137 	}
138 	return 0;
139 }
rtc_ds3231_modify_ctrl(const struct device * dev,const struct rtc_ds3231_ctrl * ctrl,const uint8_t bitmask)140 static int rtc_ds3231_modify_ctrl(const struct device *dev, const struct rtc_ds3231_ctrl *ctrl,
141 				  const uint8_t bitmask)
142 {
143 	uint8_t reg = DS3231_REG_CTRL;
144 	uint8_t buf = 0;
145 
146 	int err = rtc_ds3231_ctrl_to_buf(ctrl, &buf);
147 
148 	if (err != 0) {
149 		return err;
150 	}
151 
152 	return rtc_ds3231_modify_register(dev, reg, &buf, bitmask);
153 }
154 
155 struct rtc_ds3231_ctrl_sts {
156 	bool osf;
157 	bool en_32khz;
158 	bool bsy;
159 	bool a1f;
160 	bool a2f;
161 };
rtc_ds3231_ctrl_sts_to_buf(const struct rtc_ds3231_ctrl_sts * ctrl,uint8_t * buf)162 static int rtc_ds3231_ctrl_sts_to_buf(const struct rtc_ds3231_ctrl_sts *ctrl, uint8_t *buf)
163 {
164 	if (ctrl->a1f) {
165 		*buf |= DS3231_BITS_CTRL_STS_ALARM_1_FLAG;
166 	}
167 	if (ctrl->a2f) {
168 		*buf |= DS3231_BITS_CTRL_STS_ALARM_2_FLAG;
169 	}
170 	if (ctrl->osf) {
171 		*buf |= DS3231_BITS_CTRL_STS_OSF;
172 	}
173 	if (ctrl->en_32khz) {
174 		*buf |= DS3231_BITS_CTRL_STS_32_EN;
175 	}
176 	if (ctrl->bsy) {
177 		*buf |= DS3231_BITS_CTRL_STS_BSY;
178 	}
179 	return 0;
180 }
rtc_ds3231_modify_ctrl_sts(const struct device * dev,const struct rtc_ds3231_ctrl_sts * ctrl,const uint8_t bitmask)181 static int rtc_ds3231_modify_ctrl_sts(const struct device *dev,
182 				      const struct rtc_ds3231_ctrl_sts *ctrl, const uint8_t bitmask)
183 {
184 	const uint8_t reg = DS3231_REG_CTRL_STS;
185 	uint8_t buf = 0;
186 
187 	int err = rtc_ds3231_ctrl_sts_to_buf(ctrl, &buf);
188 
189 	if (err != 0) {
190 		return err;
191 	}
192 
193 	return rtc_ds3231_modify_register(dev, reg, &buf, bitmask);
194 }
195 
196 #ifdef CONFIG_RTC_ALARM
rtc_ds3231_get_ctrl_sts(const struct device * dev,uint8_t * buf)197 static int rtc_ds3231_get_ctrl_sts(const struct device *dev, uint8_t *buf)
198 {
199 	const struct rtc_ds3231_conf *config = dev->config;
200 
201 	return mfd_ds3231_i2c_get_registers(config->mfd, DS3231_REG_CTRL_STS, buf, 1);
202 }
203 #endif /* CONFIG_RTC_ALARM */
204 
205 struct rtc_ds3231_settings {
206 	bool osc;                      /* bit 0 */
207 	bool intctrl_or_sqw;           /* bit 1 */
208 	enum rtc_ds3231_freq freq_sqw; /* bit 2 */
209 	bool freq_32khz;               /* bit 3 */
210 	bool alarm_1;                  /* bit 4 */
211 	bool alarm_2;                  /* bit 5 */
212 };
rtc_ds3231_modify_settings(const struct device * dev,struct rtc_ds3231_settings * conf,uint8_t mask)213 static int rtc_ds3231_modify_settings(const struct device *dev, struct rtc_ds3231_settings *conf,
214 				      uint8_t mask)
215 {
216 	struct rtc_ds3231_ctrl ctrl = {};
217 	uint8_t ctrl_mask = 0;
218 
219 	struct rtc_ds3231_ctrl_sts ctrl_sts = {};
220 	uint8_t ctrl_sts_mask = 0;
221 
222 	if (mask & DS3231_BITS_STS_OSC) {
223 		ctrl.en_osc = conf->osc;
224 		ctrl_mask |= DS3231_BITS_CTRL_EOSC;
225 	}
226 	if (mask & DS3231_BITS_STS_INTCTRL) {
227 		ctrl.intctrl = !conf->intctrl_or_sqw;
228 		ctrl_mask |= DS3231_BITS_CTRL_BBSQW;
229 	}
230 	if (mask & DS3231_BITS_STS_SQW) {
231 		ctrl.sqw_freq = conf->freq_sqw;
232 		ctrl_mask |= DS3231_BITS_CTRL_RS1;
233 		ctrl_mask |= DS3231_BITS_CTRL_RS2;
234 	}
235 	if (mask & DS3231_BITS_STS_32KHZ) {
236 		ctrl_sts.en_32khz = conf->freq_32khz;
237 		ctrl_sts_mask |= DS3231_BITS_CTRL_STS_32_EN;
238 	}
239 	if (mask & DS3231_BITS_STS_ALARM_1) {
240 		ctrl.en_alarm_1 = conf->alarm_1;
241 		ctrl_mask |= DS3231_BITS_CTRL_ALARM_1_EN;
242 	}
243 	if (mask & DS3231_BITS_STS_ALARM_2) {
244 		ctrl.en_alarm_2 = conf->alarm_2;
245 		ctrl_mask |= DS3231_BITS_CTRL_ALARM_2_EN;
246 	}
247 
248 	ctrl.conv = false;
249 
250 	int err = rtc_ds3231_modify_ctrl(dev, &ctrl, ctrl_mask);
251 
252 	if (err != 0) {
253 		LOG_ERR("Couldn't set control register.");
254 		return -EIO;
255 	}
256 	err = rtc_ds3231_modify_ctrl_sts(dev, &ctrl_sts, ctrl_sts_mask);
257 	if (err != 0) {
258 		LOG_ERR("Couldn't set status register.");
259 		return -EIO;
260 	}
261 	return 0;
262 }
263 
rtc_ds3231_rtc_time_to_buf(const struct rtc_time * tm,uint8_t * buf)264 static int rtc_ds3231_rtc_time_to_buf(const struct rtc_time *tm, uint8_t *buf)
265 {
266 	buf[0] = bin2bcd(tm->tm_sec) & DS3231_BITS_TIME_SECONDS;
267 	buf[1] = bin2bcd(tm->tm_min) & DS3231_BITS_TIME_MINUTES;
268 	buf[2] = bin2bcd(tm->tm_hour) & DS3231_BITS_TIME_HOURS;
269 	buf[3] = bin2bcd(tm->tm_wday) & DS3231_BITS_TIME_DAY_OF_WEEK;
270 	buf[4] = bin2bcd(tm->tm_mday) & DS3231_BITS_TIME_DATE;
271 	buf[5] = bin2bcd(tm->tm_mon) & DS3231_BITS_TIME_MONTH;
272 
273 	/* here modulo 100 returns the last two digits of the year,
274 	 * as the DS3231 chip can only store year data for 0-99,
275 	 * hitting that ceiling can be detected with the century bit.
276 	 */
277 
278 	/* TODO: figure out a way to store the WHOLE year, not just the last 2 digits. */
279 	buf[6] = bin2bcd((tm->tm_year % 100)) & DS3231_BITS_TIME_YEAR;
280 	return 0;
281 }
rtc_ds3231_set_time(const struct device * dev,const struct rtc_time * tm)282 static int rtc_ds3231_set_time(const struct device *dev, const struct rtc_time *tm)
283 {
284 	const struct rtc_ds3231_conf *config = dev->config;
285 
286 	int buf_size = 7;
287 	uint8_t buf[buf_size];
288 	int err = rtc_ds3231_rtc_time_to_buf(tm, buf);
289 
290 	if (err != 0) {
291 		return err;
292 	}
293 
294 	return mfd_ds3231_i2c_set_registers(config->mfd, DS3231_REG_TIME_SECONDS, buf, buf_size);
295 }
296 
rtc_ds3231_reset_rtc_time(struct rtc_time * tm)297 static void rtc_ds3231_reset_rtc_time(struct rtc_time *tm)
298 {
299 	tm->tm_sec = 0;
300 	tm->tm_min = 0;
301 	tm->tm_hour = 0;
302 	tm->tm_wday = 0;
303 	tm->tm_mday = 0;
304 	tm->tm_mon = 0;
305 	tm->tm_year = 0;
306 	tm->tm_nsec = 0;
307 	tm->tm_isdst = -1;
308 	tm->tm_yday = -1;
309 }
rtc_ds3231_buf_to_rtc_time(const uint8_t * buf,struct rtc_time * timeptr)310 static int rtc_ds3231_buf_to_rtc_time(const uint8_t *buf, struct rtc_time *timeptr)
311 {
312 	rtc_ds3231_reset_rtc_time(timeptr);
313 
314 	timeptr->tm_sec = bcd2bin(buf[0] & DS3231_BITS_TIME_SECONDS);
315 	timeptr->tm_min = bcd2bin(buf[1] & DS3231_BITS_TIME_MINUTES);
316 
317 	int hour = buf[2] & DS3231_BITS_TIME_HOURS;
318 
319 	if (hour & DS3231_BITS_TIME_12HR) {
320 		bool pm = hour & DS3231_BITS_TIME_PM;
321 
322 		hour &= ~DS3231_BITS_TIME_12HR;
323 		hour &= ~DS3231_BITS_TIME_PM;
324 		timeptr->tm_hour = bcd2bin(hour + 12 * pm);
325 	} else {
326 		timeptr->tm_hour = bcd2bin(hour);
327 	}
328 
329 	timeptr->tm_wday = bcd2bin(buf[3] & DS3231_BITS_TIME_DAY_OF_WEEK);
330 	timeptr->tm_mday = bcd2bin(buf[4] & DS3231_BITS_TIME_DATE);
331 	timeptr->tm_mon = bcd2bin(buf[5] & DS3231_BITS_TIME_MONTH);
332 	timeptr->tm_year = bcd2bin(buf[6] & DS3231_BITS_TIME_YEAR);
333 
334 	/* FIXME: we will always just set us to 20xx for year */
335 	timeptr->tm_year = timeptr->tm_year + 100;
336 
337 	return 0;
338 }
rtc_ds3231_get_time(const struct device * dev,struct rtc_time * timeptr)339 static int rtc_ds3231_get_time(const struct device *dev, struct rtc_time *timeptr)
340 {
341 	const struct rtc_ds3231_conf *config = dev->config;
342 
343 	const size_t buf_size = 7;
344 	uint8_t buf[buf_size];
345 	int err = mfd_ds3231_i2c_get_registers(config->mfd, DS3231_REG_TIME_SECONDS, buf, buf_size);
346 
347 	if (err != 0) {
348 		return err;
349 	}
350 
351 	return rtc_ds3231_buf_to_rtc_time(buf, timeptr);
352 }
353 
354 #ifdef CONFIG_RTC_ALARM
355 struct rtc_ds3231_alarm_details {
356 	uint8_t start_reg;
357 	size_t buf_size;
358 };
359 static struct rtc_ds3231_alarm_details alarms[] = {{DS3231_REG_ALARM_1_SECONDS, 4},
360 						   {DS3231_REG_ALARM_2_MINUTES, 3}};
rtc_ds3231_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)361 static int rtc_ds3231_alarm_get_supported_fields(const struct device *dev, uint16_t id,
362 						 uint16_t *mask)
363 {
364 	*mask = RTC_ALARM_TIME_MASK_MONTHDAY | RTC_ALARM_TIME_MASK_WEEKDAY |
365 		RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MINUTE;
366 
367 	switch (id) {
368 	case 0:
369 		*mask |= RTC_ALARM_TIME_MASK_SECOND;
370 		break;
371 	case 1:
372 		break;
373 	default:
374 		return -EINVAL;
375 	}
376 
377 	return 0;
378 }
379 
rtc_ds3231_rtc_time_to_alarm_buf(const struct rtc_time * tm,int id,const uint16_t mask,uint8_t * buf)380 static int rtc_ds3231_rtc_time_to_alarm_buf(const struct rtc_time *tm, int id, const uint16_t mask,
381 					    uint8_t *buf)
382 {
383 	if ((mask & RTC_ALARM_TIME_MASK_WEEKDAY) && (mask & RTC_ALARM_TIME_MASK_MONTHDAY)) {
384 		LOG_ERR("rtc_time_to_alarm_buf: Mask is invalid (%d)!\n", mask);
385 		return -EINVAL;
386 	}
387 	if (id < 0 || id >= ALARM_COUNT) {
388 		LOG_ERR("rtc_time_to_alarm_buf: Alarm ID is out of range (%d)!\n", id);
389 		return -EINVAL;
390 	}
391 
392 	if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
393 		buf[1] = bin2bcd(tm->tm_min) & DS3231_BITS_TIME_MINUTES;
394 	} else {
395 		buf[1] |= DS3231_BITS_ALARM_RATE;
396 	}
397 
398 	if (mask & RTC_ALARM_TIME_MASK_HOUR) {
399 		buf[2] = bin2bcd(tm->tm_hour) & DS3231_BITS_TIME_HOURS;
400 	} else {
401 		buf[2] |= DS3231_BITS_ALARM_RATE;
402 	}
403 
404 	if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) {
405 		buf[3] = bin2bcd(tm->tm_wday) & DS3231_BITS_TIME_DAY_OF_WEEK;
406 		buf[3] |= DS3231_BITS_ALARM_DATE_W_OR_M;
407 	} else if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) {
408 		buf[3] = bin2bcd(tm->tm_mday) & DS3231_BITS_TIME_DATE;
409 	} else {
410 		buf[3] |= DS3231_BITS_ALARM_RATE;
411 	}
412 
413 	switch (id) {
414 	case 0:
415 		if (mask & RTC_ALARM_TIME_MASK_SECOND) {
416 			buf[0] = bin2bcd(tm->tm_sec) & DS3231_BITS_TIME_SECONDS;
417 		} else {
418 			buf[0] |= DS3231_BITS_ALARM_RATE;
419 		}
420 		break;
421 	case 1:
422 		if (mask & RTC_ALARM_TIME_MASK_SECOND) {
423 			return -EINVAL;
424 		}
425 
426 		for (int i = 0; i < 3; i++) {
427 			buf[i] = buf[i + 1];
428 		}
429 
430 		break;
431 	default:
432 		return -EINVAL;
433 	}
434 
435 	return 0;
436 }
437 
rtc_ds3231_modify_alarm_time(const struct device * dev,int id,const struct rtc_time * tm,const uint8_t mask)438 static int rtc_ds3231_modify_alarm_time(const struct device *dev, int id, const struct rtc_time *tm,
439 					const uint8_t mask)
440 {
441 	const struct rtc_ds3231_conf *config = dev->config;
442 
443 	if (id >= ALARM_COUNT) {
444 		return -EINVAL;
445 	}
446 	struct rtc_ds3231_alarm_details details = alarms[id];
447 	uint8_t start_reg = details.start_reg;
448 	size_t buf_size = details.buf_size;
449 
450 	uint8_t buf[buf_size];
451 	int err = rtc_ds3231_rtc_time_to_alarm_buf(tm, id, mask, buf);
452 
453 	if (err != 0) {
454 		return err;
455 	}
456 
457 	return mfd_ds3231_i2c_set_registers(config->mfd, start_reg, buf, buf_size);
458 }
459 
rtc_ds3231_modify_alarm_state(const struct device * dev,uint16_t id,bool state)460 static int rtc_ds3231_modify_alarm_state(const struct device *dev, uint16_t id, bool state)
461 {
462 	struct rtc_ds3231_settings conf;
463 	uint8_t mask = 0;
464 
465 	switch (id) {
466 	case 0:
467 		conf.alarm_1 = state;
468 		mask = DS3231_BITS_STS_ALARM_1;
469 		break;
470 	case 1:
471 		conf.alarm_2 = state;
472 		mask = DS3231_BITS_STS_ALARM_2;
473 		break;
474 	default:
475 		return -EINVAL;
476 	}
477 
478 	return rtc_ds3231_modify_settings(dev, &conf, mask);
479 }
rtc_ds3231_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)480 static int rtc_ds3231_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
481 				     const struct rtc_time *timeptr)
482 {
483 	if (mask == 0) {
484 		return rtc_ds3231_modify_alarm_state(dev, id, false);
485 	}
486 
487 	int err = rtc_ds3231_modify_alarm_state(dev, id, true);
488 
489 	if (err != 0) {
490 		return err;
491 	}
492 
493 	return rtc_ds3231_modify_alarm_time(dev, id, timeptr, mask);
494 }
495 
rtc_ds3231_alarm_buf_to_rtc_time(uint8_t * buf,int id,struct rtc_time * tm,uint16_t * mask)496 static int rtc_ds3231_alarm_buf_to_rtc_time(uint8_t *buf, int id, struct rtc_time *tm,
497 					    uint16_t *mask)
498 {
499 	rtc_ds3231_reset_rtc_time(tm);
500 
501 	if (id < 0 || id > 1) {
502 		return -EINVAL;
503 	} else if (id == 1) {
504 		/* shift to the right to match original func */
505 		for (int i = 3; i > 0; i--) {
506 			buf[i] = buf[i - 1];
507 		}
508 		buf[0] = 0;
509 	}
510 
511 	*mask = 0;
512 	if (!(buf[1] & DS3231_BITS_ALARM_RATE)) {
513 		tm->tm_min = bcd2bin(buf[1] & DS3231_BITS_TIME_MINUTES);
514 		*mask |= RTC_ALARM_TIME_MASK_MINUTE;
515 	}
516 	if (!(buf[2] & DS3231_BITS_ALARM_RATE)) {
517 		tm->tm_hour = bcd2bin(buf[2] & DS3231_BITS_TIME_HOURS);
518 		*mask |= RTC_ALARM_TIME_MASK_HOUR;
519 	}
520 	if (!(buf[3] & DS3231_BITS_ALARM_RATE)) {
521 		if (buf[3] & DS3231_BITS_ALARM_DATE_W_OR_M) {
522 			tm->tm_wday = bcd2bin(buf[3] & DS3231_BITS_TIME_DAY_OF_WEEK);
523 			*mask |= RTC_ALARM_TIME_MASK_WEEKDAY;
524 		} else {
525 			tm->tm_mday = bcd2bin(buf[3] & DS3231_BITS_TIME_DATE);
526 			*mask |= RTC_ALARM_TIME_MASK_MONTHDAY;
527 		}
528 	}
529 	if (!(buf[0] & DS3231_BITS_ALARM_RATE)) {
530 		tm->tm_sec = bcd2bin(buf[0] & DS3231_BITS_TIME_SECONDS);
531 		*mask |= RTC_ALARM_TIME_MASK_SECOND;
532 	}
533 
534 	if ((*mask & RTC_ALARM_TIME_MASK_WEEKDAY) && (*mask & RTC_ALARM_TIME_MASK_MONTHDAY)) {
535 		return -EINVAL;
536 	}
537 
538 	return 0;
539 }
rtc_ds3231_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)540 static int rtc_ds3231_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
541 				     struct rtc_time *timeptr)
542 {
543 	const struct rtc_ds3231_conf *config = dev->config;
544 
545 	if (id >= ALARM_COUNT) {
546 		return -EINVAL;
547 	}
548 	struct rtc_ds3231_alarm_details details = alarms[id];
549 	uint8_t start_reg = details.start_reg;
550 	size_t buf_size = details.buf_size;
551 
552 	uint8_t buf[4];
553 	int err = mfd_ds3231_i2c_get_registers(config->mfd, start_reg, buf, buf_size);
554 
555 	if (err != 0) {
556 		return err;
557 	}
558 
559 	return rtc_ds3231_alarm_buf_to_rtc_time(buf, id, timeptr, mask);
560 }
561 
rtc_ds3231_alarm_is_pending(const struct device * dev,uint16_t id)562 static int rtc_ds3231_alarm_is_pending(const struct device *dev, uint16_t id)
563 {
564 	uint8_t buf;
565 	int err = rtc_ds3231_get_ctrl_sts(dev, &buf);
566 
567 	if (err != 0) {
568 		return err;
569 	}
570 
571 	uint8_t mask = 0;
572 
573 	switch (id) {
574 	case 0:
575 		mask |= DS3231_BITS_CTRL_STS_ALARM_1_FLAG;
576 		break;
577 	case 1:
578 		mask |= DS3231_BITS_CTRL_STS_ALARM_2_FLAG;
579 		break;
580 	default:
581 		return -EINVAL;
582 	}
583 
584 	bool state = buf & mask;
585 
586 	if (state) {
587 		const struct rtc_ds3231_ctrl_sts ctrl = {.a1f = false, .a2f = false};
588 
589 		err = rtc_ds3231_modify_ctrl_sts(dev, &ctrl, mask);
590 		if (err != 0) {
591 			return err;
592 		}
593 	}
594 	return state;
595 }
596 
rtc_ds3231_get_alarm_states(const struct device * dev,bool * states)597 static int rtc_ds3231_get_alarm_states(const struct device *dev, bool *states)
598 {
599 	int err = 0;
600 
601 	for (int i = 0; i < ALARM_COUNT; i++) {
602 		states[i] = rtc_ds3231_alarm_is_pending(dev, i);
603 		if (!(states[i] == 0 || states[i] == 1)) {
604 			states[i] = -EINVAL;
605 			err = -EINVAL;
606 		}
607 	}
608 	return err;
609 }
610 
rtc_ds3231_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback cb,void * user_data)611 static int rtc_ds3231_alarm_set_callback(const struct device *dev, uint16_t id,
612 					 rtc_alarm_callback cb, void *user_data)
613 {
614 	if (id < 0 || id >= ALARM_COUNT) {
615 		return -EINVAL;
616 	}
617 
618 	struct rtc_ds3231_data *data = dev->data;
619 
620 	data->alarms[id] = (struct rtc_ds3231_alarm){cb, user_data};
621 
622 	return 0;
623 }
624 
rtc_ds3231_check_alarms(const struct device * dev)625 static void rtc_ds3231_check_alarms(const struct device *dev)
626 {
627 	struct rtc_ds3231_data *data = dev->data;
628 
629 	bool states[2];
630 
631 	rtc_ds3231_get_alarm_states(dev, states);
632 
633 	for (int i = 0; i < ALARM_COUNT; i++) {
634 		if (states[i]) {
635 			if (data->alarms[i].cb) {
636 				data->alarms[i].cb(dev, i, data->alarms[i].user_data);
637 			}
638 		}
639 	}
640 }
rtc_ds3231_init_alarms(struct rtc_ds3231_data * data)641 static int rtc_ds3231_init_alarms(struct rtc_ds3231_data *data)
642 {
643 	data->alarms[0] = (struct rtc_ds3231_alarm){NULL, NULL};
644 	data->alarms[1] = (struct rtc_ds3231_alarm){NULL, NULL};
645 	return 0;
646 }
647 #endif /* CONFIG_RTC_ALARM */
648 
649 #ifdef CONFIG_RTC_UPDATE
rtc_ds3231_init_update(struct rtc_ds3231_data * data)650 static int rtc_ds3231_init_update(struct rtc_ds3231_data *data)
651 {
652 	data->update = (struct rtc_ds3231_update){NULL, NULL};
653 	return 0;
654 }
rtc_ds3231_update_set_callback(const struct device * dev,rtc_update_callback cb,void * user_data)655 static int rtc_ds3231_update_set_callback(const struct device *dev, rtc_update_callback cb,
656 					  void *user_data)
657 {
658 	struct rtc_ds3231_data *data = dev->data;
659 
660 	data->update = (struct rtc_ds3231_update){cb, user_data};
661 	return 0;
662 }
rtc_ds3231_update_callback(const struct device * dev)663 static void rtc_ds3231_update_callback(const struct device *dev)
664 {
665 	struct rtc_ds3231_data *data = dev->data;
666 
667 	if (data->update.cb) {
668 		data->update.cb(dev, data->update.user_data);
669 	}
670 }
671 #endif /* CONFIG_RTC_UPDATE */
672 
673 #if defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM)
rtc_ds3231_isw_h(struct k_work * work)674 static void rtc_ds3231_isw_h(struct k_work *work)
675 {
676 	struct rtc_ds3231_data *data = CONTAINER_OF(work, struct rtc_ds3231_data, work);
677 	const struct device *dev = data->dev;
678 
679 #ifdef CONFIG_RTC_UPDATE
680 	rtc_ds3231_update_callback(dev);
681 #endif /* CONFIG_RTC_UPDATE */
682 
683 #ifdef CONFIG_RTC_ALARM
684 	rtc_ds3231_check_alarms(dev);
685 #endif /* CONFIG_RTC_ALARM */
686 }
rtc_ds3231_isw_isr(const struct device * port,struct gpio_callback * cb,uint32_t pins)687 static void rtc_ds3231_isw_isr(const struct device *port, struct gpio_callback *cb, uint32_t pins)
688 {
689 	struct rtc_ds3231_data *data = CONTAINER_OF(cb, struct rtc_ds3231_data, isw_cb_data);
690 
691 	k_work_submit(&data->work);
692 }
rtc_ds3231_init_isw(const struct rtc_ds3231_conf * config,struct rtc_ds3231_data * data)693 static int rtc_ds3231_init_isw(const struct rtc_ds3231_conf *config, struct rtc_ds3231_data *data)
694 {
695 	if (!gpio_is_ready_dt(&config->isw_gpios)) {
696 		LOG_ERR("ISW GPIO pin is not ready.");
697 		return -ENODEV;
698 	}
699 
700 	k_work_init(&data->work, rtc_ds3231_isw_h);
701 
702 	int err = gpio_pin_configure_dt(&(config->isw_gpios), GPIO_INPUT);
703 
704 	if (err != 0) {
705 		LOG_ERR("Couldn't configure ISW GPIO pin.");
706 		return err;
707 	}
708 	err = gpio_pin_interrupt_configure_dt(&(config->isw_gpios), GPIO_INT_EDGE_TO_ACTIVE);
709 	if (err != 0) {
710 		LOG_ERR("Couldn't configure ISW interrupt.");
711 		return err;
712 	}
713 
714 	gpio_init_callback(&data->isw_cb_data, rtc_ds3231_isw_isr, BIT((config->isw_gpios).pin));
715 	err = gpio_add_callback((config->isw_gpios).port, &data->isw_cb_data);
716 	if (err != 0) {
717 		LOG_ERR("Couldn't add ISW interrupt callback.");
718 		return err;
719 	}
720 
721 	return 0;
722 }
723 #endif /* defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM) */
724 
725 static DEVICE_API(rtc, driver_api) = {
726 	.set_time = rtc_ds3231_set_time,
727 	.get_time = rtc_ds3231_get_time,
728 
729 #ifdef CONFIG_RTC_ALARM
730 	.alarm_get_supported_fields = rtc_ds3231_alarm_get_supported_fields,
731 	.alarm_set_time = rtc_ds3231_alarm_set_time,
732 	.alarm_get_time = rtc_ds3231_alarm_get_time,
733 	.alarm_is_pending = rtc_ds3231_alarm_is_pending,
734 	.alarm_set_callback = rtc_ds3231_alarm_set_callback,
735 #endif /* CONFIG_RTC_ALARM */
736 
737 #ifdef CONFIG_RTC_UPDATE
738 	.update_set_callback = rtc_ds3231_update_set_callback,
739 #endif /* CONFIG_RTC_UPDATE */
740 
741 #ifdef CONFIG_RTC_CALIBRATION
742 /*.set_calibration = set_calibration,
743  * .get_calibration = get_calibration,
744  */
745 #endif /* CONFIG_RTC_CALIBRATION */
746 };
747 
rtc_ds3231_init_settings(const struct device * dev,const struct rtc_ds3231_conf * config)748 static int rtc_ds3231_init_settings(const struct device *dev, const struct rtc_ds3231_conf *config)
749 {
750 	struct rtc_ds3231_settings conf = {
751 		.osc = true,
752 #ifdef CONFIG_RTC_UPDATE
753 		.intctrl_or_sqw = false,
754 		.freq_sqw = FREQ_1000,
755 #else
756 		.intctrl_or_sqw = true,
757 #endif
758 		.freq_32khz = config->freq_32k_gpios.port,
759 	};
760 	uint8_t mask = 255 & ~DS3231_BITS_STS_ALARM_1 & ~DS3231_BITS_STS_ALARM_2;
761 	int err = rtc_ds3231_modify_settings(dev, &conf, mask);
762 
763 	if (err != 0) {
764 		return err;
765 	}
766 	return 0;
767 }
768 
769 #ifdef CONFIG_PM_DEVICE
rtc_ds3231_pm_action(const struct device * dev,enum pm_device_action action)770 static int rtc_ds3231_pm_action(const struct device *dev, enum pm_device_action action)
771 {
772 	int err = 0;
773 
774 	switch (action) {
775 	case PM_DEVICE_ACTION_SUSPEND: {
776 		struct rtc_ds3231_settings conf = {.osc = true,
777 						   .intctrl_or_sqw = false,
778 						   .freq_sqw = FREQ_1000,
779 						   .freq_32khz = false};
780 		uint8_t mask = 255 & ~DS3231_BITS_STS_ALARM_1 & ~DS3231_BITS_STS_ALARM_2;
781 
782 		err = rtc_ds3231_modify_settings(dev, &conf, mask);
783 		if (err != 0) {
784 			return err;
785 		}
786 		break;
787 	}
788 	case PM_DEVICE_ACTION_RESUME: {
789 		/* TODO: trigger a temp CONV */
790 		const struct rtc_ds3231_conf *config = dev->config;
791 
792 		err = rtc_ds3231_init_settings(dev, config);
793 		if (err != 0) {
794 			return err;
795 		}
796 		break;
797 	}
798 	default:
799 		return -ENOTSUP;
800 	}
801 
802 	return 0;
803 }
804 #endif /* CONFIG_PM_DEVICE */
805 
rtc_ds3231_init(const struct device * dev)806 static int rtc_ds3231_init(const struct device *dev)
807 {
808 	int err = 0;
809 
810 	const struct rtc_ds3231_conf *config = dev->config;
811 	struct rtc_ds3231_data __maybe_unused *data = dev->data;
812 
813 	if (!device_is_ready(config->mfd)) {
814 		return -ENODEV;
815 	}
816 
817 #ifdef CONFIG_RTC_ALARM
818 	err = rtc_ds3231_init_alarms(data);
819 	if (err != 0) {
820 		LOG_ERR("Failed to init alarms.");
821 		return err;
822 	}
823 #endif
824 
825 #ifdef CONFIG_RTC_UPDATE
826 	err = rtc_ds3231_init_update(data);
827 	if (err != 0) {
828 		LOG_ERR("Failed to init update callback.");
829 		return err;
830 	}
831 #endif
832 
833 	err = rtc_ds3231_init_settings(dev, config);
834 	if (err != 0) {
835 		LOG_ERR("Failed to init settings.");
836 		return err;
837 	}
838 
839 #if defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM)
840 	data->dev = dev;
841 	err = rtc_ds3231_init_isw(config, data);
842 	if (err != 0) {
843 		LOG_ERR("Initing ISW interrupt failed!");
844 		return err;
845 	}
846 #endif /* defined(CONFIG_RTC_UPDATE) || defined(CONFIG_RTC_ALARM) */
847 
848 	return 0;
849 }
850 
851 #define RTC_DS3231_DEFINE(inst)                                                                    \
852 	static struct rtc_ds3231_data rtc_ds3231_data_##inst;                                      \
853 	static const struct rtc_ds3231_conf rtc_ds3231_conf_##inst = {                             \
854 		.mfd = DEVICE_DT_GET(DT_INST_PARENT(inst)),                                        \
855 		.isw_gpios = GPIO_DT_SPEC_INST_GET(inst, isw_gpios),                               \
856 		.freq_32k_gpios = GPIO_DT_SPEC_INST_GET_OR(inst, freq_32khz_gpios, {NULL})};       \
857 	PM_DEVICE_DT_INST_DEFINE(inst, rtc_ds3231_pm_action);                                      \
858 	DEVICE_DT_INST_DEFINE(inst, &rtc_ds3231_init, PM_DEVICE_DT_INST_GET(inst),                 \
859 			      &rtc_ds3231_data_##inst, &rtc_ds3231_conf_##inst, POST_KERNEL,       \
860 			      CONFIG_RTC_DS3231_INIT_PRIORITY, &driver_api);
861 
862 DT_INST_FOREACH_STATUS_OKAY(RTC_DS3231_DEFINE)
863