1 /*
2  * Copyright (c) 2024 Renesas Electronics Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/device.h>
9 #include <zephyr/irq.h>
10 #include <zephyr/drivers/pwm.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/dt-bindings/pwm/renesas_rz_pwm.h>
13 #include "r_gpt.h"
14 #include "r_gpt_cfg.h"
15 #include <zephyr/logging/log.h>
16 
17 LOG_MODULE_REGISTER(pwm_renesas_rz_gpt, CONFIG_PWM_LOG_LEVEL);
18 
19 #define DT_DRV_COMPAT renesas_rz_gpt_pwm
20 
21 #define GPT_PRV_GTIO_HIGH_COMPARE_MATCH_LOW_CYCLE_END 0x6U
22 #define GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END 0x9U
23 #define GPT_PRV_GTIOR_INITIAL_LEVEL_BIT               4
24 
25 #define CAPTURE_BOTH_MODE_FIRST_EVENT_IS_CAPTURE_PULSE   1
26 #define CAPTURE_BOTH_MODE_SECOND_EVENT_IS_CAPTURE_PERIOD 2
27 
28 struct pwm_rz_gpt_capture_data {
29 	pwm_capture_callback_handler_t callback;
30 	void *user_data;
31 	uint64_t period;
32 	uint64_t pulse;
33 	uint16_t capture_type_flag;
34 	uint32_t capture_both_event_count;
35 	bool is_busy;
36 	uint32_t overflows;
37 	bool continuous;
38 	uint32_t capture_channel;
39 };
40 
41 struct pwm_rz_gpt_data {
42 	timer_cfg_t *fsp_cfg;
43 	gpt_instance_ctrl_t *fsp_ctrl;
44 #ifdef CONFIG_PWM_CAPTURE
45 	struct pwm_rz_gpt_capture_data capture;
46 #endif /* CONFIG_PWM_CAPTURE */
47 };
48 
49 struct pwm_rz_gpt_config {
50 	const struct pinctrl_dev_config *pincfg;
51 	const timer_api_t *fsp_api;
52 };
53 
pwm_rz_gpt_gtior_calculate(gpt_pin_level_t const stop_level)54 static uint32_t pwm_rz_gpt_gtior_calculate(gpt_pin_level_t const stop_level)
55 {
56 	/* The stop level is used as both the initial level and the stop level. */
57 	uint32_t gtior = R_GPT0_GTIOR_OAE_Msk | ((uint32_t)stop_level << R_GPT0_GTIOR_OADFLT_Pos) |
58 			 ((uint32_t)stop_level << GPT_PRV_GTIOR_INITIAL_LEVEL_BIT);
59 
60 	uint32_t gtion = GPT_PRV_GTIO_LOW_COMPARE_MATCH_HIGH_CYCLE_END;
61 
62 	/* Calculate the gtior value for PWM mode only */
63 	gtior |= gtion;
64 
65 	return gtior;
66 }
67 
pwm_rz_gpt_apply_gtior_config(gpt_instance_ctrl_t * const p_ctrl,timer_cfg_t const * const p_cfg)68 static int pwm_rz_gpt_apply_gtior_config(gpt_instance_ctrl_t *const p_ctrl,
69 					 timer_cfg_t const *const p_cfg)
70 {
71 	gpt_extended_cfg_t *p_extend = (gpt_extended_cfg_t *)p_cfg->p_extend;
72 	uint32_t gtior = p_extend->gtior_setting.gtior;
73 
74 #if GPT_CFG_OUTPUT_SUPPORT_ENABLE
75 	/* Check if custom GTIOR settings are provided. */
76 	if (p_extend->gtior_setting.gtior == 0) {
77 		/* If custom GTIOR settings are not provided, calculate GTIOR. */
78 		if (p_extend->gtioca.output_enabled) {
79 			uint32_t gtioca_gtior =
80 				pwm_rz_gpt_gtior_calculate(p_extend->gtioca.stop_level);
81 			gtior |= gtioca_gtior << R_GPT0_GTIOR_GTIOA_Pos;
82 		}
83 
84 		if (p_extend->gtiocb.output_enabled) {
85 			uint32_t gtiocb_gtior =
86 				pwm_rz_gpt_gtior_calculate(p_extend->gtiocb.stop_level);
87 			gtior |= gtiocb_gtior << R_GPT0_GTIOR_GTIOB_Pos;
88 		}
89 	}
90 #endif
91 
92 	/* Check if custom GTIOR settings are provided. */
93 	if (p_extend->gtior_setting.gtior == 0) {
94 		/*
95 		 * If custom GTIOR settings are not provided, configure the noise filter for
96 		 * the GTIOC pins.
97 		 */
98 		gtior |= (uint32_t)(p_extend->capture_filter_gtioca << R_GPT0_GTIOR_NFAEN_Pos);
99 		gtior |= (uint32_t)(p_extend->capture_filter_gtiocb << R_GPT0_GTIOR_NFBEN_Pos);
100 	}
101 
102 	/* Set the I/O control register. */
103 	p_ctrl->p_reg->GTIOR = gtior;
104 
105 	return 0;
106 }
107 
pwm_rz_gpt_set_cycles(const struct device * dev,uint32_t channel,uint32_t period_cycles,uint32_t pulse_cycles,pwm_flags_t flags)108 static int pwm_rz_gpt_set_cycles(const struct device *dev, uint32_t channel, uint32_t period_cycles,
109 				 uint32_t pulse_cycles, pwm_flags_t flags)
110 {
111 	const struct pwm_rz_gpt_config *cfg = dev->config;
112 	struct pwm_rz_gpt_data *data = dev->data;
113 	gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend;
114 	uint32_t pulse;
115 	fsp_err_t err;
116 	uint32_t pin;
117 
118 	/* gtioca and gtiocb setting */
119 	if (channel == RZ_PWM_GPT_IO_A) {
120 		pin = GPT_IO_PIN_GTIOCA;
121 		fsp_cfg_extend->gtioca.output_enabled = true;
122 	} else if (channel == RZ_PWM_GPT_IO_B) {
123 		pin = GPT_IO_PIN_GTIOCB;
124 		fsp_cfg_extend->gtiocb.output_enabled = true;
125 	} else {
126 		LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins");
127 		return -EINVAL;
128 	}
129 
130 	if ((data->fsp_ctrl->variant == TIMER_VARIANT_16_BIT && period_cycles > UINT16_MAX) ||
131 	    (data->fsp_ctrl->variant == TIMER_VARIANT_32_BIT && period_cycles > UINT32_MAX)) {
132 		LOG_ERR("Out of range period cycles are not valid");
133 		return -EINVAL;
134 	}
135 
136 	pulse = (flags & PWM_POLARITY_INVERTED) ? period_cycles - pulse_cycles : pulse_cycles;
137 
138 	/* Apply gtio output setting */
139 	pwm_rz_gpt_apply_gtior_config(data->fsp_ctrl, data->fsp_cfg);
140 
141 	/* Stop timer */
142 	err = cfg->fsp_api->stop(data->fsp_ctrl);
143 	if (err != FSP_SUCCESS) {
144 		return -EIO;
145 	}
146 
147 	/* Update period cycles, reflected at an overflow */
148 	err = cfg->fsp_api->periodSet(data->fsp_ctrl, period_cycles);
149 	if (err != FSP_SUCCESS) {
150 		return -EIO;
151 	}
152 
153 	/* Update pulse cycles, reflected at an overflow */
154 	err = cfg->fsp_api->dutyCycleSet(data->fsp_ctrl, pulse, pin);
155 	if (err != FSP_SUCCESS) {
156 		return -EIO;
157 	}
158 
159 	/* Start timer */
160 	err = cfg->fsp_api->start(data->fsp_ctrl);
161 	if (err != FSP_SUCCESS) {
162 		return -EIO;
163 	}
164 
165 	return 0;
166 };
167 
pwm_rz_gpt_get_cycles_per_sec(const struct device * dev,uint32_t channel,uint64_t * cycles)168 static int pwm_rz_gpt_get_cycles_per_sec(const struct device *dev, uint32_t channel,
169 					 uint64_t *cycles)
170 {
171 	const struct pwm_rz_gpt_config *cfg = dev->config;
172 	struct pwm_rz_gpt_data *data = dev->data;
173 	timer_info_t info;
174 	fsp_err_t err;
175 
176 	if (!(channel == RZ_PWM_GPT_IO_A || channel == RZ_PWM_GPT_IO_B)) {
177 		LOG_ERR("Valid only for RZ_PWM_GPT_IO_A and RZ_PWM_GPT_IO_B pins");
178 		return -EINVAL;
179 	}
180 
181 	err = cfg->fsp_api->infoGet(data->fsp_ctrl, &info);
182 	if (err != FSP_SUCCESS) {
183 		return -EIO;
184 	}
185 	*cycles = (uint64_t)info.clock_frequency;
186 
187 	return 0;
188 };
189 
190 extern void gpt_capture_a_isr(void);
191 extern void gpt_capture_b_isr(void);
192 extern void gpt_counter_overflow_isr(void);
193 
194 #ifdef CONFIG_PWM_CAPTURE
195 
pwm_rz_gpt_configure_capture(const struct device * dev,uint32_t channel,pwm_flags_t flags,pwm_capture_callback_handler_t cb,void * user_data)196 static int pwm_rz_gpt_configure_capture(const struct device *dev, uint32_t channel,
197 					pwm_flags_t flags, pwm_capture_callback_handler_t cb,
198 					void *user_data)
199 {
200 	struct pwm_rz_gpt_data *data = dev->data;
201 	gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend;
202 
203 	if (!(flags & PWM_CAPTURE_TYPE_MASK)) {
204 		LOG_ERR("No PWWM capture type specified");
205 		return -EINVAL;
206 	}
207 	data->capture.capture_type_flag = flags & PWM_CAPTURE_TYPE_MASK;
208 	data->capture.capture_channel = channel;
209 	if (data->capture.is_busy) {
210 		LOG_ERR("Capture already active on this pin");
211 		return -EBUSY;
212 	}
213 	if (channel == RZ_PWM_GPT_IO_A) {
214 		if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) {
215 			data->capture.capture_both_event_count = 0;
216 			if (flags & PWM_POLARITY_INVERTED) {
217 				fsp_cfg_extend->start_source =
218 					(gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
219 						       GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
220 						       GPT_SOURCE_NONE);
221 			} else {
222 				fsp_cfg_extend->start_source =
223 					(gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW |
224 						       GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH |
225 						       GPT_SOURCE_NONE);
226 			}
227 			fsp_cfg_extend->capture_a_source =
228 				(gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW |
229 					       GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH |
230 					       GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
231 					       GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
232 					       GPT_SOURCE_NONE);
233 		} else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PERIOD) {
234 			if (flags & PWM_POLARITY_INVERTED) {
235 				fsp_cfg_extend->start_source =
236 					(gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
237 						       GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
238 						       GPT_SOURCE_NONE);
239 				fsp_cfg_extend->capture_a_source = fsp_cfg_extend->start_source;
240 			} else {
241 				fsp_cfg_extend->start_source =
242 					(gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW |
243 						       GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH |
244 						       GPT_SOURCE_NONE);
245 				fsp_cfg_extend->capture_a_source = fsp_cfg_extend->start_source;
246 			}
247 		} else {
248 			if (flags & PWM_POLARITY_INVERTED) {
249 				fsp_cfg_extend->start_source =
250 					(gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
251 						       GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
252 						       GPT_SOURCE_NONE);
253 				fsp_cfg_extend->capture_a_source =
254 					(gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW |
255 						       GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH |
256 						       GPT_SOURCE_NONE);
257 			} else {
258 				fsp_cfg_extend->start_source =
259 					(gpt_source_t)(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW |
260 						       GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH |
261 						       GPT_SOURCE_NONE);
262 				fsp_cfg_extend->capture_a_source =
263 					(gpt_source_t)(GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
264 						       GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
265 						       GPT_SOURCE_NONE);
266 			}
267 		}
268 	} else if (channel == RZ_PWM_GPT_IO_B) {
269 		if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) {
270 			data->capture.capture_both_event_count = 0;
271 			if (flags & PWM_POLARITY_INVERTED) {
272 				fsp_cfg_extend->start_source =
273 					(gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW |
274 						       GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH |
275 						       GPT_SOURCE_NONE);
276 			} else {
277 				fsp_cfg_extend->start_source =
278 					(gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW |
279 						       GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH |
280 						       GPT_SOURCE_NONE);
281 			}
282 			fsp_cfg_extend->capture_b_source =
283 				(gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW |
284 					       GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH |
285 					       GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW |
286 					       GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH |
287 					       GPT_SOURCE_NONE);
288 		} else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PERIOD) {
289 			if (flags & PWM_POLARITY_INVERTED) {
290 				fsp_cfg_extend->start_source =
291 					(gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW |
292 						       GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH |
293 						       GPT_SOURCE_NONE);
294 				fsp_cfg_extend->capture_b_source = fsp_cfg_extend->start_source;
295 			} else {
296 				fsp_cfg_extend->start_source =
297 					(gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW |
298 						       GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH |
299 						       GPT_SOURCE_NONE);
300 				fsp_cfg_extend->capture_b_source = fsp_cfg_extend->start_source;
301 			}
302 		} else {
303 			if (flags & PWM_POLARITY_INVERTED) {
304 				fsp_cfg_extend->start_source =
305 					(gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW |
306 						       GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH |
307 						       GPT_SOURCE_NONE);
308 				fsp_cfg_extend->capture_b_source =
309 					(gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW |
310 						       GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH |
311 						       GPT_SOURCE_NONE);
312 			} else {
313 				fsp_cfg_extend->start_source =
314 					(gpt_source_t)(GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW |
315 						       GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH |
316 						       GPT_SOURCE_NONE);
317 				fsp_cfg_extend->capture_b_source =
318 					(gpt_source_t)(GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW |
319 						       GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH |
320 						       GPT_SOURCE_NONE);
321 			}
322 		}
323 	}
324 
325 	data->capture.callback = cb;
326 	data->capture.user_data = user_data;
327 	data->capture.continuous = flags & PWM_CAPTURE_MODE_CONTINUOUS;
328 	if (data->capture.continuous) {
329 		if (channel == RZ_PWM_GPT_IO_A) {
330 			fsp_cfg_extend->stop_source = fsp_cfg_extend->capture_a_source;
331 		} else if (channel == RZ_PWM_GPT_IO_B) {
332 			fsp_cfg_extend->stop_source = fsp_cfg_extend->capture_b_source;
333 		}
334 		fsp_cfg_extend->clear_source = fsp_cfg_extend->start_source;
335 	}
336 
337 	else {
338 		fsp_cfg_extend->stop_source = (gpt_source_t)(GPT_SOURCE_NONE);
339 		fsp_cfg_extend->clear_source = (gpt_source_t)(GPT_SOURCE_NONE);
340 	}
341 
342 	return 0;
343 }
344 
pwm_rz_gpt_enable_capture(const struct device * dev,uint32_t channel)345 static int pwm_rz_gpt_enable_capture(const struct device *dev, uint32_t channel)
346 {
347 	const struct pwm_rz_gpt_config *cfg = dev->config;
348 	struct pwm_rz_gpt_data *data = dev->data;
349 	gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend;
350 	fsp_err_t err;
351 
352 	data->capture.capture_channel = channel;
353 
354 	if (data->capture.is_busy) {
355 		LOG_ERR("Capture already active on this pin");
356 		return -EBUSY;
357 	}
358 
359 	if (!data->capture.callback) {
360 		LOG_ERR("PWM capture not configured");
361 		return -EINVAL;
362 	}
363 
364 	data->capture.is_busy = true;
365 
366 	/* Enable capture source */
367 	err = cfg->fsp_api->enable(data->fsp_ctrl);
368 	if (err != FSP_SUCCESS) {
369 		return -EIO;
370 	}
371 
372 	/* Enable interruption */
373 	irq_enable(data->fsp_cfg->cycle_end_irq);
374 	if (channel == RZ_PWM_GPT_IO_A) {
375 		irq_enable(fsp_cfg_extend->capture_a_irq);
376 	} else if (channel == RZ_PWM_GPT_IO_B) {
377 		irq_enable(fsp_cfg_extend->capture_b_irq);
378 	}
379 
380 	return 0;
381 }
382 
pwm_rz_gpt_disable_capture(const struct device * dev,uint32_t channel)383 static int pwm_rz_gpt_disable_capture(const struct device *dev, uint32_t channel)
384 {
385 	const struct pwm_rz_gpt_config *cfg = dev->config;
386 	struct pwm_rz_gpt_data *data = dev->data;
387 	fsp_err_t err;
388 	gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend;
389 
390 	data->capture.capture_channel = channel;
391 	data->capture.is_busy = false;
392 
393 	/* Disable interruption */
394 	irq_disable(data->fsp_cfg->cycle_end_irq);
395 	if (channel == RZ_PWM_GPT_IO_A) {
396 		irq_disable(fsp_cfg_extend->capture_a_irq);
397 	} else if (channel == RZ_PWM_GPT_IO_B) {
398 		irq_disable(fsp_cfg_extend->capture_b_irq);
399 	}
400 
401 	/* Disable capture source */
402 	err = cfg->fsp_api->disable(data->fsp_ctrl);
403 	if (err != FSP_SUCCESS) {
404 		return -EIO;
405 	}
406 
407 	/* Stop timer */
408 	err = cfg->fsp_api->stop(data->fsp_ctrl);
409 	if (err != FSP_SUCCESS) {
410 		return -EIO;
411 	}
412 
413 	/* Clear timer */
414 	err = cfg->fsp_api->reset(data->fsp_ctrl);
415 	if (err != FSP_SUCCESS) {
416 		return -EIO;
417 	}
418 
419 	return 0;
420 }
421 
fsp_callback(timer_callback_args_t * p_args)422 static void fsp_callback(timer_callback_args_t *p_args)
423 {
424 	const struct device *dev = p_args->p_context;
425 	const struct pwm_rz_gpt_config *cfg = dev->config;
426 	struct pwm_rz_gpt_data *data = dev->data;
427 	timer_info_t info;
428 
429 	(void)cfg->fsp_api->infoGet(data->fsp_ctrl, &info);
430 
431 	uint64_t period = info.period_counts;
432 
433 	/* The maximum period is one more than the maximum 16,32-bit number, but will be reflected
434 	 * as 0
435 	 */
436 	if (period == 0U) {
437 		if (data->fsp_ctrl->variant == TIMER_VARIANT_16_BIT) {
438 			period = UINT16_MAX + 1U;
439 		} else {
440 			period = UINT32_MAX + 1U;
441 		}
442 	}
443 
444 	/* Capture event */
445 	if (p_args->event == TIMER_EVENT_CAPTURE_A) {
446 		if (p_args->capture != 0U) {
447 			bool check_disable_capture = false;
448 
449 			if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) {
450 				data->capture.capture_both_event_count++;
451 				if (data->capture.capture_both_event_count ==
452 				    CAPTURE_BOTH_MODE_FIRST_EVENT_IS_CAPTURE_PULSE) {
453 					data->capture.pulse = (data->capture.overflows * period) +
454 							      p_args->capture;
455 				}
456 				if (data->capture.capture_both_event_count ==
457 				    CAPTURE_BOTH_MODE_SECOND_EVENT_IS_CAPTURE_PERIOD) {
458 					data->capture.capture_both_event_count = 0;
459 					data->capture.period = (data->capture.overflows * period) +
460 							       p_args->capture;
461 					data->capture.callback(
462 						dev, GPT_IO_PIN_GTIOCA, data->capture.period,
463 						data->capture.pulse, 0, data->capture.user_data);
464 
465 					check_disable_capture = true;
466 				}
467 			} else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PULSE) {
468 				data->capture.pulse =
469 					(data->capture.overflows * period) + p_args->capture;
470 				data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0,
471 						       data->capture.pulse, 0,
472 						       data->capture.user_data);
473 
474 				check_disable_capture = true;
475 			} else {
476 				data->capture.period =
477 					(data->capture.overflows * period) + p_args->capture;
478 				data->capture.callback(dev, GPT_IO_PIN_GTIOCA, data->capture.period,
479 						       0, 0, data->capture.user_data);
480 
481 				check_disable_capture = true;
482 			}
483 			if (check_disable_capture) {
484 				data->capture.overflows = 0U;
485 				/* Disable capture in single mode */
486 				if (data->capture.continuous == false) {
487 					pwm_rz_gpt_disable_capture(dev, GPT_IO_PIN_GTIOCA);
488 				}
489 			}
490 		}
491 	} else if (p_args->event == TIMER_EVENT_CAPTURE_B) {
492 		if (p_args->capture != 0U) {
493 			bool check_disable_capture = false;
494 
495 			if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_BOTH) {
496 				data->capture.capture_both_event_count++;
497 				if (data->capture.capture_both_event_count ==
498 				    CAPTURE_BOTH_MODE_FIRST_EVENT_IS_CAPTURE_PULSE) {
499 					data->capture.pulse = (data->capture.overflows * period) +
500 							      p_args->capture;
501 				}
502 				if (data->capture.capture_both_event_count ==
503 				    CAPTURE_BOTH_MODE_SECOND_EVENT_IS_CAPTURE_PERIOD) {
504 					data->capture.capture_both_event_count = 0;
505 					data->capture.period = (data->capture.overflows * period) +
506 							       p_args->capture;
507 					data->capture.callback(
508 						dev, GPT_IO_PIN_GTIOCB, data->capture.period,
509 						data->capture.pulse, 0, data->capture.user_data);
510 
511 					check_disable_capture = true;
512 				}
513 			} else if (data->capture.capture_type_flag == PWM_CAPTURE_TYPE_PULSE) {
514 				data->capture.pulse =
515 					(data->capture.overflows * period) + p_args->capture;
516 				data->capture.callback(dev, GPT_IO_PIN_GTIOCB, 0,
517 						       data->capture.pulse, 0,
518 						       data->capture.user_data);
519 
520 				check_disable_capture = true;
521 			} else {
522 				data->capture.period =
523 					(data->capture.overflows * period) + p_args->capture;
524 				data->capture.callback(dev, GPT_IO_PIN_GTIOCB, data->capture.period,
525 						       0, 0, data->capture.user_data);
526 
527 				check_disable_capture = true;
528 			}
529 			if (check_disable_capture) {
530 				data->capture.overflows = 0U;
531 				/* Disable capture in single mode */
532 				if (data->capture.continuous == false) {
533 					pwm_rz_gpt_disable_capture(dev, GPT_IO_PIN_GTIOCB);
534 				}
535 			}
536 		}
537 	} else if (p_args->event == TIMER_EVENT_CYCLE_END) {
538 		data->capture.overflows++;
539 	} else {
540 		if (data->capture.capture_channel == RZ_PWM_GPT_IO_A) {
541 			data->capture.callback(dev, GPT_IO_PIN_GTIOCA, 0, 0, -ECANCELED,
542 					       data->capture.user_data);
543 		} else if (data->capture.capture_channel == RZ_PWM_GPT_IO_B) {
544 			data->capture.callback(dev, GPT_IO_PIN_GTIOCB, 0, 0, -ECANCELED,
545 					       data->capture.user_data);
546 		}
547 	}
548 }
549 
550 #endif /* CONFIG_PWM_CAPTURE */
551 
552 static DEVICE_API(pwm, pwm_rz_gpt_driver_api) = {
553 	.get_cycles_per_sec = pwm_rz_gpt_get_cycles_per_sec,
554 	.set_cycles = pwm_rz_gpt_set_cycles,
555 #ifdef CONFIG_PWM_CAPTURE
556 	.configure_capture = pwm_rz_gpt_configure_capture,
557 	.enable_capture = pwm_rz_gpt_enable_capture,
558 	.disable_capture = pwm_rz_gpt_disable_capture,
559 #endif /* CONFIG_PWM_CAPTURE */
560 };
561 
pwm_rz_gpt_init(const struct device * dev)562 static int pwm_rz_gpt_init(const struct device *dev)
563 {
564 	const struct pwm_rz_gpt_config *cfg = dev->config;
565 	struct pwm_rz_gpt_data *data = dev->data;
566 	gpt_extended_cfg_t *fsp_cfg_extend = (gpt_extended_cfg_t *)data->fsp_cfg->p_extend;
567 	int err;
568 
569 	err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
570 	if (err) {
571 		LOG_ERR("Failed to configure pins for PWM (%d)", err);
572 		return err;
573 	}
574 
575 #if defined(CONFIG_PWM_CAPTURE)
576 	data->fsp_cfg->p_callback = fsp_callback;
577 	data->fsp_cfg->p_context = dev;
578 #endif /* defined(CONFIG_PWM_CAPTURE) */
579 
580 	err = cfg->fsp_api->open(data->fsp_ctrl, data->fsp_cfg);
581 	if (err != FSP_SUCCESS) {
582 		return -EIO;
583 	}
584 
585 	irq_disable(data->fsp_cfg->cycle_end_irq);
586 	irq_disable(fsp_cfg_extend->capture_a_irq);
587 	irq_disable(fsp_cfg_extend->capture_b_irq);
588 
589 	return 0;
590 }
591 
592 #define GPT(idx) DT_INST_PARENT(idx)
593 
594 #define PWM_RZ_IRQ_CONFIG_INIT(inst)                                                               \
595 	do {                                                                                       \
596 		IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ccmpa, irq),                                 \
597 			    DT_IRQ_BY_NAME(GPT(inst), ccmpa, priority), gpt_capture_a_isr, NULL,   \
598 			    0);                                                                    \
599 		IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ccmpb, irq),                                 \
600 			    DT_IRQ_BY_NAME(GPT(inst), ccmpb, priority), gpt_capture_b_isr, NULL,   \
601 			    0);                                                                    \
602 		IRQ_CONNECT(DT_IRQ_BY_NAME(GPT(inst), ovf, irq),                                   \
603 			    DT_IRQ_BY_NAME(GPT(inst), ovf, priority), gpt_counter_overflow_isr,    \
604 			    NULL, 0);                                                              \
605 	} while (0)
606 
607 #define PWM_RZG_INIT(inst)                                                                         \
608 	PINCTRL_DT_INST_DEFINE(inst);                                                              \
609 	static gpt_instance_ctrl_t g_timer##inst##_ctrl;                                           \
610 	static gpt_extended_cfg_t g_timer##inst##_extend = {                                       \
611 		.gtioca =                                                                          \
612 			{                                                                          \
613 				.output_enabled = false,                                           \
614 				.stop_level = GPT_PIN_LEVEL_LOW,                                   \
615 			},                                                                         \
616 		.gtiocb =                                                                          \
617 			{                                                                          \
618 				.output_enabled = false,                                           \
619 				.stop_level = GPT_PIN_LEVEL_LOW,                                   \
620 			},                                                                         \
621 		.start_source = (gpt_source_t)(GPT_SOURCE_NONE),                                   \
622 		.stop_source = (gpt_source_t)(GPT_SOURCE_NONE),                                    \
623 		.clear_source = (gpt_source_t)(GPT_SOURCE_NONE),                                   \
624 		.count_up_source = (gpt_source_t)(GPT_SOURCE_NONE),                                \
625 		.count_down_source = (gpt_source_t)(GPT_SOURCE_NONE),                              \
626 		.capture_a_source = (gpt_source_t)(GPT_SOURCE_NONE),                               \
627 		.capture_b_source = (gpt_source_t)(GPT_SOURCE_NONE),                               \
628 		.capture_a_ipl = DT_IRQ_BY_NAME(GPT(inst), ccmpa, priority),                       \
629 		.capture_b_ipl = DT_IRQ_BY_NAME(GPT(inst), ccmpb, priority),                       \
630 		.capture_a_irq = DT_IRQ_BY_NAME(GPT(inst), ccmpa, irq),                            \
631 		.capture_b_irq = DT_IRQ_BY_NAME(GPT(inst), ccmpb, irq),                            \
632 		.capture_filter_gtioca = GPT_CAPTURE_FILTER_NONE,                                  \
633 		.capture_filter_gtiocb = GPT_CAPTURE_FILTER_NONE,                                  \
634 		.p_pwm_cfg = NULL,                                                                 \
635 		.gtior_setting.gtior = (0x0U),                                                     \
636 	};                                                                                         \
637 	static timer_cfg_t g_timer##inst##_cfg = {                                                 \
638 		.mode = TIMER_MODE_PWM,                                                            \
639 		.channel = DT_PROP(GPT(inst), channel),                                            \
640 		.source_div = DT_ENUM_IDX(GPT(inst), prescaler),                                   \
641 		.cycle_end_ipl = DT_IRQ_BY_NAME(GPT(inst), ovf, priority),                         \
642 		.cycle_end_irq = DT_IRQ_BY_NAME(GPT(inst), ovf, irq),                              \
643 		.p_extend = &g_timer##inst##_extend,                                               \
644 	};                                                                                         \
645 	static const struct pwm_rz_gpt_config pwm_rz_gpt_config_##inst = {                         \
646 		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),                                    \
647 		.fsp_api = &g_timer_on_gpt,                                                        \
648 	};                                                                                         \
649 	static struct pwm_rz_gpt_data pwm_rz_gpt_data_##inst = {                                   \
650 		.fsp_cfg = &g_timer##inst##_cfg, .fsp_ctrl = &g_timer##inst##_ctrl};               \
651 	static int pwm_rz_gpt_init_##inst(const struct device *dev)                                \
652 	{                                                                                          \
653 		PWM_RZ_IRQ_CONFIG_INIT(inst);                                                      \
654 		int err = pwm_rz_gpt_init(dev);                                                    \
655 		if (err != 0) {                                                                    \
656 			return err;                                                                \
657 		}                                                                                  \
658 		return 0;                                                                          \
659 	}                                                                                          \
660 	DEVICE_DT_INST_DEFINE(inst, pwm_rz_gpt_init_##inst, NULL, &pwm_rz_gpt_data_##inst,         \
661 			      &pwm_rz_gpt_config_##inst, POST_KERNEL, CONFIG_PWM_INIT_PRIORITY,    \
662 			      &pwm_rz_gpt_driver_api);
663 
664 DT_INST_FOREACH_STATUS_OKAY(PWM_RZG_INIT);
665