1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/pinctrl.h>
8 
9 #include <hal/nrf_gpio.h>
10 #ifdef CONFIG_SOC_NRF54H20_GPD
11 #include <nrf/gpd.h>
12 #endif
13 
14 BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) &&
15 	      (NRF_PULL_DOWN == NRF_GPIO_PIN_PULLDOWN) &&
16 	      (NRF_PULL_UP == NRF_GPIO_PIN_PULLUP)),
17 	      "nRF pinctrl pull settings do not match HAL values");
18 
19 #if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(GPIO_PIN_CNF_DRIVE0_E0)
20 #define NRF_DRIVE_COUNT (NRF_DRIVE_E0E1 + 1)
21 #else
22 #define NRF_DRIVE_COUNT (NRF_DRIVE_H0D1 + 1)
23 #endif
24 static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = {
25 	[NRF_DRIVE_S0S1] = NRF_GPIO_PIN_S0S1,
26 	[NRF_DRIVE_H0S1] = NRF_GPIO_PIN_H0S1,
27 	[NRF_DRIVE_S0H1] = NRF_GPIO_PIN_S0H1,
28 	[NRF_DRIVE_H0H1] = NRF_GPIO_PIN_H0H1,
29 	[NRF_DRIVE_D0S1] = NRF_GPIO_PIN_D0S1,
30 	[NRF_DRIVE_D0H1] = NRF_GPIO_PIN_D0H1,
31 	[NRF_DRIVE_S0D1] = NRF_GPIO_PIN_S0D1,
32 	[NRF_DRIVE_H0D1] = NRF_GPIO_PIN_H0D1,
33 #if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(GPIO_PIN_CNF_DRIVE0_E0)
34 	[NRF_DRIVE_E0E1] = NRF_GPIO_PIN_E0E1,
35 #endif
36 };
37 
38 /* value to indicate pin level doesn't need initialization */
39 #define NO_WRITE UINT32_MAX
40 
41 #define PSEL_DISCONNECTED 0xFFFFFFFFUL
42 
43 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_uart) || defined(CONFIG_NRFX_UART)
44 #define NRF_PSEL_UART(reg, line) ((NRF_UART_Type *)reg)->PSEL##line
45 #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_uarte) || defined(CONFIG_NRFX_UARTE)
46 #include <hal/nrf_uarte.h>
47 #define NRF_PSEL_UART(reg, line) ((NRF_UARTE_Type *)reg)->PSEL.line
48 #endif
49 
50 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_spi) || defined(CONFIG_NRFX_SPI)
51 #define NRF_PSEL_SPIM(reg, line) ((NRF_SPI_Type *)reg)->PSEL##line
52 #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_spim) || defined(CONFIG_NRFX_SPIM)
53 #include <hal/nrf_spim.h>
54 #define NRF_PSEL_SPIM(reg, line) ((NRF_SPIM_Type *)reg)->PSEL.line
55 #endif
56 
57 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_spis) || defined(CONFIG_NRFX_SPIS)
58 #include <hal/nrf_spis.h>
59 #if defined(NRF51)
60 #define NRF_PSEL_SPIS(reg, line) ((NRF_SPIS_Type *)reg)->PSEL##line
61 #else
62 #define NRF_PSEL_SPIS(reg, line) ((NRF_SPIS_Type *)reg)->PSEL.line
63 #endif
64 #endif
65 
66 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_twi) || defined(CONFIG_NRFX_TWI)
67 #if !defined(TWI_PSEL_SCL_CONNECT_Pos)
68 #define NRF_PSEL_TWIM(reg, line) ((NRF_TWI_Type *)reg)->PSEL##line
69 #else
70 #define NRF_PSEL_TWIM(reg, line) ((NRF_TWI_Type *)reg)->PSEL.line
71 #endif
72 #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_twim) || defined(CONFIG_NRFX_TWIM)
73 #include <hal/nrf_twim.h>
74 #define NRF_PSEL_TWIM(reg, line) ((NRF_TWIM_Type *)reg)->PSEL.line
75 #endif
76 
77 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_i2s) || defined(CONFIG_NRFX_I2S)
78 #define NRF_PSEL_I2S(reg, line) ((NRF_I2S_Type *)reg)->PSEL.line
79 #endif
80 
81 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_pdm) || defined(CONFIG_NRFX_PDM)
82 #define NRF_PSEL_PDM(reg, line) ((NRF_PDM_Type *)reg)->PSEL.line
83 #endif
84 
85 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_pwm) || defined(CONFIG_NRFX_PWM)
86 #define NRF_PSEL_PWM(reg, line) ((NRF_PWM_Type *)reg)->PSEL.line
87 #endif
88 
89 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_qdec) || defined(CONFIG_NRFX_QDEC)
90 #define NRF_PSEL_QDEC(reg, line) ((NRF_QDEC_Type *)reg)->PSEL.line
91 #endif
92 
93 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_qspi) || defined(CONFIG_NRFX_QSPI)
94 #define NRF_PSEL_QSPI(reg, line) ((NRF_QSPI_Type *)reg)->PSEL.line
95 #endif
96 
97 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_twis) || defined(CONFIG_NRFX_TWIS)
98 #include <hal/nrf_twis.h>
99 #define NRF_PSEL_TWIS(reg, line) ((NRF_TWIS_Type *)reg)->PSEL.line
100 #endif
101 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)102 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
103 			   uintptr_t reg)
104 {
105 #ifdef CONFIG_SOC_NRF54H20_GPD
106 	bool gpd_requested = false;
107 #endif
108 
109 	for (uint8_t i = 0U; i < pin_cnt; i++) {
110 		nrf_gpio_pin_drive_t drive;
111 		uint8_t drive_idx = NRF_GET_DRIVE(pins[i]);
112 		uint32_t psel = NRF_GET_PIN(pins[i]);
113 		uint32_t write = NO_WRITE;
114 		nrf_gpio_pin_dir_t dir;
115 		nrf_gpio_pin_input_t input;
116 
117 		if (drive_idx < ARRAY_SIZE(drive_modes)) {
118 			drive = drive_modes[drive_idx];
119 		} else {
120 			return -EINVAL;
121 		}
122 
123 		if (psel == NRF_PIN_DISCONNECTED) {
124 			psel = PSEL_DISCONNECTED;
125 		}
126 
127 		switch (NRF_GET_FUN(pins[i])) {
128 #if defined(NRF_PSEL_UART)
129 		case NRF_FUN_UART_TX:
130 			NRF_PSEL_UART(reg, TXD) = psel;
131 			write = 1U;
132 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
133 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
134 			break;
135 		case NRF_FUN_UART_RX:
136 			NRF_PSEL_UART(reg, RXD) = psel;
137 			dir = NRF_GPIO_PIN_DIR_INPUT;
138 			input = NRF_GPIO_PIN_INPUT_CONNECT;
139 			break;
140 		case NRF_FUN_UART_RTS:
141 			NRF_PSEL_UART(reg, RTS) = psel;
142 			write = 1U;
143 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
144 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
145 			break;
146 		case NRF_FUN_UART_CTS:
147 			NRF_PSEL_UART(reg, CTS) = psel;
148 			dir = NRF_GPIO_PIN_DIR_INPUT;
149 			input = NRF_GPIO_PIN_INPUT_CONNECT;
150 			break;
151 #endif /* defined(NRF_PSEL_UART) */
152 #if defined(NRF_PSEL_SPIM)
153 		case NRF_FUN_SPIM_SCK:
154 			NRF_PSEL_SPIM(reg, SCK) = psel;
155 			write = 0U;
156 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
157 			input = NRF_GPIO_PIN_INPUT_CONNECT;
158 			break;
159 		case NRF_FUN_SPIM_MOSI:
160 			NRF_PSEL_SPIM(reg, MOSI) = psel;
161 			write = 0U;
162 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
163 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
164 			break;
165 		case NRF_FUN_SPIM_MISO:
166 			NRF_PSEL_SPIM(reg, MISO) = psel;
167 			dir = NRF_GPIO_PIN_DIR_INPUT;
168 			input = NRF_GPIO_PIN_INPUT_CONNECT;
169 			break;
170 #endif /* defined(NRF_PSEL_SPIM) */
171 #if defined(NRF_PSEL_SPIS)
172 		case NRF_FUN_SPIS_SCK:
173 			NRF_PSEL_SPIS(reg, SCK) = psel;
174 			dir = NRF_GPIO_PIN_DIR_INPUT;
175 			input = NRF_GPIO_PIN_INPUT_CONNECT;
176 			break;
177 		case NRF_FUN_SPIS_MOSI:
178 			NRF_PSEL_SPIS(reg, MOSI) = psel;
179 			dir = NRF_GPIO_PIN_DIR_INPUT;
180 			input = NRF_GPIO_PIN_INPUT_CONNECT;
181 			break;
182 		case NRF_FUN_SPIS_MISO:
183 			NRF_PSEL_SPIS(reg, MISO) = psel;
184 			dir = NRF_GPIO_PIN_DIR_INPUT;
185 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
186 			break;
187 		case NRF_FUN_SPIS_CSN:
188 			NRF_PSEL_SPIS(reg, CSN) = psel;
189 			dir = NRF_GPIO_PIN_DIR_INPUT;
190 			input = NRF_GPIO_PIN_INPUT_CONNECT;
191 			break;
192 #endif /* defined(NRF_PSEL_SPIS) */
193 #if defined(NRF_PSEL_TWIM)
194 		case NRF_FUN_TWIM_SCL:
195 			NRF_PSEL_TWIM(reg, SCL) = psel;
196 			if (drive == NRF_GPIO_PIN_S0S1) {
197 				/* Override the default drive setting with one
198 				 * suitable for TWI/TWIM peripherals (S0D1).
199 				 * This drive cannot be used always so that
200 				 * users are able to select e.g. H0D1 or E0E1
201 				 * in devicetree.
202 				 */
203 				drive = NRF_GPIO_PIN_S0D1;
204 			}
205 			dir = NRF_GPIO_PIN_DIR_INPUT;
206 			input = NRF_GPIO_PIN_INPUT_CONNECT;
207 			break;
208 		case NRF_FUN_TWIM_SDA:
209 			NRF_PSEL_TWIM(reg, SDA) = psel;
210 			if (drive == NRF_GPIO_PIN_S0S1) {
211 				drive = NRF_GPIO_PIN_S0D1;
212 			}
213 			dir = NRF_GPIO_PIN_DIR_INPUT;
214 			input = NRF_GPIO_PIN_INPUT_CONNECT;
215 			break;
216 #endif /* defined(NRF_PSEL_TWIM) */
217 #if defined(NRF_PSEL_I2S)
218 		case NRF_FUN_I2S_SCK_M:
219 			NRF_PSEL_I2S(reg, SCK) = psel;
220 			write = 0U;
221 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
222 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
223 			break;
224 		case NRF_FUN_I2S_SCK_S:
225 			NRF_PSEL_I2S(reg, SCK) = psel;
226 			dir = NRF_GPIO_PIN_DIR_INPUT;
227 			input = NRF_GPIO_PIN_INPUT_CONNECT;
228 			break;
229 		case NRF_FUN_I2S_LRCK_M:
230 			NRF_PSEL_I2S(reg, LRCK) = psel;
231 			write = 0U;
232 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
233 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
234 			break;
235 		case NRF_FUN_I2S_LRCK_S:
236 			NRF_PSEL_I2S(reg, LRCK) = psel;
237 			dir = NRF_GPIO_PIN_DIR_INPUT;
238 			input = NRF_GPIO_PIN_INPUT_CONNECT;
239 			break;
240 		case NRF_FUN_I2S_SDIN:
241 			NRF_PSEL_I2S(reg, SDIN) = psel;
242 			dir = NRF_GPIO_PIN_DIR_INPUT;
243 			input = NRF_GPIO_PIN_INPUT_CONNECT;
244 			break;
245 		case NRF_FUN_I2S_SDOUT:
246 			NRF_PSEL_I2S(reg, SDOUT) = psel;
247 			write = 0U;
248 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
249 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
250 			break;
251 		case NRF_FUN_I2S_MCK:
252 			NRF_PSEL_I2S(reg, MCK) = psel;
253 			write = 0U;
254 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
255 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
256 			break;
257 #endif /* defined(NRF_PSEL_I2S) */
258 #if defined(NRF_PSEL_PDM)
259 		case NRF_FUN_PDM_CLK:
260 			NRF_PSEL_PDM(reg, CLK) = psel;
261 			write = 0U;
262 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
263 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
264 			break;
265 		case NRF_FUN_PDM_DIN:
266 			NRF_PSEL_PDM(reg, DIN) = psel;
267 			dir = NRF_GPIO_PIN_DIR_INPUT;
268 			input = NRF_GPIO_PIN_INPUT_CONNECT;
269 			break;
270 #endif /* defined(NRF_PSEL_PDM) */
271 #if defined(NRF_PSEL_PWM)
272 		case NRF_FUN_PWM_OUT0:
273 			NRF_PSEL_PWM(reg, OUT[0]) = psel;
274 			write = NRF_GET_INVERT(pins[i]);
275 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
276 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
277 			break;
278 		case NRF_FUN_PWM_OUT1:
279 			NRF_PSEL_PWM(reg, OUT[1]) = psel;
280 			write = NRF_GET_INVERT(pins[i]);
281 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
282 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
283 			break;
284 		case NRF_FUN_PWM_OUT2:
285 			NRF_PSEL_PWM(reg, OUT[2]) = psel;
286 			write = NRF_GET_INVERT(pins[i]);
287 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
288 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
289 			break;
290 		case NRF_FUN_PWM_OUT3:
291 			NRF_PSEL_PWM(reg, OUT[3]) = psel;
292 			write = NRF_GET_INVERT(pins[i]);
293 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
294 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
295 			break;
296 #endif /* defined(NRF_PSEL_PWM) */
297 #if defined(NRF_PSEL_QDEC)
298 		case NRF_FUN_QDEC_A:
299 			NRF_PSEL_QDEC(reg, A) = psel;
300 			dir = NRF_GPIO_PIN_DIR_INPUT;
301 			input = NRF_GPIO_PIN_INPUT_CONNECT;
302 			break;
303 		case NRF_FUN_QDEC_B:
304 			NRF_PSEL_QDEC(reg, B) = psel;
305 			dir = NRF_GPIO_PIN_DIR_INPUT;
306 			input = NRF_GPIO_PIN_INPUT_CONNECT;
307 			break;
308 		case NRF_FUN_QDEC_LED:
309 			NRF_PSEL_QDEC(reg, LED) = psel;
310 			dir = NRF_GPIO_PIN_DIR_INPUT;
311 			input = NRF_GPIO_PIN_INPUT_CONNECT;
312 			break;
313 #endif /* defined(NRF_PSEL_QDEC) */
314 #if defined(NRF_PSEL_QSPI)
315 		case NRF_FUN_QSPI_SCK:
316 			NRF_PSEL_QSPI(reg, SCK) = psel;
317 			dir = NRF_GPIO_PIN_DIR_INPUT;
318 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
319 			break;
320 		case NRF_FUN_QSPI_CSN:
321 			NRF_PSEL_QSPI(reg, CSN) = psel;
322 			write = 1U;
323 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
324 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
325 			break;
326 		case NRF_FUN_QSPI_IO0:
327 			NRF_PSEL_QSPI(reg, IO0) = psel;
328 			dir = NRF_GPIO_PIN_DIR_INPUT;
329 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
330 			break;
331 		case NRF_FUN_QSPI_IO1:
332 			NRF_PSEL_QSPI(reg, IO1) = psel;
333 			dir = NRF_GPIO_PIN_DIR_INPUT;
334 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
335 			break;
336 		case NRF_FUN_QSPI_IO2:
337 			NRF_PSEL_QSPI(reg, IO2) = psel;
338 			dir = NRF_GPIO_PIN_DIR_INPUT;
339 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
340 			break;
341 		case NRF_FUN_QSPI_IO3:
342 			NRF_PSEL_QSPI(reg, IO3) = psel;
343 			write = 1U;
344 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
345 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
346 			break;
347 #endif /* defined(NRF_PSEL_QSPI) */
348 #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_can)
349 		/* Pin routing is controlled by secure domain, via UICR */
350 		case NRF_FUN_CAN_TX:
351 			dir = NRF_GPIO_PIN_DIR_OUTPUT;
352 			input = NRF_GPIO_PIN_INPUT_DISCONNECT;
353 			break;
354 		case NRF_FUN_CAN_RX:
355 			dir = NRF_GPIO_PIN_DIR_INPUT;
356 			input = NRF_GPIO_PIN_INPUT_CONNECT;
357 			break;
358 #endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_can) */
359 #if defined(NRF_PSEL_TWIS)
360 		case NRF_FUN_TWIS_SCL:
361 			NRF_PSEL_TWIS(reg, SCL) = psel;
362 			if (drive == NRF_GPIO_PIN_S0S1) {
363 				drive = NRF_GPIO_PIN_S0D1;
364 			}
365 			dir = NRF_GPIO_PIN_DIR_INPUT;
366 			input = NRF_GPIO_PIN_INPUT_CONNECT;
367 			break;
368 		case NRF_FUN_TWIS_SDA:
369 			NRF_PSEL_TWIS(reg, SDA) = psel;
370 			if (drive == NRF_GPIO_PIN_S0S1) {
371 				drive = NRF_GPIO_PIN_S0D1;
372 			}
373 			dir = NRF_GPIO_PIN_DIR_INPUT;
374 			input = NRF_GPIO_PIN_INPUT_CONNECT;
375 			break;
376 #endif /* defined(NRF_PSEL_TWIS) */
377 		default:
378 			return -ENOTSUP;
379 		}
380 
381 		/* configure GPIO properties */
382 		if (psel != PSEL_DISCONNECTED) {
383 			uint32_t pin = psel;
384 
385 #ifdef CONFIG_SOC_NRF54H20_GPD
386 			if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) {
387 				if (!gpd_requested) {
388 					int ret;
389 
390 					ret = nrf_gpd_request(NRF_GPD_SLOW_ACTIVE);
391 					if (ret < 0) {
392 						return ret;
393 					}
394 					gpd_requested = true;
395 				}
396 
397 				nrf_gpio_pin_retain_disable(pin);
398 			}
399 #endif /* CONFIG_SOC_NRF54H20_GPD */
400 
401 			if (write != NO_WRITE) {
402 				nrf_gpio_pin_write(pin, write);
403 			}
404 
405 			/* force input and disconnected buffer for low power */
406 			if (NRF_GET_LP(pins[i]) == NRF_LP_ENABLE) {
407 				dir = NRF_GPIO_PIN_DIR_INPUT;
408 				input = NRF_GPIO_PIN_INPUT_DISCONNECT;
409 			}
410 
411 			nrf_gpio_cfg(pin, dir, input, NRF_GET_PULL(pins[i]),
412 				     drive, NRF_GPIO_PIN_NOSENSE);
413 #if NRF_GPIO_HAS_CLOCKPIN
414 			nrf_gpio_pin_clock_set(pin, NRF_GET_CLOCKPIN_ENABLE(pins[i]));
415 #endif
416 #ifdef CONFIG_SOC_NRF54H20_GPD
417 			if (NRF_GET_GPD_FAST_ACTIVE1(pins[i]) == 1U) {
418 				nrf_gpio_pin_retain_enable(pin);
419 			}
420 #endif /* CONFIG_SOC_NRF54H20_GPD */
421 		}
422 	}
423 
424 #ifdef CONFIG_SOC_NRF54H20_GPD
425 	if (gpd_requested) {
426 		int ret;
427 
428 		ret = nrf_gpd_release(NRF_GPD_SLOW_ACTIVE);
429 		if (ret < 0) {
430 			return ret;
431 		}
432 	}
433 #endif
434 
435 	return 0;
436 }
437