1 /*
2  * Copyright (c) 2016 Open-RnD Sp. z o.o.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT st_stm32_gpio
8 
9 #include <errno.h>
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/device.h>
13 #include <soc.h>
14 #include <stm32_ll_bus.h>
15 #include <stm32_ll_exti.h>
16 #include <stm32_ll_gpio.h>
17 #include <stm32_ll_pwr.h>
18 #include <zephyr/drivers/gpio.h>
19 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
20 #include <zephyr/sys/util.h>
21 #include <zephyr/drivers/interrupt_controller/gpio_intc_stm32.h>
22 #include <zephyr/pm/device.h>
23 #include <zephyr/pm/device_runtime.h>
24 #include <zephyr/drivers/misc/stm32_wkup_pins/stm32_wkup_pins.h>
25 #include <zephyr/dt-bindings/gpio/stm32-gpio.h>
26 
27 #include "stm32_hsem.h"
28 #include "gpio_stm32.h"
29 #include <zephyr/drivers/gpio/gpio_utils.h>
30 
31 #include <zephyr/logging/log.h>
32 
33 LOG_MODULE_REGISTER(stm32, CONFIG_GPIO_LOG_LEVEL);
34 
35 /**
36  * @brief Common GPIO driver for STM32 MCUs.
37  */
38 
39 /**
40  * @brief EXTI interrupt callback
41  */
gpio_stm32_isr(gpio_port_pins_t pin,void * arg)42 static void gpio_stm32_isr(gpio_port_pins_t pin, void *arg)
43 {
44 	struct gpio_stm32_data *data = arg;
45 
46 	gpio_fire_callbacks(&data->cb, data->dev, pin);
47 }
48 
49 /**
50  * @brief Common gpio flags to custom flags
51  */
gpio_stm32_flags_to_conf(gpio_flags_t flags,uint32_t * pincfg)52 static int gpio_stm32_flags_to_conf(gpio_flags_t flags, uint32_t *pincfg)
53 {
54 
55 	if ((flags & GPIO_OUTPUT) != 0) {
56 		/* Output only or Output/Input */
57 
58 		*pincfg = STM32_PINCFG_MODE_OUTPUT;
59 
60 		if ((flags & GPIO_SINGLE_ENDED) != 0) {
61 			if (flags & GPIO_LINE_OPEN_DRAIN) {
62 				*pincfg |= STM32_PINCFG_OPEN_DRAIN;
63 			} else  {
64 				/* Output can't be open source */
65 				return -ENOTSUP;
66 			}
67 		} else {
68 			*pincfg |= STM32_PINCFG_PUSH_PULL;
69 		}
70 
71 		if ((flags & GPIO_PULL_UP) != 0) {
72 			*pincfg |= STM32_PINCFG_PULL_UP;
73 		} else if ((flags & GPIO_PULL_DOWN) != 0) {
74 			*pincfg |= STM32_PINCFG_PULL_DOWN;
75 		}
76 
77 	} else if  ((flags & GPIO_INPUT) != 0) {
78 		/* Input */
79 
80 		*pincfg = STM32_PINCFG_MODE_INPUT;
81 
82 		if ((flags & GPIO_PULL_UP) != 0) {
83 			*pincfg |= STM32_PINCFG_PULL_UP;
84 		} else if ((flags & GPIO_PULL_DOWN) != 0) {
85 			*pincfg |= STM32_PINCFG_PULL_DOWN;
86 		} else {
87 			*pincfg |= STM32_PINCFG_FLOATING;
88 		}
89 	} else {
90 		/* Deactivated: Analog */
91 		*pincfg = STM32_PINCFG_MODE_ANALOG;
92 	}
93 
94 #if !defined(CONFIG_SOC_SERIES_STM32F1X)
95 	switch (flags & (STM32_GPIO_SPEED_MASK << STM32_GPIO_SPEED_SHIFT)) {
96 	case STM32_GPIO_VERY_HIGH_SPEED:
97 		*pincfg |= STM32_OSPEEDR_VERY_HIGH_SPEED;
98 		break;
99 	case STM32_GPIO_HIGH_SPEED:
100 		*pincfg |= STM32_OSPEEDR_HIGH_SPEED;
101 		break;
102 	case STM32_GPIO_MEDIUM_SPEED:
103 		*pincfg |= STM32_OSPEEDR_MEDIUM_SPEED;
104 		break;
105 	default:
106 		*pincfg |= STM32_OSPEEDR_LOW_SPEED;
107 		break;
108 	}
109 #endif /* !CONFIG_SOC_SERIES_STM32F1X */
110 
111 	return 0;
112 }
113 
114 #if defined(CONFIG_GPIO_GET_CONFIG) && !defined(CONFIG_SOC_SERIES_STM32F1X)
115 /**
116  * @brief Custom stm32 flags to zephyr
117  */
gpio_stm32_pincfg_to_flags(struct gpio_stm32_pin pin_cfg,gpio_flags_t * out_flags)118 static int gpio_stm32_pincfg_to_flags(struct gpio_stm32_pin pin_cfg,
119 				      gpio_flags_t *out_flags)
120 {
121 	gpio_flags_t flags = 0;
122 
123 	if (pin_cfg.mode == LL_GPIO_MODE_OUTPUT) {
124 		flags |= GPIO_OUTPUT;
125 		if (pin_cfg.type == LL_GPIO_OUTPUT_OPENDRAIN) {
126 			flags |= GPIO_OPEN_DRAIN;
127 		}
128 	} else if (pin_cfg.mode == LL_GPIO_MODE_INPUT) {
129 		flags |= GPIO_INPUT;
130 #ifdef CONFIG_SOC_SERIES_STM32F1X
131 	} else if (pin_cfg.mode == LL_GPIO_MODE_FLOATING) {
132 		flags |= GPIO_INPUT;
133 #endif
134 	} else {
135 		flags |= GPIO_DISCONNECTED;
136 	}
137 
138 	if (pin_cfg.pupd == LL_GPIO_PULL_UP) {
139 		flags |= GPIO_PULL_UP;
140 	} else if (pin_cfg.pupd == LL_GPIO_PULL_DOWN) {
141 		flags |= GPIO_PULL_DOWN;
142 	}
143 
144 	if (pin_cfg.out_state != 0) {
145 		flags |= GPIO_OUTPUT_HIGH;
146 	} else {
147 		flags |= GPIO_OUTPUT_LOW;
148 	}
149 
150 	*out_flags = flags;
151 
152 	return 0;
153 }
154 #endif /* CONFIG_GPIO_GET_CONFIG */
155 
156 /**
157  * @brief Translate pin to pinval that the LL library needs
158  */
stm32_pinval_get(gpio_pin_t pin)159 static inline uint32_t stm32_pinval_get(gpio_pin_t pin)
160 {
161 	uint32_t pinval;
162 
163 #ifdef CONFIG_SOC_SERIES_STM32F1X
164 	pinval = (1 << pin) << GPIO_PIN_MASK_POS;
165 	if (pin < 8) {
166 		pinval |= 1 << pin;
167 	} else {
168 		pinval |= (1 << (pin % 8)) | 0x04000000;
169 	}
170 #else
171 	pinval = 1 << pin;
172 #endif
173 	return pinval;
174 }
175 
ll_gpio_set_pin_pull(GPIO_TypeDef * GPIOx,uint32_t Pin,uint32_t Pull)176 static inline void ll_gpio_set_pin_pull(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Pull)
177 {
178 #if defined(CONFIG_SOC_SERIES_STM32WB0X)
179 	/* On STM32WB0, the PWRC PU/PD control registers should be used instead
180 	 * of the GPIO controller registers, so we cannot use LL_GPIO_SetPinPull.
181 	 */
182 	const uint32_t gpio = (GPIOx == GPIOA) ? LL_PWR_GPIO_A : LL_PWR_GPIO_B;
183 
184 	if (Pull == LL_GPIO_PULL_UP) {
185 		LL_PWR_EnableGPIOPullUp(gpio, Pin);
186 		LL_PWR_DisableGPIOPullDown(gpio, Pin);
187 	} else if (Pull == LL_GPIO_PULL_DOWN) {
188 		LL_PWR_EnableGPIOPullDown(gpio, Pin);
189 		LL_PWR_DisableGPIOPullUp(gpio, Pin);
190 	} else if (Pull == LL_GPIO_PULL_NO) {
191 		LL_PWR_DisableGPIOPullUp(gpio, Pin);
192 		LL_PWR_DisableGPIOPullDown(gpio, Pin);
193 	}
194 #else
195 	LL_GPIO_SetPinPull(GPIOx, Pin, Pull);
196 #endif /* CONFIG_SOC_SERIES_STM32WB0X */
197 }
198 
ll_gpio_get_pin_pull(GPIO_TypeDef * GPIOx,uint32_t Pin)199 __maybe_unused static inline uint32_t ll_gpio_get_pin_pull(GPIO_TypeDef *GPIOx, uint32_t Pin)
200 {
201 #if defined(CONFIG_SOC_SERIES_STM32WB0X)
202 	/* On STM32WB0, the PWRC PU/PD control registers should be used instead
203 	 * of the GPIO controller registers, so we cannot use LL_GPIO_GetPinPull.
204 	 */
205 	const uint32_t gpio = (GPIOx == GPIOA) ? LL_PWR_GPIO_A : LL_PWR_GPIO_B;
206 
207 	if (LL_PWR_IsEnabledGPIOPullDown(gpio, Pin)) {
208 		return LL_GPIO_PULL_DOWN;
209 	} else if (LL_PWR_IsEnabledGPIOPullUp(gpio, Pin)) {
210 		return LL_GPIO_PULL_UP;
211 	} else {
212 		return LL_GPIO_PULL_NO;
213 	}
214 #else
215 	return LL_GPIO_GetPinPull(GPIOx, Pin);
216 #endif /* CONFIG_SOC_SERIES_STM32WB0X */
217 }
218 
gpio_stm32_disable_pin_irqs(uint32_t port,gpio_pin_t pin)219 static inline void gpio_stm32_disable_pin_irqs(uint32_t port, gpio_pin_t pin)
220 {
221 #if defined(CONFIG_EXTI_STM32)
222 	if (port != stm32_exti_get_line_src_port(pin)) {
223 		/* EXTI line not owned by this port - do nothing */
224 		return;
225 	}
226 #endif
227 	stm32_gpio_irq_line_t irq_line = stm32_gpio_intc_get_pin_irq_line(port, pin);
228 
229 	stm32_gpio_intc_disable_line(irq_line);
230 	stm32_gpio_intc_remove_irq_callback(irq_line);
231 	stm32_gpio_intc_select_line_trigger(irq_line, STM32_GPIO_IRQ_TRIG_NONE);
232 }
233 
234 /**
235  * @brief Configure the hardware.
236  */
gpio_stm32_configure_raw(const struct device * dev,gpio_pin_t pin,uint32_t conf,uint32_t func)237 static void gpio_stm32_configure_raw(const struct device *dev, gpio_pin_t pin,
238 					uint32_t conf, uint32_t func)
239 {
240 	const struct gpio_stm32_config *cfg = dev->config;
241 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
242 
243 	uint32_t pin_ll = stm32_pinval_get(pin);
244 
245 #ifdef CONFIG_SOC_SERIES_STM32F1X
246 	ARG_UNUSED(func);
247 
248 	uint32_t temp = conf &
249 			      (STM32_MODE_INOUT_MASK << STM32_MODE_INOUT_SHIFT);
250 
251 	if (temp == STM32_MODE_INPUT) {
252 		temp = conf & (STM32_CNF_IN_MASK << STM32_CNF_IN_SHIFT);
253 
254 		if (temp == STM32_CNF_IN_ANALOG) {
255 			LL_GPIO_SetPinMode(gpio, pin_ll, LL_GPIO_MODE_ANALOG);
256 		} else if (temp == STM32_CNF_IN_FLOAT) {
257 			LL_GPIO_SetPinMode(gpio, pin_ll, LL_GPIO_MODE_FLOATING);
258 		} else {
259 			temp = conf & (STM32_PUPD_MASK << STM32_PUPD_SHIFT);
260 
261 			if (temp == STM32_PUPD_PULL_UP) {
262 				LL_GPIO_SetPinPull(gpio, pin_ll,
263 							       LL_GPIO_PULL_UP);
264 			} else {
265 				LL_GPIO_SetPinPull(gpio, pin_ll,
266 							     LL_GPIO_PULL_DOWN);
267 			}
268 
269 			LL_GPIO_SetPinMode(gpio, pin_ll, LL_GPIO_MODE_INPUT);
270 		}
271 
272 	} else {
273 		temp = conf & (STM32_CNF_OUT_1_MASK << STM32_CNF_OUT_1_SHIFT);
274 
275 		if (temp == STM32_CNF_GP_OUTPUT) {
276 			LL_GPIO_SetPinMode(gpio, pin_ll, LL_GPIO_MODE_OUTPUT);
277 		} else {
278 			LL_GPIO_SetPinMode(gpio, pin_ll,
279 							LL_GPIO_MODE_ALTERNATE);
280 		}
281 
282 		temp = conf & (STM32_CNF_OUT_0_MASK << STM32_CNF_OUT_0_SHIFT);
283 
284 		if (temp == STM32_CNF_PUSH_PULL) {
285 			LL_GPIO_SetPinOutputType(gpio, pin_ll,
286 						       LL_GPIO_OUTPUT_PUSHPULL);
287 		} else {
288 			LL_GPIO_SetPinOutputType(gpio, pin_ll,
289 						      LL_GPIO_OUTPUT_OPENDRAIN);
290 		}
291 
292 		temp = conf &
293 			    (STM32_MODE_OSPEED_MASK << STM32_MODE_OSPEED_SHIFT);
294 
295 		if (temp == STM32_MODE_OUTPUT_MAX_2) {
296 			LL_GPIO_SetPinSpeed(gpio, pin_ll,
297 							LL_GPIO_SPEED_FREQ_LOW);
298 		} else if (temp == STM32_MODE_OUTPUT_MAX_10) {
299 			LL_GPIO_SetPinSpeed(gpio, pin_ll,
300 						     LL_GPIO_SPEED_FREQ_MEDIUM);
301 		} else {
302 			LL_GPIO_SetPinSpeed(gpio, pin_ll,
303 						       LL_GPIO_SPEED_FREQ_HIGH);
304 		}
305 	}
306 #else
307 	uint32_t mode, otype, ospeed, pupd;
308 
309 	mode = conf & (STM32_MODER_MASK << STM32_MODER_SHIFT);
310 	otype = conf & (STM32_OTYPER_MASK << STM32_OTYPER_SHIFT);
311 	ospeed = conf & (STM32_OSPEEDR_MASK << STM32_OSPEEDR_SHIFT);
312 	pupd = conf & (STM32_PUPDR_MASK << STM32_PUPDR_SHIFT);
313 
314 	z_stm32_hsem_lock(CFG_HW_GPIO_SEMID, HSEM_LOCK_DEFAULT_RETRY);
315 
316 #if defined(CONFIG_SOC_SERIES_STM32L4X) && defined(GPIO_ASCR_ASC0)
317 	/*
318 	 * For STM32L47xx/48xx, register ASCR should be configured to connect
319 	 * analog switch of gpio lines to the ADC.
320 	 */
321 	if (mode == STM32_MODER_ANALOG_MODE) {
322 		LL_GPIO_EnablePinAnalogControl(gpio, pin_ll);
323 	}
324 #endif
325 
326 	LL_GPIO_SetPinOutputType(gpio, pin_ll, otype >> STM32_OTYPER_SHIFT);
327 
328 	LL_GPIO_SetPinSpeed(gpio, pin_ll, ospeed >> STM32_OSPEEDR_SHIFT);
329 
330 	ll_gpio_set_pin_pull(gpio, pin_ll, pupd >> STM32_PUPDR_SHIFT);
331 
332 	if (mode == STM32_MODER_ALT_MODE) {
333 		if (pin < 8) {
334 			LL_GPIO_SetAFPin_0_7(gpio, pin_ll, func);
335 		} else {
336 			LL_GPIO_SetAFPin_8_15(gpio, pin_ll, func);
337 		}
338 	}
339 
340 	LL_GPIO_SetPinMode(gpio, pin_ll, mode >> STM32_MODER_SHIFT);
341 
342 	z_stm32_hsem_unlock(CFG_HW_GPIO_SEMID);
343 #endif  /* CONFIG_SOC_SERIES_STM32F1X */
344 
345 }
346 
347 /**
348  * @brief GPIO port clock handling
349  */
gpio_stm32_clock_request(const struct device * dev,bool on)350 static int gpio_stm32_clock_request(const struct device *dev, bool on)
351 {
352 	const struct gpio_stm32_config *cfg = dev->config;
353 	int ret;
354 
355 	__ASSERT_NO_MSG(dev != NULL);
356 
357 	/* enable clock for subsystem */
358 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
359 
360 	if (on) {
361 		ret = clock_control_on(clk,
362 					(clock_control_subsys_t)&cfg->pclken);
363 	} else {
364 		ret = clock_control_off(clk,
365 					(clock_control_subsys_t)&cfg->pclken);
366 	}
367 
368 	return ret;
369 }
370 
gpio_stm32_port_get_raw(const struct device * dev,uint32_t * value)371 static int gpio_stm32_port_get_raw(const struct device *dev, uint32_t *value)
372 {
373 	const struct gpio_stm32_config *cfg = dev->config;
374 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
375 
376 	*value = LL_GPIO_ReadInputPort(gpio);
377 
378 	return 0;
379 }
380 
gpio_stm32_port_set_masked_raw(const struct device * dev,gpio_port_pins_t mask,gpio_port_value_t value)381 static int gpio_stm32_port_set_masked_raw(const struct device *dev,
382 					  gpio_port_pins_t mask,
383 					  gpio_port_value_t value)
384 {
385 	const struct gpio_stm32_config *cfg = dev->config;
386 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
387 	uint32_t port_value;
388 
389 	z_stm32_hsem_lock(CFG_HW_GPIO_SEMID, HSEM_LOCK_DEFAULT_RETRY);
390 
391 	port_value = LL_GPIO_ReadOutputPort(gpio);
392 	LL_GPIO_WriteOutputPort(gpio, (port_value & ~mask) | (mask & value));
393 
394 	z_stm32_hsem_unlock(CFG_HW_GPIO_SEMID);
395 
396 	return 0;
397 }
398 
gpio_stm32_port_set_bits_raw(const struct device * dev,gpio_port_pins_t pins)399 static int gpio_stm32_port_set_bits_raw(const struct device *dev,
400 					gpio_port_pins_t pins)
401 {
402 	const struct gpio_stm32_config *cfg = dev->config;
403 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
404 
405 	/*
406 	 * On F1 series, using LL API requires a costly pin mask translation.
407 	 * Skip it and use CMSIS API directly. Valid also on other series.
408 	 */
409 	WRITE_REG(gpio->BSRR, pins);
410 
411 	return 0;
412 }
413 
gpio_stm32_port_clear_bits_raw(const struct device * dev,gpio_port_pins_t pins)414 static int gpio_stm32_port_clear_bits_raw(const struct device *dev,
415 					  gpio_port_pins_t pins)
416 {
417 	const struct gpio_stm32_config *cfg = dev->config;
418 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
419 
420 #ifdef CONFIG_SOC_SERIES_STM32F1X
421 	/*
422 	 * On F1 series, using LL API requires a costly pin mask translation.
423 	 * Skip it and use CMSIS API directly.
424 	 */
425 	WRITE_REG(gpio->BRR, pins);
426 #else
427 	/* On other series, LL abstraction is needed  */
428 	LL_GPIO_ResetOutputPin(gpio, pins);
429 #endif
430 
431 	return 0;
432 }
433 
gpio_stm32_port_toggle_bits(const struct device * dev,gpio_port_pins_t pins)434 static int gpio_stm32_port_toggle_bits(const struct device *dev,
435 				       gpio_port_pins_t pins)
436 {
437 	const struct gpio_stm32_config *cfg = dev->config;
438 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
439 
440 	/*
441 	 * On F1 series, using LL API requires a costly pin mask translation.
442 	 * Skip it and use CMSIS API directly. Valid also on other series.
443 	 */
444 	z_stm32_hsem_lock(CFG_HW_GPIO_SEMID, HSEM_LOCK_DEFAULT_RETRY);
445 	WRITE_REG(gpio->ODR, READ_REG(gpio->ODR) ^ pins);
446 	z_stm32_hsem_unlock(CFG_HW_GPIO_SEMID);
447 
448 	return 0;
449 }
450 
451 #ifdef CONFIG_SOC_SERIES_STM32F1X
452 #define IS_GPIO_OUT GPIO_OUT
453 #else
454 #define IS_GPIO_OUT STM32_GPIO
455 #endif
456 
gpio_stm32_configure(const struct device * dev,gpio_pin_t pin,uint32_t conf,uint32_t func)457 int gpio_stm32_configure(const struct device *dev, gpio_pin_t pin, uint32_t conf, uint32_t func)
458 {
459 	int ret;
460 
461 	ret = pm_device_runtime_get(dev);
462 	if (ret < 0) {
463 		return ret;
464 	}
465 
466 	gpio_stm32_configure_raw(dev, pin, conf, func);
467 
468 	if (func == IS_GPIO_OUT) {
469 		uint32_t gpio_out = conf & (STM32_ODR_MASK << STM32_ODR_SHIFT);
470 
471 		if (gpio_out == STM32_ODR_1) {
472 			gpio_stm32_port_set_bits_raw(dev, BIT(pin));
473 		} else if (gpio_out == STM32_ODR_0) {
474 			gpio_stm32_port_clear_bits_raw(dev, BIT(pin));
475 		}
476 	}
477 
478 	return pm_device_runtime_put(dev);
479 }
480 
481 /**
482  * @brief Configure pin or port
483  */
gpio_stm32_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)484 static int gpio_stm32_config(const struct device *dev,
485 			     gpio_pin_t pin, gpio_flags_t flags)
486 {
487 	int err;
488 	uint32_t pincfg;
489 	struct gpio_stm32_data *data = dev->data;
490 
491 	/* figure out if we can map the requested GPIO
492 	 * configuration
493 	 */
494 	err = gpio_stm32_flags_to_conf(flags, &pincfg);
495 	if (err != 0) {
496 		return err;
497 	}
498 
499 	/* Enable device clock before configuration (requires bank writes) */
500 	if ((((flags & GPIO_OUTPUT) != 0) || ((flags & GPIO_INPUT) != 0)) &&
501 	    !(data->pin_has_clock_enabled & BIT(pin))) {
502 		err = pm_device_runtime_get(dev);
503 		if (err < 0) {
504 			return err;
505 		}
506 		data->pin_has_clock_enabled |= BIT(pin);
507 	}
508 
509 	if ((flags & GPIO_OUTPUT) != 0) {
510 		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
511 			gpio_stm32_port_set_bits_raw(dev, BIT(pin));
512 		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
513 			gpio_stm32_port_clear_bits_raw(dev, BIT(pin));
514 		}
515 	}
516 
517 	gpio_stm32_configure_raw(dev, pin, pincfg, 0);
518 
519 #ifdef CONFIG_STM32_WKUP_PINS
520 	if (flags & STM32_GPIO_WKUP) {
521 #ifdef CONFIG_POWEROFF
522 		struct gpio_dt_spec gpio_dt_cfg = {
523 			.port = dev,
524 			.pin = pin,
525 			.dt_flags = (gpio_dt_flags_t)flags,
526 		};
527 
528 		if (stm32_pwr_wkup_pin_cfg_gpio((const struct gpio_dt_spec *)&gpio_dt_cfg)) {
529 			LOG_ERR("Could not configure GPIO %s pin %d as a wake-up source",
530 					gpio_dt_cfg.port->name, gpio_dt_cfg.pin);
531 		}
532 #else
533 		LOG_DBG("STM32_GPIO_WKUP flag has no effect when CONFIG_POWEROFF=n");
534 #endif /* CONFIG_POWEROFF */
535 	}
536 #endif /* CONFIG_STM32_WKUP_PINS */
537 
538 	/* Decrement GPIO usage count only if pin is now disconnected after being connected */
539 	if (((flags & GPIO_OUTPUT) == 0) && ((flags & GPIO_INPUT) == 0) &&
540 	    (data->pin_has_clock_enabled & BIT(pin))) {
541 		err = pm_device_runtime_put(dev);
542 		if (err < 0) {
543 			return err;
544 		}
545 		data->pin_has_clock_enabled &= ~BIT(pin);
546 	}
547 
548 	return 0;
549 }
550 
551 #if defined(CONFIG_GPIO_GET_CONFIG) && !defined(CONFIG_SOC_SERIES_STM32F1X)
552 /**
553  * @brief Get configuration of pin
554  */
gpio_stm32_get_config(const struct device * dev,gpio_pin_t pin,gpio_flags_t * flags)555 static int gpio_stm32_get_config(const struct device *dev,
556 				 gpio_pin_t pin, gpio_flags_t *flags)
557 {
558 	const struct gpio_stm32_config *cfg = dev->config;
559 	GPIO_TypeDef *gpio = (GPIO_TypeDef *)cfg->base;
560 	struct gpio_stm32_pin pin_config;
561 	uint32_t pin_ll;
562 	int err;
563 
564 	err = pm_device_runtime_get(dev);
565 	if (err < 0) {
566 		return err;
567 	}
568 
569 	pin_ll = stm32_pinval_get(pin);
570 	pin_config.type = LL_GPIO_GetPinOutputType(gpio, pin_ll);
571 	pin_config.pupd = ll_gpio_get_pin_pull(gpio, pin_ll);
572 	pin_config.mode = LL_GPIO_GetPinMode(gpio, pin_ll);
573 	pin_config.out_state = LL_GPIO_IsOutputPinSet(gpio, pin_ll);
574 
575 	gpio_stm32_pincfg_to_flags(pin_config, flags);
576 
577 	return pm_device_runtime_put(dev);
578 }
579 #endif /* CONFIG_GPIO_GET_CONFIG */
580 
gpio_stm32_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)581 static int gpio_stm32_pin_interrupt_configure(const struct device *dev,
582 					      gpio_pin_t pin,
583 					      enum gpio_int_mode mode,
584 					      enum gpio_int_trig trig)
585 {
586 	const struct gpio_stm32_config *cfg = dev->config;
587 	struct gpio_stm32_data *data = dev->data;
588 	const stm32_gpio_irq_line_t irq_line = stm32_gpio_intc_get_pin_irq_line(cfg->port, pin);
589 	uint32_t irq_trigger = 0;
590 	int err = 0;
591 
592 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
593 	if (mode == GPIO_INT_MODE_DISABLE_ONLY) {
594 		stm32_gpio_intc_disable_line(irq_line);
595 		goto exit;
596 	} else if (mode == GPIO_INT_MODE_ENABLE_ONLY) {
597 		stm32_gpio_intc_enable_line(irq_line);
598 		goto exit;
599 	}
600 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
601 
602 	if (mode == GPIO_INT_MODE_DISABLED) {
603 		gpio_stm32_disable_pin_irqs(cfg->port, pin);
604 		goto exit;
605 	}
606 
607 	if (mode == GPIO_INT_MODE_LEVEL) {
608 		/* Level-sensitive interrupts are only supported on STM32WB0. */
609 		if (!IS_ENABLED(CONFIG_SOC_SERIES_STM32WB0X)) {
610 			err = -ENOTSUP;
611 			goto exit;
612 		} else {
613 			switch (trig) {
614 			case GPIO_INT_TRIG_LOW:
615 				irq_trigger = STM32_GPIO_IRQ_TRIG_LOW_LEVEL;
616 				break;
617 			case GPIO_INT_TRIG_HIGH:
618 				irq_trigger = STM32_GPIO_IRQ_TRIG_HIGH_LEVEL;
619 				break;
620 			default:
621 				err = -EINVAL;
622 				goto exit;
623 			}
624 		}
625 	} else {
626 		switch (trig) {
627 		case GPIO_INT_TRIG_LOW:
628 			irq_trigger = STM32_GPIO_IRQ_TRIG_FALLING;
629 			break;
630 		case GPIO_INT_TRIG_HIGH:
631 			irq_trigger = STM32_GPIO_IRQ_TRIG_RISING;
632 			break;
633 		case GPIO_INT_TRIG_BOTH:
634 			irq_trigger = STM32_GPIO_IRQ_TRIG_BOTH;
635 			break;
636 		default:
637 			err = -EINVAL;
638 			goto exit;
639 		}
640 	}
641 
642 	if (stm32_gpio_intc_set_irq_callback(irq_line, gpio_stm32_isr, data) != 0) {
643 		err = -EBUSY;
644 		goto exit;
645 	}
646 
647 #if defined(CONFIG_EXTI_STM32)
648 	stm32_exti_set_line_src_port(pin, cfg->port);
649 #endif
650 
651 	stm32_gpio_intc_select_line_trigger(irq_line, irq_trigger);
652 
653 	stm32_gpio_intc_enable_line(irq_line);
654 
655 exit:
656 	return err;
657 }
658 
gpio_stm32_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)659 static int gpio_stm32_manage_callback(const struct device *dev,
660 				      struct gpio_callback *callback,
661 				      bool set)
662 {
663 	struct gpio_stm32_data *data = dev->data;
664 
665 	return gpio_manage_callback(&data->cb, callback, set);
666 }
667 
668 static DEVICE_API(gpio, gpio_stm32_driver) = {
669 	.pin_configure = gpio_stm32_config,
670 #if defined(CONFIG_GPIO_GET_CONFIG) && !defined(CONFIG_SOC_SERIES_STM32F1X)
671 	.pin_get_config = gpio_stm32_get_config,
672 #endif /* CONFIG_GPIO_GET_CONFIG */
673 	.port_get_raw = gpio_stm32_port_get_raw,
674 	.port_set_masked_raw = gpio_stm32_port_set_masked_raw,
675 	.port_set_bits_raw = gpio_stm32_port_set_bits_raw,
676 	.port_clear_bits_raw = gpio_stm32_port_clear_bits_raw,
677 	.port_toggle_bits = gpio_stm32_port_toggle_bits,
678 	.pin_interrupt_configure = gpio_stm32_pin_interrupt_configure,
679 	.manage_callback = gpio_stm32_manage_callback,
680 };
681 
682 #ifdef CONFIG_PM_DEVICE
gpio_stm32_pm_action(const struct device * dev,enum pm_device_action action)683 static int gpio_stm32_pm_action(const struct device *dev,
684 				enum pm_device_action action)
685 {
686 	switch (action) {
687 	case PM_DEVICE_ACTION_RESUME:
688 		return gpio_stm32_clock_request(dev, true);
689 	case PM_DEVICE_ACTION_SUSPEND:
690 		return gpio_stm32_clock_request(dev, false);
691 	default:
692 		return -ENOTSUP;
693 	}
694 
695 	return 0;
696 }
697 #endif /* CONFIG_PM_DEVICE */
698 
699 
700 /**
701  * @brief Initialize GPIO port
702  *
703  * Perform basic initialization of a GPIO port. The code will
704  * enable the clock for corresponding peripheral.
705  *
706  * @param dev GPIO device struct
707  *
708  * @return 0
709  */
gpio_stm32_init(const struct device * dev)710 static int gpio_stm32_init(const struct device *dev)
711 {
712 	struct gpio_stm32_data *data = dev->data;
713 	int ret;
714 
715 	data->dev = dev;
716 
717 	if (!device_is_ready(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE))) {
718 		return -ENODEV;
719 	}
720 
721 #if (defined(PWR_CR2_IOSV) || defined(PWR_SVMCR_IO2SV)) && \
722 	DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpiog))
723 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
724 	/* Port G[15:2] requires external power supply */
725 	/* Cf: L4/L5 RM, Chapter "Independent I/O supply rail" */
726 	LL_PWR_EnableVddIO2();
727 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
728 #endif
729 	/* enable port clock (if runtime PM is not enabled) */
730 	ret = gpio_stm32_clock_request(dev, !IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME));
731 	if (ret < 0) {
732 		return ret;
733 	}
734 
735 	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
736 		pm_device_init_suspended(dev);
737 	}
738 	(void)pm_device_runtime_enable(dev);
739 
740 	return 0;
741 }
742 
743 #define GPIO_DEVICE_INIT(__node, __suffix, __base_addr, __port, __cenr, __bus) \
744 	static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = {   \
745 		.common = {						       \
746 			 .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_NGPIOS(16U), \
747 		},							       \
748 		.base = (uint32_t *)__base_addr,				       \
749 		.port = __port,						       \
750 		.pclken = { .bus = __bus, .enr = __cenr }		       \
751 	};								       \
752 	static struct gpio_stm32_data gpio_stm32_data_## __suffix;	       \
753 	PM_DEVICE_DT_DEFINE(__node, gpio_stm32_pm_action);		       \
754 	DEVICE_DT_DEFINE(__node,					       \
755 			    gpio_stm32_init,				       \
756 			    PM_DEVICE_DT_GET(__node),			       \
757 			    &gpio_stm32_data_## __suffix,		       \
758 			    &gpio_stm32_cfg_## __suffix,		       \
759 			    PRE_KERNEL_1,				       \
760 			    CONFIG_GPIO_INIT_PRIORITY,			       \
761 			    &gpio_stm32_driver)
762 
763 #define GPIO_DEVICE_INIT_STM32(__suffix, __SUFFIX)			\
764 	GPIO_DEVICE_INIT(DT_NODELABEL(gpio##__suffix),	\
765 			 __suffix,					\
766 			 DT_REG_ADDR(DT_NODELABEL(gpio##__suffix)),	\
767 			 STM32_PORT##__SUFFIX,				\
768 			 DT_CLOCKS_CELL(DT_NODELABEL(gpio##__suffix), bits),\
769 			 DT_CLOCKS_CELL(DT_NODELABEL(gpio##__suffix), bus))
770 
771 #define GPIO_DEVICE_INIT_STM32_IF_OKAY(__suffix, __SUFFIX) \
772 	COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(gpio##__suffix)), \
773 		    (GPIO_DEVICE_INIT_STM32(__suffix, __SUFFIX)), \
774 		    ())
775 
776 GPIO_DEVICE_INIT_STM32_IF_OKAY(a, A);
777 GPIO_DEVICE_INIT_STM32_IF_OKAY(b, B);
778 GPIO_DEVICE_INIT_STM32_IF_OKAY(c, C);
779 GPIO_DEVICE_INIT_STM32_IF_OKAY(d, D);
780 GPIO_DEVICE_INIT_STM32_IF_OKAY(e, E);
781 GPIO_DEVICE_INIT_STM32_IF_OKAY(f, F);
782 GPIO_DEVICE_INIT_STM32_IF_OKAY(g, G);
783 GPIO_DEVICE_INIT_STM32_IF_OKAY(h, H);
784 GPIO_DEVICE_INIT_STM32_IF_OKAY(i, I);
785 GPIO_DEVICE_INIT_STM32_IF_OKAY(j, J);
786 GPIO_DEVICE_INIT_STM32_IF_OKAY(k, K);
787 
788 GPIO_DEVICE_INIT_STM32_IF_OKAY(m, M);
789 GPIO_DEVICE_INIT_STM32_IF_OKAY(n, N);
790 GPIO_DEVICE_INIT_STM32_IF_OKAY(o, O);
791 GPIO_DEVICE_INIT_STM32_IF_OKAY(p, P);
792 GPIO_DEVICE_INIT_STM32_IF_OKAY(q, Q);
793