1 /*
2 * Copyright 2025 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT zephyr_rtc_counter
8
9 #include <zephyr/drivers/rtc.h>
10 #include <zephyr/drivers/counter.h>
11 #include <zephyr/device.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/types.h>
14 #include <zephyr/logging/log.h>
15 #include <zephyr/sys/timeutil.h>
16 #include "rtc_utils.h"
17
18 LOG_MODULE_REGISTER(rtc_counter, CONFIG_RTC_LOG_LEVEL);
19
20 struct rtc_counter_config {
21 const struct device *counter_dev;
22 /* Number of alarm channels */
23 uint8_t alarms_count;
24 };
25
26 struct rtc_counter_data {
27 /* Offset in counter ticks between raw counter and Unix epoch */
28 int64_t epoch_offset;
29 /* protects epoch_offset */
30 struct k_spinlock lock;
31 #ifdef CONFIG_RTC_ALARM
32 /* false if counter has no alarm channels */
33 bool alarm_capable;
34 /* number of alarm channels exposed (<= underlying counter channels) */
35 uint8_t num_alarm_chans;
36 const struct device *rtc_dev;
37 /* Per-instance arrays provided by init macro */
38 rtc_alarm_callback *alarm_callback;
39 void **alarm_user_data;
40 uint16_t *alarm_mask;
41 struct rtc_time *alarm_time;
42 bool *alarm_pending;
43 #endif /* CONFIG_RTC_ALARM */
44 };
45
46 /*
47 * Generic RTC time to ticks conversion using time.h and counter API.
48 * Returns 0 on success, -EINVAL on invalid time or overflow.
49 */
rtc_counter_time_to_ticks(const struct rtc_time * timeptr,uint32_t tick_freq,uint64_t * ticks_out)50 static int rtc_counter_time_to_ticks(const struct rtc_time *timeptr, uint32_t tick_freq,
51 uint64_t *ticks_out)
52 {
53 struct tm tm_val;
54 int64_t seconds64;
55
56 if (timeptr == NULL || ticks_out == NULL) {
57 return -EINVAL;
58 }
59
60 /* Populate broken-down time structure */
61 memset(&tm_val, 0, sizeof(tm_val));
62 tm_val.tm_sec = timeptr->tm_sec;
63 tm_val.tm_min = timeptr->tm_min;
64 tm_val.tm_hour = timeptr->tm_hour;
65 tm_val.tm_mday = timeptr->tm_mday;
66 tm_val.tm_mon = timeptr->tm_mon;
67 tm_val.tm_year = timeptr->tm_year;
68 tm_val.tm_isdst = -1;
69
70 /* UTC, 64-bit, no DST/timezone ambiguity */
71 seconds64 = timeutil_timegm64(&tm_val);
72
73 if (seconds64 < 0) {
74 return -EINVAL;
75 }
76
77 if (tick_freq == 0U) {
78 return -ERANGE;
79 }
80
81 /* Guard overflow: ticks = seconds * freq must fit into 64-bit */
82 if ((uint64_t)seconds64 > (uint64_t)INT64_MAX / (uint64_t)tick_freq) {
83 return -ERANGE;
84 }
85
86 *ticks_out = (uint64_t)seconds64 * (uint64_t)tick_freq;
87 return 0;
88 }
89
90 /* Generic RTC ticks to time conversion using time.h and counter API */
rtc_counter_ticks_to_time(uint64_t ticks,uint32_t tick_freq,struct rtc_time * timeptr)91 static void rtc_counter_ticks_to_time(uint64_t ticks, uint32_t tick_freq, struct rtc_time *timeptr)
92 {
93 time_t seconds;
94 struct tm tm_val;
95
96 if (tick_freq == 0U) {
97 memset(timeptr, 0, sizeof(struct rtc_time));
98 return;
99 }
100
101 seconds = (time_t)(ticks / (uint64_t)tick_freq);
102
103 if (gmtime_r(&seconds, &tm_val) == NULL) {
104 memset(timeptr, 0, sizeof(struct rtc_time));
105 return;
106 }
107
108 timeptr->tm_sec = tm_val.tm_sec;
109 timeptr->tm_min = tm_val.tm_min;
110 timeptr->tm_hour = tm_val.tm_hour;
111 timeptr->tm_mday = tm_val.tm_mday;
112 timeptr->tm_mon = tm_val.tm_mon;
113 timeptr->tm_year = tm_val.tm_year;
114 timeptr->tm_wday = tm_val.tm_wday;
115 timeptr->tm_yday = tm_val.tm_yday;
116 timeptr->tm_isdst = -1;
117 timeptr->tm_nsec = 0;
118 }
119
120 #if defined(CONFIG_RTC_ALARM)
121
rtc_counter_alarm_callback(const struct device * counter_dev,uint8_t chan_id,uint32_t ticks,void * user_data)122 static void rtc_counter_alarm_callback(const struct device *counter_dev, uint8_t chan_id,
123 uint32_t ticks, void *user_data)
124 {
125 struct rtc_counter_data *data = (struct rtc_counter_data *)user_data;
126 const struct device *rtc_dev = data->rtc_dev;
127
128 if (chan_id < data->num_alarm_chans && data->alarm_callback[chan_id] != NULL) {
129 data->alarm_callback[chan_id](rtc_dev, chan_id, data->alarm_user_data[chan_id]);
130 data->alarm_pending[chan_id] = false;
131 } else if (chan_id < data->num_alarm_chans) {
132 data->alarm_pending[chan_id] = true;
133 } else {
134 LOG_DBG("Spurious alarm callback on channel %u (max %u)", chan_id,
135 data->num_alarm_chans ? (data->num_alarm_chans - 1U) : 0U);
136 }
137 }
138
rtc_counter_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)139 static int rtc_counter_alarm_get_supported_fields(const struct device *dev, uint16_t id,
140 uint16_t *mask)
141 {
142 struct rtc_counter_data *data = dev->data;
143
144 if (!data->alarm_capable) {
145 return -ENOTSUP;
146 }
147
148 if (id >= data->num_alarm_chans) {
149 return -EINVAL;
150 }
151
152 *mask = (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE |
153 RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_MONTHDAY |
154 RTC_ALARM_TIME_MASK_MONTH | RTC_ALARM_TIME_MASK_YEAR |
155 RTC_ALARM_TIME_MASK_WEEKDAY | RTC_ALARM_TIME_MASK_YEARDAY);
156
157 return 0;
158 }
159
rtc_counter_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)160 static int rtc_counter_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
161 const struct rtc_time *timeptr)
162 {
163 const struct rtc_counter_config *config = dev->config;
164 struct rtc_counter_data *data = dev->data;
165 uint64_t desired_ticks;
166 uint32_t freq;
167 int ret;
168 int64_t epoch;
169 int64_t raw_alarm_ticks_64;
170 uint32_t top;
171 uint32_t alarm_ticks;
172 uint32_t now_raw;
173 struct counter_alarm_cfg alarm_cfg;
174
175 if (!data->alarm_capable) {
176 return -ENOTSUP;
177 }
178
179 if (id >= data->num_alarm_chans) {
180 return -EINVAL;
181 }
182
183 if (mask == 0U) {
184 /* Disable alarm on selected channel */
185 ret = counter_cancel_channel_alarm(config->counter_dev, (uint8_t)id);
186 if (ret == 0) {
187 K_SPINLOCK(&data->lock) {
188 data->alarm_mask[id] = 0U;
189 data->alarm_pending[id] = false;
190 memset(&data->alarm_time[id], 0, sizeof(struct rtc_time));
191 }
192 }
193 return ret;
194 }
195
196 if (timeptr == NULL) {
197 return -EINVAL;
198 }
199
200 if (!rtc_utils_validate_rtc_time(timeptr, mask)) {
201 return -EINVAL;
202 }
203
204 freq = counter_get_frequency(config->counter_dev);
205
206 ret = rtc_counter_time_to_ticks(timeptr, freq, &desired_ticks);
207
208 /* -EINVAL on overflow/invalid time */
209 if (ret < 0) {
210 return ret;
211 }
212
213 /* Convert desired absolute Unix time to a raw tick value for the counter */
214 K_SPINLOCK(&data->lock) {
215 epoch = data->epoch_offset;
216 }
217
218 raw_alarm_ticks_64 = (int64_t)desired_ticks - epoch;
219 /* Reject wraparound: must be within current window and not in the past */
220 top = counter_get_top_value(config->counter_dev);
221
222 /* would require wrap */
223 if (raw_alarm_ticks_64 < 0 || raw_alarm_ticks_64 > (int64_t)top) {
224 return -ERANGE;
225 }
226
227 alarm_ticks = (uint32_t)raw_alarm_ticks_64;
228
229 ret = counter_get_value(config->counter_dev, &now_raw);
230 if (ret < 0) {
231 return ret;
232 }
233
234 /* target already passed in this window or equals 'now' */
235 if (alarm_ticks <= now_raw) {
236 /* 1-tick guard, but cannot wrap */
237 if (now_raw == top) {
238 return -ERANGE;
239 }
240 alarm_ticks = now_raw + 1U;
241 }
242
243 alarm_cfg.callback = rtc_counter_alarm_callback;
244 alarm_cfg.ticks = alarm_ticks;
245 alarm_cfg.user_data = data;
246 alarm_cfg.flags = COUNTER_ALARM_CFG_ABSOLUTE | COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
247
248 /* Record configured mask and time for get_time; clear pending */
249 K_SPINLOCK(&data->lock) {
250 data->alarm_mask[id] = mask;
251 data->alarm_time[id] = *timeptr;
252 data->alarm_pending[id] = false;
253 }
254
255 return counter_set_channel_alarm(config->counter_dev, (uint8_t)id, &alarm_cfg);
256 }
257
rtc_counter_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)258 static int rtc_counter_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
259 struct rtc_time *timeptr)
260 {
261 struct rtc_counter_data *data = dev->data;
262 int ret = 0;
263
264 if (!data->alarm_capable) {
265 return -ENOTSUP;
266 }
267
268 if (id >= data->num_alarm_chans) {
269 return -EINVAL;
270 }
271
272 if (mask == NULL || timeptr == NULL) {
273 return -EINVAL;
274 }
275
276 K_SPINLOCK(&data->lock) {
277 if (data->alarm_mask[id] == 0U) {
278 ret = -EINVAL;
279 } else {
280 *mask = data->alarm_mask[id];
281 *timeptr = data->alarm_time[id];
282 }
283 }
284
285 return ret;
286 }
287
rtc_counter_alarm_is_pending(const struct device * dev,uint16_t id)288 static int rtc_counter_alarm_is_pending(const struct device *dev, uint16_t id)
289 {
290 int ret = 0;
291 struct rtc_counter_data *data = dev->data;
292
293 if (!data->alarm_capable) {
294 return -ENOTSUP;
295 }
296
297 if (id >= data->num_alarm_chans) {
298 return -EINVAL;
299 }
300
301 K_SPINLOCK(&data->lock) {
302 ret = data->alarm_pending[id] ? 1 : 0;
303 data->alarm_pending[id] = false;
304 }
305
306 return ret;
307 }
308
rtc_counter_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback callback,void * user_data)309 static int rtc_counter_alarm_set_callback(const struct device *dev, uint16_t id,
310 rtc_alarm_callback callback, void *user_data)
311 {
312 struct rtc_counter_data *data = dev->data;
313
314 if (!data->alarm_capable) {
315 return -ENOTSUP;
316 }
317
318 if (id >= data->num_alarm_chans) {
319 return -EINVAL;
320 }
321
322 K_SPINLOCK(&data->lock) {
323 data->alarm_callback[id] = callback;
324 data->alarm_user_data[id] = user_data;
325 }
326
327 return 0;
328 }
329
330 /* Compute rearm tick within current counter window.
331 * Returns true and writes the tick to out_ticks; returns false if it should be skipped.
332 */
rtc_counter_compute_rearm_ticks(int64_t raw_alarm_ticks_64,uint32_t now_raw,uint32_t top,uint32_t * out_ticks)333 static inline bool rtc_counter_compute_rearm_ticks(int64_t raw_alarm_ticks_64, uint32_t now_raw,
334 uint32_t top, uint32_t *out_ticks)
335 {
336 /* Out of range */
337 if (raw_alarm_ticks_64 > (int64_t)top) {
338 return false;
339 }
340
341 /* In the past: arm to next tick if possible */
342 if (raw_alarm_ticks_64 < 0) {
343 if (now_raw == top) {
344 return false;
345 }
346 *out_ticks = now_raw + 1U;
347 return true;
348 }
349
350 /* Within range */
351 *out_ticks = (uint32_t)raw_alarm_ticks_64;
352 if (*out_ticks <= now_raw) {
353 if (now_raw == top) {
354 return false;
355 }
356 *out_ticks = now_raw + 1U;
357 }
358
359 return true;
360 }
361
362 /* Recompute and rearm all active alarms after a time base (epoch) change */
rtc_counter_reschedule_alarms(const struct device * dev)363 static void rtc_counter_reschedule_alarms(const struct device *dev)
364 {
365 const struct rtc_counter_config *config = dev->config;
366 struct rtc_counter_data *data = dev->data;
367 uint16_t configured_mask;
368 struct rtc_time configured_time;
369 uint64_t alarm_abs_ticks;
370 uint32_t freq;
371 int64_t epoch;
372 int64_t raw_alarm_ticks_64;
373 uint32_t top;
374 uint32_t now_raw;
375 uint32_t alarm_ticks;
376 struct counter_alarm_cfg alarm_cfg;
377
378 /* Time base changed: reschedule any active alarms to the new epoch */
379 if (!(data->alarm_capable && data->num_alarm_chans > 0U)) {
380 return;
381 }
382
383 for (uint8_t id = 0U; id < data->num_alarm_chans; id++) {
384 /* Snapshot configured alarm (if any) and clear pending */
385 K_SPINLOCK(&data->lock) {
386 configured_mask = data->alarm_mask[id];
387 configured_time = data->alarm_time[id];
388 data->alarm_pending[id] = false;
389 }
390
391 if (configured_mask == 0U) {
392 continue;
393 }
394
395 /* Cancel any in-flight alarm before reprogramming */
396 (void)counter_cancel_channel_alarm(config->counter_dev, (uint8_t)id);
397
398 freq = counter_get_frequency(config->counter_dev);
399 if (rtc_counter_time_to_ticks(&configured_time, freq, &alarm_abs_ticks) < 0) {
400 /* Should not happen: skip this alarm */
401 continue;
402 }
403
404 K_SPINLOCK(&data->lock) {
405 epoch = data->epoch_offset;
406 }
407
408 raw_alarm_ticks_64 = (int64_t)alarm_abs_ticks - epoch;
409 top = counter_get_top_value(config->counter_dev);
410 if (counter_get_value(config->counter_dev, &now_raw) < 0) {
411 continue;
412 }
413
414 if (!rtc_counter_compute_rearm_ticks(raw_alarm_ticks_64, now_raw, top,
415 &alarm_ticks)) {
416 continue;
417 }
418
419 alarm_cfg.callback = rtc_counter_alarm_callback;
420 alarm_cfg.ticks = alarm_ticks;
421 alarm_cfg.user_data = data;
422 alarm_cfg.flags = COUNTER_ALARM_CFG_ABSOLUTE | COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
423
424 (void)counter_set_channel_alarm(config->counter_dev, (uint8_t)id, &alarm_cfg);
425 }
426 }
427
428 #endif /* CONFIG_RTC_ALARM */
429
rtc_counter_set_time(const struct device * dev,const struct rtc_time * timeptr)430 static int rtc_counter_set_time(const struct device *dev, const struct rtc_time *timeptr)
431 {
432 const struct rtc_counter_config *config = dev->config;
433 struct rtc_counter_data *data = dev->data;
434 uint64_t desired_ticks = 0;
435 uint32_t now_ticks = 0;
436 int ret;
437 uint32_t freq;
438
439 if (timeptr == NULL) {
440 return -EINVAL;
441 }
442
443 freq = counter_get_frequency(config->counter_dev);
444
445 ret = rtc_counter_time_to_ticks(timeptr, freq, &desired_ticks);
446
447 /* -EINVAL on overflow/invalid time */
448 if (ret < 0) {
449 return ret;
450 }
451
452 /* Stop counter */
453 ret = counter_stop(config->counter_dev);
454
455 if (ret < 0) {
456 return ret;
457 }
458
459 ret = counter_get_value(config->counter_dev, &now_ticks);
460 if (ret < 0) {
461 return ret;
462 }
463
464 /* Update the software offset (in ticks): offset = desired_ticks - now_ticks */
465 K_SPINLOCK(&data->lock) {
466 data->epoch_offset = (int64_t)desired_ticks - (int64_t)now_ticks;
467 }
468
469 #ifdef CONFIG_RTC_ALARM
470 rtc_counter_reschedule_alarms(dev);
471 #endif /* CONFIG_RTC_ALARM */
472
473 /* Restart counter */
474 ret = counter_start(config->counter_dev);
475 if (ret < 0) {
476 return ret;
477 }
478
479 return 0;
480 }
481
rtc_counter_get_time(const struct device * dev,struct rtc_time * timeptr)482 static int rtc_counter_get_time(const struct device *dev, struct rtc_time *timeptr)
483 {
484 const struct rtc_counter_config *config = dev->config;
485 struct rtc_counter_data *data = dev->data;
486 uint32_t now_ticks;
487 int ret;
488 int64_t epoch;
489 uint64_t current_ticks_64;
490 uint32_t freq;
491
492 if (timeptr == NULL) {
493 return -EINVAL;
494 }
495
496 ret = counter_get_value(config->counter_dev, &now_ticks);
497
498 if (ret < 0) {
499 return ret;
500 }
501
502 K_SPINLOCK(&data->lock) {
503 epoch = data->epoch_offset;
504 }
505
506 /* Compute accumulated ticks (may be > 32-bit) */
507 int64_t sum_ticks = (int64_t)now_ticks + epoch;
508
509 if (sum_ticks < 0) {
510 return -ERANGE;
511 }
512 current_ticks_64 = (uint64_t)sum_ticks;
513 freq = counter_get_frequency(config->counter_dev);
514
515 /* Optional guard: derived seconds must fit 32-bit to mirror prior check */
516 if (freq == 0U) {
517 return -ERANGE;
518 }
519 if ((current_ticks_64 / (uint64_t)freq) > (uint64_t)UINT32_MAX) {
520 return -ERANGE;
521 }
522
523 memset(timeptr, 0, sizeof(struct rtc_time));
524 rtc_counter_ticks_to_time(current_ticks_64, freq, timeptr);
525
526 return 0;
527 }
528
529 #if defined(CONFIG_RTC_UPDATE)
530
rtc_counter_update_set_callback(const struct device * dev,rtc_update_callback callback,void * user_data)531 static int rtc_counter_update_set_callback(const struct device *dev, rtc_update_callback callback,
532 void *user_data)
533 {
534 ARG_UNUSED(dev);
535 ARG_UNUSED(callback);
536 ARG_UNUSED(user_data);
537
538 return -ENOTSUP;
539 }
540
541 #endif /* CONFIG_RTC_UPDATE */
542
543 #if defined(CONFIG_RTC_CALIBRATION)
544
rtc_counter_set_calibration(const struct device * dev,int32_t calibration)545 static int rtc_counter_set_calibration(const struct device *dev, int32_t calibration)
546 {
547 ARG_UNUSED(dev);
548 ARG_UNUSED(calibration);
549 return -ENOTSUP;
550 }
551
rtc_counter_get_calibration(const struct device * dev,int32_t * calibration)552 static int rtc_counter_get_calibration(const struct device *dev, int32_t *calibration)
553 {
554 ARG_UNUSED(dev);
555 ARG_UNUSED(calibration);
556 return -ENOTSUP;
557 }
558
559 #endif /* CONFIG_RTC_CALIBRATION */
560
rtc_counter_init(const struct device * dev)561 static int rtc_counter_init(const struct device *dev)
562 {
563 const struct rtc_counter_config *config = dev->config;
564 struct rtc_counter_data *data = dev->data;
565 uint32_t freq;
566
567 if (!device_is_ready(config->counter_dev)) {
568 LOG_ERR("Counter device %s not ready", config->counter_dev->name);
569 return -ENODEV;
570 }
571
572 /* Validate counter frequency (must be non-zero) */
573 freq = counter_get_frequency(config->counter_dev);
574 if (freq == 0U) {
575 LOG_ERR("Unsupported counter frequency: %u Hz", freq);
576 return -ENOTSUP;
577 }
578
579 /* Start with zero offset until rtc_set_time is called */
580 data->epoch_offset = 0;
581
582 #ifdef CONFIG_RTC_ALARM
583 data->rtc_dev = dev;
584 if (config->alarms_count == 0U) {
585 data->alarm_capable = false;
586 } else {
587 data->alarm_capable = true;
588 data->num_alarm_chans = config->alarms_count;
589 /* Clear per-channel state */
590 for (uint8_t i = 0; i < data->num_alarm_chans; i++) {
591 data->alarm_callback[i] = NULL;
592 data->alarm_user_data[i] = NULL;
593 data->alarm_mask[i] = 0;
594 memset(&data->alarm_time[i], 0, sizeof(struct rtc_time));
595 data->alarm_pending[i] = false;
596 }
597 }
598 #endif /* CONFIG_RTC_ALARM */
599
600 return 0;
601 }
602
603 static DEVICE_API(rtc, rtc_counter_driver_api) = {
604 .set_time = rtc_counter_set_time,
605 .get_time = rtc_counter_get_time,
606 #if defined(CONFIG_RTC_ALARM)
607 .alarm_get_supported_fields = rtc_counter_alarm_get_supported_fields,
608 .alarm_set_time = rtc_counter_alarm_set_time,
609 .alarm_get_time = rtc_counter_alarm_get_time,
610 .alarm_is_pending = rtc_counter_alarm_is_pending,
611 .alarm_set_callback = rtc_counter_alarm_set_callback,
612 #endif /* CONFIG_RTC_ALARM */
613 #if defined(CONFIG_RTC_UPDATE)
614 .update_set_callback = rtc_counter_update_set_callback,
615 #endif /* CONFIG_RTC_UPDATE */
616 #if defined(CONFIG_RTC_CALIBRATION)
617 .set_calibration = rtc_counter_set_calibration,
618 .get_calibration = rtc_counter_get_calibration,
619 #endif /* CONFIG_RTC_CALIBRATION */
620 };
621
622 /* Ensure RTC init priority is bigger than counter */
623 BUILD_ASSERT(CONFIG_RTC_INIT_PRIORITY > CONFIG_COUNTER_INIT_PRIORITY,
624 "RTC init priority must be bigger than counter");
625
626 #define RTC_COUNTER_ALARMS_COUNT(n) DT_PROP_OR(DT_DRV_INST(n), alarms_count, 0)
627 #define RTC_COUNTER_ALARMS_SZ(n) MAX(RTC_COUNTER_ALARMS_COUNT(n), 1)
628
629 #if defined(CONFIG_RTC_ALARM)
630
631 /* Per-instance static storage for alarm context, sized from DT */
632 #define RTC_COUNTER_DECLARE_ALARM_STORAGE(n) \
633 static rtc_alarm_callback rtc_counter_alarm_callback_arr_##n[RTC_COUNTER_ALARMS_SZ(n)]; \
634 static void *rtc_counter_alarm_user_data_arr_##n[RTC_COUNTER_ALARMS_SZ(n)]; \
635 static uint16_t rtc_counter_alarm_mask_arr_##n[RTC_COUNTER_ALARMS_SZ(n)]; \
636 static struct rtc_time rtc_counter_alarm_time_arr_##n[RTC_COUNTER_ALARMS_SZ(n)]; \
637 static bool rtc_counter_alarm_pending_arr_##n[RTC_COUNTER_ALARMS_SZ(n)];
638
639 DT_INST_FOREACH_STATUS_OKAY(RTC_COUNTER_DECLARE_ALARM_STORAGE)
640
641 #endif /* CONFIG_RTC_ALARM */
642
643 #define RTC_COUNTER_DEVICE_INIT(n) \
644 static const struct rtc_counter_config rtc_counter_config_##n = { \
645 .counter_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \
646 .alarms_count = DT_PROP_OR(DT_DRV_INST(n), alarms_count, 0), \
647 }; \
648 static struct rtc_counter_data rtc_counter_data_##n = { \
649 IF_ENABLED(CONFIG_RTC_ALARM, ( \
650 .alarm_callback = rtc_counter_alarm_callback_arr_##n, \
651 .alarm_user_data = rtc_counter_alarm_user_data_arr_##n, \
652 .alarm_mask = rtc_counter_alarm_mask_arr_##n, \
653 .alarm_time = rtc_counter_alarm_time_arr_##n, \
654 .alarm_pending = rtc_counter_alarm_pending_arr_##n, \
655 )) \
656 }; \
657 DEVICE_DT_INST_DEFINE(n, rtc_counter_init, NULL, &rtc_counter_data_##n, \
658 &rtc_counter_config_##n, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \
659 &rtc_counter_driver_api);
660
661 DT_INST_FOREACH_STATUS_OKAY(RTC_COUNTER_DEVICE_INIT)
662