pinctrl: sunxi: Add the A64 PWM pinmux
[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         { "pwm",        2 },    /* PD22 */
585 #if IS_ENABLED(CONFIG_UART0_PORT_F)
586         { "uart0",      3 },    /* PF2-PF4 */
587 #else
588         { "uart0",      4 },    /* PB8-PB9 */
589 #endif
590         { "uart1",      2 },    /* PG6-PG7 */
591         { "uart2",      2 },    /* PB0-PB1 */
592 };
593
594 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = {
595         .functions      = sun50i_a64_pinctrl_functions,
596         .num_functions  = ARRAY_SIZE(sun50i_a64_pinctrl_functions),
597         .first_bank     = SUNXI_GPIO_A,
598         .num_banks      = 8,
599 };
600
601 static const struct sunxi_pinctrl_function sun50i_a64_r_pinctrl_functions[] = {
602         { "gpio_in",    0 },
603         { "gpio_out",   1 },
604         { "s_i2c",      2 },    /* PL8-PL9 */
605         { "s_uart",     2 },    /* PL2-PL3 */
606 };
607
608 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = {
609         .functions      = sun50i_a64_r_pinctrl_functions,
610         .num_functions  = ARRAY_SIZE(sun50i_a64_r_pinctrl_functions),
611         .first_bank     = SUNXI_GPIO_L,
612         .num_banks      = 1,
613 };
614
615 static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = {
616         { "emac",       2 },    /* PD0-PD17 */
617         { "gpio_in",    0 },
618         { "gpio_out",   1 },
619         { "i2c0",       2 },    /* PA11-PA12 */
620         { "i2c1",       3 },    /* PA18-PA19 */
621         { "mmc0",       2 },    /* PF0-PF5 */
622         { "mmc1",       2 },    /* PG0-PG5 */
623         { "mmc2",       3 },    /* PC1-PC16 */
624 #if IS_ENABLED(CONFIG_UART0_PORT_F)
625         { "uart0",      3 },    /* PF2-PF4 */
626 #else
627         { "uart0",      2 },    /* PA4-PA5 */
628 #endif
629         { "uart1",      2 },    /* PG6-PG7 */
630         { "uart2",      2 },    /* PA0-PA1 */
631 };
632
633 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = {
634         .functions      = sun50i_h5_pinctrl_functions,
635         .num_functions  = ARRAY_SIZE(sun50i_h5_pinctrl_functions),
636         .first_bank     = SUNXI_GPIO_A,
637         .num_banks      = 7,
638 };
639
640 static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = {
641         { "emac",       5 },    /* PD0-PD20 */
642         { "gpio_in",    0 },
643         { "gpio_out",   1 },
644         { "i2c0",       2 },    /* PD25-PD26 */
645         { "i2c1",       4 },    /* PH5-PH6 */
646         { "mmc0",       2 },    /* PF0-PF5 */
647         { "mmc1",       2 },    /* PG0-PG5 */
648         { "mmc2",       3 },    /* PC1-PC14 */
649 #if IS_ENABLED(CONFIG_UART0_PORT_F)
650         { "uart0",      3 },    /* PF2-PF4 */
651 #else
652         { "uart0",      2 },    /* PH0-PH1 */
653 #endif
654         { "uart1",      2 },    /* PG6-PG7 */
655 };
656
657 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = {
658         .functions      = sun50i_h6_pinctrl_functions,
659         .num_functions  = ARRAY_SIZE(sun50i_h6_pinctrl_functions),
660         .first_bank     = SUNXI_GPIO_A,
661         .num_banks      = 8,
662 };
663
664 static const struct sunxi_pinctrl_function sun50i_h6_r_pinctrl_functions[] = {
665         { "gpio_in",    0 },
666         { "gpio_out",   1 },
667         { "s_i2c",      3 },    /* PL0-PL1 */
668         { "s_uart",     2 },    /* PL2-PL3 */
669 };
670
671 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = {
672         .functions      = sun50i_h6_r_pinctrl_functions,
673         .num_functions  = ARRAY_SIZE(sun50i_h6_r_pinctrl_functions),
674         .first_bank     = SUNXI_GPIO_L,
675         .num_banks      = 2,
676 };
677
678 static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = {
679         { "emac0",      2 },    /* PI0-PI16 */
680         { "gpio_in",    0 },
681         { "gpio_out",   1 },
682         { "mmc0",       2 },    /* PF0-PF5 */
683         { "mmc1",       2 },    /* PG0-PG5 */
684         { "mmc2",       3 },    /* PC0-PC16 */
685 #if IS_ENABLED(CONFIG_UART0_PORT_F)
686         { "uart0",      3 },    /* PF2-PF4 */
687 #else
688         { "uart0",      2 },    /* PH0-PH1 */
689 #endif
690         { "uart1",      2 },    /* PG6-PG7 */
691 };
692
693 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = {
694         .functions      = sun50i_h616_pinctrl_functions,
695         .num_functions  = ARRAY_SIZE(sun50i_h616_pinctrl_functions),
696         .first_bank     = SUNXI_GPIO_A,
697         .num_banks      = 9,
698 };
699
700 static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = {
701         { "gpio_in",    0 },
702         { "gpio_out",   1 },
703         { "s_i2c",      3 },    /* PL0-PL1 */
704         { "s_uart",     2 },    /* PL2-PL3 */
705 };
706
707 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = {
708         .functions      = sun50i_h616_r_pinctrl_functions,
709         .num_functions  = ARRAY_SIZE(sun50i_h616_r_pinctrl_functions),
710         .first_bank     = SUNXI_GPIO_L,
711         .num_banks      = 1,
712 };
713
714 static const struct udevice_id sunxi_pinctrl_ids[] = {
715 #ifdef CONFIG_PINCTRL_SUNIV_F1C100S
716         {
717                 .compatible = "allwinner,suniv-f1c100s-pinctrl",
718                 .data = (ulong)&suniv_f1c100s_pinctrl_desc,
719         },
720 #endif
721 #ifdef CONFIG_PINCTRL_SUN4I_A10
722         {
723                 .compatible = "allwinner,sun4i-a10-pinctrl",
724                 .data = (ulong)&sun4i_a10_pinctrl_desc,
725         },
726 #endif
727 #ifdef CONFIG_PINCTRL_SUN5I_A13
728         {
729                 .compatible = "allwinner,sun5i-a10s-pinctrl",
730                 .data = (ulong)&sun5i_a13_pinctrl_desc,
731         },
732         {
733                 .compatible = "allwinner,sun5i-a13-pinctrl",
734                 .data = (ulong)&sun5i_a13_pinctrl_desc,
735         },
736 #endif
737 #ifdef CONFIG_PINCTRL_SUN6I_A31
738         {
739                 .compatible = "allwinner,sun6i-a31-pinctrl",
740                 .data = (ulong)&sun6i_a31_pinctrl_desc,
741         },
742         {
743                 .compatible = "allwinner,sun6i-a31s-pinctrl",
744                 .data = (ulong)&sun6i_a31_pinctrl_desc,
745         },
746 #endif
747 #ifdef CONFIG_PINCTRL_SUN6I_A31_R
748         {
749                 .compatible = "allwinner,sun6i-a31-r-pinctrl",
750                 .data = (ulong)&sun6i_a31_r_pinctrl_desc,
751         },
752 #endif
753 #ifdef CONFIG_PINCTRL_SUN7I_A20
754         {
755                 .compatible = "allwinner,sun7i-a20-pinctrl",
756                 .data = (ulong)&sun7i_a20_pinctrl_desc,
757         },
758 #endif
759 #ifdef CONFIG_PINCTRL_SUN8I_A23
760         {
761                 .compatible = "allwinner,sun8i-a23-pinctrl",
762                 .data = (ulong)&sun8i_a23_pinctrl_desc,
763         },
764 #endif
765 #ifdef CONFIG_PINCTRL_SUN8I_A23_R
766         {
767                 .compatible = "allwinner,sun8i-a23-r-pinctrl",
768                 .data = (ulong)&sun8i_a23_r_pinctrl_desc,
769         },
770 #endif
771 #ifdef CONFIG_PINCTRL_SUN8I_A33
772         {
773                 .compatible = "allwinner,sun8i-a33-pinctrl",
774                 .data = (ulong)&sun8i_a33_pinctrl_desc,
775         },
776 #endif
777 #ifdef CONFIG_PINCTRL_SUN8I_A83T
778         {
779                 .compatible = "allwinner,sun8i-a83t-pinctrl",
780                 .data = (ulong)&sun8i_a83t_pinctrl_desc,
781         },
782 #endif
783 #ifdef CONFIG_PINCTRL_SUN8I_A83T_R
784         {
785                 .compatible = "allwinner,sun8i-a83t-r-pinctrl",
786                 .data = (ulong)&sun8i_a83t_r_pinctrl_desc,
787         },
788 #endif
789 #ifdef CONFIG_PINCTRL_SUN8I_H3
790         {
791                 .compatible = "allwinner,sun8i-h3-pinctrl",
792                 .data = (ulong)&sun8i_h3_pinctrl_desc,
793         },
794 #endif
795 #ifdef CONFIG_PINCTRL_SUN8I_H3_R
796         {
797                 .compatible = "allwinner,sun8i-h3-r-pinctrl",
798                 .data = (ulong)&sun8i_h3_r_pinctrl_desc,
799         },
800 #endif
801 #ifdef CONFIG_PINCTRL_SUN7I_A20
802         {
803                 .compatible = "allwinner,sun8i-r40-pinctrl",
804                 .data = (ulong)&sun7i_a20_pinctrl_desc,
805         },
806 #endif
807 #ifdef CONFIG_PINCTRL_SUN8I_V3S
808         {
809                 .compatible = "allwinner,sun8i-v3-pinctrl",
810                 .data = (ulong)&sun8i_v3s_pinctrl_desc,
811         },
812         {
813                 .compatible = "allwinner,sun8i-v3s-pinctrl",
814                 .data = (ulong)&sun8i_v3s_pinctrl_desc,
815         },
816 #endif
817 #ifdef CONFIG_PINCTRL_SUN9I_A80
818         {
819                 .compatible = "allwinner,sun9i-a80-pinctrl",
820                 .data = (ulong)&sun9i_a80_pinctrl_desc,
821         },
822 #endif
823 #ifdef CONFIG_PINCTRL_SUN9I_A80_R
824         {
825                 .compatible = "allwinner,sun9i-a80-r-pinctrl",
826                 .data = (ulong)&sun9i_a80_r_pinctrl_desc,
827         },
828 #endif
829 #ifdef CONFIG_PINCTRL_SUN50I_A64
830         {
831                 .compatible = "allwinner,sun50i-a64-pinctrl",
832                 .data = (ulong)&sun50i_a64_pinctrl_desc,
833         },
834 #endif
835 #ifdef CONFIG_PINCTRL_SUN50I_A64_R
836         {
837                 .compatible = "allwinner,sun50i-a64-r-pinctrl",
838                 .data = (ulong)&sun50i_a64_r_pinctrl_desc,
839         },
840 #endif
841 #ifdef CONFIG_PINCTRL_SUN50I_H5
842         {
843                 .compatible = "allwinner,sun50i-h5-pinctrl",
844                 .data = (ulong)&sun50i_h5_pinctrl_desc,
845         },
846 #endif
847 #ifdef CONFIG_PINCTRL_SUN50I_H6
848         {
849                 .compatible = "allwinner,sun50i-h6-pinctrl",
850                 .data = (ulong)&sun50i_h6_pinctrl_desc,
851         },
852 #endif
853 #ifdef CONFIG_PINCTRL_SUN50I_H6_R
854         {
855                 .compatible = "allwinner,sun50i-h6-r-pinctrl",
856                 .data = (ulong)&sun50i_h6_r_pinctrl_desc,
857         },
858 #endif
859 #ifdef CONFIG_PINCTRL_SUN50I_H616
860         {
861                 .compatible = "allwinner,sun50i-h616-pinctrl",
862                 .data = (ulong)&sun50i_h616_pinctrl_desc,
863         },
864 #endif
865 #ifdef CONFIG_PINCTRL_SUN50I_H616_R
866         {
867                 .compatible = "allwinner,sun50i-h616-r-pinctrl",
868                 .data = (ulong)&sun50i_h616_r_pinctrl_desc,
869         },
870 #endif
871         {}
872 };
873
874 U_BOOT_DRIVER(sunxi_pinctrl) = {
875         .name           = "sunxi-pinctrl",
876         .id             = UCLASS_PINCTRL,
877         .of_match       = sunxi_pinctrl_ids,
878         .bind           = sunxi_pinctrl_bind,
879         .probe          = sunxi_pinctrl_probe,
880         .plat_auto      = sizeof(struct sunxi_pinctrl_plat),
881         .ops            = &sunxi_pinctrl_ops,
882 };