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