1 /*
2  * Copyright (c) 2019-2020 Peter Bigot Consulting, LLC
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifdef CONFIG_SOC_POSIX
8 #undef _POSIX_C_SOURCE
9 #define _POSIX_C_SOURCE 200809L /* Required for gmtime_r */
10 #endif
11 
12 #define DT_DRV_COMPAT maxim_ds3231
13 
14 #include <zephyr/device.h>
15 #include <zephyr/drivers/rtc/maxim_ds3231.h>
16 #include <zephyr/drivers/gpio.h>
17 #include <zephyr/drivers/i2c.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/logging/log.h>
20 #include <zephyr/sys/timeutil.h>
21 #include <zephyr/sys/util.h>
22 
23 LOG_MODULE_REGISTER(DS3231, CONFIG_COUNTER_LOG_LEVEL);
24 
25 #define REG_MONCEN_CENTURY 0x80
26 #define REG_HOURS_12H 0x40
27 #define REG_HOURS_PM 0x20
28 #define REG_HOURS_20 0x20
29 #define REG_HOURS_10 0x20
30 #define REG_DAYDATE_DOW 0x40
31 #define REG_ALARM_IGN 0x80
32 
33 /* Return lower 32-bits of time as counter value */
34 #define COUNTER_GET(t) ((uint32_t) (t & UINT32_MAX))
35 
36 enum {
37 	SYNCSM_IDLE,
38 	SYNCSM_PREP_READ,
39 	SYNCSM_FINISH_READ,
40 	SYNCSM_PREP_WRITE,
41 	SYNCSM_FINISH_WRITE,
42 };
43 
44 struct register_map {
45 	uint8_t sec;
46 	uint8_t min;
47 	uint8_t hour;
48 	uint8_t dow;
49 	uint8_t dom;
50 	uint8_t moncen;
51 	uint8_t year;
52 
53 	struct {
54 		uint8_t sec;
55 		uint8_t min;
56 		uint8_t hour;
57 		uint8_t date;
58 	} __packed alarm1;
59 
60 	struct {
61 		uint8_t min;
62 		uint8_t hour;
63 		uint8_t date;
64 	} __packed alarm2;
65 
66 	uint8_t ctrl;
67 	uint8_t ctrl_stat;
68 	uint8_t aging;
69 	int8_t temp_units;
70 	uint8_t temp_frac256;
71 };
72 
73 struct ds3231_config {
74 	/* Common structure first because generic API expects this here. */
75 	struct counter_config_info generic;
76 	struct i2c_dt_spec bus;
77 	struct gpio_dt_spec isw_gpios;
78 };
79 
80 struct ds3231_data {
81 	const struct device *ds3231;
82 	struct register_map registers;
83 
84 	struct k_sem lock;
85 
86 	/* Timer structure used for synchronization */
87 	struct k_timer sync_timer;
88 
89 	/* Work structures for the various cases of ISW interrupt. */
90 	struct k_work alarm_work;
91 	struct k_work sqw_work;
92 	struct k_work sync_work;
93 
94 	/* Forward ISW interrupt to proper worker. */
95 	struct gpio_callback isw_callback;
96 
97 	/* syncclock captured in the last ISW interrupt handler */
98 	uint32_t isw_syncclock;
99 
100 	struct maxim_ds3231_syncpoint syncpoint;
101 	struct maxim_ds3231_syncpoint new_sp;
102 
103 	uint32_t syncclock_base;
104 
105 	/* Pointer to the structure used to notify when a synchronize
106 	 * or set operation completes.  Null when nobody's waiting for
107 	 * such an operation, or when doing a no-notify synchronize
108 	 * through the signal API.
109 	 */
110 	union {
111 		void *ptr;
112 		struct sys_notify *notify;
113 		struct k_poll_signal *signal;
114 	} sync;
115 
116 	/* Handlers and state when using the counter alarm API. */
117 	counter_alarm_callback_t counter_handler[2];
118 	uint32_t counter_ticks[2];
119 
120 	/* Handlers and state for DS3231 alarm API. */
121 	maxim_ds3231_alarm_callback_handler_t alarm_handler[2];
122 	void *alarm_user_data[2];
123 	uint8_t alarm_flags[2];
124 
125 	/* Flags recording requests for ISW monitoring. */
126 	uint8_t isw_mon_req;
127 #define ISW_MON_REQ_Alarm 0x01
128 #define ISW_MON_REQ_Sync 0x02
129 
130 	/* Status of synchronization operations. */
131 	uint8_t sync_state;
132 	bool sync_signal;
133 };
134 
135 /*
136  * Set and clear specific bits in the control register.
137  *
138  * This function assumes the device register cache is valid and will
139  * update the device only if the value changes as a result of applying
140  * the set and clear changes.
141  *
142  * Caches and returns the value with the changes applied.
143  */
sc_ctrl(const struct device * dev,uint8_t set,uint8_t clear)144 static int sc_ctrl(const struct device *dev,
145 		   uint8_t set,
146 		   uint8_t clear)
147 {
148 	struct ds3231_data *data = dev->data;
149 	const struct ds3231_config *cfg = dev->config;
150 	struct register_map *rp = &data->registers;
151 	uint8_t ctrl = (rp->ctrl & ~clear) | set;
152 	int rc = ctrl;
153 
154 	if (rp->ctrl != ctrl) {
155 		uint8_t buf[2] = {
156 			offsetof(struct register_map, ctrl),
157 			ctrl,
158 		};
159 		rc = i2c_write_dt(&cfg->bus, buf, sizeof(buf));
160 		if (rc >= 0) {
161 			rp->ctrl = ctrl;
162 			rc = ctrl;
163 		}
164 	}
165 	return rc;
166 }
167 
maxim_ds3231_ctrl_update(const struct device * dev,uint8_t set_bits,uint8_t clear_bits)168 int maxim_ds3231_ctrl_update(const struct device *dev,
169 			     uint8_t set_bits,
170 			     uint8_t clear_bits)
171 {
172 	struct ds3231_data *data = dev->data;
173 
174 	k_sem_take(&data->lock, K_FOREVER);
175 
176 	int rc = sc_ctrl(dev, set_bits, clear_bits);
177 
178 	k_sem_give(&data->lock);
179 
180 	return rc;
181 }
182 
183 /*
184  * Read the ctrl_stat register then set and clear bits in it.
185  *
186  * OSF, A1F, and A2F will be written with 1s if the corresponding bits
187  * do not appear in either set or clear.  This ensures that if any
188  * flag becomes set between the read and the write that indicator will
189  * not be cleared.
190  *
191  * Returns the value as originally read (disregarding the effect of
192  * clears and sets).
193  */
rsc_stat(const struct device * dev,uint8_t set,uint8_t clear)194 static inline int rsc_stat(const struct device *dev,
195 			   uint8_t set,
196 			   uint8_t clear)
197 {
198 	uint8_t const ign = MAXIM_DS3231_REG_STAT_OSF | MAXIM_DS3231_ALARM1
199 			 | MAXIM_DS3231_ALARM2;
200 	struct ds3231_data *data = dev->data;
201 	const struct ds3231_config *cfg = dev->config;
202 	struct register_map *rp = &data->registers;
203 	uint8_t addr = offsetof(struct register_map, ctrl_stat);
204 	int rc;
205 
206 	rc = i2c_write_read_dt(&cfg->bus, &addr, sizeof(addr), &rp->ctrl_stat,
207 			       sizeof(rp->ctrl_stat));
208 	if (rc >= 0) {
209 		uint8_t stat = rp->ctrl_stat & ~clear;
210 
211 		if (rp->ctrl_stat != stat) {
212 			uint8_t buf[2] = {
213 				addr,
214 				stat | (ign & ~(set | clear)),
215 			};
216 			rc = i2c_write_dt(&cfg->bus, buf, sizeof(buf));
217 		}
218 		if (rc >= 0) {
219 			rc = rp->ctrl_stat;
220 		}
221 	}
222 	return rc;
223 }
224 
maxim_ds3231_stat_update(const struct device * dev,uint8_t set_bits,uint8_t clear_bits)225 int maxim_ds3231_stat_update(const struct device *dev,
226 			     uint8_t set_bits,
227 			     uint8_t clear_bits)
228 {
229 	struct ds3231_data *data = dev->data;
230 
231 	k_sem_take(&data->lock, K_FOREVER);
232 
233 	int rv = rsc_stat(dev, set_bits, clear_bits);
234 
235 	k_sem_give(&data->lock);
236 
237 	return rv;
238 }
239 
240 /*
241  * Look for current users of the interrupt/square-wave signal and
242  * enable monitoring if and only if at least one consumer is active.
243  */
validate_isw_monitoring(const struct device * dev)244 static void validate_isw_monitoring(const struct device *dev)
245 {
246 	struct ds3231_data *data = dev->data;
247 	const struct ds3231_config *cfg = dev->config;
248 	const struct register_map *rp = &data->registers;
249 	uint8_t isw_mon_req = 0;
250 
251 	if (rp->ctrl & (MAXIM_DS3231_ALARM1 | MAXIM_DS3231_ALARM2)) {
252 		isw_mon_req |= ISW_MON_REQ_Alarm;
253 	}
254 	if (data->sync_state != SYNCSM_IDLE) {
255 		isw_mon_req |= ISW_MON_REQ_Sync;
256 	}
257 	LOG_DBG("ISW %p : %d ?= %d", cfg->isw_gpios.port, isw_mon_req,
258 		data->isw_mon_req);
259 	if ((cfg->isw_gpios.port != NULL)
260 	    && (isw_mon_req != data->isw_mon_req)) {
261 		int rc = 0;
262 
263 		/* Disable before reconfigure */
264 		rc = gpio_pin_interrupt_configure_dt(&cfg->isw_gpios,
265 						     GPIO_INT_DISABLE);
266 
267 		if ((rc >= 0)
268 		    && ((isw_mon_req & ISW_MON_REQ_Sync)
269 			!= (data->isw_mon_req & ISW_MON_REQ_Sync))) {
270 			if (isw_mon_req & ISW_MON_REQ_Sync) {
271 				rc = sc_ctrl(dev, 0,
272 					     MAXIM_DS3231_REG_CTRL_INTCN
273 					     | MAXIM_DS3231_REG_CTRL_RS_Msk);
274 			} else {
275 				rc = sc_ctrl(dev, MAXIM_DS3231_REG_CTRL_INTCN, 0);
276 			}
277 		}
278 
279 		data->isw_mon_req = isw_mon_req;
280 
281 		/* Enable if any requests active */
282 		if ((rc >= 0) && (isw_mon_req != 0)) {
283 			rc = gpio_pin_interrupt_configure_dt(
284 				&cfg->isw_gpios, GPIO_INT_EDGE_TO_ACTIVE);
285 		}
286 
287 		LOG_INF("ISW reconfigure to %x: %d", isw_mon_req, rc);
288 	}
289 }
290 
decode_time(struct tm * tp,const uint8_t * rp,bool with_sec)291 static const uint8_t *decode_time(struct tm *tp,
292 			       const uint8_t *rp,
293 			       bool with_sec)
294 {
295 	uint8_t reg;
296 
297 	if (with_sec) {
298 		reg = *rp++;
299 
300 		tp->tm_sec = bcd2bin(reg & 0x7F);
301 	}
302 
303 	reg = *rp++;
304 	tp->tm_min = bcd2bin(reg & 0x7F);
305 
306 	reg = *rp++;
307 	tp->tm_hour = (reg & 0x0F);
308 	if (REG_HOURS_12H & reg) {
309 		/* 12-hour */
310 		if (REG_HOURS_10 & reg) {
311 			tp->tm_hour += 10;
312 		}
313 		if (REG_HOURS_PM & reg) {
314 			tp->tm_hour += 12;
315 		}
316 	} else {
317 		/* 24 hour */
318 		tp->tm_hour += 10 * ((reg >> 4) & 0x03);
319 	}
320 
321 	return rp;
322 }
323 
decode_alarm(const uint8_t * ap,bool with_sec,time_t * tp)324 static uint8_t decode_alarm(const uint8_t *ap,
325 			 bool with_sec,
326 			 time_t *tp)
327 {
328 	struct tm tm = {
329 		/* tm_year zero is 1900 with underflows a 32-bit counter
330 		 * representation.  Use 1978-01, the first January after the
331 		 * POSIX epoch where the first day of the month is the first
332 		 * day of the week.
333 		 */
334 		.tm_year = 78,
335 	};
336 	const uint8_t *dp = decode_time(&tm, ap, with_sec);
337 	uint8_t flags = 0;
338 	uint8_t amf = MAXIM_DS3231_ALARM_FLAGS_IGNDA;
339 
340 	/* Done decoding time, now decode day/date. */
341 	if (REG_DAYDATE_DOW & *dp) {
342 		flags |= MAXIM_DS3231_ALARM_FLAGS_DOW;
343 
344 		/* Because tm.tm_wday does not contribute to the UNIX
345 		 * time that the civil time translates into, we need
346 		 * to also record the tm_mday for our selected base
347 		 * 1978-01 that will produce the correct tm_wday.
348 		 */
349 		tm.tm_mday = (*dp & 0x07);
350 		tm.tm_wday = tm.tm_mday - 1;
351 	} else {
352 		tm.tm_mday = bcd2bin(*dp & 0x3F);
353 	}
354 
355 	/* Walk backwards to extract the alarm mask flags. */
356 	while (true) {
357 		if (REG_ALARM_IGN & *dp) {
358 			flags |= amf;
359 		}
360 		amf >>= 1;
361 		if (dp-- == ap) {
362 			break;
363 		}
364 	}
365 
366 	/* Convert to the reduced representation. */
367 	*tp = timeutil_timegm(&tm);
368 	return flags;
369 }
370 
encode_alarm(uint8_t * ap,bool with_sec,time_t time,uint8_t flags)371 static int encode_alarm(uint8_t *ap,
372 			bool with_sec,
373 			time_t time,
374 			uint8_t flags)
375 {
376 	struct tm tm;
377 	uint8_t val;
378 
379 	(void)gmtime_r(&time, &tm);
380 
381 	/* For predictable behavior the low 4 bits of flags
382 	 * (corresponding to AxMy) must be 0b1111, 0b1110, 0b1100,
383 	 * 0b1000, or 0b0000.  This corresponds to the bitwise inverse
384 	 * being one less than a power of two.
385 	 */
386 	if (!is_power_of_two(1U + (0x0F & ~flags))) {
387 		LOG_DBG("invalid alarm mask in flags: %02x", flags);
388 		return -EINVAL;
389 	}
390 
391 	if (with_sec) {
392 		if (flags & MAXIM_DS3231_ALARM_FLAGS_IGNSE) {
393 			val = REG_ALARM_IGN;
394 		} else {
395 			val = bin2bcd(tm.tm_sec);
396 		}
397 		*ap++ = val;
398 	}
399 
400 	if (flags & MAXIM_DS3231_ALARM_FLAGS_IGNMN) {
401 		val = REG_ALARM_IGN;
402 	} else {
403 		val = bin2bcd(tm.tm_min);
404 	}
405 	*ap++ = val;
406 
407 	if (flags & MAXIM_DS3231_ALARM_FLAGS_IGNHR) {
408 		val = REG_ALARM_IGN;
409 	} else {
410 		val = bin2bcd(tm.tm_hour);
411 	}
412 	*ap++ = val;
413 
414 	if (flags & MAXIM_DS3231_ALARM_FLAGS_IGNDA) {
415 		val = REG_ALARM_IGN;
416 	} else if (flags & MAXIM_DS3231_ALARM_FLAGS_DOW) {
417 		val = REG_DAYDATE_DOW | (tm.tm_wday + 1);
418 	} else {
419 		val = bin2bcd(tm.tm_mday);
420 	}
421 	*ap++ = val;
422 
423 	return 0;
424 }
425 
decode_rtc(struct ds3231_data * data)426 static uint32_t decode_rtc(struct ds3231_data *data)
427 {
428 	struct tm tm = { 0 };
429 	const struct register_map *rp = &data->registers;
430 	time_t t;
431 
432 	decode_time(&tm, &rp->sec, true);
433 	tm.tm_wday = (rp->dow & 0x07) - 1;
434 	tm.tm_mday = bcd2bin(rp->dom & 0x3F);
435 	tm.tm_mon = 10 * (((0xF0 & ~REG_MONCEN_CENTURY) & rp->moncen) >> 4)
436 		    + (rp->moncen & 0x0F) - 1;
437 	tm.tm_year = bcd2bin(rp->year);
438 	if (REG_MONCEN_CENTURY & rp->moncen) {
439 		tm.tm_year += 100;
440 	}
441 
442 	t = timeutil_timegm(&tm);
443 	return COUNTER_GET(t);
444 }
445 
update_registers(const struct device * dev)446 static int update_registers(const struct device *dev)
447 {
448 	struct ds3231_data *data = dev->data;
449 	const struct ds3231_config *cfg = dev->config;
450 	uint32_t syncclock;
451 	int rc;
452 	uint8_t addr = 0;
453 
454 	data->syncclock_base = maxim_ds3231_read_syncclock(dev);
455 	rc = i2c_write_read_dt(&cfg->bus, &addr, sizeof(addr), &data->registers,
456 			       sizeof(data->registers));
457 	syncclock = maxim_ds3231_read_syncclock(dev);
458 	if (rc < 0) {
459 		return rc;
460 	}
461 
462 	return 0;
463 }
464 
maxim_ds3231_get_alarm(const struct device * dev,uint8_t id,struct maxim_ds3231_alarm * cp)465 int maxim_ds3231_get_alarm(const struct device *dev,
466 			   uint8_t id,
467 			   struct maxim_ds3231_alarm *cp)
468 {
469 	struct ds3231_data *data = dev->data;
470 	const struct ds3231_config *cfg = dev->config;
471 	int rv = 0;
472 	uint8_t addr;
473 	uint8_t len;
474 
475 	if (id == 0) {
476 		addr = offsetof(struct register_map, alarm1);
477 		len = sizeof(data->registers.alarm1);
478 	} else if (id < cfg->generic.channels) {
479 		addr = offsetof(struct register_map, alarm2);
480 		len = sizeof(data->registers.alarm2);
481 	} else {
482 		rv = -EINVAL;
483 		goto out;
484 	}
485 
486 	k_sem_take(&data->lock, K_FOREVER);
487 
488 	/* Update alarm structure */
489 	uint8_t *rbp = &data->registers.sec + addr;
490 
491 	rv = i2c_write_read_dt(&cfg->bus, &addr, sizeof(addr), rbp, len);
492 
493 	if (rv < 0) {
494 		LOG_DBG("get_config at %02x failed: %d\n", addr, rv);
495 		goto out_locked;
496 	}
497 
498 	*cp = (struct maxim_ds3231_alarm){ 0 };
499 	cp->flags = decode_alarm(rbp, (id == 0), &cp->time);
500 	cp->handler = data->alarm_handler[id];
501 	cp->user_data = data->alarm_user_data[id];
502 
503 out_locked:
504 	k_sem_give(&data->lock);
505 
506 out:
507 	return rv;
508 }
509 
cancel_alarm(const struct device * dev,uint8_t id)510 static int cancel_alarm(const struct device *dev,
511 			uint8_t id)
512 {
513 	struct ds3231_data *data = dev->data;
514 
515 	data->alarm_handler[id] = NULL;
516 	data->alarm_user_data[id] = NULL;
517 
518 	return sc_ctrl(dev, 0, MAXIM_DS3231_ALARM1 << id);
519 }
520 
ds3231_counter_cancel_alarm(const struct device * dev,uint8_t id)521 static int ds3231_counter_cancel_alarm(const struct device *dev,
522 				       uint8_t id)
523 {
524 	struct ds3231_data *data = dev->data;
525 	const struct ds3231_config *cfg = dev->config;
526 	int rv = 0;
527 
528 	if (id >= cfg->generic.channels) {
529 		rv = -EINVAL;
530 		goto out;
531 	}
532 
533 	k_sem_take(&data->lock, K_FOREVER);
534 
535 	rv = cancel_alarm(dev, id);
536 
537 	k_sem_give(&data->lock);
538 
539 out:
540 	/* Throw away information counter API disallows */
541 	if (rv >= 0) {
542 		rv = 0;
543 	}
544 
545 	return rv;
546 }
547 
set_alarm(const struct device * dev,uint8_t id,const struct maxim_ds3231_alarm * cp)548 static int set_alarm(const struct device *dev,
549 		     uint8_t id,
550 		     const struct maxim_ds3231_alarm *cp)
551 {
552 	struct ds3231_data *data = dev->data;
553 	const struct ds3231_config *cfg = dev->config;
554 	uint8_t addr;
555 	uint8_t len;
556 
557 	if (id == 0) {
558 		addr = offsetof(struct register_map, alarm1);
559 		len = sizeof(data->registers.alarm1);
560 	} else if (id < cfg->generic.channels) {
561 		addr = offsetof(struct register_map, alarm2);
562 		len = sizeof(data->registers.alarm2);
563 	} else {
564 		return -EINVAL;
565 	}
566 
567 	uint8_t buf[5] = { addr };
568 	int rc = encode_alarm(buf + 1, (id == 0), cp->time, cp->flags);
569 
570 	if (rc < 0) {
571 		return rc;
572 	}
573 
574 	/* @todo resolve race condition: a previously stored alarm may
575 	 * trigger between clear of AxF and the write of the new alarm
576 	 * control.
577 	 */
578 	rc = rsc_stat(dev, 0U, (MAXIM_DS3231_ALARM1 << id));
579 	if (rc >= 0) {
580 		rc = i2c_write_dt(&cfg->bus, buf, len + 1);
581 	}
582 	if ((rc >= 0)
583 	    && (cp->handler != NULL)) {
584 		rc = sc_ctrl(dev, MAXIM_DS3231_ALARM1 << id, 0);
585 	}
586 	if (rc >= 0) {
587 		memmove(&data->registers.sec + addr, buf + 1, len);
588 		data->alarm_handler[id] = cp->handler;
589 		data->alarm_user_data[id] = cp->user_data;
590 		data->alarm_flags[id] = cp->flags;
591 		validate_isw_monitoring(dev);
592 	}
593 
594 	return rc;
595 }
596 
maxim_ds3231_set_alarm(const struct device * dev,uint8_t id,const struct maxim_ds3231_alarm * cp)597 int maxim_ds3231_set_alarm(const struct device *dev,
598 			   uint8_t id,
599 			   const struct maxim_ds3231_alarm *cp)
600 {
601 	struct ds3231_data *data = dev->data;
602 
603 	k_sem_take(&data->lock, K_FOREVER);
604 
605 	int rc = set_alarm(dev, id, cp);
606 
607 	k_sem_give(&data->lock);
608 
609 	return rc;
610 }
611 
maxim_ds3231_check_alarms(const struct device * dev)612 int maxim_ds3231_check_alarms(const struct device *dev)
613 {
614 	struct ds3231_data *data = dev->data;
615 	const struct register_map *rp = &data->registers;
616 	uint8_t mask = (MAXIM_DS3231_ALARM1 | MAXIM_DS3231_ALARM2);
617 
618 	k_sem_take(&data->lock, K_FOREVER);
619 
620 	/* Fetch and clear only the alarm flags that are not
621 	 * interrupt-enabled.
622 	 */
623 	int rv = rsc_stat(dev, 0U, (rp->ctrl & mask) ^ mask);
624 
625 	if (rv >= 0) {
626 		rv &= mask;
627 	}
628 
629 	k_sem_give(&data->lock);
630 
631 	return rv;
632 }
633 
check_handled_alarms(const struct device * dev)634 static int check_handled_alarms(const struct device *dev)
635 {
636 	struct ds3231_data *data = dev->data;
637 	const struct register_map *rp = &data->registers;
638 	uint8_t mask = (MAXIM_DS3231_ALARM1 | MAXIM_DS3231_ALARM2);
639 
640 	/* Fetch and clear only the alarm flags that are
641 	 * interrupt-enabled.  Leave any flags that are not enabled;
642 	 * it may be an alarm that triggered a wakeup.
643 	 */
644 	mask &= rp->ctrl;
645 
646 	int rv = rsc_stat(dev, 0U, mask);
647 
648 	if (rv > 0) {
649 		rv &= mask;
650 	}
651 
652 	return rv;
653 }
654 
counter_alarm_forwarder(const struct device * dev,uint8_t id,uint32_t syncclock,void * ud)655 static void counter_alarm_forwarder(const struct device *dev,
656 				    uint8_t id,
657 				    uint32_t syncclock,
658 				    void *ud)
659 {
660 	/* Dummy handler marking a counter callback. */
661 }
662 
alarm_worker(struct k_work * work)663 static void alarm_worker(struct k_work *work)
664 {
665 	struct ds3231_data *data = CONTAINER_OF(work, struct ds3231_data,
666 						alarm_work);
667 	const struct device *ds3231 = data->ds3231;
668 	const struct ds3231_config *cfg = ds3231->config;
669 
670 	k_sem_take(&data->lock, K_FOREVER);
671 
672 	int af = check_handled_alarms(ds3231);
673 
674 	while (af > 0) {
675 		uint8_t id;
676 
677 		for (id = 0; id < cfg->generic.channels; ++id) {
678 			if ((af & (MAXIM_DS3231_ALARM1 << id)) == 0) {
679 				continue;
680 			}
681 
682 
683 			maxim_ds3231_alarm_callback_handler_t handler
684 				= data->alarm_handler[id];
685 			void *ud = data->alarm_user_data[id];
686 
687 			if (data->alarm_flags[id] & MAXIM_DS3231_ALARM_FLAGS_AUTODISABLE) {
688 				int rc = cancel_alarm(ds3231, id);
689 
690 				LOG_DBG("autodisable %d: %d", id, rc);
691 				validate_isw_monitoring(ds3231);
692 			}
693 
694 			if (handler == counter_alarm_forwarder) {
695 				counter_alarm_callback_t cb = data->counter_handler[id];
696 				uint32_t ticks = data->counter_ticks[id];
697 
698 				data->counter_handler[id] = NULL;
699 				data->counter_ticks[id] = 0;
700 
701 				if (cb) {
702 					k_sem_give(&data->lock);
703 
704 					cb(ds3231, id, ticks, ud);
705 
706 					k_sem_take(&data->lock, K_FOREVER);
707 				}
708 
709 			} else if (handler != NULL) {
710 				k_sem_give(&data->lock);
711 
712 				handler(ds3231, id, data->isw_syncclock, ud);
713 
714 				k_sem_take(&data->lock, K_FOREVER);
715 			}
716 		}
717 		af = check_handled_alarms(ds3231);
718 	}
719 
720 	k_sem_give(&data->lock);
721 
722 	if (af < 0) {
723 		LOG_ERR("failed to read alarm flags");
724 		return;
725 	}
726 
727 	LOG_DBG("ALARM %02x at %u latency %u", af, data->isw_syncclock,
728 		maxim_ds3231_read_syncclock(ds3231) - data->isw_syncclock);
729 }
730 
sqw_worker(struct k_work * work)731 static void sqw_worker(struct k_work *work)
732 {
733 	struct ds3231_data *data = CONTAINER_OF(work, struct ds3231_data, sqw_work);
734 	uint32_t syncclock = maxim_ds3231_read_syncclock(data->ds3231);
735 
736 	/* This is a placeholder for potential application-controlled
737 	 * use of the square wave functionality.
738 	 */
739 	LOG_DBG("SQW %u latency %u", data->isw_syncclock,
740 		syncclock - data->isw_syncclock);
741 }
742 
read_time(const struct device * dev,time_t * time)743 static int read_time(const struct device *dev,
744 		     time_t *time)
745 {
746 	struct ds3231_data *data = dev->data;
747 	const struct ds3231_config *cfg = dev->config;
748 	uint8_t addr = 0;
749 
750 	int rc = i2c_write_read_dt(&cfg->bus, &addr, sizeof(addr),
751 				   &data->registers, 7);
752 
753 	if (rc >= 0) {
754 		*time = decode_rtc(data);
755 	}
756 
757 	return rc;
758 }
759 
ds3231_counter_get_value(const struct device * dev,uint32_t * ticks)760 static int ds3231_counter_get_value(const struct device *dev,
761 				    uint32_t *ticks)
762 {
763 	struct ds3231_data *data = dev->data;
764 	time_t time = 0;
765 
766 	k_sem_take(&data->lock, K_FOREVER);
767 
768 	int rc = read_time(dev, &time);
769 
770 	k_sem_give(&data->lock);
771 
772 	if (rc >= 0) {
773 		*ticks = COUNTER_GET(time);
774 	}
775 
776 	return rc;
777 }
778 
sync_finish(const struct device * dev,int rc)779 static void sync_finish(const struct device *dev,
780 			int rc)
781 {
782 	struct ds3231_data *data = dev->data;
783 	struct sys_notify *notify = NULL;
784 	struct k_poll_signal *signal = NULL;
785 
786 	if (data->sync_signal) {
787 		signal = data->sync.signal;
788 	} else {
789 		notify = data->sync.notify;
790 	}
791 	data->sync.ptr = NULL;
792 	data->sync_signal = false;
793 	data->sync_state = SYNCSM_IDLE;
794 	(void)validate_isw_monitoring(dev);
795 
796 	LOG_DBG("sync complete, notify %d to %p or %p\n", rc, notify, signal);
797 	k_sem_give(&data->lock);
798 
799 	if (notify != NULL) {
800 		maxim_ds3231_notify_callback cb =
801 			(maxim_ds3231_notify_callback)sys_notify_finalize(notify, rc);
802 
803 		if (cb) {
804 			cb(dev, notify, rc);
805 		}
806 	} else if (signal != NULL) {
807 		k_poll_signal_raise(signal, rc);
808 	}
809 }
810 
sync_prep_read(const struct device * dev)811 static void sync_prep_read(const struct device *dev)
812 {
813 	struct ds3231_data *data = dev->data;
814 	int rc = sc_ctrl(dev, 0U, MAXIM_DS3231_REG_CTRL_INTCN
815 			 | MAXIM_DS3231_REG_CTRL_RS_Msk);
816 
817 	if (rc < 0) {
818 		sync_finish(dev, rc);
819 		return;
820 	}
821 	data->sync_state = SYNCSM_FINISH_READ;
822 	validate_isw_monitoring(dev);
823 }
824 
sync_finish_read(const struct device * dev)825 static void sync_finish_read(const struct device *dev)
826 {
827 	struct ds3231_data *data = dev->data;
828 	time_t time = 0;
829 
830 	(void)read_time(dev, &time);
831 	data->syncpoint.rtc.tv_sec = time;
832 	data->syncpoint.rtc.tv_nsec = 0;
833 	data->syncpoint.syncclock = data->isw_syncclock;
834 	sync_finish(dev, 0);
835 }
836 
sync_timer_handler(struct k_timer * tmr)837 static void sync_timer_handler(struct k_timer *tmr)
838 {
839 	struct ds3231_data *data = CONTAINER_OF(tmr, struct ds3231_data,
840 						sync_timer);
841 
842 	LOG_INF("sync_timer fired");
843 	k_work_submit(&data->sync_work);
844 }
845 
sync_prep_write(const struct device * dev)846 static void sync_prep_write(const struct device *dev)
847 {
848 	struct ds3231_data *data = dev->data;
849 	uint32_t syncclock = maxim_ds3231_read_syncclock(dev);
850 	uint32_t offset = syncclock - data->new_sp.syncclock;
851 	uint32_t syncclock_Hz = maxim_ds3231_syncclock_frequency(dev);
852 	uint32_t offset_s = offset / syncclock_Hz;
853 	uint32_t offset_ms = (offset % syncclock_Hz) * 1000U / syncclock_Hz;
854 	time_t when = data->new_sp.rtc.tv_sec;
855 
856 	when += offset_s;
857 	offset_ms += data->new_sp.rtc.tv_nsec / NSEC_PER_USEC / USEC_PER_MSEC;
858 	if (offset_ms >= MSEC_PER_SEC) {
859 		offset_ms -= MSEC_PER_SEC;
860 	} else {
861 		when += 1;
862 	}
863 
864 	uint32_t rem_ms = MSEC_PER_SEC - offset_ms;
865 
866 	if (rem_ms < 5) {
867 		when += 1;
868 		rem_ms += MSEC_PER_SEC;
869 	}
870 	data->new_sp.rtc.tv_sec = when;
871 	data->new_sp.rtc.tv_nsec = 0;
872 
873 	data->sync_state = SYNCSM_FINISH_WRITE;
874 	k_timer_start(&data->sync_timer, K_MSEC(rem_ms), K_NO_WAIT);
875 	LOG_INF("sync %u in %u ms after %u", COUNTER_GET(when), rem_ms, syncclock);
876 }
877 
sync_finish_write(const struct device * dev)878 static void sync_finish_write(const struct device *dev)
879 {
880 	struct ds3231_data *data = dev->data;
881 	const struct ds3231_config *cfg = dev->config;
882 	time_t when = data->new_sp.rtc.tv_sec;
883 	struct tm tm;
884 	uint8_t buf[8];
885 	uint8_t *bp = buf;
886 	uint8_t val;
887 
888 	*bp++ = offsetof(struct register_map, sec);
889 
890 	(void)gmtime_r(&when, &tm);
891 	val = bin2bcd(tm.tm_sec);
892 	*bp++ = val;
893 
894 	val = bin2bcd(tm.tm_min);
895 	*bp++ = val;
896 
897 	val = bin2bcd(tm.tm_hour);
898 	*bp++ = val;
899 
900 	*bp++ = 1 + tm.tm_wday;
901 
902 	val = bin2bcd(tm.tm_mday);
903 	*bp++ = val;
904 
905 	tm.tm_mon += 1;
906 	val = bin2bcd(tm.tm_mon);
907 	if (tm.tm_year >= 100) {
908 		tm.tm_year -= 100;
909 		val |= REG_MONCEN_CENTURY;
910 	}
911 	*bp++ = val;
912 
913 	val = bin2bcd(tm.tm_year);
914 	*bp++ = val;
915 
916 	uint32_t syncclock = maxim_ds3231_read_syncclock(dev);
917 	int rc = i2c_write_dt(&cfg->bus, buf, bp - buf);
918 
919 	if (rc >= 0) {
920 		data->syncpoint.rtc.tv_sec = when;
921 		data->syncpoint.rtc.tv_nsec = 0;
922 		data->syncpoint.syncclock = syncclock;
923 		LOG_INF("sync %u at %u", COUNTER_GET(when), syncclock);
924 	}
925 	sync_finish(dev, rc);
926 }
927 
sync_worker(struct k_work * work)928 static void sync_worker(struct k_work *work)
929 {
930 	struct ds3231_data *data = CONTAINER_OF(work, struct ds3231_data, sync_work);
931 	uint32_t syncclock = maxim_ds3231_read_syncclock(data->ds3231);
932 	bool unlock = true;
933 
934 	k_sem_take(&data->lock, K_FOREVER);
935 
936 	LOG_DBG("SYNC.%u %u latency %u", data->sync_state, data->isw_syncclock,
937 		syncclock - data->isw_syncclock);
938 	switch (data->sync_state) {
939 	default:
940 	case SYNCSM_IDLE:
941 		break;
942 	case SYNCSM_PREP_READ:
943 		sync_prep_read(data->ds3231);
944 		break;
945 	case SYNCSM_FINISH_READ:
946 		sync_finish_read(data->ds3231);
947 		break;
948 	case SYNCSM_PREP_WRITE:
949 		sync_prep_write(data->ds3231);
950 		break;
951 	case SYNCSM_FINISH_WRITE:
952 		sync_finish_write(data->ds3231);
953 		unlock = false;
954 		break;
955 	}
956 
957 	if (unlock) {
958 		k_sem_give(&data->lock);
959 	}
960 }
961 
isw_gpio_callback(const struct device * port,struct gpio_callback * cb,uint32_t pins)962 static void isw_gpio_callback(const struct device *port,
963 			      struct gpio_callback *cb,
964 			      uint32_t pins)
965 {
966 	struct ds3231_data *data = CONTAINER_OF(cb, struct ds3231_data,
967 						isw_callback);
968 
969 	data->isw_syncclock = maxim_ds3231_read_syncclock(data->ds3231);
970 	if (data->registers.ctrl & MAXIM_DS3231_REG_CTRL_INTCN) {
971 		k_work_submit(&data->alarm_work);
972 	} else if (data->sync_state != SYNCSM_IDLE) {
973 		k_work_submit(&data->sync_work);
974 	} else {
975 		k_work_submit(&data->sqw_work);
976 	}
977 }
978 
z_impl_maxim_ds3231_get_syncpoint(const struct device * dev,struct maxim_ds3231_syncpoint * syncpoint)979 int z_impl_maxim_ds3231_get_syncpoint(const struct device *dev,
980 				      struct maxim_ds3231_syncpoint *syncpoint)
981 {
982 	struct ds3231_data *data = dev->data;
983 	int rv = 0;
984 
985 	k_sem_take(&data->lock, K_FOREVER);
986 
987 	if (data->syncpoint.rtc.tv_sec == 0) {
988 		rv = -ENOENT;
989 	} else {
990 		__ASSERT_NO_MSG(syncpoint != NULL);
991 		*syncpoint = data->syncpoint;
992 	}
993 
994 	k_sem_give(&data->lock);
995 
996 	return rv;
997 }
998 
maxim_ds3231_synchronize(const struct device * dev,struct sys_notify * notify)999 int maxim_ds3231_synchronize(const struct device *dev,
1000 			     struct sys_notify *notify)
1001 {
1002 	const struct ds3231_config *cfg = dev->config;
1003 	struct ds3231_data *data = dev->data;
1004 	int rv = 0;
1005 
1006 	if (notify == NULL) {
1007 		rv = -EINVAL;
1008 		goto out;
1009 	}
1010 
1011 	if (cfg->isw_gpios.port == NULL) {
1012 		rv = -ENOTSUP;
1013 		goto out;
1014 	}
1015 
1016 	k_sem_take(&data->lock, K_FOREVER);
1017 
1018 	if (data->sync_state != SYNCSM_IDLE) {
1019 		rv = -EBUSY;
1020 		goto out_locked;
1021 	}
1022 
1023 	data->sync_signal = false;
1024 	data->sync.notify = notify;
1025 	data->sync_state = SYNCSM_PREP_READ;
1026 
1027 out_locked:
1028 	k_sem_give(&data->lock);
1029 
1030 	if (rv >= 0) {
1031 		k_work_submit(&data->sync_work);
1032 	}
1033 
1034 out:
1035 	return rv;
1036 }
1037 
z_impl_maxim_ds3231_req_syncpoint(const struct device * dev,struct k_poll_signal * sig)1038 int z_impl_maxim_ds3231_req_syncpoint(const struct device *dev,
1039 				      struct k_poll_signal *sig)
1040 {
1041 	const struct ds3231_config *cfg = dev->config;
1042 	struct ds3231_data *data = dev->data;
1043 	int rv = 0;
1044 
1045 	if (cfg->isw_gpios.port == NULL) {
1046 		rv = -ENOTSUP;
1047 		goto out;
1048 	}
1049 
1050 	k_sem_take(&data->lock, K_FOREVER);
1051 
1052 	if (data->sync_state != SYNCSM_IDLE) {
1053 		rv = -EBUSY;
1054 		goto out_locked;
1055 	}
1056 
1057 	data->sync_signal = true;
1058 	data->sync.signal = sig;
1059 	data->sync_state = SYNCSM_PREP_READ;
1060 
1061 out_locked:
1062 	k_sem_give(&data->lock);
1063 
1064 	if (rv >= 0) {
1065 		k_work_submit(&data->sync_work);
1066 	}
1067 
1068 out:
1069 	return rv;
1070 }
1071 
maxim_ds3231_set(const struct device * dev,const struct maxim_ds3231_syncpoint * syncpoint,struct sys_notify * notify)1072 int maxim_ds3231_set(const struct device *dev,
1073 		     const struct maxim_ds3231_syncpoint *syncpoint,
1074 		     struct sys_notify *notify)
1075 {
1076 	const struct ds3231_config *cfg = dev->config;
1077 	struct ds3231_data *data = dev->data;
1078 	int rv = 0;
1079 
1080 	if ((syncpoint == NULL)
1081 	    || (notify == NULL)) {
1082 		rv = -EINVAL;
1083 		goto out;
1084 	}
1085 	if (cfg->isw_gpios.port == NULL) {
1086 		rv = -ENOTSUP;
1087 		goto out;
1088 	}
1089 
1090 	k_sem_take(&data->lock, K_FOREVER);
1091 
1092 	if (data->sync_state != SYNCSM_IDLE) {
1093 		rv = -EBUSY;
1094 		goto out_locked;
1095 	}
1096 
1097 	data->new_sp = *syncpoint;
1098 	data->sync_signal = false;
1099 	data->sync.notify = notify;
1100 	data->sync_state = SYNCSM_PREP_WRITE;
1101 
1102 out_locked:
1103 	k_sem_give(&data->lock);
1104 
1105 	if (rv >= 0) {
1106 		k_work_submit(&data->sync_work);
1107 	}
1108 
1109 out:
1110 	return rv;
1111 }
1112 
ds3231_init(const struct device * dev)1113 static int ds3231_init(const struct device *dev)
1114 {
1115 	struct ds3231_data *data = dev->data;
1116 	const struct ds3231_config *cfg = dev->config;
1117 	int rc;
1118 
1119 	/* Initialize and take the lock */
1120 	k_sem_init(&data->lock, 0, 1);
1121 
1122 	data->ds3231 = dev;
1123 	if (!device_is_ready(cfg->bus.bus)) {
1124 		LOG_ERR("I2C device not ready");
1125 		rc = -ENODEV;
1126 		goto out;
1127 	}
1128 
1129 	rc = update_registers(dev);
1130 	if (rc < 0) {
1131 		LOG_WRN("Failed to fetch registers: %d", rc);
1132 		goto out;
1133 	}
1134 
1135 	/* INTCN and AxIE to power-up default, RS to 1 Hz */
1136 	rc = sc_ctrl(dev,
1137 		     MAXIM_DS3231_REG_CTRL_INTCN,
1138 		     MAXIM_DS3231_REG_CTRL_RS_Msk
1139 		     | MAXIM_DS3231_ALARM1 | MAXIM_DS3231_ALARM2);
1140 	if (rc < 0) {
1141 		LOG_WRN("Failed to reset config: %d", rc);
1142 		goto out;
1143 	}
1144 
1145 	/* Do not clear pending flags in the status register.  This
1146 	 * device may have been used for external wakeup, which can be
1147 	 * detected using the extended API.
1148 	 */
1149 
1150 	if (cfg->isw_gpios.port != NULL) {
1151 		if (!gpio_is_ready_dt(&cfg->isw_gpios)) {
1152 			LOG_ERR("INTn/SQW GPIO device not ready");
1153 			rc = -ENODEV;
1154 			goto out;
1155 		}
1156 
1157 		k_timer_init(&data->sync_timer, sync_timer_handler, NULL);
1158 		k_work_init(&data->alarm_work, alarm_worker);
1159 		k_work_init(&data->sqw_work, sqw_worker);
1160 		k_work_init(&data->sync_work, sync_worker);
1161 		gpio_init_callback(&data->isw_callback,
1162 				   isw_gpio_callback,
1163 				   BIT(cfg->isw_gpios.pin));
1164 
1165 		rc = gpio_pin_configure_dt(&cfg->isw_gpios, GPIO_INPUT);
1166 		if (rc >= 0) {
1167 			rc = gpio_pin_interrupt_configure_dt(&cfg->isw_gpios,
1168 							     GPIO_INT_DISABLE);
1169 		}
1170 		if (rc >= 0) {
1171 			rc = gpio_add_callback(cfg->isw_gpios.port,
1172 					       &data->isw_callback);
1173 			if (rc < 0) {
1174 				LOG_ERR("Failed to configure ISW callback: %d",
1175 					rc);
1176 			}
1177 		}
1178 	}
1179 
1180 out:
1181 	k_sem_give(&data->lock);
1182 
1183 	LOG_DBG("Initialized %d", rc);
1184 	if (rc > 0) {
1185 		rc = 0;
1186 	}
1187 
1188 	return rc;
1189 }
1190 
ds3231_counter_start(const struct device * dev)1191 static int ds3231_counter_start(const struct device *dev)
1192 {
1193 	return -EALREADY;
1194 }
1195 
ds3231_counter_stop(const struct device * dev)1196 static int ds3231_counter_stop(const struct device *dev)
1197 {
1198 	return -ENOTSUP;
1199 }
1200 
ds3231_counter_set_alarm(const struct device * dev,uint8_t id,const struct counter_alarm_cfg * alarm_cfg)1201 int ds3231_counter_set_alarm(const struct device *dev,
1202 			     uint8_t id,
1203 			     const struct counter_alarm_cfg *alarm_cfg)
1204 {
1205 	struct ds3231_data *data = dev->data;
1206 	const struct register_map *rp = &data->registers;
1207 	const struct ds3231_config *cfg = dev->config;
1208 	time_t when;
1209 	int rc = 0;
1210 
1211 	if (id >= cfg->generic.channels) {
1212 		rc = -ENOTSUP;
1213 		goto out;
1214 	}
1215 
1216 	k_sem_take(&data->lock, K_FOREVER);
1217 
1218 	if (rp->ctrl & (MAXIM_DS3231_ALARM1 << id)) {
1219 		rc = -EBUSY;
1220 		goto out_locked;
1221 	}
1222 
1223 	if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
1224 		rc = read_time(dev, &when);
1225 		if (rc >= 0) {
1226 			when += alarm_cfg->ticks;
1227 		}
1228 	} else {
1229 		when = alarm_cfg->ticks;
1230 	}
1231 
1232 	struct maxim_ds3231_alarm alarm = {
1233 		.time = COUNTER_GET(when),
1234 		.handler = counter_alarm_forwarder,
1235 		.user_data = alarm_cfg->user_data,
1236 		.flags = MAXIM_DS3231_ALARM_FLAGS_AUTODISABLE,
1237 	};
1238 
1239 	if (rc >= 0) {
1240 		data->counter_handler[id] = alarm_cfg->callback;
1241 		data->counter_ticks[id] = COUNTER_GET(alarm.time);
1242 		rc = set_alarm(dev, id, &alarm);
1243 	}
1244 
1245 out_locked:
1246 	k_sem_give(&data->lock);
1247 
1248 out:
1249 	/* Throw away information counter API disallows */
1250 	if (rc >= 0) {
1251 		rc = 0;
1252 	}
1253 
1254 	return rc;
1255 }
1256 
ds3231_counter_get_top_value(const struct device * dev)1257 static uint32_t ds3231_counter_get_top_value(const struct device *dev)
1258 {
1259 	return UINT32_MAX;
1260 }
1261 
ds3231_counter_get_pending_int(const struct device * dev)1262 static uint32_t ds3231_counter_get_pending_int(const struct device *dev)
1263 {
1264 	return 0;
1265 }
1266 
ds3231_counter_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)1267 static int ds3231_counter_set_top_value(const struct device *dev,
1268 					const struct counter_top_cfg *cfg)
1269 {
1270 	return -ENOTSUP;
1271 }
1272 
1273 static DEVICE_API(counter, ds3231_api) = {
1274 	.start = ds3231_counter_start,
1275 	.stop = ds3231_counter_stop,
1276 	.get_value = ds3231_counter_get_value,
1277 	.set_alarm = ds3231_counter_set_alarm,
1278 	.cancel_alarm = ds3231_counter_cancel_alarm,
1279 	.set_top_value = ds3231_counter_set_top_value,
1280 	.get_pending_int = ds3231_counter_get_pending_int,
1281 	.get_top_value = ds3231_counter_get_top_value,
1282 };
1283 
1284 static const struct ds3231_config ds3231_0_config = {
1285 	.generic = {
1286 		.max_top_value = UINT32_MAX,
1287 		.freq = 1,
1288 		.flags = COUNTER_CONFIG_INFO_COUNT_UP,
1289 		.channels = 2,
1290 	},
1291 	.bus = I2C_DT_SPEC_INST_GET(0),
1292 	/* Driver does not currently use 32k GPIO. */
1293 	.isw_gpios = GPIO_DT_SPEC_INST_GET_OR(0, isw_gpios, {}),
1294 };
1295 
1296 static struct ds3231_data ds3231_0_data;
1297 
1298 #if CONFIG_COUNTER_INIT_PRIORITY <= CONFIG_I2C_INIT_PRIORITY
1299 #error CONFIG_COUNTER_INIT_PRIORITY must be greater than I2C_INIT_PRIORITY
1300 #endif
1301 
1302 DEVICE_DT_INST_DEFINE(0, ds3231_init, NULL, &ds3231_0_data,
1303 		    &ds3231_0_config,
1304 		    POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY,
1305 		    &ds3231_api);
1306 
1307 #ifdef CONFIG_USERSPACE
1308 
1309 #include <zephyr/internal/syscall_handler.h>
1310 
z_vrfy_maxim_ds3231_get_syncpoint(const struct device * dev,struct maxim_ds3231_syncpoint * syncpoint)1311 int z_vrfy_maxim_ds3231_get_syncpoint(const struct device *dev,
1312 				      struct maxim_ds3231_syncpoint *syncpoint)
1313 {
1314 	struct maxim_ds3231_syncpoint value;
1315 	int rv;
1316 
1317 	K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api));
1318 	K_OOPS(K_SYSCALL_MEMORY_WRITE(syncpoint, sizeof(*syncpoint)));
1319 
1320 	rv = z_impl_maxim_ds3231_get_syncpoint(dev, &value);
1321 
1322 	if (rv >= 0) {
1323 		K_OOPS(k_usermode_to_copy(syncpoint, &value, sizeof(*syncpoint)));
1324 	}
1325 
1326 	return rv;
1327 }
1328 
1329 #include <zephyr/syscalls/maxim_ds3231_get_syncpoint_mrsh.c>
1330 
z_vrfy_maxim_ds3231_req_syncpoint(const struct device * dev,struct k_poll_signal * sig)1331 int z_vrfy_maxim_ds3231_req_syncpoint(const struct device *dev,
1332 				      struct k_poll_signal *sig)
1333 {
1334 	K_OOPS(K_SYSCALL_SPECIFIC_DRIVER(dev, K_OBJ_DRIVER_COUNTER, &ds3231_api));
1335 	if (sig != NULL) {
1336 		K_OOPS(K_SYSCALL_OBJ(sig, K_OBJ_POLL_SIGNAL));
1337 	}
1338 
1339 	return z_impl_maxim_ds3231_req_syncpoint(dev, sig);
1340 }
1341 
1342 #include <zephyr/syscalls/maxim_ds3231_req_syncpoint_mrsh.c>
1343 
1344 #endif /* CONFIG_USERSPACE */
1345