1 /*
2  * Copyright (c) 2016 Open-RnD Sp. z o.o.
3  * Copyright (c) 2021 Linaro Limited
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @brief
10  *
11  * A common driver for STM32 pinmux.
12  */
13 
14 #include <errno.h>
15 
16 #include <kernel.h>
17 #include <device.h>
18 #include <soc.h>
19 #include <stm32_ll_bus.h>
20 #include <stm32_ll_gpio.h>
21 #include <drivers/pinmux.h>
22 #include <gpio/gpio_stm32.h>
23 #include <drivers/clock_control/stm32_clock_control.h>
24 #include <pinmux/pinmux_stm32.h>
25 #include <pm/device_runtime.h>
26 
27 #define GPIO_DEVICE(gpio_port)						\
28 	COND_CODE_1(DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_port), okay),	\
29 		    (DEVICE_DT_GET(DT_NODELABEL(gpio_port))),		\
30 		    ((const struct device *)NULL))
31 
32 const struct device * const gpio_ports[STM32_PORTS_MAX] = {
33 	GPIO_DEVICE(gpioa),
34 	GPIO_DEVICE(gpiob),
35 	GPIO_DEVICE(gpioc),
36 	GPIO_DEVICE(gpiod),
37 	GPIO_DEVICE(gpioe),
38 	GPIO_DEVICE(gpiof),
39 	GPIO_DEVICE(gpiog),
40 	GPIO_DEVICE(gpioh),
41 	GPIO_DEVICE(gpioi),
42 	GPIO_DEVICE(gpioj),
43 	GPIO_DEVICE(gpiok),
44 };
45 
stm32_pin_configure(uint32_t pin,uint32_t func,uint32_t altf)46 static int stm32_pin_configure(uint32_t pin, uint32_t func, uint32_t altf)
47 {
48 	const struct device *port_device;
49 	int ret = 0;
50 
51 	if (STM32_PORT(pin) >= STM32_PORTS_MAX) {
52 		return -EINVAL;
53 	}
54 
55 	port_device = gpio_ports[STM32_PORT(pin)];
56 
57 	if ((port_device == NULL) || (!device_is_ready(port_device))) {
58 		return -ENODEV;
59 	}
60 
61 #ifdef CONFIG_PM_DEVICE_RUNTIME
62 	ret = pm_device_get(port_device);
63 	if (ret != 0) {
64 		return ret;
65 	}
66 #endif
67 
68 	gpio_stm32_configure(port_device, STM32_PIN(pin), func, altf);
69 
70 #ifdef CONFIG_PM_DEVICE_RUNTIME
71 	ret = pm_device_put(port_device);
72 #endif
73 
74 	return ret;
75 }
76 
77 /**
78  * @brief helper for converting dt stm32 pinctrl format to existing pin config
79  *        format
80  *
81  * @param *pinctrl pointer to soc_gpio_pinctrl list
82  * @param list_size list size
83  * @param base device base register value
84  *
85  * @return 0 on success, -EINVAL otherwise
86  */
stm32_dt_pinctrl_configure(const struct soc_gpio_pinctrl * pinctrl,size_t list_size,uint32_t base)87 int stm32_dt_pinctrl_configure(const struct soc_gpio_pinctrl *pinctrl,
88 			       size_t list_size, uint32_t base)
89 {
90 	uint32_t pin, mux;
91 	uint32_t func = 0;
92 	int ret = 0;
93 
94 	if (!list_size) {
95 		/* Empty pinctrl. Exit */
96 		return 0;
97 	}
98 
99 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
100 	if (stm32_dt_pinctrl_remap(pinctrl, list_size, base)) {
101 		/* Wrong remap config. Exit */
102 		return -EINVAL;
103 	}
104 #else
105 	ARG_UNUSED(base);
106 #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
107 
108 	for (int i = 0; i < list_size; i++) {
109 		mux = pinctrl[i].pinmux;
110 
111 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
112 		uint32_t pupd;
113 
114 		if (STM32_DT_PINMUX_FUNC(mux) == ALTERNATE) {
115 			func = pinctrl[i].pincfg | STM32_MODE_OUTPUT |
116 							STM32_CNF_ALT_FUNC;
117 		} else if (STM32_DT_PINMUX_FUNC(mux) == ANALOG) {
118 			func = pinctrl[i].pincfg | STM32_MODE_INPUT |
119 							STM32_CNF_IN_ANALOG;
120 		} else if (STM32_DT_PINMUX_FUNC(mux) == GPIO_IN) {
121 			func = pinctrl[i].pincfg | STM32_MODE_INPUT;
122 			pupd = func & (STM32_PUPD_MASK << STM32_PUPD_SHIFT);
123 			if (pupd == STM32_PUPD_NO_PULL) {
124 				func = func | STM32_CNF_IN_FLOAT;
125 			} else {
126 				func = func | STM32_CNF_IN_PUPD;
127 			}
128 		} else {
129 			/* Not supported */
130 			__ASSERT_NO_MSG(STM32_DT_PINMUX_FUNC(mux));
131 		}
132 #else
133 		if (STM32_DT_PINMUX_FUNC(mux) < STM32_ANALOG) {
134 			func = pinctrl[i].pincfg | STM32_MODER_ALT_MODE;
135 		} else if (STM32_DT_PINMUX_FUNC(mux) == STM32_ANALOG) {
136 			func = STM32_MODER_ANALOG_MODE;
137 		} else {
138 			/* Not supported */
139 			__ASSERT_NO_MSG(STM32_DT_PINMUX_FUNC(mux));
140 		}
141 #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
142 
143 		pin = STM32PIN(STM32_DT_PINMUX_PORT(mux),
144 			       STM32_DT_PINMUX_LINE(mux));
145 
146 		ret = stm32_pin_configure(pin, func, STM32_DT_PINMUX_FUNC(mux));
147 		if (ret != 0) {
148 			return ret;
149 		}
150 	}
151 
152 	return 0;
153 }
154 
155 #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl)
156 /**
157  * @brief Helper function to check and apply provided pinctrl remap
158  *        configuration
159  *
160  * Check operation verifies that pin remapping configuration is the same on all
161  * pins. If configuration is valid AFIO clock is enabled and remap is applied
162  *
163  * @param *pinctrl pointer to soc_gpio_pinctrl list
164  * @param list_size list size
165  * @param base device base register value
166  *
167  * @return 0 on success, -EINVAL otherwise
168  */
stm32_dt_pinctrl_remap(const struct soc_gpio_pinctrl * pinctrl,size_t list_size,uint32_t base)169 int stm32_dt_pinctrl_remap(const struct soc_gpio_pinctrl *pinctrl,
170 			   size_t list_size, uint32_t base)
171 {
172 	uint8_t remap;
173 
174 	remap = (uint8_t)STM32_DT_PINMUX_REMAP(pinctrl[0].pinmux);
175 
176 	for (size_t i = 1U; i < list_size; i++) {
177 		if (STM32_DT_PINMUX_REMAP(pinctrl[i].pinmux) != remap) {
178 			return -EINVAL;
179 		}
180 	}
181 
182 	/* A valid remapping configuration is available */
183 	/* Apply remapping before proceeding with pin configuration */
184 	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
185 
186 	switch (base) {
187 #if DT_NODE_HAS_STATUS(DT_NODELABEL(can1), okay)
188 	case DT_REG_ADDR(DT_NODELABEL(can1)):
189 		if (remap == REMAP_1) {
190 			/* PB8/PB9 */
191 			LL_GPIO_AF_RemapPartial2_CAN1();
192 		} else if (remap == REMAP_2) {
193 			/* PD0/PD1 */
194 			LL_GPIO_AF_RemapPartial3_CAN1();
195 		} else {
196 			/* NO_REMAP: PA11/PA12 */
197 			LL_GPIO_AF_RemapPartial1_CAN1();
198 		}
199 		break;
200 #endif
201 #if DT_NODE_HAS_STATUS(DT_NODELABEL(can2), okay)
202 	case DT_REG_ADDR(DT_NODELABEL(can2)):
203 		if (remap == REMAP_1) {
204 			/* PB5/PB6 */
205 			LL_GPIO_AF_EnableRemap_CAN2();
206 		} else {
207 			/* PB12/PB13 */
208 			LL_GPIO_AF_DisableRemap_CAN2();
209 		}
210 		break;
211 #endif
212 #if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay)
213 	case DT_REG_ADDR(DT_NODELABEL(i2c1)):
214 		if (remap == REMAP_1) {
215 			LL_GPIO_AF_EnableRemap_I2C1();
216 		} else {
217 			LL_GPIO_AF_DisableRemap_I2C1();
218 		}
219 		break;
220 #endif
221 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers1), okay)
222 	case DT_REG_ADDR(DT_NODELABEL(timers1)):
223 		if (remap == REMAP_1) {
224 			LL_GPIO_AF_RemapPartial_TIM1();
225 		} else if (remap == REMAP_2) {
226 			LL_GPIO_AF_EnableRemap_TIM1();
227 		} else {
228 			LL_GPIO_AF_DisableRemap_TIM1();
229 		}
230 		break;
231 #endif
232 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers2), okay)
233 	case DT_REG_ADDR(DT_NODELABEL(timers2)):
234 		if (remap == REMAP_1) {
235 			LL_GPIO_AF_RemapPartial1_TIM2();
236 		} else if (remap == REMAP_2) {
237 			LL_GPIO_AF_RemapPartial2_TIM2();
238 		} else if (remap == REMAP_FULL) {
239 			LL_GPIO_AF_EnableRemap_TIM2();
240 		} else {
241 			LL_GPIO_AF_DisableRemap_TIM2();
242 		}
243 		break;
244 #endif
245 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers3), okay)
246 	case DT_REG_ADDR(DT_NODELABEL(timers3)):
247 		if (remap == REMAP_1) {
248 			LL_GPIO_AF_RemapPartial_TIM3();
249 		} else if (remap == REMAP_2) {
250 			LL_GPIO_AF_EnableRemap_TIM3();
251 		} else {
252 			LL_GPIO_AF_DisableRemap_TIM3();
253 		}
254 		break;
255 #endif
256 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers4), okay)
257 	case DT_REG_ADDR(DT_NODELABEL(timers4)):
258 		if (remap == REMAP_1) {
259 			LL_GPIO_AF_EnableRemap_TIM4();
260 		} else {
261 			LL_GPIO_AF_DisableRemap_TIM4();
262 		}
263 		break;
264 #endif
265 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers9), okay)
266 	case DT_REG_ADDR(DT_NODELABEL(timers9)):
267 		if (remap == REMAP_1) {
268 			LL_GPIO_AF_EnableRemap_TIM9();
269 		} else {
270 			LL_GPIO_AF_DisableRemap_TIM9();
271 		}
272 		break;
273 #endif
274 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers10), okay)
275 	case DT_REG_ADDR(DT_NODELABEL(timers10)):
276 		if (remap == REMAP_1) {
277 			LL_GPIO_AF_EnableRemap_TIM10();
278 		} else {
279 			LL_GPIO_AF_DisableRemap_TIM10();
280 		}
281 		break;
282 #endif
283 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers11), okay)
284 	case DT_REG_ADDR(DT_NODELABEL(timers11)):
285 		if (remap == REMAP_1) {
286 			LL_GPIO_AF_EnableRemap_TIM11();
287 		} else {
288 			LL_GPIO_AF_DisableRemap_TIM11();
289 		}
290 		break;
291 #endif
292 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers12), okay)
293 	case DT_REG_ADDR(DT_NODELABEL(timers12)):
294 		if (remap == REMAP_1) {
295 			LL_GPIO_AF_EnableRemap_TIM12();
296 		} else {
297 			LL_GPIO_AF_DisableRemap_TIM12();
298 		}
299 		break;
300 #endif
301 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers13), okay)
302 	case DT_REG_ADDR(DT_NODELABEL(timers13)):
303 		if (remap == REMAP_1) {
304 			LL_GPIO_AF_EnableRemap_TIM13();
305 		} else {
306 			LL_GPIO_AF_DisableRemap_TIM13();
307 		}
308 		break;
309 #endif
310 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers14), okay)
311 	case DT_REG_ADDR(DT_NODELABEL(timers14)):
312 		if (remap == REMAP_1) {
313 			LL_GPIO_AF_EnableRemap_TIM14();
314 		} else {
315 			LL_GPIO_AF_DisableRemap_TIM14();
316 		}
317 		break;
318 #endif
319 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers15), okay)
320 	case DT_REG_ADDR(DT_NODELABEL(timers15)):
321 		if (remap == REMAP_1) {
322 			LL_GPIO_AF_EnableRemap_TIM15();
323 		} else {
324 			LL_GPIO_AF_DisableRemap_TIM15();
325 		}
326 		break;
327 #endif
328 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers16), okay)
329 	case DT_REG_ADDR(DT_NODELABEL(timers16)):
330 		if (remap == REMAP_1) {
331 			LL_GPIO_AF_EnableRemap_TIM16();
332 		} else {
333 			LL_GPIO_AF_DisableRemap_TIM16();
334 		}
335 		break;
336 #endif
337 #if DT_NODE_HAS_STATUS(DT_NODELABEL(timers17), okay)
338 	case DT_REG_ADDR(DT_NODELABEL(timers17)):
339 		if (remap == REMAP_1) {
340 			LL_GPIO_AF_EnableRemap_TIM17();
341 		} else {
342 			LL_GPIO_AF_DisableRemap_TIM17();
343 		}
344 		break;
345 #endif
346 #if DT_NODE_HAS_STATUS(DT_NODELABEL(usart1), okay)
347 	case DT_REG_ADDR(DT_NODELABEL(usart1)):
348 		if (remap == REMAP_1) {
349 			LL_GPIO_AF_EnableRemap_USART1();
350 		} else {
351 			LL_GPIO_AF_DisableRemap_USART1();
352 		}
353 		break;
354 #endif
355 #if DT_NODE_HAS_STATUS(DT_NODELABEL(usart2), okay)
356 	case DT_REG_ADDR(DT_NODELABEL(usart2)):
357 		if (remap == REMAP_1) {
358 			LL_GPIO_AF_EnableRemap_USART2();
359 		} else {
360 			LL_GPIO_AF_DisableRemap_USART2();
361 		}
362 		break;
363 #endif
364 #if DT_NODE_HAS_STATUS(DT_NODELABEL(usart3), okay)
365 	case DT_REG_ADDR(DT_NODELABEL(usart3)):
366 		if (remap == REMAP_2) {
367 			LL_GPIO_AF_EnableRemap_USART3();
368 		} else if (remap == REMAP_1) {
369 			LL_GPIO_AF_RemapPartial_USART3();
370 		} else {
371 			LL_GPIO_AF_DisableRemap_USART3();
372 		}
373 		break;
374 #endif
375 #if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay)
376 	case DT_REG_ADDR(DT_NODELABEL(spi1)):
377 		if (remap == REMAP_1) {
378 			LL_GPIO_AF_EnableRemap_SPI1();
379 		} else {
380 			LL_GPIO_AF_DisableRemap_SPI1();
381 		}
382 		break;
383 #endif
384 	}
385 
386 	return 0;
387 }
388 #endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32f1_pinctrl) */
389 
390 
391 /**
392  * @brief pin setup
393  *
394  * @param pin  STM32PIN() encoded pin ID
395  * @param func SoC specific function assignment
396  * @param clk  optional clock device
397  *
398  * @return 0 on success, error otherwise
399  */
z_pinmux_stm32_set(uint32_t pin,uint32_t func)400 int z_pinmux_stm32_set(uint32_t pin, uint32_t func)
401 {
402 	const struct device *port_device = gpio_ports[STM32_PORT(pin)];
403 
404 	/* make sure to enable port clock first */
405 	if (gpio_stm32_clock_request(port_device, true)) {
406 		return -EIO;
407 	}
408 
409 	return stm32_pin_configure(pin, func, func & STM32_AFR_MASK);
410 }
411 
412 /**
413  * @brief setup pins according to their assignments
414  *
415  * @param pinconf  board pin configuration array
416  * @param pins     array size
417  */
stm32_setup_pins(const struct pin_config * pinconf,size_t pins)418 void stm32_setup_pins(const struct pin_config *pinconf,
419 		      size_t pins)
420 {
421 	int i;
422 
423 	for (i = 0; i < pins; i++) {
424 		z_pinmux_stm32_set(pinconf[i].pin_num,
425 				  pinconf[i].mode);
426 	}
427 }
428