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