1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for BCM6368 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 BCM6368_NUM_GPIOS 38
23 #define BCM6368_MODE_REG 0x18
24 #define BCM6368_BASEMODE_REG 0x38
25 #define BCM6368_BASEMODE_MASK 0x7
26 #define BCM6368_BASEMODE_GPIO 0x0
27 #define BCM6368_BASEMODE_UART1 0x1
29 struct bcm6368_function
{
31 const char * const *groups
;
32 const unsigned num_groups
;
39 struct regmap_field
*overlays
;
42 #define BCM6368_BASEMODE_PIN(a, b) \
46 .drv_data = (void *)true \
49 static const struct pinctrl_pin_desc bcm6368_pins
[] = {
50 PINCTRL_PIN(0, "gpio0"),
51 PINCTRL_PIN(1, "gpio1"),
52 PINCTRL_PIN(2, "gpio2"),
53 PINCTRL_PIN(3, "gpio3"),
54 PINCTRL_PIN(4, "gpio4"),
55 PINCTRL_PIN(5, "gpio5"),
56 PINCTRL_PIN(6, "gpio6"),
57 PINCTRL_PIN(7, "gpio7"),
58 PINCTRL_PIN(8, "gpio8"),
59 PINCTRL_PIN(9, "gpio9"),
60 PINCTRL_PIN(10, "gpio10"),
61 PINCTRL_PIN(11, "gpio11"),
62 PINCTRL_PIN(12, "gpio12"),
63 PINCTRL_PIN(13, "gpio13"),
64 PINCTRL_PIN(14, "gpio14"),
65 PINCTRL_PIN(15, "gpio15"),
66 PINCTRL_PIN(16, "gpio16"),
67 PINCTRL_PIN(17, "gpio17"),
68 PINCTRL_PIN(18, "gpio18"),
69 PINCTRL_PIN(19, "gpio19"),
70 PINCTRL_PIN(20, "gpio20"),
71 PINCTRL_PIN(21, "gpio21"),
72 PINCTRL_PIN(22, "gpio22"),
73 PINCTRL_PIN(23, "gpio23"),
74 PINCTRL_PIN(24, "gpio24"),
75 PINCTRL_PIN(25, "gpio25"),
76 PINCTRL_PIN(26, "gpio26"),
77 PINCTRL_PIN(27, "gpio27"),
78 PINCTRL_PIN(28, "gpio28"),
79 PINCTRL_PIN(29, "gpio29"),
80 BCM6368_BASEMODE_PIN(30, "gpio30"),
81 BCM6368_BASEMODE_PIN(31, "gpio31"),
82 BCM6368_BASEMODE_PIN(32, "gpio32"),
83 BCM6368_BASEMODE_PIN(33, "gpio33"),
84 PINCTRL_PIN(34, "gpio34"),
85 PINCTRL_PIN(35, "gpio35"),
86 PINCTRL_PIN(36, "gpio36"),
87 PINCTRL_PIN(37, "gpio37"),
90 static unsigned gpio0_pins
[] = { 0 };
91 static unsigned gpio1_pins
[] = { 1 };
92 static unsigned gpio2_pins
[] = { 2 };
93 static unsigned gpio3_pins
[] = { 3 };
94 static unsigned gpio4_pins
[] = { 4 };
95 static unsigned gpio5_pins
[] = { 5 };
96 static unsigned gpio6_pins
[] = { 6 };
97 static unsigned gpio7_pins
[] = { 7 };
98 static unsigned gpio8_pins
[] = { 8 };
99 static unsigned gpio9_pins
[] = { 9 };
100 static unsigned gpio10_pins
[] = { 10 };
101 static unsigned gpio11_pins
[] = { 11 };
102 static unsigned gpio12_pins
[] = { 12 };
103 static unsigned gpio13_pins
[] = { 13 };
104 static unsigned gpio14_pins
[] = { 14 };
105 static unsigned gpio15_pins
[] = { 15 };
106 static unsigned gpio16_pins
[] = { 16 };
107 static unsigned gpio17_pins
[] = { 17 };
108 static unsigned gpio18_pins
[] = { 18 };
109 static unsigned gpio19_pins
[] = { 19 };
110 static unsigned gpio20_pins
[] = { 20 };
111 static unsigned gpio21_pins
[] = { 21 };
112 static unsigned gpio22_pins
[] = { 22 };
113 static unsigned gpio23_pins
[] = { 23 };
114 static unsigned gpio24_pins
[] = { 24 };
115 static unsigned gpio25_pins
[] = { 25 };
116 static unsigned gpio26_pins
[] = { 26 };
117 static unsigned gpio27_pins
[] = { 27 };
118 static unsigned gpio28_pins
[] = { 28 };
119 static unsigned gpio29_pins
[] = { 29 };
120 static unsigned gpio30_pins
[] = { 30 };
121 static unsigned gpio31_pins
[] = { 31 };
122 static unsigned uart1_grp_pins
[] = { 30, 31, 32, 33 };
124 static struct pingroup bcm6368_groups
[] = {
125 BCM_PIN_GROUP(gpio0
),
126 BCM_PIN_GROUP(gpio1
),
127 BCM_PIN_GROUP(gpio2
),
128 BCM_PIN_GROUP(gpio3
),
129 BCM_PIN_GROUP(gpio4
),
130 BCM_PIN_GROUP(gpio5
),
131 BCM_PIN_GROUP(gpio6
),
132 BCM_PIN_GROUP(gpio7
),
133 BCM_PIN_GROUP(gpio8
),
134 BCM_PIN_GROUP(gpio9
),
135 BCM_PIN_GROUP(gpio10
),
136 BCM_PIN_GROUP(gpio11
),
137 BCM_PIN_GROUP(gpio12
),
138 BCM_PIN_GROUP(gpio13
),
139 BCM_PIN_GROUP(gpio14
),
140 BCM_PIN_GROUP(gpio15
),
141 BCM_PIN_GROUP(gpio16
),
142 BCM_PIN_GROUP(gpio17
),
143 BCM_PIN_GROUP(gpio18
),
144 BCM_PIN_GROUP(gpio19
),
145 BCM_PIN_GROUP(gpio20
),
146 BCM_PIN_GROUP(gpio21
),
147 BCM_PIN_GROUP(gpio22
),
148 BCM_PIN_GROUP(gpio23
),
149 BCM_PIN_GROUP(gpio24
),
150 BCM_PIN_GROUP(gpio25
),
151 BCM_PIN_GROUP(gpio26
),
152 BCM_PIN_GROUP(gpio27
),
153 BCM_PIN_GROUP(gpio28
),
154 BCM_PIN_GROUP(gpio29
),
155 BCM_PIN_GROUP(gpio30
),
156 BCM_PIN_GROUP(gpio31
),
157 BCM_PIN_GROUP(uart1_grp
),
160 static const char * const analog_afe_0_groups
[] = {
164 static const char * const analog_afe_1_groups
[] = {
168 static const char * const sys_irq_groups
[] = {
172 static const char * const serial_led_data_groups
[] = {
176 static const char * const serial_led_clk_groups
[] = {
180 static const char * const inet_led_groups
[] = {
184 static const char * const ephy0_led_groups
[] = {
188 static const char * const ephy1_led_groups
[] = {
192 static const char * const ephy2_led_groups
[] = {
196 static const char * const ephy3_led_groups
[] = {
200 static const char * const robosw_led_data_groups
[] = {
204 static const char * const robosw_led_clk_groups
[] = {
208 static const char * const robosw_led0_groups
[] = {
212 static const char * const robosw_led1_groups
[] = {
216 static const char * const usb_device_led_groups
[] = {
220 static const char * const pci_req1_groups
[] = {
224 static const char * const pci_gnt1_groups
[] = {
228 static const char * const pci_intb_groups
[] = {
232 static const char * const pci_req0_groups
[] = {
236 static const char * const pci_gnt0_groups
[] = {
240 static const char * const pcmcia_cd1_groups
[] = {
244 static const char * const pcmcia_cd2_groups
[] = {
248 static const char * const pcmcia_vs1_groups
[] = {
252 static const char * const pcmcia_vs2_groups
[] = {
256 static const char * const ebi_cs2_groups
[] = {
260 static const char * const ebi_cs3_groups
[] = {
264 static const char * const spi_cs2_groups
[] = {
268 static const char * const spi_cs3_groups
[] = {
272 static const char * const spi_cs4_groups
[] = {
276 static const char * const spi_cs5_groups
[] = {
280 static const char * const uart1_groups
[] = {
284 #define BCM6368_FUN(n, out) \
287 .groups = n##_groups, \
288 .num_groups = ARRAY_SIZE(n##_groups), \
292 #define BCM6368_BASEMODE_FUN(n, val, out) \
295 .groups = n##_groups, \
296 .num_groups = ARRAY_SIZE(n##_groups), \
297 .basemode = BCM6368_BASEMODE_##val, \
301 static const struct bcm6368_function bcm6368_funcs
[] = {
302 BCM6368_FUN(analog_afe_0
, 1),
303 BCM6368_FUN(analog_afe_1
, 1),
304 BCM6368_FUN(sys_irq
, 1),
305 BCM6368_FUN(serial_led_data
, 1),
306 BCM6368_FUN(serial_led_clk
, 1),
307 BCM6368_FUN(inet_led
, 1),
308 BCM6368_FUN(ephy0_led
, 1),
309 BCM6368_FUN(ephy1_led
, 1),
310 BCM6368_FUN(ephy2_led
, 1),
311 BCM6368_FUN(ephy3_led
, 1),
312 BCM6368_FUN(robosw_led_data
, 1),
313 BCM6368_FUN(robosw_led_clk
, 1),
314 BCM6368_FUN(robosw_led0
, 1),
315 BCM6368_FUN(robosw_led1
, 1),
316 BCM6368_FUN(usb_device_led
, 1),
317 BCM6368_FUN(pci_req1
, 0),
318 BCM6368_FUN(pci_gnt1
, 0),
319 BCM6368_FUN(pci_intb
, 0),
320 BCM6368_FUN(pci_req0
, 0),
321 BCM6368_FUN(pci_gnt0
, 0),
322 BCM6368_FUN(pcmcia_cd1
, 0),
323 BCM6368_FUN(pcmcia_cd2
, 0),
324 BCM6368_FUN(pcmcia_vs1
, 0),
325 BCM6368_FUN(pcmcia_vs2
, 0),
326 BCM6368_FUN(ebi_cs2
, 1),
327 BCM6368_FUN(ebi_cs3
, 1),
328 BCM6368_FUN(spi_cs2
, 1),
329 BCM6368_FUN(spi_cs3
, 1),
330 BCM6368_FUN(spi_cs4
, 1),
331 BCM6368_FUN(spi_cs5
, 1),
332 BCM6368_BASEMODE_FUN(uart1
, UART1
, 0x6),
335 static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev
*pctldev
)
337 return ARRAY_SIZE(bcm6368_groups
);
340 static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev
*pctldev
,
343 return bcm6368_groups
[group
].name
;
346 static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev
*pctldev
,
347 unsigned group
, const unsigned **pins
,
350 *pins
= bcm6368_groups
[group
].pins
;
351 *npins
= bcm6368_groups
[group
].npins
;
356 static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev
*pctldev
)
358 return ARRAY_SIZE(bcm6368_funcs
);
361 static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev
*pctldev
,
364 return bcm6368_funcs
[selector
].name
;
367 static int bcm6368_pinctrl_get_groups(struct pinctrl_dev
*pctldev
,
369 const char * const **groups
,
370 unsigned * const num_groups
)
372 *groups
= bcm6368_funcs
[selector
].groups
;
373 *num_groups
= bcm6368_funcs
[selector
].num_groups
;
378 static int bcm6368_pinctrl_set_mux(struct pinctrl_dev
*pctldev
,
379 unsigned selector
, unsigned group
)
381 struct bcm63xx_pinctrl
*pc
= pinctrl_dev_get_drvdata(pctldev
);
382 struct bcm6368_priv
*priv
= pc
->driver_data
;
383 const struct pingroup
*pg
= &bcm6368_groups
[group
];
384 const struct bcm6368_function
*fun
= &bcm6368_funcs
[selector
];
388 unsigned int mask
= 0;
390 for (i
= 0; i
< pg
->npins
; i
++) {
392 if (pin
< BCM63XX_BANK_GPIOS
)
396 regmap_update_bits(pc
->regs
, BCM6368_MODE_REG
, mask
, 0);
397 regmap_field_write(priv
->overlays
, fun
->basemode
);
401 if (bcm6368_pins
[pin
].drv_data
)
402 regmap_field_write(priv
->overlays
,
403 BCM6368_BASEMODE_GPIO
);
405 regmap_update_bits(pc
->regs
, BCM6368_MODE_REG
, BIT(pin
),
409 for (pin
= 0; pin
< pg
->npins
; pin
++) {
410 struct pinctrl_gpio_range
*range
;
411 int hw_gpio
= bcm6368_pins
[pin
].number
;
413 range
= pinctrl_find_gpio_range_from_pin(pctldev
, hw_gpio
);
415 struct gpio_chip
*gc
= range
->gc
;
417 if (fun
->dir_out
& BIT(pin
))
418 gc
->direction_output(gc
, hw_gpio
, 0);
420 gc
->direction_input(gc
, hw_gpio
);
427 static int bcm6368_gpio_request_enable(struct pinctrl_dev
*pctldev
,
428 struct pinctrl_gpio_range
*range
,
431 struct bcm63xx_pinctrl
*pc
= pinctrl_dev_get_drvdata(pctldev
);
432 struct bcm6368_priv
*priv
= pc
->driver_data
;
434 if (offset
>= BCM63XX_BANK_GPIOS
&& !bcm6368_pins
[offset
].drv_data
)
437 /* disable all functions using this pin */
438 if (offset
< BCM63XX_BANK_GPIOS
)
439 regmap_update_bits(pc
->regs
, BCM6368_MODE_REG
, BIT(offset
), 0);
441 if (bcm6368_pins
[offset
].drv_data
)
442 regmap_field_write(priv
->overlays
, BCM6368_BASEMODE_GPIO
);
447 static const struct pinctrl_ops bcm6368_pctl_ops
= {
448 .dt_free_map
= pinctrl_utils_free_map
,
449 .dt_node_to_map
= pinconf_generic_dt_node_to_map_pin
,
450 .get_group_name
= bcm6368_pinctrl_get_group_name
,
451 .get_group_pins
= bcm6368_pinctrl_get_group_pins
,
452 .get_groups_count
= bcm6368_pinctrl_get_group_count
,
455 static const struct pinmux_ops bcm6368_pmx_ops
= {
456 .get_function_groups
= bcm6368_pinctrl_get_groups
,
457 .get_function_name
= bcm6368_pinctrl_get_func_name
,
458 .get_functions_count
= bcm6368_pinctrl_get_func_count
,
459 .gpio_request_enable
= bcm6368_gpio_request_enable
,
460 .set_mux
= bcm6368_pinctrl_set_mux
,
464 static const struct bcm63xx_pinctrl_soc bcm6368_soc
= {
465 .ngpios
= BCM6368_NUM_GPIOS
,
466 .npins
= ARRAY_SIZE(bcm6368_pins
),
467 .pctl_ops
= &bcm6368_pctl_ops
,
468 .pins
= bcm6368_pins
,
469 .pmx_ops
= &bcm6368_pmx_ops
,
472 static int bcm6368_pinctrl_probe(struct platform_device
*pdev
)
474 struct reg_field overlays
= REG_FIELD(BCM6368_BASEMODE_REG
, 0, 15);
475 struct device
*dev
= &pdev
->dev
;
476 struct bcm63xx_pinctrl
*pc
;
477 struct bcm6368_priv
*priv
;
480 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
484 err
= bcm63xx_pinctrl_probe(pdev
, &bcm6368_soc
, (void *) priv
);
488 pc
= platform_get_drvdata(pdev
);
490 priv
->overlays
= devm_regmap_field_alloc(dev
, pc
->regs
, overlays
);
491 if (IS_ERR(priv
->overlays
))
492 return PTR_ERR(priv
->overlays
);
497 static const struct of_device_id bcm6368_pinctrl_match
[] = {
498 { .compatible
= "brcm,bcm6368-pinctrl", },
502 static struct platform_driver bcm6368_pinctrl_driver
= {
503 .probe
= bcm6368_pinctrl_probe
,
505 .name
= "bcm6368-pinctrl",
506 .of_match_table
= bcm6368_pinctrl_match
,
510 builtin_platform_driver(bcm6368_pinctrl_driver
);