1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for BCM6362 GPIO unit (pinctrl + GPIO)
5 * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
6 * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
9 #include <linux/bits.h>
10 #include <linux/gpio/driver.h>
11 #include <linux/kernel.h>
13 #include <linux/pinctrl/pinmux.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
17 #include "../pinctrl-utils.h"
19 #include "pinctrl-bcm63xx.h"
21 #define BCM6362_BANK_GPIOS 32
22 #define BCM6362_NUM_GPIOS 48
23 #define BCM6362_NUM_LEDS 24
25 #define BCM6362_LED_REG 0x10
26 #define BCM6362_MODE_REG 0x18
27 #define BCM6362_CTRL_REG 0x1c
28 #define BCM6362_BASEMODE_REG 0x38
29 #define BASEMODE_NAND BIT(2)
31 enum bcm6362_pinctrl_reg {
38 struct bcm6362_pingroup {
40 const unsigned * const pins;
41 const unsigned num_pins;
44 struct bcm6362_function {
46 const char * const *groups;
47 const unsigned num_groups;
49 enum bcm6362_pinctrl_reg reg;
50 uint32_t basemode_mask;
53 #define BCM6362_PIN(a, b, mask) \
57 .drv_data = (void *)(mask), \
60 static const struct pinctrl_pin_desc bcm6362_pins[] = {
61 PINCTRL_PIN(0, "gpio0"),
62 PINCTRL_PIN(1, "gpio1"),
63 PINCTRL_PIN(2, "gpio2"),
64 PINCTRL_PIN(3, "gpio3"),
65 PINCTRL_PIN(4, "gpio4"),
66 PINCTRL_PIN(5, "gpio5"),
67 PINCTRL_PIN(6, "gpio6"),
68 PINCTRL_PIN(7, "gpio7"),
69 BCM6362_PIN(8, "gpio8", BASEMODE_NAND),
70 PINCTRL_PIN(9, "gpio9"),
71 PINCTRL_PIN(10, "gpio10"),
72 PINCTRL_PIN(11, "gpio11"),
73 BCM6362_PIN(12, "gpio12", BASEMODE_NAND),
74 BCM6362_PIN(13, "gpio13", BASEMODE_NAND),
75 BCM6362_PIN(14, "gpio14", BASEMODE_NAND),
76 BCM6362_PIN(15, "gpio15", BASEMODE_NAND),
77 BCM6362_PIN(16, "gpio16", BASEMODE_NAND),
78 BCM6362_PIN(17, "gpio17", BASEMODE_NAND),
79 BCM6362_PIN(18, "gpio18", BASEMODE_NAND),
80 BCM6362_PIN(19, "gpio19", BASEMODE_NAND),
81 BCM6362_PIN(20, "gpio20", BASEMODE_NAND),
82 BCM6362_PIN(21, "gpio21", BASEMODE_NAND),
83 BCM6362_PIN(22, "gpio22", BASEMODE_NAND),
84 BCM6362_PIN(23, "gpio23", BASEMODE_NAND),
85 PINCTRL_PIN(24, "gpio24"),
86 PINCTRL_PIN(25, "gpio25"),
87 PINCTRL_PIN(26, "gpio26"),
88 BCM6362_PIN(27, "gpio27", BASEMODE_NAND),
89 PINCTRL_PIN(28, "gpio28"),
90 PINCTRL_PIN(29, "gpio29"),
91 PINCTRL_PIN(30, "gpio30"),
92 PINCTRL_PIN(31, "gpio31"),
93 PINCTRL_PIN(32, "gpio32"),
94 PINCTRL_PIN(33, "gpio33"),
95 PINCTRL_PIN(34, "gpio34"),
96 PINCTRL_PIN(35, "gpio35"),
97 PINCTRL_PIN(36, "gpio36"),
98 PINCTRL_PIN(37, "gpio37"),
99 PINCTRL_PIN(38, "gpio38"),
100 PINCTRL_PIN(39, "gpio39"),
101 PINCTRL_PIN(40, "gpio40"),
102 PINCTRL_PIN(41, "gpio41"),
103 PINCTRL_PIN(42, "gpio42"),
104 PINCTRL_PIN(43, "gpio43"),
105 PINCTRL_PIN(44, "gpio44"),
106 PINCTRL_PIN(45, "gpio45"),
107 PINCTRL_PIN(46, "gpio46"),
108 PINCTRL_PIN(47, "gpio47"),
111 static unsigned gpio0_pins[] = { 0 };
112 static unsigned gpio1_pins[] = { 1 };
113 static unsigned gpio2_pins[] = { 2 };
114 static unsigned gpio3_pins[] = { 3 };
115 static unsigned gpio4_pins[] = { 4 };
116 static unsigned gpio5_pins[] = { 5 };
117 static unsigned gpio6_pins[] = { 6 };
118 static unsigned gpio7_pins[] = { 7 };
119 static unsigned gpio8_pins[] = { 8 };
120 static unsigned gpio9_pins[] = { 9 };
121 static unsigned gpio10_pins[] = { 10 };
122 static unsigned gpio11_pins[] = { 11 };
123 static unsigned gpio12_pins[] = { 12 };
124 static unsigned gpio13_pins[] = { 13 };
125 static unsigned gpio14_pins[] = { 14 };
126 static unsigned gpio15_pins[] = { 15 };
127 static unsigned gpio16_pins[] = { 16 };
128 static unsigned gpio17_pins[] = { 17 };
129 static unsigned gpio18_pins[] = { 18 };
130 static unsigned gpio19_pins[] = { 19 };
131 static unsigned gpio20_pins[] = { 20 };
132 static unsigned gpio21_pins[] = { 21 };
133 static unsigned gpio22_pins[] = { 22 };
134 static unsigned gpio23_pins[] = { 23 };
135 static unsigned gpio24_pins[] = { 24 };
136 static unsigned gpio25_pins[] = { 25 };
137 static unsigned gpio26_pins[] = { 26 };
138 static unsigned gpio27_pins[] = { 27 };
139 static unsigned gpio28_pins[] = { 28 };
140 static unsigned gpio29_pins[] = { 29 };
141 static unsigned gpio30_pins[] = { 30 };
142 static unsigned gpio31_pins[] = { 31 };
143 static unsigned gpio32_pins[] = { 32 };
144 static unsigned gpio33_pins[] = { 33 };
145 static unsigned gpio34_pins[] = { 34 };
146 static unsigned gpio35_pins[] = { 35 };
147 static unsigned gpio36_pins[] = { 36 };
148 static unsigned gpio37_pins[] = { 37 };
149 static unsigned gpio38_pins[] = { 38 };
150 static unsigned gpio39_pins[] = { 39 };
151 static unsigned gpio40_pins[] = { 40 };
152 static unsigned gpio41_pins[] = { 41 };
153 static unsigned gpio42_pins[] = { 42 };
154 static unsigned gpio43_pins[] = { 43 };
155 static unsigned gpio44_pins[] = { 44 };
156 static unsigned gpio45_pins[] = { 45 };
157 static unsigned gpio46_pins[] = { 46 };
158 static unsigned gpio47_pins[] = { 47 };
160 static unsigned nand_grp_pins[] = {
161 8, 12, 13, 14, 15, 16, 17,
162 18, 19, 20, 21, 22, 23, 27,
165 #define BCM6362_GROUP(n) \
169 .num_pins = ARRAY_SIZE(n##_pins), \
172 static struct bcm6362_pingroup bcm6362_groups[] = {
173 BCM6362_GROUP(gpio0),
174 BCM6362_GROUP(gpio1),
175 BCM6362_GROUP(gpio2),
176 BCM6362_GROUP(gpio3),
177 BCM6362_GROUP(gpio4),
178 BCM6362_GROUP(gpio5),
179 BCM6362_GROUP(gpio6),
180 BCM6362_GROUP(gpio7),
181 BCM6362_GROUP(gpio8),
182 BCM6362_GROUP(gpio9),
183 BCM6362_GROUP(gpio10),
184 BCM6362_GROUP(gpio11),
185 BCM6362_GROUP(gpio12),
186 BCM6362_GROUP(gpio13),
187 BCM6362_GROUP(gpio14),
188 BCM6362_GROUP(gpio15),
189 BCM6362_GROUP(gpio16),
190 BCM6362_GROUP(gpio17),
191 BCM6362_GROUP(gpio18),
192 BCM6362_GROUP(gpio19),
193 BCM6362_GROUP(gpio20),
194 BCM6362_GROUP(gpio21),
195 BCM6362_GROUP(gpio22),
196 BCM6362_GROUP(gpio23),
197 BCM6362_GROUP(gpio24),
198 BCM6362_GROUP(gpio25),
199 BCM6362_GROUP(gpio26),
200 BCM6362_GROUP(gpio27),
201 BCM6362_GROUP(gpio28),
202 BCM6362_GROUP(gpio29),
203 BCM6362_GROUP(gpio30),
204 BCM6362_GROUP(gpio31),
205 BCM6362_GROUP(gpio32),
206 BCM6362_GROUP(gpio33),
207 BCM6362_GROUP(gpio34),
208 BCM6362_GROUP(gpio35),
209 BCM6362_GROUP(gpio36),
210 BCM6362_GROUP(gpio37),
211 BCM6362_GROUP(gpio38),
212 BCM6362_GROUP(gpio39),
213 BCM6362_GROUP(gpio40),
214 BCM6362_GROUP(gpio41),
215 BCM6362_GROUP(gpio42),
216 BCM6362_GROUP(gpio43),
217 BCM6362_GROUP(gpio44),
218 BCM6362_GROUP(gpio45),
219 BCM6362_GROUP(gpio46),
220 BCM6362_GROUP(gpio47),
221 BCM6362_GROUP(nand_grp),
224 static const char * const led_groups[] = {
251 static const char * const usb_device_led_groups[] = {
255 static const char * const sys_irq_groups[] = {
259 static const char * const serial_led_clk_groups[] = {
263 static const char * const serial_led_data_groups[] = {
267 static const char * const robosw_led_data_groups[] = {
271 static const char * const robosw_led_clk_groups[] = {
275 static const char * const robosw_led0_groups[] = {
279 static const char * const robosw_led1_groups[] = {
283 static const char * const inet_led_groups[] = {
287 static const char * const spi_cs2_groups[] = {
291 static const char * const spi_cs3_groups[] = {
295 static const char * const ntr_pulse_groups[] = {
299 static const char * const uart1_scts_groups[] = {
303 static const char * const uart1_srts_groups[] = {
307 static const char * const uart1_sdin_groups[] = {
311 static const char * const uart1_sdout_groups[] = {
315 static const char * const adsl_spi_miso_groups[] = {
319 static const char * const adsl_spi_mosi_groups[] = {
323 static const char * const adsl_spi_clk_groups[] = {
327 static const char * const adsl_spi_cs_groups[] = {
331 static const char * const ephy0_led_groups[] = {
335 static const char * const ephy1_led_groups[] = {
339 static const char * const ephy2_led_groups[] = {
343 static const char * const ephy3_led_groups[] = {
347 static const char * const ext_irq0_groups[] = {
351 static const char * const ext_irq1_groups[] = {
355 static const char * const ext_irq2_groups[] = {
359 static const char * const ext_irq3_groups[] = {
363 static const char * const wifi_groups[] = {
382 static const char * const nand_groups[] = {
386 #define BCM6362_LED_FUN(n) \
389 .groups = n##_groups, \
390 .num_groups = ARRAY_SIZE(n##_groups), \
391 .reg = BCM6362_LEDCTRL, \
394 #define BCM6362_MODE_FUN(n) \
397 .groups = n##_groups, \
398 .num_groups = ARRAY_SIZE(n##_groups), \
399 .reg = BCM6362_MODE, \
402 #define BCM6362_CTRL_FUN(n) \
405 .groups = n##_groups, \
406 .num_groups = ARRAY_SIZE(n##_groups), \
407 .reg = BCM6362_CTRL, \
410 #define BCM6362_BASEMODE_FUN(n, mask) \
413 .groups = n##_groups, \
414 .num_groups = ARRAY_SIZE(n##_groups), \
415 .reg = BCM6362_BASEMODE, \
416 .basemode_mask = (mask), \
419 static const struct bcm6362_function bcm6362_funcs[] = {
420 BCM6362_LED_FUN(led),
421 BCM6362_MODE_FUN(usb_device_led),
422 BCM6362_MODE_FUN(sys_irq),
423 BCM6362_MODE_FUN(serial_led_clk),
424 BCM6362_MODE_FUN(serial_led_data),
425 BCM6362_MODE_FUN(robosw_led_data),
426 BCM6362_MODE_FUN(robosw_led_clk),
427 BCM6362_MODE_FUN(robosw_led0),
428 BCM6362_MODE_FUN(robosw_led1),
429 BCM6362_MODE_FUN(inet_led),
430 BCM6362_MODE_FUN(spi_cs2),
431 BCM6362_MODE_FUN(spi_cs3),
432 BCM6362_MODE_FUN(ntr_pulse),
433 BCM6362_MODE_FUN(uart1_scts),
434 BCM6362_MODE_FUN(uart1_srts),
435 BCM6362_MODE_FUN(uart1_sdin),
436 BCM6362_MODE_FUN(uart1_sdout),
437 BCM6362_MODE_FUN(adsl_spi_miso),
438 BCM6362_MODE_FUN(adsl_spi_mosi),
439 BCM6362_MODE_FUN(adsl_spi_clk),
440 BCM6362_MODE_FUN(adsl_spi_cs),
441 BCM6362_MODE_FUN(ephy0_led),
442 BCM6362_MODE_FUN(ephy1_led),
443 BCM6362_MODE_FUN(ephy2_led),
444 BCM6362_MODE_FUN(ephy3_led),
445 BCM6362_MODE_FUN(ext_irq0),
446 BCM6362_MODE_FUN(ext_irq1),
447 BCM6362_MODE_FUN(ext_irq2),
448 BCM6362_MODE_FUN(ext_irq3),
449 BCM6362_CTRL_FUN(wifi),
450 BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND),
453 static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
455 return ARRAY_SIZE(bcm6362_groups);
458 static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
461 return bcm6362_groups[group].name;
464 static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
465 unsigned group, const unsigned **pins,
468 *pins = bcm6362_groups[group].pins;
469 *num_pins = bcm6362_groups[group].num_pins;
474 static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
476 return ARRAY_SIZE(bcm6362_funcs);
479 static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
482 return bcm6362_funcs[selector].name;
485 static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev,
487 const char * const **groups,
488 unsigned * const num_groups)
490 *groups = bcm6362_funcs[selector].groups;
491 *num_groups = bcm6362_funcs[selector].num_groups;
496 static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
498 const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
499 unsigned int basemode = (uintptr_t)desc->drv_data;
500 unsigned int mask = bcm63xx_bank_pin(pin);
503 regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, basemode, 0);
505 if (pin < BCM63XX_BANK_GPIOS) {
506 /* base mode 0 => gpio 1 => mux function */
507 regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0);
509 /* pins 0-23 might be muxed to led */
510 if (pin < BCM6362_NUM_LEDS)
511 regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0);
513 /* ctrl reg 0 => wifi function 1 => gpio */
514 regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
518 static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
519 unsigned selector, unsigned group)
521 struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
522 const struct bcm6362_pingroup *pg = &bcm6362_groups[group];
523 const struct bcm6362_function *f = &bcm6362_funcs[selector];
526 unsigned int val, mask;
528 for (i = 0; i < pg->num_pins; i++)
529 bcm6362_set_gpio(pc, pg->pins[i]);
532 case BCM6362_LEDCTRL:
533 reg = BCM6362_LED_REG;
534 mask = BIT(pg->pins[0]);
535 val = BIT(pg->pins[0]);
538 reg = BCM6362_MODE_REG;
539 mask = BIT(pg->pins[0]);
540 val = BIT(pg->pins[0]);
543 reg = BCM6362_CTRL_REG;
544 mask = BIT(pg->pins[0]);
547 case BCM6362_BASEMODE:
548 reg = BCM6362_BASEMODE_REG;
549 mask = f->basemode_mask;
550 val = f->basemode_mask;
557 regmap_update_bits(pc->regs, reg, mask, val);
562 static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
563 struct pinctrl_gpio_range *range,
566 struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
568 /* disable all functions using this pin */
569 bcm6362_set_gpio(pc, offset);
574 static const struct pinctrl_ops bcm6362_pctl_ops = {
575 .dt_free_map = pinctrl_utils_free_map,
576 .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
577 .get_group_name = bcm6362_pinctrl_get_group_name,
578 .get_group_pins = bcm6362_pinctrl_get_group_pins,
579 .get_groups_count = bcm6362_pinctrl_get_group_count,
582 static const struct pinmux_ops bcm6362_pmx_ops = {
583 .get_function_groups = bcm6362_pinctrl_get_groups,
584 .get_function_name = bcm6362_pinctrl_get_func_name,
585 .get_functions_count = bcm6362_pinctrl_get_func_count,
586 .gpio_request_enable = bcm6362_gpio_request_enable,
587 .set_mux = bcm6362_pinctrl_set_mux,
591 static const struct bcm63xx_pinctrl_soc bcm6362_soc = {
592 .ngpios = BCM6362_NUM_GPIOS,
593 .npins = ARRAY_SIZE(bcm6362_pins),
594 .pctl_ops = &bcm6362_pctl_ops,
595 .pins = bcm6362_pins,
596 .pmx_ops = &bcm6362_pmx_ops,
599 static int bcm6362_pinctrl_probe(struct platform_device *pdev)
601 return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
604 static const struct of_device_id bcm6362_pinctrl_match[] = {
605 { .compatible = "brcm,bcm6362-pinctrl", },
609 static struct platform_driver bcm6362_pinctrl_driver = {
610 .probe = bcm6362_pinctrl_probe,
612 .name = "bcm6362-pinctrl",
613 .of_match_table = bcm6362_pinctrl_match,
617 builtin_platform_driver(bcm6362_pinctrl_driver);