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