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