blob: 43bb1ec650a9a110d59f4f8afd02f9b7e201d7db [file] [log] [blame]
Samuel Hollande3095022021-08-12 20:09:43 -05001// SPDX-License-Identifier: GPL-2.0
2
3#include <clk.h>
4#include <dm.h>
5#include <dm/device-internal.h>
6#include <dm/lists.h>
7#include <dm/pinctrl.h>
8#include <errno.h>
9#include <malloc.h>
10
11#include <asm/gpio.h>
12
13extern U_BOOT_DRIVER(gpio_sunxi);
14
15struct sunxi_pinctrl_desc {
16 u8 first_bank;
17 u8 num_banks;
18};
19
20struct sunxi_pinctrl_plat {
21 struct sunxi_gpio __iomem *base;
22};
23
24static const struct pinctrl_ops sunxi_pinctrl_ops = {
25 .set_state = pinctrl_generic_set_state,
26};
27
28static int sunxi_pinctrl_bind(struct udevice *dev)
29{
30 struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
31 struct sunxi_pinctrl_desc *desc;
32 struct sunxi_gpio_plat *gpio_plat;
33 struct udevice *gpio_dev;
34 int i, ret;
35
36 desc = (void *)dev_get_driver_data(dev);
37 if (!desc)
38 return -EINVAL;
39 dev_set_priv(dev, desc);
40
41 plat->base = dev_read_addr_ptr(dev);
42
43 ret = device_bind_driver_to_node(dev, "gpio_sunxi", dev->name,
44 dev_ofnode(dev), &gpio_dev);
45 if (ret)
46 return ret;
47
48 for (i = 0; i < desc->num_banks; ++i) {
49 gpio_plat = malloc(sizeof(*gpio_plat));
50 if (!gpio_plat)
51 return -ENOMEM;
52
53 gpio_plat->regs = plat->base + i;
54 gpio_plat->bank_name[0] = 'P';
55 gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
56 gpio_plat->bank_name[2] = '\0';
57
58 ret = device_bind(gpio_dev, DM_DRIVER_REF(gpio_sunxi),
59 gpio_plat->bank_name, gpio_plat,
60 ofnode_null(), NULL);
61 if (ret)
62 return ret;
63 }
64
65 return 0;
66}
67
68static int sunxi_pinctrl_probe(struct udevice *dev)
69{
70 struct clk *apb_clk;
71
72 apb_clk = devm_clk_get(dev, "apb");
73 if (!IS_ERR(apb_clk))
74 clk_enable(apb_clk);
75
76 return 0;
77}
78
79static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = {
80 .first_bank = SUNXI_GPIO_A,
81 .num_banks = 6,
82};
83
84static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = {
85 .first_bank = SUNXI_GPIO_A,
86 .num_banks = 9,
87};
88
89static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = {
90 .first_bank = SUNXI_GPIO_A,
91 .num_banks = 7,
92};
93
94static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = {
95 .first_bank = SUNXI_GPIO_A,
96 .num_banks = 8,
97};
98
99static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = {
100 .first_bank = SUNXI_GPIO_L,
101 .num_banks = 2,
102};
103
104static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = {
105 .first_bank = SUNXI_GPIO_A,
106 .num_banks = 9,
107};
108
109static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = {
110 .first_bank = SUNXI_GPIO_A,
111 .num_banks = 8,
112};
113
114static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = {
115 .first_bank = SUNXI_GPIO_L,
116 .num_banks = 1,
117};
118
119static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = {
120 .first_bank = SUNXI_GPIO_A,
121 .num_banks = 8,
122};
123
124static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = {
125 .first_bank = SUNXI_GPIO_A,
126 .num_banks = 8,
127};
128
129static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = {
130 .first_bank = SUNXI_GPIO_L,
131 .num_banks = 1,
132};
133
134static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = {
135 .first_bank = SUNXI_GPIO_A,
136 .num_banks = 7,
137};
138
139static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = {
140 .first_bank = SUNXI_GPIO_L,
141 .num_banks = 1,
142};
143
144static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = {
145 .first_bank = SUNXI_GPIO_A,
146 .num_banks = 7,
147};
148
149static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = {
150 .first_bank = SUNXI_GPIO_A,
151 .num_banks = 8,
152};
153
154static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = {
155 .first_bank = SUNXI_GPIO_L,
156 .num_banks = 3,
157};
158
159static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = {
160 .first_bank = SUNXI_GPIO_A,
161 .num_banks = 8,
162};
163
164static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = {
165 .first_bank = SUNXI_GPIO_L,
166 .num_banks = 1,
167};
168
169static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = {
170 .first_bank = SUNXI_GPIO_A,
171 .num_banks = 7,
172};
173
174static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = {
175 .first_bank = SUNXI_GPIO_A,
176 .num_banks = 8,
177};
178
179static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = {
180 .first_bank = SUNXI_GPIO_L,
181 .num_banks = 2,
182};
183
184static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = {
185 .first_bank = SUNXI_GPIO_A,
186 .num_banks = 9,
187};
188
189static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = {
190 .first_bank = SUNXI_GPIO_L,
191 .num_banks = 1,
192};
193
194static const struct udevice_id sunxi_pinctrl_ids[] = {
195#ifdef CONFIG_PINCTRL_SUNIV_F1C100S
196 {
197 .compatible = "allwinner,suniv-f1c100s-pinctrl",
198 .data = (ulong)&suniv_f1c100s_pinctrl_desc,
199 },
200#endif
201#ifdef CONFIG_PINCTRL_SUN4I_A10
202 {
203 .compatible = "allwinner,sun4i-a10-pinctrl",
204 .data = (ulong)&sun4i_a10_pinctrl_desc,
205 },
206#endif
207#ifdef CONFIG_PINCTRL_SUN5I_A13
208 {
209 .compatible = "allwinner,sun5i-a10s-pinctrl",
210 .data = (ulong)&sun5i_a13_pinctrl_desc,
211 },
212 {
213 .compatible = "allwinner,sun5i-a13-pinctrl",
214 .data = (ulong)&sun5i_a13_pinctrl_desc,
215 },
216#endif
217#ifdef CONFIG_PINCTRL_SUN6I_A31
218 {
219 .compatible = "allwinner,sun6i-a31-pinctrl",
220 .data = (ulong)&sun6i_a31_pinctrl_desc,
221 },
222 {
223 .compatible = "allwinner,sun6i-a31s-pinctrl",
224 .data = (ulong)&sun6i_a31_pinctrl_desc,
225 },
226#endif
227#ifdef CONFIG_PINCTRL_SUN6I_A31_R
228 {
229 .compatible = "allwinner,sun6i-a31-r-pinctrl",
230 .data = (ulong)&sun6i_a31_r_pinctrl_desc,
231 },
232#endif
233#ifdef CONFIG_PINCTRL_SUN7I_A20
234 {
235 .compatible = "allwinner,sun7i-a20-pinctrl",
236 .data = (ulong)&sun7i_a20_pinctrl_desc,
237 },
238#endif
239#ifdef CONFIG_PINCTRL_SUN8I_A23
240 {
241 .compatible = "allwinner,sun8i-a23-pinctrl",
242 .data = (ulong)&sun8i_a23_pinctrl_desc,
243 },
244#endif
245#ifdef CONFIG_PINCTRL_SUN8I_A23_R
246 {
247 .compatible = "allwinner,sun8i-a23-r-pinctrl",
248 .data = (ulong)&sun8i_a23_r_pinctrl_desc,
249 },
250#endif
251#ifdef CONFIG_PINCTRL_SUN8I_A33
252 {
253 .compatible = "allwinner,sun8i-a33-pinctrl",
254 .data = (ulong)&sun8i_a33_pinctrl_desc,
255 },
256#endif
257#ifdef CONFIG_PINCTRL_SUN8I_A83T
258 {
259 .compatible = "allwinner,sun8i-a83t-pinctrl",
260 .data = (ulong)&sun8i_a83t_pinctrl_desc,
261 },
262#endif
263#ifdef CONFIG_PINCTRL_SUN8I_A83T_R
264 {
265 .compatible = "allwinner,sun8i-a83t-r-pinctrl",
266 .data = (ulong)&sun8i_a83t_r_pinctrl_desc,
267 },
268#endif
269#ifdef CONFIG_PINCTRL_SUN8I_H3
270 {
271 .compatible = "allwinner,sun8i-h3-pinctrl",
272 .data = (ulong)&sun8i_h3_pinctrl_desc,
273 },
274#endif
275#ifdef CONFIG_PINCTRL_SUN8I_H3_R
276 {
277 .compatible = "allwinner,sun8i-h3-r-pinctrl",
278 .data = (ulong)&sun8i_h3_r_pinctrl_desc,
279 },
280#endif
281#ifdef CONFIG_PINCTRL_SUN7I_A20
282 {
283 .compatible = "allwinner,sun8i-r40-pinctrl",
284 .data = (ulong)&sun7i_a20_pinctrl_desc,
285 },
286#endif
287#ifdef CONFIG_PINCTRL_SUN8I_V3S
288 {
289 .compatible = "allwinner,sun8i-v3-pinctrl",
290 .data = (ulong)&sun8i_v3s_pinctrl_desc,
291 },
292 {
293 .compatible = "allwinner,sun8i-v3s-pinctrl",
294 .data = (ulong)&sun8i_v3s_pinctrl_desc,
295 },
296#endif
297#ifdef CONFIG_PINCTRL_SUN9I_A80
298 {
299 .compatible = "allwinner,sun9i-a80-pinctrl",
300 .data = (ulong)&sun9i_a80_pinctrl_desc,
301 },
302#endif
303#ifdef CONFIG_PINCTRL_SUN9I_A80_R
304 {
305 .compatible = "allwinner,sun9i-a80-r-pinctrl",
306 .data = (ulong)&sun9i_a80_r_pinctrl_desc,
307 },
308#endif
309#ifdef CONFIG_PINCTRL_SUN50I_A64
310 {
311 .compatible = "allwinner,sun50i-a64-pinctrl",
312 .data = (ulong)&sun50i_a64_pinctrl_desc,
313 },
314#endif
315#ifdef CONFIG_PINCTRL_SUN50I_A64_R
316 {
317 .compatible = "allwinner,sun50i-a64-r-pinctrl",
318 .data = (ulong)&sun50i_a64_r_pinctrl_desc,
319 },
320#endif
321#ifdef CONFIG_PINCTRL_SUN50I_H5
322 {
323 .compatible = "allwinner,sun50i-h5-pinctrl",
324 .data = (ulong)&sun50i_h5_pinctrl_desc,
325 },
326#endif
327#ifdef CONFIG_PINCTRL_SUN50I_H6
328 {
329 .compatible = "allwinner,sun50i-h6-pinctrl",
330 .data = (ulong)&sun50i_h6_pinctrl_desc,
331 },
332#endif
333#ifdef CONFIG_PINCTRL_SUN50I_H6_R
334 {
335 .compatible = "allwinner,sun50i-h6-r-pinctrl",
336 .data = (ulong)&sun50i_h6_r_pinctrl_desc,
337 },
338#endif
339#ifdef CONFIG_PINCTRL_SUN50I_H616
340 {
341 .compatible = "allwinner,sun50i-h616-pinctrl",
342 .data = (ulong)&sun50i_h616_pinctrl_desc,
343 },
344#endif
345#ifdef CONFIG_PINCTRL_SUN50I_H616_R
346 {
347 .compatible = "allwinner,sun50i-h616-r-pinctrl",
348 .data = (ulong)&sun50i_h616_r_pinctrl_desc,
349 },
350#endif
351 {}
352};
353
354U_BOOT_DRIVER(sunxi_pinctrl) = {
355 .name = "sunxi-pinctrl",
356 .id = UCLASS_PINCTRL,
357 .of_match = sunxi_pinctrl_ids,
358 .bind = sunxi_pinctrl_bind,
359 .probe = sunxi_pinctrl_probe,
360 .plat_auto = sizeof(struct sunxi_pinctrl_plat),
361 .ops = &sunxi_pinctrl_ops,
362};