1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2021 NXP
4  */
5 
6 #include <linux/err.h>
7 #include <linux/init.h>
8 #include <linux/io.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/of_device.h>
12 #include <linux/pinctrl/pinctrl.h>
13 
14 #include "pinctrl-imx.h"
15 
16 enum imx8ulp_pads {
17 	IMX8ULP_PAD_PTD0 = 0,
18 	IMX8ULP_PAD_PTD1,
19 	IMX8ULP_PAD_PTD2,
20 	IMX8ULP_PAD_PTD3,
21 	IMX8ULP_PAD_PTD4,
22 	IMX8ULP_PAD_PTD5,
23 	IMX8ULP_PAD_PTD6,
24 	IMX8ULP_PAD_PTD7,
25 	IMX8ULP_PAD_PTD8,
26 	IMX8ULP_PAD_PTD9,
27 	IMX8ULP_PAD_PTD10,
28 	IMX8ULP_PAD_PTD11,
29 	IMX8ULP_PAD_PTD12,
30 	IMX8ULP_PAD_PTD13,
31 	IMX8ULP_PAD_PTD14,
32 	IMX8ULP_PAD_PTD15,
33 	IMX8ULP_PAD_PTD16,
34 	IMX8ULP_PAD_PTD17,
35 	IMX8ULP_PAD_PTD18,
36 	IMX8ULP_PAD_PTD19,
37 	IMX8ULP_PAD_PTD20,
38 	IMX8ULP_PAD_PTD21,
39 	IMX8ULP_PAD_PTD22,
40 	IMX8ULP_PAD_PTD23,
41 	IMX8ULP_PAD_RESERVE0,
42 	IMX8ULP_PAD_RESERVE1,
43 	IMX8ULP_PAD_RESERVE2,
44 	IMX8ULP_PAD_RESERVE3,
45 	IMX8ULP_PAD_RESERVE4,
46 	IMX8ULP_PAD_RESERVE5,
47 	IMX8ULP_PAD_RESERVE6,
48 	IMX8ULP_PAD_RESERVE7,
49 	IMX8ULP_PAD_PTE0,
50 	IMX8ULP_PAD_PTE1,
51 	IMX8ULP_PAD_PTE2,
52 	IMX8ULP_PAD_PTE3,
53 	IMX8ULP_PAD_PTE4,
54 	IMX8ULP_PAD_PTE5,
55 	IMX8ULP_PAD_PTE6,
56 	IMX8ULP_PAD_PTE7,
57 	IMX8ULP_PAD_PTE8,
58 	IMX8ULP_PAD_PTE9,
59 	IMX8ULP_PAD_PTE10,
60 	IMX8ULP_PAD_PTE11,
61 	IMX8ULP_PAD_PTE12,
62 	IMX8ULP_PAD_PTE13,
63 	IMX8ULP_PAD_PTE14,
64 	IMX8ULP_PAD_PTE15,
65 	IMX8ULP_PAD_PTE16,
66 	IMX8ULP_PAD_PTE17,
67 	IMX8ULP_PAD_PTE18,
68 	IMX8ULP_PAD_PTE19,
69 	IMX8ULP_PAD_PTE20,
70 	IMX8ULP_PAD_PTE21,
71 	IMX8ULP_PAD_PTE22,
72 	IMX8ULP_PAD_PTE23,
73 	IMX8ULP_PAD_RESERVE8,
74 	IMX8ULP_PAD_RESERVE9,
75 	IMX8ULP_PAD_RESERVE10,
76 	IMX8ULP_PAD_RESERVE11,
77 	IMX8ULP_PAD_RESERVE12,
78 	IMX8ULP_PAD_RESERVE13,
79 	IMX8ULP_PAD_RESERVE14,
80 	IMX8ULP_PAD_RESERVE15,
81 	IMX8ULP_PAD_PTF0,
82 	IMX8ULP_PAD_PTF1,
83 	IMX8ULP_PAD_PTF2,
84 	IMX8ULP_PAD_PTF3,
85 	IMX8ULP_PAD_PTF4,
86 	IMX8ULP_PAD_PTF5,
87 	IMX8ULP_PAD_PTF6,
88 	IMX8ULP_PAD_PTF7,
89 	IMX8ULP_PAD_PTF8,
90 	IMX8ULP_PAD_PTF9,
91 	IMX8ULP_PAD_PTF10,
92 	IMX8ULP_PAD_PTF11,
93 	IMX8ULP_PAD_PTF12,
94 	IMX8ULP_PAD_PTF13,
95 	IMX8ULP_PAD_PTF14,
96 	IMX8ULP_PAD_PTF15,
97 	IMX8ULP_PAD_PTF16,
98 	IMX8ULP_PAD_PTF17,
99 	IMX8ULP_PAD_PTF18,
100 	IMX8ULP_PAD_PTF19,
101 	IMX8ULP_PAD_PTF20,
102 	IMX8ULP_PAD_PTF21,
103 	IMX8ULP_PAD_PTF22,
104 	IMX8ULP_PAD_PTF23,
105 	IMX8ULP_PAD_PTF24,
106 	IMX8ULP_PAD_PTF25,
107 	IMX8ULP_PAD_PTF26,
108 	IMX8ULP_PAD_PTF27,
109 	IMX8ULP_PAD_PTF28,
110 	IMX8ULP_PAD_PTF29,
111 	IMX8ULP_PAD_PTF30,
112 	IMX8ULP_PAD_PTF31,
113 };
114 
115 /* Pad names for the pinmux subsystem */
116 static const struct pinctrl_pin_desc imx8ulp_pinctrl_pads[] = {
117 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD0),
118 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD1),
119 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD2),
120 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD3),
121 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD4),
122 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD5),
123 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD6),
124 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD7),
125 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD8),
126 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD9),
127 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD10),
128 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD11),
129 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD12),
130 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD13),
131 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD14),
132 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD15),
133 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD16),
134 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD17),
135 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD18),
136 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD19),
137 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD20),
138 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD21),
139 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD22),
140 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTD23),
141 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE0),
142 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE1),
143 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE2),
144 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE3),
145 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE4),
146 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE5),
147 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE6),
148 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE7),
149 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE0),
150 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE1),
151 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE2),
152 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE3),
153 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE4),
154 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE5),
155 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE6),
156 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE7),
157 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE8),
158 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE9),
159 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE10),
160 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE11),
161 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE12),
162 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE13),
163 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE14),
164 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE15),
165 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE16),
166 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE17),
167 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE18),
168 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE19),
169 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE20),
170 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE21),
171 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE22),
172 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTE23),
173 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE8),
174 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE9),
175 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE10),
176 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE11),
177 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE12),
178 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE13),
179 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE14),
180 	IMX_PINCTRL_PIN(IMX8ULP_PAD_RESERVE15),
181 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF0),
182 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF1),
183 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF2),
184 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF3),
185 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF4),
186 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF5),
187 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF6),
188 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF7),
189 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF8),
190 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF9),
191 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF10),
192 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF11),
193 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF12),
194 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF13),
195 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF14),
196 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF15),
197 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF16),
198 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF17),
199 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF18),
200 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF19),
201 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF20),
202 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF21),
203 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF22),
204 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF23),
205 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF24),
206 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF25),
207 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF26),
208 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF27),
209 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF28),
210 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF29),
211 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF30),
212 	IMX_PINCTRL_PIN(IMX8ULP_PAD_PTF31),
213 };
214 
215 #define BM_OBE_ENABLED		BIT(17)
216 #define BM_IBE_ENABLED		BIT(16)
217 #define BM_MUX_MODE		0xf00
218 #define BP_MUX_MODE		8
219 
220 static int imx8ulp_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
221 					  struct pinctrl_gpio_range *range,
222 					  unsigned offset, bool input)
223 {
224 	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
225 	const struct imx_pin_reg *pin_reg;
226 	u32 reg;
227 
228 	pin_reg = &ipctl->pin_regs[offset];
229 	if (pin_reg->mux_reg == -1)
230 		return -EINVAL;
231 
232 	reg = readl(ipctl->base + pin_reg->mux_reg);
233 	if (input)
234 		reg = (reg & ~BM_OBE_ENABLED) | BM_IBE_ENABLED;
235 	else
236 		reg = (reg & ~BM_IBE_ENABLED) | BM_OBE_ENABLED;
237 	writel(reg, ipctl->base + pin_reg->mux_reg);
238 
239 	return 0;
240 }
241 
242 static const struct imx_pinctrl_soc_info imx8ulp_pinctrl_info = {
243 	.pins = imx8ulp_pinctrl_pads,
244 	.npins = ARRAY_SIZE(imx8ulp_pinctrl_pads),
245 	.flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG,
246 	.gpio_set_direction = imx8ulp_pmx_gpio_set_direction,
247 	.mux_mask = BM_MUX_MODE,
248 	.mux_shift = BP_MUX_MODE,
249 };
250 
251 static const struct of_device_id imx8ulp_pinctrl_of_match[] = {
252 	{ .compatible = "fsl,imx8ulp-iomuxc1", },
253 	{ /* sentinel */ }
254 };
255 
256 static int imx8ulp_pinctrl_probe(struct platform_device *pdev)
257 {
258 	return imx_pinctrl_probe(pdev, &imx8ulp_pinctrl_info);
259 }
260 
261 static struct platform_driver imx8ulp_pinctrl_driver = {
262 	.driver = {
263 		.name = "imx8ulp-pinctrl",
264 		.of_match_table = imx8ulp_pinctrl_of_match,
265 		.suppress_bind_attrs = true,
266 	},
267 	.probe = imx8ulp_pinctrl_probe,
268 };
269 
270 static int __init imx8ulp_pinctrl_init(void)
271 {
272 	return platform_driver_register(&imx8ulp_pinctrl_driver);
273 }
274 arch_initcall(imx8ulp_pinctrl_init);
275 
276 MODULE_AUTHOR("Jacky Bai <ping.bai@nxp.com>");
277 MODULE_DESCRIPTION("NXP i.MX8ULP pinctrl driver");
278 MODULE_LICENSE("GPL v2");
279