1 /*
2  * Copyright (c) 2022, NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_SOC_ARM_NXP_IMX_MCIMX6X_PINCTRL_SOC_H_
8 #define ZEPHYR_SOC_ARM_NXP_IMX_MCIMX6X_PINCTRL_SOC_H_
9 
10 #include <zephyr/devicetree.h>
11 #include <zephyr/types.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 #define IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(x) ((x) & 0xF)
18 #define IOMUXC_SW_MUX_CTL_PAD_SION(x) (((x) & 0x1) << 4)
19 #define IOMUXC_SELECT_INPUT_DAISY(x) ((x) & 0x7)
20 
21 #define MCUX_IMX_BIAS_PULL_UP_SHIFT 5
22 #define MCUX_IMX_PULL_ENABLE_SHIFT 4
23 #define MCUX_IMX_INPUT_SCHMITT_ENABLE_SHIFT 3
24 #define MCUX_IMX_SLEW_RATE_SHIFT 2
25 #define MCUX_IMX_DRIVE_STRENGTH_SHIFT 0
26 #define MCUX_IMX_INPUT_ENABLE_SHIFT 31 /* Shift to a bit not used by IOMUXC_SW_PAD_CTL */
27 #define MCUX_IMX_INPUT_ENABLE(x) ((x >> MCUX_IMX_INPUT_ENABLE_SHIFT) & 0x1)
28 
29 #define Z_PINCTRL_MCUX_IMX_PINCFG_INIT(node_id)							\
30 	((DT_PROP(node_id, input_schmitt_enable) << MCUX_IMX_INPUT_SCHMITT_ENABLE_SHIFT) |	\
31 	IF_ENABLED(DT_PROP(node_id, bias_pull_up), (DT_ENUM_IDX(node_id, bias_pull_up_value)	\
32 		<< MCUX_IMX_BIAS_PULL_UP_SHIFT) |)						\
33 	((DT_PROP(node_id, bias_pull_down) | DT_PROP(node_id, bias_pull_up))		\
34 		<< MCUX_IMX_PULL_ENABLE_SHIFT) |					\
35 	 (DT_ENUM_IDX(node_id, drive_strength) << MCUX_IMX_DRIVE_STRENGTH_SHIFT) |	\
36 	 (DT_ENUM_IDX(node_id, slew_rate) << MCUX_IMX_SLEW_RATE_SHIFT) |		\
37 	 (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT))
38 
39 
40 #define Z_PINCTRL_MCUX_IMX_LPSR_PINCFG_INIT(node_id)						\
41 	(IF_ENABLED(DT_PROP(node_id, bias_pull_up), (DT_ENUM_IDX(node_id, bias_pull_up_value)	\
42 		<< MCUX_IMX_BIAS_PULL_UP_SHIFT) |)						\
43 	IF_ENABLED(DT_PROP(node_id, bias_pull_down), (DT_ENUM_IDX(node_id, bias_pull_down_value)\
44 		<< MCUX_IMX_BIAS_PULL_DOWN_SHIFT) |)						\
45 	((DT_PROP(node_id, bias_pull_down) | DT_PROP(node_id, bias_pull_up))			\
46 		<< MCUX_IMX_PULL_ENABLE_SHIFT) |						\
47 	 (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT))
48 
49 
50 /* This struct must be present. It is used by the mcux gpio driver */
51 struct pinctrl_soc_pinmux {
52 	uint32_t mux_register; /*!< IOMUXC SW_PAD_MUX register */
53 	uint32_t config_register; /*!< IOMUXC SW_PAD_CTL register */
54 	uint32_t input_register; /*!< IOMUXC SELECT_INPUT DAISY register */
55 	uint8_t mux_mode: 4; /*!< Mux value for SW_PAD_MUX register */
56 	uint32_t input_daisy:4; /*!< Mux value for SELECT_INPUT_DAISY register */
57 };
58 
59 struct pinctrl_soc_pin {
60 	struct pinctrl_soc_pinmux pinmux;
61 	uint32_t pin_ctrl_flags; /*!< value to write to IOMUXC_SW_PAD_CTL register */
62 };
63 
64 typedef struct pinctrl_soc_pin pinctrl_soc_pin_t;
65 
66 /* This definition must be present. It is used by the mcux gpio driver */
67 #define MCUX_IMX_PINMUX(node_id)						\
68 	{									\
69 	  .mux_register = DT_PROP_BY_IDX(node_id, pinmux, 0),			\
70 	  .config_register = DT_PROP_BY_IDX(node_id, pinmux, 4),		\
71 	  .input_register = DT_PROP_BY_IDX(node_id, pinmux, 2),			\
72 	  .mux_mode = DT_PROP_BY_IDX(node_id, pinmux, 1),			\
73 	  .input_daisy = DT_PROP_BY_IDX(node_id, pinmux, 3),			\
74 	}
75 
76 #define Z_PINCTRL_PINMUX(group_id, pin_prop, idx)				\
77 	MCUX_IMX_PINMUX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx))
78 
79 #define Z_PINCTRL_STATE_PIN_INIT(group_id, pin_prop, idx)			\
80 	{									\
81 	  .pinmux = Z_PINCTRL_PINMUX(group_id, pin_prop, idx),			\
82 	  .pin_ctrl_flags = COND_CODE_0(					\
83 		DT_PROP(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx), pin_lpsr),	\
84 		(Z_PINCTRL_MCUX_IMX_PINCFG_INIT(group_id)),			\
85 		(Z_PINCTRL_MCUX_IMX_LPSR_PINCFG_INIT(group_id))),		\
86 	},
87 
88 
89 #define Z_PINCTRL_STATE_PINS_INIT(node_id, prop)			\
90 	{DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop),		\
91 		DT_FOREACH_PROP_ELEM, pinmux, Z_PINCTRL_STATE_PIN_INIT)};	\
92 
93 
94 #ifdef __cplusplus
95 }
96 #endif
97 
98 #endif /* ZEPHYR_SOC_ARM_NXP_IMX_MCIMX6X_PINCTRL_SOC_H_ */
99