1 /*
2 * Copyright (c) 2023 Nuvoton Technology Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nuvoton_numaker_pwm
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/reset.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/drivers/pwm.h>
13 #include <zephyr/drivers/clock_control.h>
14 #include <zephyr/drivers/clock_control/clock_control_numaker.h>
15 #include <zephyr/logging/log.h>
16 #include <soc.h>
17 #include <NuMicro.h>
18
19 LOG_MODULE_REGISTER(pwm_numaker, CONFIG_PWM_LOG_LEVEL);
20
21 /* 11-bit prescaler in Numaker EPWM modules */
22 #define NUMAKER_PWM_MAX_PRESCALER BIT(11)
23 #define NUMAKER_PWM_CHANNEL_COUNT 6
24 #define NUMAKER_PWM_RELOAD_CNT (0xFFFFU)
25 #define NUMAKER_SYSCLK_FREQ DT_PROP(DT_NODELABEL(sysclk), clock_frequency)
26 /* EPWM channel 0~5 mask */
27 #define NUMAKER_PWM_CHANNEL_MASK (0x3FU)
28
29 /* Device config */
30 struct pwm_numaker_config {
31 /* EPWM base address */
32 EPWM_T *epwm;
33 uint32_t prescale;
34 const struct reset_dt_spec reset;
35 /* clock configuration */
36 uint32_t clk_modidx;
37 uint32_t clk_src;
38 uint32_t clk_div;
39 const struct device *clk_dev;
40 const struct pinctrl_dev_config *pincfg;
41 void (*irq_config_func)(const struct device *dev);
42 };
43
44 struct pwm_numaker_capture_data {
45 pwm_capture_callback_handler_t callback;
46 void *user_data;
47 /* Only support either one of PWM_CAPTURE_TYPE_PULSE, PWM_CAPTURE_TYPE_PERIOD */
48 bool pulse_capture;
49 bool single_mode;
50 bool is_busy;
51 uint32_t curr_edge_mode;
52 uint32_t next_edge_mode;
53 };
54
55 /* Driver context/data */
56 struct pwm_numaker_data {
57 uint32_t clock_freq;
58 uint32_t cycles_per_sec;
59 #ifdef CONFIG_PWM_CAPTURE
60 uint32_t overflows;
61 struct pwm_numaker_capture_data capture[NUMAKER_PWM_CHANNEL_COUNT];
62 #endif /* CONFIG_PWM_CAPTURE */
63 };
64
pwm_numaker_configure(const struct device * dev)65 static void pwm_numaker_configure(const struct device *dev)
66 {
67 const struct pwm_numaker_config *cfg = dev->config;
68 EPWM_T *epwm = cfg->epwm;
69
70 /* Disable EPWM channel 0~5 before config */
71 EPWM_ForceStop(epwm, NUMAKER_PWM_CHANNEL_MASK);
72
73 /* Set EPWM default normal polarity as inverse disabled */
74 epwm->POLCTL &= ~(NUMAKER_PWM_CHANNEL_MASK << EPWM_POLCTL_PINV0_Pos);
75 }
76
77 /* PWM api functions */
pwm_numaker_set_cycles(const struct device * dev,uint32_t channel,uint32_t period_cycles,uint32_t pulse_cycles,pwm_flags_t flags)78 static int pwm_numaker_set_cycles(const struct device *dev, uint32_t channel,
79 uint32_t period_cycles, uint32_t pulse_cycles, pwm_flags_t flags)
80 {
81 const struct pwm_numaker_config *cfg = dev->config;
82 struct pwm_numaker_data *data = dev->data;
83 EPWM_T *epwm = cfg->epwm;
84 uint32_t channel_mask = BIT(channel);
85
86 LOG_DBG("Channel=0x%x, CAPIEN=0x%x, CAPIF=0x%x", channel, epwm->CAPIEN,
87 epwm->CAPIF);
88
89 /* Set EPWM polarity */
90 if (flags & PWM_POLARITY_INVERTED) {
91 epwm->POLCTL |= BIT(EPWM_POLCTL_PINV0_Pos + channel);
92 } else {
93 epwm->POLCTL &= ~BIT(EPWM_POLCTL_PINV0_Pos + channel);
94 }
95
96 /* Force disable EPWM channel as while pulse_cycles = 0 */
97 if (period_cycles == 0U) {
98 EPWM_Stop(epwm, channel_mask);
99 EPWM_ForceStop(epwm, channel_mask);
100 EPWM_DisableOutput(epwm, channel_mask);
101 return 0;
102 }
103
104 /* Set EPWM channel & output configuration */
105 EPWM_ConfigOutputChannel(epwm, channel, data->cycles_per_sec / period_cycles,
106 (100U * pulse_cycles) / period_cycles);
107
108 /* Enable EPWM Output path for EPWM channel */
109 EPWM_EnableOutput(epwm, channel_mask);
110
111 /* Enable Timer for EPWM channel */
112 EPWM_Start(epwm, channel_mask);
113
114 LOG_DBG("cycles_per_sec=0x%x, pulse_cycles=0x%x, period_cycles=0x%x",
115 data->cycles_per_sec, pulse_cycles, period_cycles);
116 LOG_DBG("CTL1=0x%x, POEN=0x%x, CNTEN=0x%x", epwm->CTL1, epwm->POEN, epwm->CNTEN);
117 LOG_DBG("Channel=0x%x, CAPIEN=0x%x, CAPIF=0x%x", channel, epwm->CAPIEN, epwm->CAPIF);
118
119 return 0;
120 }
121
pwm_numaker_get_cycles_per_sec(const struct device * dev,uint32_t channel,uint64_t * cycles)122 static int pwm_numaker_get_cycles_per_sec(const struct device *dev, uint32_t channel,
123 uint64_t *cycles)
124 {
125 const struct pwm_numaker_config *cfg = dev->config;
126 struct pwm_numaker_data *data = dev->data;
127
128 ARG_UNUSED(channel);
129
130 data->cycles_per_sec = data->clock_freq / (cfg->prescale + 1U);
131 *cycles = (uint64_t)data->cycles_per_sec;
132
133 return 0;
134 }
135
136 #ifdef CONFIG_PWM_CAPTURE
pwm_numaker_configure_capture(const struct device * dev,uint32_t channel,pwm_flags_t flags,pwm_capture_callback_handler_t cb,void * user_data)137 static int pwm_numaker_configure_capture(const struct device *dev, uint32_t channel,
138 pwm_flags_t flags, pwm_capture_callback_handler_t cb,
139 void *user_data)
140 {
141 struct pwm_numaker_data *data = dev->data;
142 uint32_t pair = channel;
143
144 LOG_DBG("");
145
146 data->capture[pair].callback = cb;
147 data->capture[pair].user_data = user_data;
148
149 if (data->capture[pair].is_busy) {
150 LOG_ERR("Capture already active on this channel %d", pair);
151 return -EBUSY;
152 }
153 if ((flags & PWM_CAPTURE_TYPE_MASK) == PWM_CAPTURE_TYPE_BOTH) {
154 LOG_ERR("Cannot capture both period and pulse width");
155 return -ENOTSUP;
156 }
157
158 if ((flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS) {
159 data->capture[pair].single_mode = false;
160 } else {
161 data->capture[pair].single_mode = true;
162 }
163
164 if (flags & PWM_CAPTURE_TYPE_PERIOD) {
165 data->capture[pair].pulse_capture = false;
166
167 if (flags & PWM_POLARITY_INVERTED) {
168 data->capture[pair].curr_edge_mode = EPWM_CAPTURE_INT_FALLING_LATCH;
169 data->capture[pair].next_edge_mode = EPWM_CAPTURE_INT_FALLING_LATCH;
170 } else {
171 data->capture[pair].curr_edge_mode = EPWM_CAPTURE_INT_RISING_LATCH;
172 data->capture[pair].next_edge_mode = EPWM_CAPTURE_INT_RISING_LATCH;
173 }
174 } else {
175 data->capture[pair].pulse_capture = true;
176
177 if (flags & PWM_POLARITY_INVERTED) {
178 data->capture[pair].curr_edge_mode = EPWM_CAPTURE_INT_FALLING_LATCH;
179 data->capture[pair].next_edge_mode = EPWM_CAPTURE_INT_RISING_LATCH;
180 } else {
181 data->capture[pair].curr_edge_mode = EPWM_CAPTURE_INT_RISING_LATCH;
182 data->capture[pair].next_edge_mode = EPWM_CAPTURE_INT_FALLING_LATCH;
183 }
184 }
185
186 return 0;
187 }
188
pwm_numaker_enable_capture(const struct device * dev,uint32_t channel)189 static int pwm_numaker_enable_capture(const struct device *dev, uint32_t channel)
190 {
191 const struct pwm_numaker_config *cfg = dev->config;
192 struct pwm_numaker_data *data = dev->data;
193 EPWM_T *epwm = cfg->epwm;
194 uint32_t pair = channel;
195 uint32_t channel_mask = BIT(channel);
196 uint32_t unit_time_nsec = (1000000000U / data->cycles_per_sec);
197
198 LOG_DBG("");
199
200 if (!data->capture[pair].callback) {
201 LOG_ERR("PWM capture not configured");
202 return -EINVAL;
203 }
204
205 if (data->capture[pair].is_busy) {
206 LOG_ERR("Capture already active on this channel %d", pair);
207 return -EBUSY;
208 }
209
210 data->capture[pair].is_busy = true;
211
212 /* Set capture configuration */
213 EPWM_ConfigCaptureChannel(epwm, channel, unit_time_nsec, 0);
214
215 /* Enable Capture Function for EPWM */
216 EPWM_EnableCapture(epwm, channel_mask);
217
218 /* Enable Timer for EPWM */
219 EPWM_Start(epwm, channel_mask);
220
221 EPWM_ClearCaptureIntFlag(epwm, channel,
222 EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);
223
224 /* EnableInterrupt */
225 EPWM_EnableCaptureInt(epwm, channel, data->capture[pair].curr_edge_mode);
226
227 LOG_DBG("Channel=0x%x, CAPIEN=0x%x, CAPIF=0x%x", channel, epwm->CAPIEN,
228 epwm->CAPIF);
229
230 return 0;
231 }
232
pwm_numaker_disable_capture(const struct device * dev,uint32_t channel)233 static int pwm_numaker_disable_capture(const struct device *dev, uint32_t channel)
234 {
235 const struct pwm_numaker_config *cfg = dev->config;
236 struct pwm_numaker_data *data = dev->data;
237 EPWM_T *epwm = cfg->epwm;
238 uint32_t channel_mask = BIT(channel);
239
240 LOG_DBG("");
241
242 data->capture[channel].is_busy = false;
243 EPWM_Stop(epwm, channel_mask);
244 EPWM_ForceStop(epwm, channel_mask);
245 EPWM_DisableCapture(epwm, channel_mask);
246 EPWM_DisableCaptureInt(epwm, channel,
247 EPWM_CAPTURE_INT_RISING_LATCH | EPWM_CAPTURE_INT_FALLING_LATCH);
248 EPWM_ClearCaptureIntFlag(epwm, channel,
249 EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);
250 LOG_DBG("CAPIEN = 0x%x\n", epwm->CAPIEN);
251 return 0;
252 }
253
254 /*
255 * Get capture cycles between current channel edge until next chnannel edge.
256 * The capture period counter down count from 0x10000, and auto-reload to 0x10000
257 */
pwm_numaker_get_cap_cycle(EPWM_T * epwm,uint32_t channel,uint32_t curr_edge,uint32_t next_edge,uint32_t * cycles)258 static int pwm_numaker_get_cap_cycle(EPWM_T *epwm, uint32_t channel, uint32_t curr_edge,
259 uint32_t next_edge, uint32_t *cycles)
260 {
261 uint16_t curr_cnt;
262 uint16_t next_cnt;
263 uint32_t next_if_mask;
264 uint32_t capif_base;
265 uint32_t time_out_cnt;
266 int status = 0;
267 uint32_t period_reloads = 0;
268
269 /* PWM counter is timing critical, to avoid print msg from irq_isr until getting cycles */
270 LOG_DBG("");
271
272 EPWM_ClearPeriodIntFlag(epwm, channel);
273
274 capif_base = (next_edge == EPWM_CAPTURE_INT_FALLING_LATCH) ? EPWM_CAPIF_CFLIF0_Pos
275 : EPWM_CAPIF_CRLIF0_Pos;
276 next_if_mask = BIT(capif_base + channel);
277 time_out_cnt = NUMAKER_SYSCLK_FREQ / 2; /* 500 ms time-out */
278 LOG_DBG("Channel=0x%x, R-Cnt=0x%x, F-Cnt0x%x, CNT-0x%x", channel,
279 EPWM_GET_CAPTURE_RISING_DATA(epwm, channel),
280 EPWM_GET_CAPTURE_FALLING_DATA(epwm, channel), epwm->CNT[channel]);
281 curr_cnt = (curr_edge == EPWM_CAPTURE_INT_FALLING_LATCH)
282 ? EPWM_GET_CAPTURE_FALLING_DATA(epwm, channel)
283 : (uint16_t)EPWM_GET_CAPTURE_RISING_DATA(epwm, channel);
284
285 /* Wait for Capture Next Indicator */
286 while ((epwm->CAPIF & next_if_mask) == 0) {
287 if (EPWM_GetPeriodIntFlag(epwm, channel)) {
288 EPWM_ClearPeriodIntFlag(epwm, channel);
289 period_reloads++;
290 }
291 if (--time_out_cnt == 0) {
292 status = -EAGAIN;
293 goto done;
294 }
295 }
296
297 /* Clear Capture Falling and Rising Indicator */
298 EPWM_ClearCaptureIntFlag(epwm, channel,
299 EPWM_CAPTURE_INT_FALLING_LATCH | EPWM_CAPTURE_INT_RISING_LATCH);
300
301 /* Get Capture Latch Counter Data */
302 next_cnt = (next_edge == EPWM_CAPTURE_INT_FALLING_LATCH)
303 ? (uint16_t)EPWM_GET_CAPTURE_FALLING_DATA(epwm, channel)
304 : (uint16_t)EPWM_GET_CAPTURE_RISING_DATA(epwm, channel);
305
306 *cycles = (period_reloads * NUMAKER_PWM_RELOAD_CNT) + curr_cnt - next_cnt;
307 LOG_DBG("cycles=0x%x, period_reloads=0x%x, CAPIF=0x%x, cur-0x%x ,next-0x%x",
308 *cycles, period_reloads, epwm->CAPIF, curr_cnt, next_cnt);
309
310 done:
311 return status;
312 }
313
pwm_numaker_channel_cap(const struct device * dev,EPWM_T * epwm,uint32_t channel)314 static void pwm_numaker_channel_cap(const struct device *dev, EPWM_T *epwm, uint32_t channel)
315 {
316 struct pwm_numaker_data *data = dev->data;
317 struct pwm_numaker_capture_data *capture;
318 uint32_t cycles = 0;
319 int status;
320
321 EPWM_DisableCaptureInt(epwm, channel, EPWM_CAPTURE_INT_RISING_LATCH |
322 EPWM_CAPTURE_INT_FALLING_LATCH);
323
324 capture = &data->capture[channel];
325
326 /* Calculate cycles */
327 status = pwm_numaker_get_cap_cycle(
328 epwm, channel, data->capture[channel].curr_edge_mode,
329 data->capture[channel].next_edge_mode, &cycles);
330 if (capture->pulse_capture) {
331 /* For PWM_CAPTURE_TYPE_PULSE */
332 capture->callback(dev, channel, 0, cycles, status, capture->user_data);
333 } else {
334 /* For PWM_CAPTURE_TYPE_PERIOD */
335 capture->callback(dev, channel, cycles, 0, status, capture->user_data);
336 }
337
338 if (capture->single_mode) {
339 EPWM_DisableCaptureInt(epwm, channel, EPWM_CAPTURE_INT_RISING_LATCH |
340 EPWM_CAPTURE_INT_FALLING_LATCH);
341 data->capture[channel].is_busy = false;
342 } else {
343 EPWM_ClearCaptureIntFlag(epwm, channel, EPWM_CAPTURE_INT_FALLING_LATCH |
344 EPWM_CAPTURE_INT_RISING_LATCH);
345 EPWM_EnableCaptureInt(epwm, channel, data->capture[channel].curr_edge_mode);
346 /* data->capture[channel].is_busy = true; */
347 }
348 }
349
pwm_numaker_isr(const struct device * dev,uint32_t st_channel,uint32_t end_channel)350 static void pwm_numaker_isr(const struct device *dev, uint32_t st_channel, uint32_t end_channel)
351 {
352 const struct pwm_numaker_config *cfg = dev->config;
353 struct pwm_numaker_data *data = dev->data;
354 EPWM_T *epwm = cfg->epwm;
355 struct pwm_numaker_capture_data *capture;
356 uint32_t int_status;
357 uint32_t cap_intsts;
358 int i;
359 uint32_t int_mask = (BIT(st_channel) | BIT(end_channel));
360 uint32_t cap_int_rise_mask, cap_int_fall_mask;
361 uint32_t cap_int_mask =
362 (EPWM_CAPIF_CFLIF0_Msk << st_channel | EPWM_CAPIF_CRLIF0_Msk << st_channel |
363 EPWM_CAPIF_CFLIF0_Msk << end_channel | EPWM_CAPIF_CRLIF0_Msk << end_channel);
364
365 /* Get Output int status */
366 int_status = epwm->AINTSTS & int_mask;
367 /* Clear Output int status */
368 if (int_status != 0x00) {
369 epwm->AINTSTS = int_status;
370 }
371
372 /* Get CAP int status */
373 cap_intsts = epwm->CAPIF & cap_int_mask;
374
375 /* PWM counter is timing critical, to avoid print msg from irq_isr
376 * until getting capture cycles.
377 */
378 LOG_DBG("Channel=0x%x, CAPIEN=0x%x, CAPIF=0x%x, capIntMask=0x%x",
379 st_channel, epwm->CAPIEN, epwm->CAPIF, cap_int_mask);
380 if (cap_intsts != 0x00) { /* Capture Interrupt */
381 /* Clear CAP int status */
382 epwm->CAPIF = cap_intsts;
383
384 /* Rising latch or Falling latch */
385 for (i = st_channel; i <= end_channel; i++) {
386 capture = &data->capture[i];
387 if (capture == NULL) {
388 continue;
389 }
390 cap_int_rise_mask = (EPWM_CAPTURE_INT_RISING_LATCH << i);
391 cap_int_fall_mask = (EPWM_CAPTURE_INT_FALLING_LATCH << i);
392 if ((cap_int_rise_mask | cap_int_fall_mask) & cap_intsts) {
393 pwm_numaker_channel_cap(dev, epwm, i);
394 }
395 }
396 }
397 }
398
pwm_numaker_p0_isr(const struct device * dev)399 static void pwm_numaker_p0_isr(const struct device *dev)
400 {
401 /* Pair0 service channel 0, 1 */
402 pwm_numaker_isr(dev, 0, 1);
403 }
404
pwm_numaker_p1_isr(const struct device * dev)405 static void pwm_numaker_p1_isr(const struct device *dev)
406 {
407 /* Pair1 service channel 2, 3 */
408 pwm_numaker_isr(dev, 2, 3);
409 }
410
pwm_numaker_p2_isr(const struct device * dev)411 static void pwm_numaker_p2_isr(const struct device *dev)
412 {
413 /* Pair2 service channel 4, 5 */
414 pwm_numaker_isr(dev, 4, 5);
415 }
416 #endif /* CONFIG_PWM_CAPTURE */
417
418 /* PWM driver registration */
419 static const struct pwm_driver_api pwm_numaker_driver_api = {
420 .set_cycles = pwm_numaker_set_cycles,
421 .get_cycles_per_sec = pwm_numaker_get_cycles_per_sec,
422 #ifdef CONFIG_PWM_CAPTURE
423 .configure_capture = pwm_numaker_configure_capture,
424 .enable_capture = pwm_numaker_enable_capture,
425 .disable_capture = pwm_numaker_disable_capture,
426 #endif /* CONFIG_PWM_CAPTURE */
427 };
428
429 /* Alternative EPWM clock get rate before support standard clock_control_get_rate */
pwm_numaker_clk_get_rate(EPWM_T * epwm,uint32_t * rate)430 static int pwm_numaker_clk_get_rate(EPWM_T *epwm, uint32_t *rate)
431 {
432 uint32_t clk_src;
433 uint32_t epwm_clk_src;
434
435 if (epwm == EPWM0) {
436 clk_src = CLK->CLKSEL2 & CLK_CLKSEL2_EPWM0SEL_Msk;
437 } else if (epwm == EPWM1) {
438 clk_src = CLK->CLKSEL2 & CLK_CLKSEL2_EPWM1SEL_Msk;
439 } else {
440 LOG_ERR("Invalid EPWM node");
441 return -EINVAL;
442 }
443
444 if (clk_src == 0U) {
445 /* clock source is from PLL clock */
446 epwm_clk_src = CLK_GetPLLClockFreq();
447 } else {
448 /* clock source is from PCLK */
449 SystemCoreClockUpdate();
450 if (epwm == EPWM0) {
451 epwm_clk_src = CLK_GetPCLK0Freq();
452 } else { /* (epwm == EPWM1) */
453 epwm_clk_src = CLK_GetPCLK1Freq();
454 }
455 }
456 *rate = epwm_clk_src;
457 return 0;
458 }
459
pwm_numaker_init(const struct device * dev)460 static int pwm_numaker_init(const struct device *dev)
461 {
462 const struct pwm_numaker_config *cfg = dev->config;
463 struct pwm_numaker_data *data = dev->data;
464 EPWM_T *epwm = cfg->epwm;
465 uint32_t clock_freq;
466 int err;
467
468 struct numaker_scc_subsys scc_subsys;
469
470 /* Validate this module's reset object */
471 if (!device_is_ready(cfg->reset.dev)) {
472 LOG_ERR("reset controller not ready");
473 return -ENODEV;
474 }
475
476 SYS_UnlockReg();
477
478 /* CLK controller */
479 memset(&scc_subsys, 0x00, sizeof(scc_subsys));
480 scc_subsys.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC;
481 scc_subsys.pcc.clk_modidx = cfg->clk_modidx;
482 scc_subsys.pcc.clk_src = cfg->clk_src;
483 scc_subsys.pcc.clk_div = cfg->clk_div;
484
485 /* Equivalent to CLK_EnableModuleClock() */
486 err = clock_control_on(cfg->clk_dev, (clock_control_subsys_t)&scc_subsys);
487 if (err != 0) {
488 goto done;
489 }
490 /* Equivalent to CLK_SetModuleClock() */
491 err = clock_control_configure(cfg->clk_dev, (clock_control_subsys_t)&scc_subsys, NULL);
492 if (err != 0) {
493 goto done;
494 }
495
496 /* Not support standard clock_control_get_rate yet */
497 /* clock_control_get_rate(cfg->clk_dev,(clock_control_subsys_t)&scc_subsys,&clock_freq); */
498 err = pwm_numaker_clk_get_rate(epwm, &clock_freq);
499
500 if (err < 0) {
501 LOG_ERR("Get EPWM clock rate failure %d", err);
502 goto done;
503 }
504 data->clock_freq = clock_freq;
505 data->cycles_per_sec = data->clock_freq / (cfg->prescale + 1U);
506
507 err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
508 if (err) {
509 LOG_ERR("Failed to apply pinctrl state");
510 goto done;
511 }
512
513 /* Reset PWM to default state, same as BSP's SYS_ResetModule(id_rst) */
514 reset_line_toggle_dt(&cfg->reset);
515
516 /* Configure PWM device initially */
517 pwm_numaker_configure(dev);
518
519 #ifdef CONFIG_PWM_CAPTURE
520 /* Enable NVIC */
521 cfg->irq_config_func(dev);
522 #endif
523
524 done:
525 SYS_LockReg();
526 return err;
527 }
528
529 #ifdef CONFIG_PWM_CAPTURE
530 #define NUMAKER_PWM_IRQ_CONFIG_FUNC(n) \
531 static void pwm_numaker_irq_config_##n(const struct device *dev) \
532 { \
533 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, pair0, irq), \
534 DT_INST_IRQ_BY_NAME(n, pair0, priority), pwm_numaker_p0_isr, \
535 DEVICE_DT_INST_GET(n), 0); \
536 \
537 irq_enable(DT_INST_IRQ_BY_NAME(n, pair0, irq)); \
538 \
539 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, pair1, irq), \
540 DT_INST_IRQ_BY_NAME(n, pair1, priority), pwm_numaker_p1_isr, \
541 DEVICE_DT_INST_GET(n), 0); \
542 \
543 irq_enable(DT_INST_IRQ_BY_NAME(n, pair1, irq)); \
544 \
545 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(n, pair2, irq), \
546 DT_INST_IRQ_BY_NAME(n, pair2, priority), pwm_numaker_p2_isr, \
547 DEVICE_DT_INST_GET(n), 0); \
548 \
549 irq_enable(DT_INST_IRQ_BY_NAME(n, pair2, irq)); \
550 }
551 #define IRQ_FUNC_INIT(n) .irq_config_func = pwm_numaker_irq_config_##n
552 #else
553 #define NUMAKER_PWM_IRQ_CONFIG_FUNC(n)
554 #define IRQ_FUNC_INIT(n)
555 #endif
556
557 #define NUMAKER_PWM_INIT(inst) \
558 PINCTRL_DT_INST_DEFINE(inst); \
559 NUMAKER_PWM_IRQ_CONFIG_FUNC(inst) \
560 \
561 static const struct pwm_numaker_config pwm_numaker_cfg_##inst = { \
562 .epwm = (EPWM_T *)DT_INST_REG_ADDR(inst), \
563 .prescale = DT_INST_PROP(inst, prescaler), \
564 .reset = RESET_DT_SPEC_INST_GET(inst), \
565 .clk_modidx = DT_INST_CLOCKS_CELL(inst, clock_module_index), \
566 .clk_src = DT_INST_CLOCKS_CELL(inst, clock_source), \
567 .clk_div = DT_INST_CLOCKS_CELL(inst, clock_divider), \
568 .clk_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))), \
569 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
570 IRQ_FUNC_INIT(inst)}; \
571 \
572 static struct pwm_numaker_data pwm_numaker_data_##inst; \
573 \
574 DEVICE_DT_INST_DEFINE(inst, &pwm_numaker_init, NULL, &pwm_numaker_data_##inst, \
575 &pwm_numaker_cfg_##inst, PRE_KERNEL_1, \
576 CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &pwm_numaker_driver_api);
577
578 DT_INST_FOREACH_STATUS_OKAY(NUMAKER_PWM_INIT)
579