1 /*
2  * Copyright 2022, 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/pinctrl.h>
9 
10 /* SIUL2 Multiplexed Signal Configuration Register */
11 #define SIUL2_MSCR(n) (0x240 + 0x4 * (n))
12 /* SIUL2 Input Multiplexed Signal Configuration Register */
13 #define SIUL2_IMCR(n) (0xa40 + 0x4 * (n))
14 
15 #define SIUL2_MSCR_MAX_IDX 512U
16 #define SIUL2_IMCR_MAX_IDX 512U
17 
18 /*
19  * Utility macro that expands to the SIUL2 base address if it exists or zero.
20  * Note that some devices may have instance gaps, hence the need to keep them in the array.
21  */
22 #define SIUL2_BASE_OR_ZERO(nodelabel)                                                              \
23 	COND_CODE_1(DT_NODE_EXISTS(DT_NODELABEL(nodelabel)),                                       \
24 		    (DT_REG_ADDR(DT_NODELABEL(nodelabel))), (0U))
25 
26 static mem_addr_t siul2_bases[] = {
27 	SIUL2_BASE_OR_ZERO(siul2_0), SIUL2_BASE_OR_ZERO(siul2_1), SIUL2_BASE_OR_ZERO(siul2_2),
28 	SIUL2_BASE_OR_ZERO(siul2_3), SIUL2_BASE_OR_ZERO(siul2_4), SIUL2_BASE_OR_ZERO(siul2_5),
29 };
30 
pinctrl_configure_pin(const pinctrl_soc_pin_t * pin)31 static void pinctrl_configure_pin(const pinctrl_soc_pin_t *pin)
32 {
33 	mem_addr_t base;
34 
35 	/* Multiplexed Signal Configuration */
36 	__ASSERT_NO_MSG(pin->mscr.inst < ARRAY_SIZE(siul2_bases));
37 	base = siul2_bases[pin->mscr.inst];
38 	__ASSERT_NO_MSG(base != 0);
39 
40 	__ASSERT_NO_MSG(pin->mscr.idx < SIUL2_MSCR_MAX_IDX);
41 	sys_write32(pin->mscr.val, (base + SIUL2_MSCR(pin->mscr.idx)));
42 
43 	/* Input Multiplexed Signal Configuration */
44 	if (pin->mscr.val & SIUL2_MSCR_IBE_MASK) {
45 		__ASSERT_NO_MSG(pin->imcr.inst < ARRAY_SIZE(siul2_bases));
46 		base = siul2_bases[pin->imcr.inst];
47 		__ASSERT_NO_MSG(base != 0);
48 
49 		__ASSERT_NO_MSG(pin->imcr.idx < SIUL2_IMCR_MAX_IDX);
50 		sys_write32(pin->imcr.val, (base + SIUL2_IMCR(pin->imcr.idx)));
51 	}
52 }
53 
pinctrl_configure_pins(const pinctrl_soc_pin_t * pins,uint8_t pin_cnt,uintptr_t reg)54 int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg)
55 {
56 	ARG_UNUSED(reg);
57 
58 	for (uint8_t i = 0; i < pin_cnt; i++) {
59 		pinctrl_configure_pin(pins++);
60 	}
61 
62 	return 0;
63 }
64