1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_SOC_ARM64_NXP_IMX95_PINCTRL_SOC_H_
8 #define ZEPHYR_SOC_ARM64_NXP_IMX95_PINCTRL_SOC_H_
9 
10 #include <zephyr/devicetree.h>
11 #include <zephyr/types.h>
12 #include "soc.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 #define PIN_CONFIG_TYPE_MUX       192
19 #define PIN_CONFIG_TYPE_CONFIG    193
20 #define PIN_CONFIG_TYPE_DAISY_ID  194
21 #define PIN_CONFIG_TYPE_DAISY_CFG 195
22 
23 #define IOMUXC_MUX_MODE(x) IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(x)
24 #define IOMUXC_SION(x)     IOMUXC_SW_MUX_CTL_PAD_SION(x)
25 
26 #define IOMUXC_MUXREG   (IOMUXC_BASE)
27 #define IOMUXC_CFGREG   (IOMUXC_BASE + 0x204)
28 #define IOMUXC_DAISYREG (IOMUXC_BASE + 0x408)
29 
30 #define IOMUXC_INPUT_SCHMITT_ENABLE_SHIFT IOMUXC_SW_PAD_CTL_PAD_HYS_SHIFT
31 #define IOMUXC_DRIVE_OPEN_DRAIN_SHIFT     IOMUXC_SW_PAD_CTL_PAD_OD_SHIFT
32 #define IOMUXC_BIAS_PULL_DOWN_SHIFT       IOMUXC_SW_PAD_CTL_PAD_PD_SHIFT
33 #define IOMUXC_BIAS_PULL_UP_SHIFT         IOMUXC_SW_PAD_CTL_PAD_PU_SHIFT
34 #define IOMUXC_SLEW_RATE_SHIFT            IOMUXC_SW_PAD_CTL_PAD_FSEL1_SHIFT
35 #define IOMUXC_DRIVE_STRENGTH_SHIFT       IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT
36 
37 #define IOMUXC_INPUT_ENABLE_SHIFT 23 /* Shift to a bit not used by IOMUXC_SW_PAD_CTL */
38 #define IOMUXC_INPUT_ENABLE(x)    ((x >> IOMUXC_INPUT_ENABLE_SHIFT) & 0x1)
39 
40 #define Z_PINCTRL_IOMUXC_PINCFG_INIT(node_id)                                                      \
41 	((DT_PROP(node_id, input_schmitt_enable) << IOMUXC_INPUT_SCHMITT_ENABLE_SHIFT) |           \
42 	 (DT_PROP(node_id, drive_open_drain) << IOMUXC_DRIVE_OPEN_DRAIN_SHIFT) |                   \
43 	 (DT_PROP(node_id, bias_pull_down) << IOMUXC_BIAS_PULL_DOWN_SHIFT) |                       \
44 	 (DT_PROP(node_id, bias_pull_up) << IOMUXC_BIAS_PULL_UP_SHIFT) |                           \
45 	 (DT_ENUM_IDX(node_id, slew_rate) << IOMUXC_SLEW_RATE_SHIFT) |                             \
46 	 ((~(0xff << DT_ENUM_IDX(node_id, drive_strength))) << IOMUXC_DRIVE_STRENGTH_SHIFT) |      \
47 	 (DT_PROP(node_id, input_enable) << IOMUXC_INPUT_ENABLE_SHIFT))
48 
49 /* This struct must be present. It is used by the mcux gpio driver */
50 struct pinctrl_soc_pinmux {
51 	uint32_t mux_register;    /*!< IOMUXC SW_PAD_MUX register */
52 	uint32_t config_register; /*!< IOMUXC SW_PAD_CTL register */
53 	uint32_t input_register;  /*!< IOMUXC SELECT_INPUT DAISY register */
54 	uint8_t mux_mode: 4;      /*!< Mux value for SW_PAD_MUX register */
55 	uint32_t input_daisy: 4;  /*!< Mux value for SELECT_INPUT_DAISY register */
56 };
57 
58 struct pinctrl_soc_pin {
59 	struct pinctrl_soc_pinmux pinmux;
60 	uint32_t pin_ctrl_flags; /*!< value to write to IOMUXC_SW_PAD_CTL register */
61 };
62 
63 typedef struct pinctrl_soc_pin pinctrl_soc_pin_t;
64 
65 /* This definition must be present. It is used by the mcux gpio driver */
66 #define IOMUXC_PINMUX(node_id)                                                                     \
67 	{                                                                                          \
68 		.mux_register = DT_PROP_BY_IDX(node_id, pinmux, 0),                                \
69 		.config_register = DT_PROP_BY_IDX(node_id, pinmux, 4),                             \
70 		.input_register = DT_PROP_BY_IDX(node_id, pinmux, 2),                              \
71 		.mux_mode = DT_PROP_BY_IDX(node_id, pinmux, 1),                                    \
72 		.input_daisy = DT_PROP_BY_IDX(node_id, pinmux, 3),                                 \
73 	}
74 
75 #define Z_PINCTRL_PINMUX(group_id, pin_prop, idx)                                                  \
76 	IOMUXC_PINMUX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx))
77 
78 #define Z_PINCTRL_STATE_PIN_INIT(group_id, pin_prop, idx)                                          \
79 	{                                                                                          \
80 		.pinmux = Z_PINCTRL_PINMUX(group_id, pin_prop, idx),                               \
81 		.pin_ctrl_flags = Z_PINCTRL_IOMUXC_PINCFG_INIT(group_id),                          \
82 	},
83 
84 #define Z_PINCTRL_STATE_PINS_INIT(node_id, prop)                                                   \
85 	{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), DT_FOREACH_PROP_ELEM, pinmux,           \
86 				Z_PINCTRL_STATE_PIN_INIT)};
87 
88 #ifdef __cplusplus
89 }
90 #endif
91 
92 #endif /* ZEPHYR_SOC_ARM64_NXP_IMX95_PINCTRL_SOC_H_ */
93