7e66c30f859c8cc9a2d87307d8c16b7f8c27de3d
[platform/kernel/u-boot.git] / drivers / pinctrl / sunxi / pinctrl-sunxi.c
1 // 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
13 extern U_BOOT_DRIVER(gpio_sunxi);
14
15 /*
16  * This structure implements a simplified view of the possible pinmux settings:
17  * Each mux value is assumed to be the same for a given function, across the
18  * pins in each group (almost universally true, with same rare exceptions not
19  * relevant to U-Boot), but also across different ports (not true in many
20  * cases). We ignore the first problem, and work around the latter by just
21  * supporting one particular port for a each function. This works fine for all
22  * board configurations so far. If this would need to be revisited, we could
23  * add a "u8 port;" below and match that, with 0 encoding the "don't care" case.
24  */
25 struct sunxi_pinctrl_function {
26         const char      name[sizeof("gpio_out")];
27         u8              mux;
28 };
29
30 struct sunxi_pinctrl_desc {
31         const struct sunxi_pinctrl_function     *functions;
32         u8                                      num_functions;
33         u8                                      first_bank;
34         u8                                      num_banks;
35 };
36
37 struct sunxi_pinctrl_plat {
38         struct sunxi_gpio __iomem *base;
39 };
40
41 static int sunxi_pinctrl_get_pins_count(struct udevice *dev)
42 {
43         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
44
45         return desc->num_banks * SUNXI_GPIOS_PER_BANK;
46 }
47
48 static const char *sunxi_pinctrl_get_pin_name(struct udevice *dev,
49                                               uint pin_selector)
50 {
51         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
52         static char pin_name[sizeof("PN31")];
53
54         snprintf(pin_name, sizeof(pin_name), "P%c%d",
55                  pin_selector / SUNXI_GPIOS_PER_BANK + desc->first_bank + 'A',
56                  pin_selector % SUNXI_GPIOS_PER_BANK);
57
58         return pin_name;
59 }
60
61 static int sunxi_pinctrl_get_functions_count(struct udevice *dev)
62 {
63         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
64
65         return desc->num_functions;
66 }
67
68 static const char *sunxi_pinctrl_get_function_name(struct udevice *dev,
69                                                    uint func_selector)
70 {
71         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
72
73         return desc->functions[func_selector].name;
74 }
75
76 static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector,
77                                     uint func_selector)
78 {
79         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
80         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
81         int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
82         int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
83
84         debug("set mux: %-4s => %s (%d)\n",
85               sunxi_pinctrl_get_pin_name(dev, pin_selector),
86               sunxi_pinctrl_get_function_name(dev, func_selector),
87               desc->functions[func_selector].mux);
88
89         sunxi_gpio_set_cfgbank(plat->base + bank, pin,
90                                desc->functions[func_selector].mux);
91
92         return 0;
93 }
94
95 static const struct pinconf_param sunxi_pinctrl_pinconf_params[] = {
96         { "bias-disable",       PIN_CONFIG_BIAS_DISABLE,         0 },
97         { "bias-pull-down",     PIN_CONFIG_BIAS_PULL_DOWN,       2 },
98         { "bias-pull-up",       PIN_CONFIG_BIAS_PULL_UP,         1 },
99         { "drive-strength",     PIN_CONFIG_DRIVE_STRENGTH,      10 },
100 };
101
102 static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
103                                           uint bank, uint pin, uint bias)
104 {
105         struct sunxi_gpio *regs = &plat->base[bank];
106
107         sunxi_gpio_set_pull_bank(regs, pin, bias);
108
109         return 0;
110 }
111
112 static int sunxi_pinctrl_pinconf_set_drive(struct sunxi_pinctrl_plat *plat,
113                                            uint bank, uint pin, uint drive)
114 {
115         struct sunxi_gpio *regs = &plat->base[bank];
116
117         if (drive < 10 || drive > 40)
118                 return -EINVAL;
119
120         /* Convert mA to the register value, rounding down. */
121         sunxi_gpio_set_drv_bank(regs, pin, drive / 10 - 1);
122
123         return 0;
124 }
125
126 static int sunxi_pinctrl_pinconf_set(struct udevice *dev, uint pin_selector,
127                                      uint param, uint val)
128 {
129         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
130         int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
131         int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
132
133         switch (param) {
134         case PIN_CONFIG_BIAS_DISABLE:
135         case PIN_CONFIG_BIAS_PULL_DOWN:
136         case PIN_CONFIG_BIAS_PULL_UP:
137                 return sunxi_pinctrl_pinconf_set_pull(plat, bank, pin, val);
138         case PIN_CONFIG_DRIVE_STRENGTH:
139                 return sunxi_pinctrl_pinconf_set_drive(plat, bank, pin, val);
140         }
141
142         return -EINVAL;
143 }
144
145 static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector,
146                                         char *buf, int size)
147 {
148         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
149         int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
150         int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
151         int mux  = sunxi_gpio_get_cfgbank(plat->base + bank, pin);
152
153         switch (mux) {
154         case SUNXI_GPIO_INPUT:
155                 strlcpy(buf, "gpio input", size);
156                 break;
157         case SUNXI_GPIO_OUTPUT:
158                 strlcpy(buf, "gpio output", size);
159                 break;
160         case SUNXI_GPIO_DISABLE:
161                 strlcpy(buf, "disabled", size);
162                 break;
163         default:
164                 snprintf(buf, size, "function %d", mux);
165                 break;
166         }
167
168         return 0;
169 }
170
171 static const struct pinctrl_ops sunxi_pinctrl_ops = {
172         .get_pins_count         = sunxi_pinctrl_get_pins_count,
173         .get_pin_name           = sunxi_pinctrl_get_pin_name,
174         .get_functions_count    = sunxi_pinctrl_get_functions_count,
175         .get_function_name      = sunxi_pinctrl_get_function_name,
176         .pinmux_set             = sunxi_pinctrl_pinmux_set,
177         .pinconf_num_params     = ARRAY_SIZE(sunxi_pinctrl_pinconf_params),
178         .pinconf_params         = sunxi_pinctrl_pinconf_params,
179         .pinconf_set            = sunxi_pinctrl_pinconf_set,
180         .set_state              = pinctrl_generic_set_state,
181         .get_pin_muxing         = sunxi_pinctrl_get_pin_muxing,
182 };
183
184 static int sunxi_pinctrl_bind(struct udevice *dev)
185 {
186         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
187         struct sunxi_pinctrl_desc *desc;
188         struct sunxi_gpio_plat *gpio_plat;
189         struct udevice *gpio_dev;
190         int i, ret;
191
192         desc = (void *)dev_get_driver_data(dev);
193         if (!desc)
194                 return -EINVAL;
195         dev_set_priv(dev, desc);
196
197         plat->base = dev_read_addr_ptr(dev);
198
199         ret = device_bind_driver_to_node(dev, "gpio_sunxi", dev->name,
200                                          dev_ofnode(dev), &gpio_dev);
201         if (ret)
202                 return ret;
203
204         for (i = 0; i < desc->num_banks; ++i) {
205                 gpio_plat = malloc(sizeof(*gpio_plat));
206                 if (!gpio_plat)
207                         return -ENOMEM;
208
209                 gpio_plat->regs = plat->base + i;
210                 gpio_plat->bank_name[0] = 'P';
211                 gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
212                 gpio_plat->bank_name[2] = '\0';
213
214                 ret = device_bind(gpio_dev, DM_DRIVER_REF(gpio_sunxi),
215                                   gpio_plat->bank_name, gpio_plat,
216                                   ofnode_null(), NULL);
217                 if (ret)
218                         return ret;
219         }
220
221         return 0;
222 }
223
224 static int sunxi_pinctrl_probe(struct udevice *dev)
225 {
226         struct clk *apb_clk;
227
228         apb_clk = devm_clk_get(dev, "apb");
229         if (!IS_ERR(apb_clk))
230                 clk_enable(apb_clk);
231
232         return 0;
233 }
234
235 static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = {
236         { "gpio_in",    0 },
237         { "gpio_out",   1 },
238         { "i2c0",       3 },    /* PE11-PE12 */
239         { "i2c1",       3 },    /* PD5-PD6 */
240         { "mmc0",       2 },    /* PF0-PF5 */
241         { "mmc1",       3 },    /* PC0-PC2 */
242 #if IS_ENABLED(CONFIG_UART0_PORT_F)
243         { "uart0",      3 },    /* PF2-PF4 */
244 #else
245         { "uart0",      5 },    /* PE0-PE1 */
246 #endif
247 };
248
249 static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = {
250         .functions      = suniv_f1c100s_pinctrl_functions,
251         .num_functions  = ARRAY_SIZE(suniv_f1c100s_pinctrl_functions),
252         .first_bank     = SUNXI_GPIO_A,
253         .num_banks      = 6,
254 };
255
256 static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = {
257         { "emac",       2 },    /* PA0-PA17 */
258         { "gpio_in",    0 },
259         { "gpio_out",   1 },
260         { "i2c0",       2 },    /* PB0-PB1 */
261         { "i2c1",       2 },    /* PB18-PB19 */
262         { "mmc0",       2 },    /* PF0-PF5 */
263 #if IS_ENABLED(CONFIG_MMC1_PINS_PH)
264         { "mmc1",       5 },    /* PH22-PH27 */
265 #else
266         { "mmc1",       4 },    /* PG0-PG5 */
267 #endif
268         { "mmc2",       3 },    /* PC6-PC15 */
269         { "mmc3",       2 },    /* PI4-PI9 */
270 #if IS_ENABLED(CONFIG_UART0_PORT_F)
271         { "uart0",      4 },    /* PF2-PF4 */
272 #else
273         { "uart0",      2 },    /* PB22-PB23 */
274 #endif
275 };
276
277 static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = {
278         .functions      = sun4i_a10_pinctrl_functions,
279         .num_functions  = ARRAY_SIZE(sun4i_a10_pinctrl_functions),
280         .first_bank     = SUNXI_GPIO_A,
281         .num_banks      = 9,
282 };
283
284 static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = {
285         { "emac",       2 },    /* PA0-PA17 */
286         { "gpio_in",    0 },
287         { "gpio_out",   1 },
288         { "i2c0",       2 },    /* PB0-PB1 */
289         { "i2c1",       2 },    /* PB15-PB16 */
290         { "mmc0",       2 },    /* PF0-PF5 */
291         { "mmc1",       2 },    /* PG3-PG8 */
292         { "mmc2",       3 },    /* PC6-PC15 */
293 #if IS_ENABLED(CONFIG_UART0_PORT_F)
294         { "uart0",      4 },    /* PF2-PF4 */
295 #else
296         { "uart0",      2 },    /* PB19-PB20 */
297 #endif
298         { "uart1",      4 },    /* PG3-PG4 */
299 };
300
301 static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = {
302         .functions      = sun5i_a13_pinctrl_functions,
303         .num_functions  = ARRAY_SIZE(sun5i_a13_pinctrl_functions),
304         .first_bank     = SUNXI_GPIO_A,
305         .num_banks      = 7,
306 };
307
308 static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = {
309         { "gmac",       2 },    /* PA0-PA27 */
310         { "gpio_in",    0 },
311         { "gpio_out",   1 },
312         { "i2c0",       2 },    /* PH14-PH15 */
313         { "i2c1",       2 },    /* PH16-PH17 */
314         { "mmc0",       2 },    /* PF0-PF5 */
315         { "mmc1",       2 },    /* PG0-PG5 */
316         { "mmc2",       3 },    /* PC6-PC15, PC24 */
317         { "mmc3",       4 },    /* PC6-PC15, PC24 */
318 #if IS_ENABLED(CONFIG_UART0_PORT_F)
319         { "uart0",      3 },    /* PF2-PF4 */
320 #else
321         { "uart0",      2 },    /* PH20-PH21 */
322 #endif
323 };
324
325 static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = {
326         .functions      = sun6i_a31_pinctrl_functions,
327         .num_functions  = ARRAY_SIZE(sun6i_a31_pinctrl_functions),
328         .first_bank     = SUNXI_GPIO_A,
329         .num_banks      = 8,
330 };
331
332 static const struct sunxi_pinctrl_function sun6i_a31_r_pinctrl_functions[] = {
333         { "gpio_in",    0 },
334         { "gpio_out",   1 },
335         { "s_i2c",      2 },    /* PL0-PL1 */
336         { "s_uart",     2 },    /* PL2-PL3 */
337 };
338
339 static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = {
340         .functions      = sun6i_a31_r_pinctrl_functions,
341         .num_functions  = ARRAY_SIZE(sun6i_a31_r_pinctrl_functions),
342         .first_bank     = SUNXI_GPIO_L,
343         .num_banks      = 2,
344 };
345
346 static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = {
347         { "emac",       2 },    /* PA0-PA17 */
348         { "gmac",       5 },    /* PA0-PA17 */
349         { "gpio_in",    0 },
350         { "gpio_out",   1 },
351         { "i2c0",       2 },    /* PB0-PB1 */
352         { "i2c1",       2 },    /* PB18-PB19 */
353         { "mmc0",       2 },    /* PF0-PF5 */
354 #if IS_ENABLED(CONFIG_MMC1_PINS_PH)
355         { "mmc1",       5 },    /* PH22-PH27 */
356 #else
357         { "mmc1",       4 },    /* PG0-PG5 */
358 #endif
359         { "mmc2",       3 },    /* PC5-PC15, PC24 */
360 #if IS_ENABLED(CONFIG_UART0_PORT_F)
361         { "uart0",      4 },    /* PF2-PF4 */
362 #else
363         { "uart0",      2 },    /* PB22-PB23 */
364 #endif
365 };
366
367 static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = {
368         .functions      = sun7i_a20_pinctrl_functions,
369         .num_functions  = ARRAY_SIZE(sun7i_a20_pinctrl_functions),
370         .first_bank     = SUNXI_GPIO_A,
371         .num_banks      = 9,
372 };
373
374 static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = {
375         { "gpio_in",    0 },
376         { "gpio_out",   1 },
377         { "i2c0",       2 },    /* PH2-PH3 */
378         { "i2c1",       2 },    /* PH4-PH5 */
379         { "mmc0",       2 },    /* PF0-PF5 */
380         { "mmc1",       2 },    /* PG0-PG5 */
381         { "mmc2",       3 },    /* PC5-PC16 */
382 #if IS_ENABLED(CONFIG_UART0_PORT_F)
383         { "uart0",      3 },    /* PF2-PF4 */
384 #endif
385         { "uart1",      2 },    /* PG6-PG7 */
386         { "uart2",      2 },    /* PB0-PB1 */
387 };
388
389 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = {
390         .functions      = sun8i_a23_pinctrl_functions,
391         .num_functions  = ARRAY_SIZE(sun8i_a23_pinctrl_functions),
392         .first_bank     = SUNXI_GPIO_A,
393         .num_banks      = 8,
394 };
395
396 static const struct sunxi_pinctrl_function sun8i_a23_r_pinctrl_functions[] = {
397         { "gpio_in",    0 },
398         { "gpio_out",   1 },
399         { "s_i2c",      3 },    /* PL0-PL1 */
400         { "s_uart",     2 },    /* PL2-PL3 */
401 };
402
403 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = {
404         .functions      = sun8i_a23_r_pinctrl_functions,
405         .num_functions  = ARRAY_SIZE(sun8i_a23_r_pinctrl_functions),
406         .first_bank     = SUNXI_GPIO_L,
407         .num_banks      = 1,
408 };
409
410 static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = {
411         { "gpio_in",    0 },
412         { "gpio_out",   1 },
413         { "i2c0",       2 },    /* PH2-PH3 */
414         { "i2c1",       2 },    /* PH4-PH5 */
415         { "mmc0",       2 },    /* PF0-PF5 */
416         { "mmc1",       2 },    /* PG0-PG5 */
417         { "mmc2",       3 },    /* PC5-PC16 */
418 #if IS_ENABLED(CONFIG_UART0_PORT_F)
419         { "uart0",      3 },    /* PF2-PF4 */
420 #else
421         { "uart0",      3 },    /* PB0-PB1 */
422 #endif
423         { "uart1",      2 },    /* PG6-PG7 */
424         { "uart2",      2 },    /* PB0-PB1 */
425 };
426
427 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = {
428         .functions      = sun8i_a33_pinctrl_functions,
429         .num_functions  = ARRAY_SIZE(sun8i_a33_pinctrl_functions),
430         .first_bank     = SUNXI_GPIO_A,
431         .num_banks      = 8,
432 };
433
434 static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = {
435         { "gmac",       4 },    /* PD2-PD23 */
436         { "gpio_in",    0 },
437         { "gpio_out",   1 },
438         { "i2c0",       2 },    /* PH0-PH1 */
439         { "i2c1",       2 },    /* PH2-PH3 */
440         { "mmc0",       2 },    /* PF0-PF5 */
441         { "mmc1",       2 },    /* PG0-PG5 */
442         { "mmc2",       3 },    /* PC5-PC16 */
443 #if IS_ENABLED(CONFIG_UART0_PORT_F)
444         { "uart0",      3 },    /* PF2-PF4 */
445 #else
446         { "uart0",      2 },    /* PB9-PB10 */
447 #endif
448         { "uart1",      2 },    /* PG6-PG7 */
449         { "uart2",      2 },    /* PB0-PB1 */
450 };
451
452 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = {
453         .functions      = sun8i_a83t_pinctrl_functions,
454         .num_functions  = ARRAY_SIZE(sun8i_a83t_pinctrl_functions),
455         .first_bank     = SUNXI_GPIO_A,
456         .num_banks      = 8,
457 };
458
459 static const struct sunxi_pinctrl_function sun8i_a83t_r_pinctrl_functions[] = {
460         { "gpio_in",    0 },
461         { "gpio_out",   1 },
462         { "s_i2c",      2 },    /* PL8-PL9 */
463         { "s_uart",     2 },    /* PL2-PL3 */
464 };
465
466 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = {
467         .functions      = sun8i_a83t_r_pinctrl_functions,
468         .num_functions  = ARRAY_SIZE(sun8i_a83t_r_pinctrl_functions),
469         .first_bank     = SUNXI_GPIO_L,
470         .num_banks      = 1,
471 };
472
473 static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = {
474         { "emac",       2 },    /* PD0-PD17 */
475         { "gpio_in",    0 },
476         { "gpio_out",   1 },
477         { "i2c0",       2 },    /* PA11-PA12 */
478         { "i2c1",       3 },    /* PA18-PA19 */
479         { "mmc0",       2 },    /* PF0-PF5 */
480         { "mmc1",       2 },    /* PG0-PG5 */
481         { "mmc2",       3 },    /* PC5-PC16 */
482 #if IS_ENABLED(CONFIG_UART0_PORT_F)
483         { "uart0",      3 },    /* PF2-PF4 */
484 #else
485         { "uart0",      2 },    /* PA4-PA5 */
486 #endif
487         { "uart1",      2 },    /* PG6-PG7 */
488         { "uart2",      2 },    /* PA0-PA1 */
489 };
490
491 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = {
492         .functions      = sun8i_h3_pinctrl_functions,
493         .num_functions  = ARRAY_SIZE(sun8i_h3_pinctrl_functions),
494         .first_bank     = SUNXI_GPIO_A,
495         .num_banks      = 7,
496 };
497
498 static const struct sunxi_pinctrl_function sun8i_h3_r_pinctrl_functions[] = {
499         { "gpio_in",    0 },
500         { "gpio_out",   1 },
501         { "s_i2c",      2 },    /* PL0-PL1 */
502         { "s_uart",     2 },    /* PL2-PL3 */
503 };
504
505 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = {
506         .functions      = sun8i_h3_r_pinctrl_functions,
507         .num_functions  = ARRAY_SIZE(sun8i_h3_r_pinctrl_functions),
508         .first_bank     = SUNXI_GPIO_L,
509         .num_banks      = 1,
510 };
511
512 static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = {
513         { "emac",       4 },    /* PD0-PD17 */
514         { "gpio_in",    0 },
515         { "gpio_out",   1 },
516         { "i2c0",       2 },    /* PB6-PB7 */
517         { "i2c1",       2 },    /* PB8-PB9 */
518         { "mmc0",       2 },    /* PF0-PF5 */
519         { "mmc1",       2 },    /* PG0-PG5 */
520         { "mmc2",       2 },    /* PC0-PC10 */
521 #if IS_ENABLED(CONFIG_UART0_PORT_F)
522         { "uart0",      3 },    /* PF2-PF4 */
523 #else
524         { "uart0",      3 },    /* PB8-PB9 */
525 #endif
526         { "uart1",      2 },    /* PG6-PG7 */
527         { "uart2",      2 },    /* PB0-PB1 */
528 };
529
530 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = {
531         .functions      = sun8i_v3s_pinctrl_functions,
532         .num_functions  = ARRAY_SIZE(sun8i_v3s_pinctrl_functions),
533         .first_bank     = SUNXI_GPIO_A,
534         .num_banks      = 7,
535 };
536
537 static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = {
538         { "gmac",       2 },    /* PA0-PA17 */
539         { "gpio_in",    0 },
540         { "gpio_out",   1 },
541         { "i2c0",       2 },    /* PH0-PH1 */
542         { "i2c1",       2 },    /* PH2-PH3 */
543         { "mmc0",       2 },    /* PF0-PF5 */
544         { "mmc1",       2 },    /* PG0-PG5 */
545         { "mmc2",       3 },    /* PC6-PC16 */
546 #if IS_ENABLED(CONFIG_UART0_PORT_F)
547         { "uart0",      4 },    /* PF2-PF4 */
548 #else
549         { "uart0",      2 },    /* PH12-PH13 */
550 #endif
551 };
552
553 static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = {
554         .functions      = sun9i_a80_pinctrl_functions,
555         .num_functions  = ARRAY_SIZE(sun9i_a80_pinctrl_functions),
556         .first_bank     = SUNXI_GPIO_A,
557         .num_banks      = 8,
558 };
559
560 static const struct sunxi_pinctrl_function sun9i_a80_r_pinctrl_functions[] = {
561         { "gpio_in",    0 },
562         { "gpio_out",   1 },
563         { "s_i2c0",     2 },    /* PN0-PN1 */
564         { "s_i2c1",     3 },    /* PM8-PM9 */
565         { "s_uart",     3 },    /* PL0-PL1 */
566 };
567
568 static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = {
569         .functions      = sun9i_a80_r_pinctrl_functions,
570         .num_functions  = ARRAY_SIZE(sun9i_a80_r_pinctrl_functions),
571         .first_bank     = SUNXI_GPIO_L,
572         .num_banks      = 3,
573 };
574
575 static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = {
576         { "emac",       4 },    /* PD8-PD23 */
577         { "gpio_in",    0 },
578         { "gpio_out",   1 },
579         { "i2c0",       2 },    /* PH0-PH1 */
580         { "i2c1",       2 },    /* PH2-PH3 */
581         { "mmc0",       2 },    /* PF0-PF5 */
582         { "mmc1",       2 },    /* PG0-PG5 */
583         { "mmc2",       3 },    /* PC1-PC16 */
584 #if IS_ENABLED(CONFIG_UART0_PORT_F)
585         { "uart0",      3 },    /* PF2-PF4 */
586 #else
587         { "uart0",      4 },    /* PB8-PB9 */
588 #endif
589         { "uart1",      2 },    /* PG6-PG7 */
590         { "uart2",      2 },    /* PB0-PB1 */
591 };
592
593 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = {
594         .functions      = sun50i_a64_pinctrl_functions,
595         .num_functions  = ARRAY_SIZE(sun50i_a64_pinctrl_functions),
596         .first_bank     = SUNXI_GPIO_A,
597         .num_banks      = 8,
598 };
599
600 static const struct sunxi_pinctrl_function sun50i_a64_r_pinctrl_functions[] = {
601         { "gpio_in",    0 },
602         { "gpio_out",   1 },
603         { "s_i2c",      2 },    /* PL8-PL9 */
604         { "s_uart",     2 },    /* PL2-PL3 */
605 };
606
607 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = {
608         .functions      = sun50i_a64_r_pinctrl_functions,
609         .num_functions  = ARRAY_SIZE(sun50i_a64_r_pinctrl_functions),
610         .first_bank     = SUNXI_GPIO_L,
611         .num_banks      = 1,
612 };
613
614 static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = {
615         { "emac",       2 },    /* PD0-PD17 */
616         { "gpio_in",    0 },
617         { "gpio_out",   1 },
618         { "i2c0",       2 },    /* PA11-PA12 */
619         { "i2c1",       3 },    /* PA18-PA19 */
620         { "mmc0",       2 },    /* PF0-PF5 */
621         { "mmc1",       2 },    /* PG0-PG5 */
622         { "mmc2",       3 },    /* PC1-PC16 */
623 #if IS_ENABLED(CONFIG_UART0_PORT_F)
624         { "uart0",      3 },    /* PF2-PF4 */
625 #else
626         { "uart0",      2 },    /* PA4-PA5 */
627 #endif
628         { "uart1",      2 },    /* PG6-PG7 */
629         { "uart2",      2 },    /* PA0-PA1 */
630 };
631
632 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = {
633         .functions      = sun50i_h5_pinctrl_functions,
634         .num_functions  = ARRAY_SIZE(sun50i_h5_pinctrl_functions),
635         .first_bank     = SUNXI_GPIO_A,
636         .num_banks      = 7,
637 };
638
639 static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = {
640         { "emac",       5 },    /* PD0-PD20 */
641         { "gpio_in",    0 },
642         { "gpio_out",   1 },
643         { "i2c0",       2 },    /* PD25-PD26 */
644         { "i2c1",       4 },    /* PH5-PH6 */
645         { "mmc0",       2 },    /* PF0-PF5 */
646         { "mmc1",       2 },    /* PG0-PG5 */
647         { "mmc2",       3 },    /* PC1-PC14 */
648 #if IS_ENABLED(CONFIG_UART0_PORT_F)
649         { "uart0",      3 },    /* PF2-PF4 */
650 #else
651         { "uart0",      2 },    /* PH0-PH1 */
652 #endif
653         { "uart1",      2 },    /* PG6-PG7 */
654 };
655
656 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = {
657         .functions      = sun50i_h6_pinctrl_functions,
658         .num_functions  = ARRAY_SIZE(sun50i_h6_pinctrl_functions),
659         .first_bank     = SUNXI_GPIO_A,
660         .num_banks      = 8,
661 };
662
663 static const struct sunxi_pinctrl_function sun50i_h6_r_pinctrl_functions[] = {
664         { "gpio_in",    0 },
665         { "gpio_out",   1 },
666         { "s_i2c",      3 },    /* PL0-PL1 */
667         { "s_uart",     2 },    /* PL2-PL3 */
668 };
669
670 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = {
671         .functions      = sun50i_h6_r_pinctrl_functions,
672         .num_functions  = ARRAY_SIZE(sun50i_h6_r_pinctrl_functions),
673         .first_bank     = SUNXI_GPIO_L,
674         .num_banks      = 2,
675 };
676
677 static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = {
678         { "emac0",      2 },    /* PI0-PI16 */
679         { "gpio_in",    0 },
680         { "gpio_out",   1 },
681         { "mmc0",       2 },    /* PF0-PF5 */
682         { "mmc1",       2 },    /* PG0-PG5 */
683         { "mmc2",       3 },    /* PC0-PC16 */
684 #if IS_ENABLED(CONFIG_UART0_PORT_F)
685         { "uart0",      3 },    /* PF2-PF4 */
686 #else
687         { "uart0",      2 },    /* PH0-PH1 */
688 #endif
689         { "uart1",      2 },    /* PG6-PG7 */
690 };
691
692 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = {
693         .functions      = sun50i_h616_pinctrl_functions,
694         .num_functions  = ARRAY_SIZE(sun50i_h616_pinctrl_functions),
695         .first_bank     = SUNXI_GPIO_A,
696         .num_banks      = 9,
697 };
698
699 static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = {
700         { "gpio_in",    0 },
701         { "gpio_out",   1 },
702         { "s_i2c",      3 },    /* PL0-PL1 */
703         { "s_uart",     2 },    /* PL2-PL3 */
704 };
705
706 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = {
707         .functions      = sun50i_h616_r_pinctrl_functions,
708         .num_functions  = ARRAY_SIZE(sun50i_h616_r_pinctrl_functions),
709         .first_bank     = SUNXI_GPIO_L,
710         .num_banks      = 1,
711 };
712
713 static const struct udevice_id sunxi_pinctrl_ids[] = {
714 #ifdef CONFIG_PINCTRL_SUNIV_F1C100S
715         {
716                 .compatible = "allwinner,suniv-f1c100s-pinctrl",
717                 .data = (ulong)&suniv_f1c100s_pinctrl_desc,
718         },
719 #endif
720 #ifdef CONFIG_PINCTRL_SUN4I_A10
721         {
722                 .compatible = "allwinner,sun4i-a10-pinctrl",
723                 .data = (ulong)&sun4i_a10_pinctrl_desc,
724         },
725 #endif
726 #ifdef CONFIG_PINCTRL_SUN5I_A13
727         {
728                 .compatible = "allwinner,sun5i-a10s-pinctrl",
729                 .data = (ulong)&sun5i_a13_pinctrl_desc,
730         },
731         {
732                 .compatible = "allwinner,sun5i-a13-pinctrl",
733                 .data = (ulong)&sun5i_a13_pinctrl_desc,
734         },
735 #endif
736 #ifdef CONFIG_PINCTRL_SUN6I_A31
737         {
738                 .compatible = "allwinner,sun6i-a31-pinctrl",
739                 .data = (ulong)&sun6i_a31_pinctrl_desc,
740         },
741         {
742                 .compatible = "allwinner,sun6i-a31s-pinctrl",
743                 .data = (ulong)&sun6i_a31_pinctrl_desc,
744         },
745 #endif
746 #ifdef CONFIG_PINCTRL_SUN6I_A31_R
747         {
748                 .compatible = "allwinner,sun6i-a31-r-pinctrl",
749                 .data = (ulong)&sun6i_a31_r_pinctrl_desc,
750         },
751 #endif
752 #ifdef CONFIG_PINCTRL_SUN7I_A20
753         {
754                 .compatible = "allwinner,sun7i-a20-pinctrl",
755                 .data = (ulong)&sun7i_a20_pinctrl_desc,
756         },
757 #endif
758 #ifdef CONFIG_PINCTRL_SUN8I_A23
759         {
760                 .compatible = "allwinner,sun8i-a23-pinctrl",
761                 .data = (ulong)&sun8i_a23_pinctrl_desc,
762         },
763 #endif
764 #ifdef CONFIG_PINCTRL_SUN8I_A23_R
765         {
766                 .compatible = "allwinner,sun8i-a23-r-pinctrl",
767                 .data = (ulong)&sun8i_a23_r_pinctrl_desc,
768         },
769 #endif
770 #ifdef CONFIG_PINCTRL_SUN8I_A33
771         {
772                 .compatible = "allwinner,sun8i-a33-pinctrl",
773                 .data = (ulong)&sun8i_a33_pinctrl_desc,
774         },
775 #endif
776 #ifdef CONFIG_PINCTRL_SUN8I_A83T
777         {
778                 .compatible = "allwinner,sun8i-a83t-pinctrl",
779                 .data = (ulong)&sun8i_a83t_pinctrl_desc,
780         },
781 #endif
782 #ifdef CONFIG_PINCTRL_SUN8I_A83T_R
783         {
784                 .compatible = "allwinner,sun8i-a83t-r-pinctrl",
785                 .data = (ulong)&sun8i_a83t_r_pinctrl_desc,
786         },
787 #endif
788 #ifdef CONFIG_PINCTRL_SUN8I_H3
789         {
790                 .compatible = "allwinner,sun8i-h3-pinctrl",
791                 .data = (ulong)&sun8i_h3_pinctrl_desc,
792         },
793 #endif
794 #ifdef CONFIG_PINCTRL_SUN8I_H3_R
795         {
796                 .compatible = "allwinner,sun8i-h3-r-pinctrl",
797                 .data = (ulong)&sun8i_h3_r_pinctrl_desc,
798         },
799 #endif
800 #ifdef CONFIG_PINCTRL_SUN7I_A20
801         {
802                 .compatible = "allwinner,sun8i-r40-pinctrl",
803                 .data = (ulong)&sun7i_a20_pinctrl_desc,
804         },
805 #endif
806 #ifdef CONFIG_PINCTRL_SUN8I_V3S
807         {
808                 .compatible = "allwinner,sun8i-v3-pinctrl",
809                 .data = (ulong)&sun8i_v3s_pinctrl_desc,
810         },
811         {
812                 .compatible = "allwinner,sun8i-v3s-pinctrl",
813                 .data = (ulong)&sun8i_v3s_pinctrl_desc,
814         },
815 #endif
816 #ifdef CONFIG_PINCTRL_SUN9I_A80
817         {
818                 .compatible = "allwinner,sun9i-a80-pinctrl",
819                 .data = (ulong)&sun9i_a80_pinctrl_desc,
820         },
821 #endif
822 #ifdef CONFIG_PINCTRL_SUN9I_A80_R
823         {
824                 .compatible = "allwinner,sun9i-a80-r-pinctrl",
825                 .data = (ulong)&sun9i_a80_r_pinctrl_desc,
826         },
827 #endif
828 #ifdef CONFIG_PINCTRL_SUN50I_A64
829         {
830                 .compatible = "allwinner,sun50i-a64-pinctrl",
831                 .data = (ulong)&sun50i_a64_pinctrl_desc,
832         },
833 #endif
834 #ifdef CONFIG_PINCTRL_SUN50I_A64_R
835         {
836                 .compatible = "allwinner,sun50i-a64-r-pinctrl",
837                 .data = (ulong)&sun50i_a64_r_pinctrl_desc,
838         },
839 #endif
840 #ifdef CONFIG_PINCTRL_SUN50I_H5
841         {
842                 .compatible = "allwinner,sun50i-h5-pinctrl",
843                 .data = (ulong)&sun50i_h5_pinctrl_desc,
844         },
845 #endif
846 #ifdef CONFIG_PINCTRL_SUN50I_H6
847         {
848                 .compatible = "allwinner,sun50i-h6-pinctrl",
849                 .data = (ulong)&sun50i_h6_pinctrl_desc,
850         },
851 #endif
852 #ifdef CONFIG_PINCTRL_SUN50I_H6_R
853         {
854                 .compatible = "allwinner,sun50i-h6-r-pinctrl",
855                 .data = (ulong)&sun50i_h6_r_pinctrl_desc,
856         },
857 #endif
858 #ifdef CONFIG_PINCTRL_SUN50I_H616
859         {
860                 .compatible = "allwinner,sun50i-h616-pinctrl",
861                 .data = (ulong)&sun50i_h616_pinctrl_desc,
862         },
863 #endif
864 #ifdef CONFIG_PINCTRL_SUN50I_H616_R
865         {
866                 .compatible = "allwinner,sun50i-h616-r-pinctrl",
867                 .data = (ulong)&sun50i_h616_r_pinctrl_desc,
868         },
869 #endif
870         {}
871 };
872
873 U_BOOT_DRIVER(sunxi_pinctrl) = {
874         .name           = "sunxi-pinctrl",
875         .id             = UCLASS_PINCTRL,
876         .of_match       = sunxi_pinctrl_ids,
877         .bind           = sunxi_pinctrl_bind,
878         .probe          = sunxi_pinctrl_probe,
879         .plat_auto      = sizeof(struct sunxi_pinctrl_plat),
880         .ops            = &sunxi_pinctrl_ops,
881 };