1 /* 2 * Copyright (c) 2022, NXP 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_SOC_ARM_NXP_IMX_RT_PINCTRL_RT11XX_H_ 8 #define ZEPHYR_SOC_ARM_NXP_IMX_RT_PINCTRL_RT11XX_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_ODE_SHIFT 4 19 #define MCUX_IMX_PUS_SHIFT 3 20 #define MCUX_IMX_PUE_SHIFT 2 21 #define MCUX_IMX_DSE_SHIFT 1 22 #define MCUX_IMX_SRE_SHIFT 0 23 #define MCUX_IMX_PULL_SHIFT 2 24 #define MCUX_IMX_PULL_PULLDOWN 0x2 25 #define MCUX_IMX_PULL_PULLUP 0x1 26 #define MCUX_IMX_PDRV_SHIFT 1 27 #define MCUX_IMX_LPSR_ODE_SHIFT 5 28 #define MCUX_IMX_SNVS_ODE_SHIFT 6 29 #define MCUX_IMX_INPUT_ENABLE_SHIFT 31 /* Shift to a bit not used by IOMUXC_SW_PAD_CTL */ 30 #define MCUX_IMX_INPUT_ENABLE(x) ((x >> MCUX_IMX_INPUT_ENABLE_SHIFT) & 0x1) 31 32 33 /* 34 * RT11xx has multiple types of register layouts defined for pin configuration 35 * registers. There are four types defined: 36 * pdrv_pull: registers lack a slew rate and pus field 37 * pue_pus: registers have a slew rate and ode field 38 * pue_pus_lpsr: in low power state retention domain, shifted ode field 39 * pue_pus_snvs: in SNVS domain, shifted ode field 40 */ 41 42 #define MCUX_IMX_PUS_PUE 0 43 #define MCUX_IMX_PDRV_PULL 1 44 #define MCUX_IMX_LPSR 2 45 #define MCUX_IMX_SNVS 3 46 47 /* 48 * Macro for MCUX_IMX_PULL_NOPULL, which needs to set field to 0x3 if two 49 * properties are false 50 */ 51 #define MCUX_IMX_NOPULL(node_id) \ 52 ((0x2 & ((!DT_PROP(node_id, bias_pull_down) && !DT_PROP(node_id, bias_pull_up)) << 1)) |\ 53 (0x1 & ((!DT_PROP(node_id, bias_pull_down) && !DT_PROP(node_id, bias_pull_up)) << 0))) \ 54 55 #define Z_PINCTRL_MCUX_IMX_PDRV(node_id) \ 56 IF_ENABLED(DT_PROP(node_id, bias_pull_down), \ 57 (MCUX_IMX_PULL_PULLDOWN << MCUX_IMX_PULL_SHIFT) |) \ 58 IF_ENABLED(DT_PROP(node_id, bias_pull_up), \ 59 (MCUX_IMX_PULL_PULLUP << MCUX_IMX_PULL_SHIFT) |) \ 60 (MCUX_IMX_NOPULL(node_id) << MCUX_IMX_PULL_SHIFT) | \ 61 (DT_ENUM_IDX_OR(node_id, drive_strength, 0) << MCUX_IMX_PDRV_SHIFT) | \ 62 (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_ODE_SHIFT) | \ 63 (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT) 64 65 #define Z_PINCTRL_MCUX_IMX_PUE_PUS(node_id) \ 66 (DT_PROP(node_id, bias_pull_up) << MCUX_IMX_PUS_SHIFT) | \ 67 ((DT_PROP(node_id, bias_pull_up) || DT_PROP(node_id, bias_pull_down)) \ 68 << MCUX_IMX_PUE_SHIFT) | \ 69 (DT_ENUM_IDX_OR(node_id, drive_strength, 0) << MCUX_IMX_DSE_SHIFT) | \ 70 (DT_ENUM_IDX_OR(node_id, slew_rate, 0) << MCUX_IMX_SRE_SHIFT) | \ 71 (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_ODE_SHIFT) | \ 72 (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT) 73 74 #define Z_PINCTRL_MCUX_IMX_LPSR(node_id) \ 75 (DT_PROP(node_id, bias_pull_up) << MCUX_IMX_PUS_SHIFT) | \ 76 ((DT_PROP(node_id, bias_pull_up) || DT_PROP(node_id, bias_pull_down)) \ 77 << MCUX_IMX_PUE_SHIFT) | \ 78 (DT_ENUM_IDX_OR(node_id, drive_strength, 0) << MCUX_IMX_DSE_SHIFT) | \ 79 (DT_ENUM_IDX_OR(node_id, slew_rate, 0) << MCUX_IMX_SRE_SHIFT) | \ 80 (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_LPSR_ODE_SHIFT) | \ 81 (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT) 82 83 #define Z_PINCTRL_MCUX_IMX_SNVS(node_id) \ 84 (DT_PROP(node_id, bias_pull_up) << MCUX_IMX_PUS_SHIFT) | \ 85 ((DT_PROP(node_id, bias_pull_up) || DT_PROP(node_id, bias_pull_down)) \ 86 << MCUX_IMX_PUE_SHIFT) | \ 87 (DT_ENUM_IDX_OR(node_id, drive_strength, 0) << MCUX_IMX_DSE_SHIFT) | \ 88 (DT_ENUM_IDX_OR(node_id, slew_rate, 0) << MCUX_IMX_SRE_SHIFT) | \ 89 (DT_PROP(node_id, drive_open_drain) << MCUX_IMX_SNVS_ODE_SHIFT) | \ 90 (DT_PROP(node_id, input_enable) << MCUX_IMX_INPUT_ENABLE_SHIFT) 91 92 /* This struct must be present. It is used by the mcux gpio driver */ 93 struct pinctrl_soc_pinmux { 94 uint32_t mux_register; /* IOMUXC SW_PAD_MUX register */ 95 uint32_t config_register; /* IOMUXC SW_PAD_CTL register */ 96 uint32_t input_register; /* IOMUXC SELECT_INPUT DAISY register */ 97 uint32_t gpr_register; /* IOMUXC GPR register */ 98 uint8_t gpr_shift: 5; /* bitshift for GPR register write */ 99 uint8_t mux_mode: 4; /* Mux value for SW_PAD_MUX register */ 100 uint32_t input_daisy:4; /* Mux value for SELECT_INPUT_DAISY register */ 101 uint8_t gpr_val: 1; /* value to write to GPR register */ 102 uint8_t pue_mux: 1; /* Is pinmux reg pue type */ 103 uint8_t pdrv_mux: 1; /* Is pinmux reg pdrv type */ 104 uint8_t lpsr_mux: 1; /* Is pinmux reg LPSR type */ 105 uint8_t snvs_mux: 1; /* Is pinmux reg SNVS type */ 106 }; 107 108 struct pinctrl_soc_pin { 109 struct pinctrl_soc_pinmux pinmux; 110 uint32_t pin_ctrl_flags; /* value to write to IOMUXC_SW_PAD_CTL register */ 111 }; 112 113 typedef struct pinctrl_soc_pin pinctrl_soc_pin_t; 114 115 /* This definition must be present. It is used by the mcux gpio driver */ 116 #define MCUX_IMX_PINMUX(node_id) \ 117 { \ 118 .mux_register = DT_PROP_BY_IDX(node_id, pinmux, 0), \ 119 .config_register = DT_PROP_BY_IDX(node_id, pinmux, 4), \ 120 .input_register = DT_PROP_BY_IDX(node_id, pinmux, 2), \ 121 .mux_mode = DT_PROP_BY_IDX(node_id, pinmux, 1), \ 122 .input_daisy = DT_PROP_BY_IDX(node_id, pinmux, 3), \ 123 IF_ENABLED(DT_PROP_HAS_IDX(node_id, gpr, 0), \ 124 (.gpr_register = DT_PROP_BY_IDX(node_id, gpr, 0),)) \ 125 IF_ENABLED(DT_PROP_HAS_IDX(node_id, gpr, 1), \ 126 (.gpr_shift = DT_PROP_BY_IDX(node_id, gpr, 1),)) \ 127 IF_ENABLED(DT_PROP_HAS_IDX(node_id, gpr, 2), \ 128 (.gpr_val = DT_PROP_BY_IDX(node_id, gpr, 2),)) \ 129 .pue_mux = DT_PROP(node_id, pin_pue), \ 130 .pdrv_mux = DT_PROP(node_id, pin_pdrv), \ 131 .lpsr_mux = DT_PROP(node_id, pin_lpsr), \ 132 .snvs_mux = DT_PROP(node_id, pin_snvs), \ 133 } 134 135 #define Z_PINCTRL_PINMUX(group_id, pin_prop, idx) \ 136 MCUX_IMX_PINMUX(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx)) 137 138 #define Z_PINCTRL_STATE_PIN_INIT(group_id, pin_prop, idx) \ 139 { \ 140 .pinmux = Z_PINCTRL_PINMUX(group_id, pin_prop, idx), \ 141 IF_ENABLED(DT_PROP(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx), pin_pue), \ 142 (.pin_ctrl_flags = Z_PINCTRL_MCUX_IMX_PUE_PUS(group_id),)) \ 143 IF_ENABLED(DT_PROP(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx), pin_pdrv), \ 144 (.pin_ctrl_flags = Z_PINCTRL_MCUX_IMX_PDRV(group_id),)) \ 145 IF_ENABLED(DT_PROP(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx), pin_lpsr), \ 146 (.pin_ctrl_flags = Z_PINCTRL_MCUX_IMX_LPSR(group_id),)) \ 147 IF_ENABLED(DT_PROP(DT_PHANDLE_BY_IDX(group_id, pin_prop, idx), pin_snvs), \ 148 (.pin_ctrl_flags = Z_PINCTRL_MCUX_IMX_SNVS(group_id),)) \ 149 }, 150 151 152 #define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ 153 {DT_FOREACH_CHILD_VARGS(DT_PHANDLE(node_id, prop), \ 154 DT_FOREACH_PROP_ELEM, pinmux, Z_PINCTRL_STATE_PIN_INIT)}; \ 155 156 157 #ifdef __cplusplus 158 } 159 #endif 160 161 #endif /* ZEPHYR_SOC_ARM_NXP_IMX_RT_PINCTRL_RT11XX_H_ */ 162