1 /*
2 * Copyright (c) 2024 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT renesas_ra_agt_counter
8
9 #include <zephyr/devicetree.h>
10 #include <zephyr/drivers/counter.h>
11 #include <zephyr/irq.h>
12 #include <r_agt.h>
13 #include <zephyr/logging/log.h>
14
15 #define FSUB_FREQUENCY_HZ (32768U)
16 typedef volatile R_AGTX0_AGT16_CTRL_Type agt_reg_ctrl_t;
17 #define AGT_AGTCR_STOP_TIMER 0xF0U /* 1111 0000 */
18 #define AGT_AGTCR_START_TIMER 0xF1U /* 1111 0001 */
19 #define AGT_AGTCR_FLAGS_MASK 0xF0U /* 1111 0000 */
20
21 #define AGT_PRV_MIN_CLOCK_FREQ (0U)
22 #define AGT_SOURCE_CLOCK_PCLKB_BITS (0x3U)
23
24 LOG_MODULE_REGISTER(ra_agt_counter, CONFIG_COUNTER_LOG_LEVEL);
25
26 struct counter_ra_agt_config {
27 /* info must be first element */
28 struct counter_config_info info; /* Counter Config info struct */
29 uint32_t channel; /* Channel no */
30 uint32_t cycle_end_irq; /* Underflow interrupt*/
31 uint32_t cycle_end_ipl; /* Underflow interrupt priority */
32 uint32_t channel_ipl; /* IPL channel no. */
33 uint32_t channel_irq; /* IRQ channel no. */
34 /* Device tree data */
35 timer_source_div_t source_div; /* Clock source divider */
36 agt_agtio_filter_t agtio_filter; /* Input filter for AGTIO */
37 agt_measure_t measurement_mode; /* Measurement mode */
38 agt_clock_t count_source; /* AGT channel clock source */
39 uint32_t resolution; /* AGT node resolution */
40 uint32_t dt_reg; /* Reg address from device tree */
41 };
42
43 struct counter_ra_agt_alarm {
44 counter_alarm_callback_t callback;
45 void *data;
46 };
47
48 struct counter_ra_agt_data {
49 /* Common data */
50 R_AGTX0_Type *agt_reg; /* AGT register base address */
51 uint32_t period; /* Current timer period (counts) */
52 uint32_t period_counts; /* Period in raw timer counts */
53 uint32_t cycle_end_ipl; /* Cycle end interrupt priority */
54 IRQn_Type cycle_end_irq; /* Cycle end interrupt */
55 /* Alarm-related data */
56 struct counter_ra_agt_alarm alarm; /* Counter alarm config struct */
57 counter_top_callback_t top_cb; /* Top level callback */
58 void *top_cb_data; /* Top level callback data */
59 uint32_t guard_period; /* Absolute counter alarm's guard period */
60 };
61
62 static void r_agt_hardware_cfg(const struct device *dev);
63 static void r_agt_period_register_set(const struct device *dev, uint32_t period_counts);
64 static uint32_t r_agt_clock_frequency_get(agt_reg_ctrl_t *p_reg);
65 static fsp_err_t r_agt_common_preamble(agt_reg_ctrl_t *p_reg);
66 static agt_reg_ctrl_t *r_agt_reg_ctrl_get(const struct device *dev);
67 static uint32_t r_agt_ticks_sub(uint32_t val, uint32_t old, uint32_t top);
68
counter_ra_agt_start(const struct device * dev)69 static int counter_ra_agt_start(const struct device *dev)
70 {
71 agt_reg_ctrl_t *const reg = r_agt_reg_ctrl_get(dev);
72 uint32_t timeout = UINT32_MAX;
73
74 reg->AGTCR = AGT_AGTCR_START_TIMER;
75
76 while (!(reg->AGTCR & BIT(R_AGTX0_AGT16_CTRL_AGTCR_TCSTF_Pos)) && likely(--timeout))
77 ;
78
79 return timeout > 0 ? 0 : -EIO;
80 }
81
counter_ra_agt_stop(const struct device * dev)82 static int counter_ra_agt_stop(const struct device *dev)
83 {
84 agt_reg_ctrl_t *const reg = r_agt_reg_ctrl_get(dev);
85 uint32_t timeout = UINT32_MAX;
86
87 reg->AGTCR = AGT_AGTCR_STOP_TIMER;
88
89 while ((reg->AGTCR & BIT(R_AGTX0_AGT16_CTRL_AGTCR_TCSTF_Pos)) && likely(--timeout))
90 ;
91
92 return timeout > 0 ? 0 : -EIO;
93 }
94
counter_ra_agt_read(const struct device * dev)95 static inline int counter_ra_agt_read(const struct device *dev)
96 {
97 struct counter_ra_agt_data *data = dev->data;
98
99 return data->agt_reg->AGT16.AGT;
100 }
counter_ra_agt_get_value(const struct device * dev,uint32_t * ticks)101 static int counter_ra_agt_get_value(const struct device *dev, uint32_t *ticks)
102 {
103 *ticks = counter_ra_agt_read(dev);
104 return 0;
105 }
106
counter_ra_agt_get_top_value(const struct device * dev)107 static uint32_t counter_ra_agt_get_top_value(const struct device *dev)
108 {
109 const struct counter_ra_agt_config *config = dev->config;
110
111 return config->info.max_top_value;
112 }
113
counter_ra_agt_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)114 static int counter_ra_agt_set_top_value(const struct device *dev, const struct counter_top_cfg *cfg)
115 {
116 const struct counter_ra_agt_config *config = dev->config;
117 struct counter_ra_agt_data *data = dev->data;
118 agt_reg_ctrl_t *p_reg_ctrl = r_agt_reg_ctrl_get(dev);
119
120 if (cfg->ticks != config->info.max_top_value) {
121 return -ENOTSUP;
122 }
123
124 if (cfg->callback == NULL) {
125 /* Disable Match Register A if callback is NULL */
126 p_reg_ctrl->AGTCR_b.TCMAF = 0;
127 } else {
128 /* Enable Match Register A */
129 p_reg_ctrl->AGTCR_b.TCMAF = 1;
130 }
131
132 data->top_cb = cfg->callback;
133 data->top_cb_data = cfg->user_data;
134
135 return 0;
136 }
137
counter_ra_agt_set_compare_value(const struct device * dev,uint8_t chan,uint32_t value)138 static inline void counter_ra_agt_set_compare_value(const struct device *dev, uint8_t chan,
139 uint32_t value)
140 {
141 struct counter_ra_agt_data *data = dev->data;
142
143 data->agt_reg->AGT16.AGTCMA = value;
144 }
145
counter_ra_agt_enable_channel_irq(const struct device * dev)146 static inline void counter_ra_agt_enable_channel_irq(const struct device *dev)
147 {
148 const struct counter_ra_agt_config *config = dev->config;
149 agt_reg_ctrl_t *p_reg_ctrl = r_agt_reg_ctrl_get(dev);
150
151 /* Enable AGT compare match A */
152 p_reg_ctrl->AGTCMSR |= BIT(R_AGTX0_AGT16_CTRL_AGTCMSR_TCMEA_Pos);
153 irq_enable(config->channel_irq);
154 }
155
counter_ra_agt_clear_channel_irq(const struct device * dev)156 static inline void counter_ra_agt_clear_channel_irq(const struct device *dev)
157 {
158 const struct counter_ra_agt_config *config = dev->config;
159 agt_reg_ctrl_t *const reg_ctrl = r_agt_reg_ctrl_get(dev);
160
161 reg_ctrl->AGTCR_b.TCMAF = 0;
162 R_BSP_IrqStatusClear(config->channel_irq);
163 NVIC_ClearPendingIRQ(config->channel_irq);
164 }
165
counter_ra_agt_set_alarm(const struct device * dev,uint8_t chan,const struct counter_alarm_cfg * alarm_cfg)166 static int counter_ra_agt_set_alarm(const struct device *dev, uint8_t chan,
167 const struct counter_alarm_cfg *alarm_cfg)
168 {
169 struct counter_ra_agt_data *data = dev->data;
170 const struct counter_ra_agt_config *config = dev->config;
171
172 const bool absolute = alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE;
173 const uint32_t top = counter_ra_agt_get_top_value(dev);
174 struct counter_ra_agt_alarm *const alarm = &data->alarm;
175 uint16_t val = alarm_cfg->ticks;
176 uint32_t now;
177 uint32_t max_rel_val;
178 bool irq_on_late;
179 int32_t diff = 0;
180 int err = 0;
181
182 if (alarm_cfg->ticks > counter_ra_agt_get_top_value(dev)) {
183 LOG_ERR("%s: alarm ticks is larger than top value", __func__);
184 return -EINVAL;
185 }
186
187 if (alarm->callback) {
188 LOG_ERR("%s: Device busy. Callback is still available.", __func__);
189 return -EBUSY;
190 }
191 alarm->callback = alarm_cfg->callback;
192 alarm->data = alarm_cfg->user_data;
193
194 /*
195 * stop AGT for writing the match register directly instead of sync when underflow event
196 * occur reference: RA6M5 User manual - 22.3.2 Reload Register and AGT Compare Match A/B
197 * Register Rewrite Operation
198 */
199 counter_ra_agt_stop(dev);
200 now = counter_ra_agt_read(dev);
201
202 if (absolute) {
203 /* Acceptable alarm value range, counting from current tick (now) */
204 max_rel_val = top - data->guard_period;
205 irq_on_late = alarm_cfg->flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
206 } else {
207 /* If relative value is smaller than half of the counter range
208 * it is assumed that there is a risk of setting value too late
209 * and late detection algorithm must be applied. When late
210 * setting is detected, interrupt shall be triggered for
211 * immediate expiration of the timer. Detection is performed
212 * by limiting relative distance between CC and counter.
213 *
214 * Note that half of counter range is an arbitrary value.
215 */
216 irq_on_late = (val < (top / 2U));
217 /* Limit max to detect short relative being set too late */
218 max_rel_val = irq_on_late ? top / 2U : top;
219 /* Recalculate alarm tick timestamp based on current tick (now) */
220 val = r_agt_ticks_sub(now, val, top);
221 }
222
223 counter_ra_agt_set_compare_value(dev, chan, val);
224
225 /* Decrement value to detect also case when val == counter_ra_agt_read(dev).
226 * Otherwise, condition would need to include comparing diff against 0.
227 */
228 diff = r_agt_ticks_sub(now, val - 1, top);
229
230 if (diff > max_rel_val) {
231 if (absolute) {
232 err = -ETIME;
233 }
234
235 /* Interrupt is triggered always for relative alarm and
236 * for absolute depending on the flag.
237 */
238 if (irq_on_late) {
239 /* Set pending IRQ */
240 counter_ra_agt_enable_channel_irq(dev);
241 NVIC_SetPendingIRQ(config->channel_irq);
242 } else {
243 alarm->callback = NULL;
244 alarm->data = NULL;
245 }
246 }
247
248 counter_ra_agt_clear_channel_irq(dev);
249 counter_ra_agt_enable_channel_irq(dev);
250 counter_ra_agt_start(dev);
251
252 return err;
253 }
254
counter_ra_agt_cancel_alarm(const struct device * dev,uint8_t chan)255 static int counter_ra_agt_cancel_alarm(const struct device *dev, uint8_t chan)
256 {
257 struct counter_ra_agt_data *data = dev->data;
258
259 agt_reg_ctrl_t *p_reg_ctrl = r_agt_reg_ctrl_get(dev);
260
261 /* Disable AGT compare match A */
262 p_reg_ctrl->AGTCMSR &= ~BIT(R_AGTX0_AGT16_CTRL_AGTCMSR_TCMEA_Pos);
263
264 data->alarm.callback = NULL;
265 data->alarm.data = NULL;
266
267 return 0;
268 }
269
counter_ra_agt_get_pending_int(const struct device * dev)270 static uint32_t counter_ra_agt_get_pending_int(const struct device *dev)
271 {
272 agt_reg_ctrl_t *const reg = r_agt_reg_ctrl_get(dev);
273
274 return (reg->AGTCR & AGT_AGTCR_FLAGS_MASK) != 0;
275 }
276
counter_ra_agt_get_freq(const struct device * dev)277 static uint32_t counter_ra_agt_get_freq(const struct device *dev)
278 {
279 struct counter_ra_agt_data *data = dev->data;
280 timer_info_t info;
281
282 agt_reg_ctrl_t *p_reg = r_agt_reg_ctrl_get(dev);
283
284 r_agt_common_preamble(p_reg);
285
286 /* Get and store period */
287 info.period_counts = data->period;
288 info.clock_frequency = r_agt_clock_frequency_get(p_reg);
289
290 /* AGT supports only counting down direction */
291 info.count_direction = TIMER_DIRECTION_DOWN;
292
293 return info.clock_frequency;
294 }
295
counter_ra_agt_agti_isr(const struct device * dev)296 static void counter_ra_agt_agti_isr(const struct device *dev)
297 {
298 const struct counter_ra_agt_config *config = dev->config;
299 struct counter_ra_agt_data *data = dev->data;
300 agt_reg_ctrl_t *const reg_ctrl = r_agt_reg_ctrl_get(dev);
301
302 R_BSP_IrqStatusClear(config->cycle_end_irq);
303
304 const uint32_t agtcr = reg_ctrl->AGTCR;
305
306 if (agtcr & BIT(R_AGTX0_AGT16_CTRL_AGTCR_TUNDF_Pos)) {
307 if (data->top_cb) {
308 data->top_cb(dev, data->top_cb_data);
309 }
310 }
311
312 reg_ctrl->AGTCR = (uint8_t)(agtcr & ~(BIT(R_AGTX0_AGT16_CTRL_AGTCR_TUNDF_Pos) |
313 BIT(R_AGTX0_AGT16_CTRL_AGTCR_TEDGF_Pos)));
314 }
315
counter_ra_agt_agtcmai_isr(const struct device * dev)316 static void counter_ra_agt_agtcmai_isr(const struct device *dev)
317 {
318 const struct counter_ra_agt_config *config = dev->config;
319 struct counter_ra_agt_data *data = dev->data;
320 agt_reg_ctrl_t *const reg_ctrl = r_agt_reg_ctrl_get(dev);
321 struct counter_ra_agt_alarm *const alarm = &data->alarm;
322
323 const uint32_t val = data->agt_reg->AGT16.AGTCMA;
324
325 const counter_alarm_callback_t cb = alarm->callback;
326 void *cb_data = alarm->data;
327
328 alarm->callback = NULL;
329 alarm->data = NULL;
330
331 /* Disable AGT compare match A */
332 reg_ctrl->AGTCMSR &= ~BIT(R_AGTX0_AGT16_CTRL_AGTCMSR_TCMEA_Pos);
333
334 R_BSP_IrqStatusClear(config->channel_irq);
335
336 if (cb) {
337 cb(dev, config->channel, val, cb_data);
338 }
339
340 reg_ctrl->AGTCR_b.TCMAF = 0;
341 }
342
counter_ra_agt_get_guard_period(const struct device * dev,uint32_t flags)343 static uint32_t counter_ra_agt_get_guard_period(const struct device *dev, uint32_t flags)
344 {
345 struct counter_ra_agt_data *data = dev->data;
346
347 return data->guard_period;
348 }
349
counter_ra_agt_set_guard_period(const struct device * dev,uint32_t guard,uint32_t flags)350 static int counter_ra_agt_set_guard_period(const struct device *dev, uint32_t guard, uint32_t flags)
351 {
352 struct counter_ra_agt_data *data = dev->data;
353
354 if (counter_ra_agt_get_top_value(dev) < guard) {
355 LOG_ERR("%s: Invalid guard rate", __func__);
356 return -EINVAL;
357 }
358
359 data->guard_period = guard;
360
361 return 0;
362 }
363
counter_ra_agt_init(const struct device * dev)364 static int counter_ra_agt_init(const struct device *dev)
365 {
366 const struct counter_ra_agt_config *config = dev->config;
367 struct counter_ra_agt_data *data = dev->data;
368
369 data->agt_reg = (R_AGTX0_Type *)config->dt_reg;
370
371 agt_reg_ctrl_t *p_reg_ctrl = r_agt_reg_ctrl_get(dev);
372
373 /* Power on the AGT channel */
374 R_BSP_MODULE_START(FSP_IP_AGT, config->channel);
375
376 /* Clear AGTCR. This stops the timer if it is running and clears the flags */
377 p_reg_ctrl->AGTCR = 0U;
378
379 /* The timer is stopped in sync with the count clock, or in sync with PCLK in event and
380 * external count modes.
381 */
382 FSP_HARDWARE_REGISTER_WAIT(0U, p_reg_ctrl->AGTCR_b.TCSTF);
383
384 /* Clear AGTMR2 before AGTMR1 is set. Reference Note 3 in section 25.2.6 "AGT Mode Register
385 * 2 (AGTMR2)" of the RA6M3 manual R01UH0886EJ0100.
386 */
387 p_reg_ctrl->AGTMR2 = 0U;
388
389 /* Set count source and divider and configure pins */
390 r_agt_hardware_cfg(dev);
391
392 /* Set period register and update duty cycle if output mode is used for one-shot or periodic
393 * mode.
394 */
395 r_agt_period_register_set(dev, data->period_counts);
396
397 /* 22.3.1 Reload Register and Counter Rewrite Operation */
398 p_reg_ctrl->AGTCMSR |= BIT(R_AGTX0_AGT16_CTRL_AGTCMSR_TCMEA_Pos);
399
400 return 0;
401 }
402
r_agt_reg_ctrl_get(const struct device * dev)403 static agt_reg_ctrl_t *r_agt_reg_ctrl_get(const struct device *dev)
404 {
405 struct counter_ra_agt_data *data = dev->data;
406 agt_reg_ctrl_t *p_reg_ctrl = &data->agt_reg->AGT16.CTRL;
407
408 return p_reg_ctrl;
409 }
410
r_agt_hardware_cfg(const struct device * dev)411 static void r_agt_hardware_cfg(const struct device *dev)
412 {
413 const struct counter_ra_agt_config *config = dev->config;
414
415 /* Update the divider for PCLKB */
416 agt_reg_ctrl_t *p_reg_ctrl = r_agt_reg_ctrl_get(dev);
417 uint32_t count_source_int = (uint32_t)config->count_source;
418 uint32_t agtmr2 = 0U;
419 uint32_t agtcmsr = 0U;
420 uint32_t tedgsel = 0U;
421 uint32_t agtioc = config->agtio_filter;
422 uint32_t mode = config->measurement_mode & R_AGTX0_AGT16_CTRL_AGTMR1_TMOD_Msk;
423 uint32_t edge = 0U;
424
425 if (AGT_CLOCK_PCLKB == config->count_source) {
426 if (TIMER_SOURCE_DIV_1 != config->source_div) {
427 /* Toggle the second bit if the count_source_int is not 0 to map PCLKB / 8
428 * to 1 and PCLKB / 2 to 3.
429 */
430 count_source_int = config->source_div ^ 2U;
431 count_source_int <<= R_AGTX0_AGT16_CTRL_AGTMR1_TCK_Pos;
432 }
433 }
434
435 else if (AGT_CLOCK_AGT_UNDERFLOW != config->count_source) {
436 /* Update the divider for LOCO/subclock */
437 agtmr2 = config->source_div;
438 } else {
439 /* No divider can be used when count source is AGT_CLOCK_AGT_UNDERFLOW */
440 }
441
442 uint32_t agtmr1 = (count_source_int | edge) | mode;
443
444 /* Configure output settings */
445
446 agtioc |= tedgsel;
447
448 p_reg_ctrl->AGTIOC = (uint8_t)agtioc;
449 p_reg_ctrl->AGTCMSR = (uint8_t)agtcmsr;
450 p_reg_ctrl->AGTMR1 = (uint8_t)agtmr1;
451 p_reg_ctrl->AGTMR2 = (uint8_t)agtmr2;
452 }
453
r_agt_period_register_set(const struct device * dev,uint32_t period_counts)454 static void r_agt_period_register_set(const struct device *dev, uint32_t period_counts)
455 {
456 struct counter_ra_agt_data *data = dev->data;
457
458 /* Store the period value so it can be retrieved later */
459 data->period = period_counts;
460
461 /* Set counter to period minus one */
462 uint32_t period_reg = (period_counts - 1U);
463
464 data->agt_reg->AGT16.AGT = (uint16_t)period_reg;
465 }
466
r_agt_clock_frequency_get(agt_reg_ctrl_t * p_reg)467 static uint32_t r_agt_clock_frequency_get(agt_reg_ctrl_t *p_reg)
468 {
469 uint32_t clock_freq_hz = 0U;
470 uint8_t count_source_int = p_reg->AGTMR1_b.TCK;
471 timer_source_div_t divider = TIMER_SOURCE_DIV_1;
472
473 if (0U == (count_source_int & (~AGT_SOURCE_CLOCK_PCLKB_BITS))) {
474 /* Call CGC function to obtain current PCLKB clock frequency */
475 clock_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKB);
476
477 /* If Clock source is PCLKB or derived from PCLKB */
478 divider = (timer_source_div_t)count_source_int;
479
480 if (divider != 0U) {
481 /* Set divider to 3 to divide by 8 when AGTMR1.TCK is 1 (PCLKB / 8). Set
482 * divider to 1 to divide by 2 when AGTMR1.TCK is 3 (PCLKB / 2). XOR with 2
483 * to convert 1 to 3 and 3 to 1.
484 */
485 divider ^= 2U;
486 }
487 } else {
488 /* Else either fSUB clock or LOCO clock is used. The frequency is set to 32Khz
489 * (32768). This function does not support AGT0 underflow as count source.
490 */
491 clock_freq_hz = FSUB_FREQUENCY_HZ;
492 divider = (timer_source_div_t)p_reg->AGTMR2_b.CKS;
493 }
494
495 clock_freq_hz >>= divider;
496
497 return clock_freq_hz;
498 }
499
r_agt_common_preamble(agt_reg_ctrl_t * p_reg)500 static fsp_err_t r_agt_common_preamble(agt_reg_ctrl_t *p_reg)
501 {
502 /* Ensure timer state reflects expected status. Reference section 25.4.1 "Count Operation
503 * Start and Stop Control" in the RA6M3 manual R01UH0886EJ0100.
504 */
505 uint32_t agtcr_tstart = p_reg->AGTCR_b.TSTART;
506
507 FSP_HARDWARE_REGISTER_WAIT(agtcr_tstart, p_reg->AGTCR_b.TCSTF);
508
509 return FSP_SUCCESS;
510 }
511
r_agt_ticks_sub(uint32_t val,uint32_t old,uint32_t top)512 static uint32_t r_agt_ticks_sub(uint32_t val, uint32_t old, uint32_t top)
513 {
514 if (likely(IS_BIT_MASK(top))) {
515 return (val - old) & top;
516 }
517
518 /* if top is not 2^n-1 */
519 return (val >= old) ? (val - old) : val + top + 1 - old;
520 }
521
522 static DEVICE_API(counter, ra_agt_driver_api) = {
523 .start = counter_ra_agt_start,
524 .stop = counter_ra_agt_stop,
525 .get_value = counter_ra_agt_get_value,
526 .set_alarm = counter_ra_agt_set_alarm,
527 .cancel_alarm = counter_ra_agt_cancel_alarm,
528 .set_top_value = counter_ra_agt_set_top_value,
529 .get_pending_int = counter_ra_agt_get_pending_int,
530 .get_top_value = counter_ra_agt_get_top_value,
531 .get_freq = counter_ra_agt_get_freq,
532 .get_guard_period = counter_ra_agt_get_guard_period,
533 .set_guard_period = counter_ra_agt_set_guard_period,
534 };
535
536 #define TIMER(idx) DT_INST_PARENT(idx)
537
538 #define _ELC_EVENT_AGT_INT(channel) ELC_EVENT_AGT##channel##_INT
539 #define _ELC_EVENT_AGT_COMPARE_A(channel) ELC_EVENT_AGT##channel##_COMPARE_A
540
541 #define ELC_EVENT_AGT_INT(channel) _ELC_EVENT_AGT_INT(channel)
542 #define ELC_EVENT_AGT_COMPARE_A(channel) _ELC_EVENT_AGT_COMPARE_A(channel)
543
544 #define AGT_DEVICE_INIT_RA(n) \
545 static const struct counter_ra_agt_config ra_agt_config_##n = { \
546 .info = \
547 { \
548 .max_top_value = UINT16_MAX, \
549 .freq = 0, \
550 .channels = 1, \
551 .flags = 0, \
552 }, \
553 .agtio_filter = AGT_AGTIO_FILTER_NONE, \
554 .measurement_mode = 0U, \
555 .source_div = DT_PROP(TIMER(n), renesas_prescaler), \
556 .count_source = DT_STRING_TOKEN(TIMER(n), renesas_count_source), \
557 .channel = DT_PROP(TIMER(n), channel), \
558 .channel_irq = DT_IRQ_BY_NAME(TIMER(n), agtcmai, irq), \
559 .channel_ipl = DT_IRQ_BY_NAME(TIMER(n), agtcmai, priority), \
560 .cycle_end_irq = DT_IRQ_BY_NAME(TIMER(n), agti, irq), \
561 .cycle_end_ipl = DT_IRQ_BY_NAME(TIMER(n), agti, priority), \
562 .resolution = DT_PROP(TIMER(n), renesas_resolution), \
563 .dt_reg = DT_REG_ADDR(TIMER(n)), \
564 }; \
565 \
566 static struct counter_ra_agt_data counter_ra_agt_data_##n = { \
567 .period_counts = 0, \
568 }; \
569 \
570 static int counter_ra_agt_##n##_init(const struct device *dev) \
571 { \
572 R_ICU->IELSR[DT_IRQ_BY_NAME(TIMER(n), agti, irq)] = \
573 ELC_EVENT_AGT_INT(DT_PROP(TIMER(n), channel)); \
574 IRQ_CONNECT(DT_IRQ_BY_NAME(TIMER(n), agti, irq), \
575 DT_IRQ_BY_NAME(TIMER(n), agti, priority), counter_ra_agt_agti_isr, \
576 DEVICE_DT_INST_GET(n), 0); \
577 irq_enable(DT_IRQ_BY_NAME(TIMER(n), agti, irq)); \
578 \
579 R_ICU->IELSR[DT_IRQ_BY_NAME(TIMER(n), agtcmai, irq)] = \
580 ELC_EVENT_AGT_COMPARE_A(DT_PROP(TIMER(n), channel)); \
581 IRQ_CONNECT(DT_IRQ_BY_NAME(TIMER(n), agtcmai, irq), \
582 DT_IRQ_BY_NAME(TIMER(n), agtcmai, priority), \
583 counter_ra_agt_agtcmai_isr, DEVICE_DT_INST_GET(n), 0); \
584 irq_disable(DT_IRQ_BY_NAME(TIMER(n), agtcmai, irq)); \
585 \
586 return counter_ra_agt_init(dev); \
587 } \
588 \
589 DEVICE_DT_INST_DEFINE(n, counter_ra_agt_##n##_init, NULL, &counter_ra_agt_data_##n, \
590 &ra_agt_config_##n, POST_KERNEL, CONFIG_COUNTER_INIT_PRIORITY, \
591 &ra_agt_driver_api);
592
593 DT_INST_FOREACH_STATUS_OKAY(AGT_DEVICE_INIT_RA)
594