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