1 /* 2 * Copyright (C) 2016 Freescale Semiconductor, Inc. 3 * Copyright (C) 2017 NXP 4 * 5 * Author: Dong Aisheng <aisheng.dong@nxp.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 */ 12 13 #include <linux/err.h> 14 #include <linux/init.h> 15 #include <linux/io.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/of_device.h> 19 #include <linux/pinctrl/pinctrl.h> 20 21 #include "pinctrl-imx.h" 22 23 enum imx7ulp_pads { 24 IMX7ULP_PAD_PTC0 = 0, 25 IMX7ULP_PAD_PTC1, 26 IMX7ULP_PAD_PTC2, 27 IMX7ULP_PAD_PTC3, 28 IMX7ULP_PAD_PTC4, 29 IMX7ULP_PAD_PTC5, 30 IMX7ULP_PAD_PTC6, 31 IMX7ULP_PAD_PTC7, 32 IMX7ULP_PAD_PTC8, 33 IMX7ULP_PAD_PTC9, 34 IMX7ULP_PAD_PTC10, 35 IMX7ULP_PAD_PTC11, 36 IMX7ULP_PAD_PTC12, 37 IMX7ULP_PAD_PTC13, 38 IMX7ULP_PAD_PTC14, 39 IMX7ULP_PAD_PTC15, 40 IMX7ULP_PAD_PTC16, 41 IMX7ULP_PAD_PTC17, 42 IMX7ULP_PAD_PTC18, 43 IMX7ULP_PAD_PTC19, 44 IMX7ULP_PAD_RESERVE0, 45 IMX7ULP_PAD_RESERVE1, 46 IMX7ULP_PAD_RESERVE2, 47 IMX7ULP_PAD_RESERVE3, 48 IMX7ULP_PAD_RESERVE4, 49 IMX7ULP_PAD_RESERVE5, 50 IMX7ULP_PAD_RESERVE6, 51 IMX7ULP_PAD_RESERVE7, 52 IMX7ULP_PAD_RESERVE8, 53 IMX7ULP_PAD_RESERVE9, 54 IMX7ULP_PAD_RESERVE10, 55 IMX7ULP_PAD_RESERVE11, 56 IMX7ULP_PAD_PTD0, 57 IMX7ULP_PAD_PTD1, 58 IMX7ULP_PAD_PTD2, 59 IMX7ULP_PAD_PTD3, 60 IMX7ULP_PAD_PTD4, 61 IMX7ULP_PAD_PTD5, 62 IMX7ULP_PAD_PTD6, 63 IMX7ULP_PAD_PTD7, 64 IMX7ULP_PAD_PTD8, 65 IMX7ULP_PAD_PTD9, 66 IMX7ULP_PAD_PTD10, 67 IMX7ULP_PAD_PTD11, 68 IMX7ULP_PAD_RESERVE12, 69 IMX7ULP_PAD_RESERVE13, 70 IMX7ULP_PAD_RESERVE14, 71 IMX7ULP_PAD_RESERVE15, 72 IMX7ULP_PAD_RESERVE16, 73 IMX7ULP_PAD_RESERVE17, 74 IMX7ULP_PAD_RESERVE18, 75 IMX7ULP_PAD_RESERVE19, 76 IMX7ULP_PAD_RESERVE20, 77 IMX7ULP_PAD_RESERVE21, 78 IMX7ULP_PAD_RESERVE22, 79 IMX7ULP_PAD_RESERVE23, 80 IMX7ULP_PAD_RESERVE24, 81 IMX7ULP_PAD_RESERVE25, 82 IMX7ULP_PAD_RESERVE26, 83 IMX7ULP_PAD_RESERVE27, 84 IMX7ULP_PAD_RESERVE28, 85 IMX7ULP_PAD_RESERVE29, 86 IMX7ULP_PAD_RESERVE30, 87 IMX7ULP_PAD_RESERVE31, 88 IMX7ULP_PAD_PTE0, 89 IMX7ULP_PAD_PTE1, 90 IMX7ULP_PAD_PTE2, 91 IMX7ULP_PAD_PTE3, 92 IMX7ULP_PAD_PTE4, 93 IMX7ULP_PAD_PTE5, 94 IMX7ULP_PAD_PTE6, 95 IMX7ULP_PAD_PTE7, 96 IMX7ULP_PAD_PTE8, 97 IMX7ULP_PAD_PTE9, 98 IMX7ULP_PAD_PTE10, 99 IMX7ULP_PAD_PTE11, 100 IMX7ULP_PAD_PTE12, 101 IMX7ULP_PAD_PTE13, 102 IMX7ULP_PAD_PTE14, 103 IMX7ULP_PAD_PTE15, 104 IMX7ULP_PAD_RESERVE32, 105 IMX7ULP_PAD_RESERVE33, 106 IMX7ULP_PAD_RESERVE34, 107 IMX7ULP_PAD_RESERVE35, 108 IMX7ULP_PAD_RESERVE36, 109 IMX7ULP_PAD_RESERVE37, 110 IMX7ULP_PAD_RESERVE38, 111 IMX7ULP_PAD_RESERVE39, 112 IMX7ULP_PAD_RESERVE40, 113 IMX7ULP_PAD_RESERVE41, 114 IMX7ULP_PAD_RESERVE42, 115 IMX7ULP_PAD_RESERVE43, 116 IMX7ULP_PAD_RESERVE44, 117 IMX7ULP_PAD_RESERVE45, 118 IMX7ULP_PAD_RESERVE46, 119 IMX7ULP_PAD_RESERVE47, 120 IMX7ULP_PAD_PTF0, 121 IMX7ULP_PAD_PTF1, 122 IMX7ULP_PAD_PTF2, 123 IMX7ULP_PAD_PTF3, 124 IMX7ULP_PAD_PTF4, 125 IMX7ULP_PAD_PTF5, 126 IMX7ULP_PAD_PTF6, 127 IMX7ULP_PAD_PTF7, 128 IMX7ULP_PAD_PTF8, 129 IMX7ULP_PAD_PTF9, 130 IMX7ULP_PAD_PTF10, 131 IMX7ULP_PAD_PTF11, 132 IMX7ULP_PAD_PTF12, 133 IMX7ULP_PAD_PTF13, 134 IMX7ULP_PAD_PTF14, 135 IMX7ULP_PAD_PTF15, 136 IMX7ULP_PAD_PTF16, 137 IMX7ULP_PAD_PTF17, 138 IMX7ULP_PAD_PTF18, 139 IMX7ULP_PAD_PTF19, 140 }; 141 142 /* Pad names for the pinmux subsystem */ 143 static const struct pinctrl_pin_desc imx7ulp_pinctrl_pads[] = { 144 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC0), 145 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC1), 146 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC2), 147 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC3), 148 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC4), 149 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC5), 150 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC6), 151 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC7), 152 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC8), 153 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC9), 154 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC10), 155 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC11), 156 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC12), 157 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC13), 158 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC14), 159 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC15), 160 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC16), 161 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC17), 162 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC18), 163 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTC19), 164 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE0), 165 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE1), 166 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE2), 167 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE3), 168 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE4), 169 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE5), 170 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE6), 171 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE7), 172 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE8), 173 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE9), 174 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE10), 175 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE11), 176 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD0), 177 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD1), 178 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD2), 179 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD3), 180 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD4), 181 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD5), 182 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD6), 183 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD7), 184 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD8), 185 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD9), 186 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD10), 187 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTD11), 188 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE12), 189 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE13), 190 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE14), 191 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE15), 192 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE16), 193 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE17), 194 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE18), 195 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE19), 196 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE20), 197 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE21), 198 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE22), 199 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE23), 200 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE24), 201 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE25), 202 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE26), 203 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE27), 204 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE28), 205 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE29), 206 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE30), 207 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE31), 208 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE0), 209 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE1), 210 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE2), 211 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE3), 212 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE4), 213 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE5), 214 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE6), 215 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE7), 216 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE8), 217 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE9), 218 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE10), 219 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE11), 220 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE12), 221 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE13), 222 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE14), 223 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTE15), 224 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE32), 225 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE33), 226 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE34), 227 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE35), 228 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE36), 229 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE37), 230 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE38), 231 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE39), 232 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE40), 233 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE41), 234 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE42), 235 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE43), 236 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE44), 237 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE45), 238 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE46), 239 IMX_PINCTRL_PIN(IMX7ULP_PAD_RESERVE47), 240 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF0), 241 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF1), 242 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF2), 243 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF3), 244 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF4), 245 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF5), 246 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF6), 247 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF7), 248 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF8), 249 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF9), 250 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF10), 251 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF11), 252 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF12), 253 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF13), 254 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF14), 255 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF15), 256 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF16), 257 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF17), 258 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF18), 259 IMX_PINCTRL_PIN(IMX7ULP_PAD_PTF19), 260 }; 261 262 #define BM_OBE_ENABLED BIT(17) 263 #define BM_IBE_ENABLED BIT(16) 264 #define BM_LK_ENABLED BIT(15) 265 #define BM_MUX_MODE 0xf00 266 #define BP_MUX_MODE 8 267 #define BM_PULL_ENABLED BIT(1) 268 269 static const struct imx_cfg_params_decode imx7ulp_cfg_decodes[] = { 270 IMX_CFG_PARAMS_DECODE(PIN_CONFIG_DRIVE_STRENGTH, BIT(6), 6), 271 IMX_CFG_PARAMS_DECODE(PIN_CONFIG_DRIVE_PUSH_PULL, BIT(5), 5), 272 IMX_CFG_PARAMS_DECODE(PIN_CONFIG_SLEW_RATE, BIT(2), 2), 273 IMX_CFG_PARAMS_DECODE(PIN_CONFIG_BIAS_DISABLE, BIT(1), 1), 274 IMX_CFG_PARAMS_DECODE(PIN_CONFIG_BIAS_PULL_UP, BIT(0), 0), 275 276 IMX_CFG_PARAMS_DECODE_INVERT(PIN_CONFIG_DRIVE_OPEN_DRAIN, BIT(5), 5), 277 IMX_CFG_PARAMS_DECODE_INVERT(PIN_CONFIG_BIAS_PULL_DOWN, BIT(0), 0), 278 }; 279 280 static void imx7ulp_cfg_params_fixup(unsigned long *configs, 281 unsigned int num_configs, 282 u32 *raw_config) 283 { 284 enum pin_config_param param; 285 u32 param_val; 286 int i; 287 288 /* lock field disabled */ 289 *raw_config &= ~BM_LK_ENABLED; 290 291 for (i = 0; i < num_configs; i++) { 292 param = pinconf_to_config_param(configs[i]); 293 param_val = pinconf_to_config_argument(configs[i]); 294 295 if ((param == PIN_CONFIG_BIAS_PULL_UP) || 296 (param == PIN_CONFIG_BIAS_PULL_DOWN)) { 297 /* pull enabled */ 298 *raw_config |= BM_PULL_ENABLED; 299 300 return; 301 } 302 } 303 } 304 305 static int imx7ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 306 struct pinctrl_gpio_range *range, 307 unsigned offset, bool input) 308 { 309 struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); 310 const struct imx_pin_reg *pin_reg; 311 u32 reg; 312 313 pin_reg = &ipctl->pin_regs[offset]; 314 if (pin_reg->mux_reg == -1) 315 return -EINVAL; 316 317 reg = readl(ipctl->base + pin_reg->mux_reg); 318 if (input) 319 reg = (reg & ~BM_OBE_ENABLED) | BM_IBE_ENABLED; 320 else 321 reg = (reg & ~BM_IBE_ENABLED) | BM_OBE_ENABLED; 322 writel(reg, ipctl->base + pin_reg->mux_reg); 323 324 return 0; 325 } 326 327 static const struct imx_pinctrl_soc_info imx7ulp_pinctrl_info = { 328 .pins = imx7ulp_pinctrl_pads, 329 .npins = ARRAY_SIZE(imx7ulp_pinctrl_pads), 330 .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG, 331 .gpio_set_direction = imx7ulp_pmx_gpio_set_direction, 332 .mux_mask = BM_MUX_MODE, 333 .mux_shift = BP_MUX_MODE, 334 .generic_pinconf = true, 335 .decodes = imx7ulp_cfg_decodes, 336 .num_decodes = ARRAY_SIZE(imx7ulp_cfg_decodes), 337 .fixup = imx7ulp_cfg_params_fixup, 338 }; 339 340 static const struct of_device_id imx7ulp_pinctrl_of_match[] = { 341 { .compatible = "fsl,imx7ulp-iomuxc1", }, 342 { /* sentinel */ } 343 }; 344 345 static int imx7ulp_pinctrl_probe(struct platform_device *pdev) 346 { 347 return imx_pinctrl_probe(pdev, &imx7ulp_pinctrl_info); 348 } 349 350 static struct platform_driver imx7ulp_pinctrl_driver = { 351 .driver = { 352 .name = "imx7ulp-pinctrl", 353 .of_match_table = of_match_ptr(imx7ulp_pinctrl_of_match), 354 .suppress_bind_attrs = true, 355 }, 356 .probe = imx7ulp_pinctrl_probe, 357 }; 358 359 static int __init imx7ulp_pinctrl_init(void) 360 { 361 return platform_driver_register(&imx7ulp_pinctrl_driver); 362 } 363 arch_initcall(imx7ulp_pinctrl_init); 364