xref: /linux/drivers/pinctrl/bcm/pinctrl-bcm6362.c (revision bdd1a21b52557ea8f61d0a5dc2f77151b576eb70)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for BCM6362 GPIO unit (pinctrl + GPIO)
4  *
5  * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
6  * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
7  */
8 
9 #include <linux/bits.h>
10 #include <linux/gpio/driver.h>
11 #include <linux/kernel.h>
12 #include <linux/of.h>
13 #include <linux/pinctrl/pinmux.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
16 
17 #include "../pinctrl-utils.h"
18 
19 #include "pinctrl-bcm63xx.h"
20 
21 #define BCM6362_BANK_GPIOS	32
22 #define BCM6362_NUM_GPIOS	48
23 #define BCM6362_NUM_LEDS	24
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)
30 
31 enum bcm6362_pinctrl_reg {
32 	BCM6362_LEDCTRL,
33 	BCM6362_MODE,
34 	BCM6362_CTRL,
35 	BCM6362_BASEMODE,
36 };
37 
38 struct bcm6362_pingroup {
39 	const char *name;
40 	const unsigned * const pins;
41 	const unsigned num_pins;
42 };
43 
44 struct bcm6362_function {
45 	const char *name;
46 	const char * const *groups;
47 	const unsigned num_groups;
48 
49 	enum bcm6362_pinctrl_reg reg;
50 	uint32_t basemode_mask;
51 };
52 
53 #define BCM6362_PIN(a, b, mask)			\
54 	{					\
55 		.number = a,			\
56 		.name = b,			\
57 		.drv_data = (void *)(mask),	\
58 	}
59 
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"),
109 };
110 
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 };
159 
160 static unsigned nand_grp_pins[] = {
161 	8, 12, 13, 14, 15, 16, 17,
162 	18, 19, 20, 21, 22, 23, 27,
163 };
164 
165 #define BCM6362_GROUP(n)				\
166 	{						\
167 		.name = #n,				\
168 		.pins = n##_pins,			\
169 		.num_pins = ARRAY_SIZE(n##_pins),	\
170 	}
171 
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),
222 };
223 
224 static const char * const led_groups[] = {
225 	"gpio0",
226 	"gpio1",
227 	"gpio2",
228 	"gpio3",
229 	"gpio4",
230 	"gpio5",
231 	"gpio6",
232 	"gpio7",
233 	"gpio8",
234 	"gpio9",
235 	"gpio10",
236 	"gpio11",
237 	"gpio12",
238 	"gpio13",
239 	"gpio14",
240 	"gpio15",
241 	"gpio16",
242 	"gpio17",
243 	"gpio18",
244 	"gpio19",
245 	"gpio20",
246 	"gpio21",
247 	"gpio22",
248 	"gpio23",
249 };
250 
251 static const char * const usb_device_led_groups[] = {
252 	"gpio0",
253 };
254 
255 static const char * const sys_irq_groups[] = {
256 	"gpio1",
257 };
258 
259 static const char * const serial_led_clk_groups[] = {
260 	"gpio2",
261 };
262 
263 static const char * const serial_led_data_groups[] = {
264 	"gpio3",
265 };
266 
267 static const char * const robosw_led_data_groups[] = {
268 	"gpio4",
269 };
270 
271 static const char * const robosw_led_clk_groups[] = {
272 	"gpio5",
273 };
274 
275 static const char * const robosw_led0_groups[] = {
276 	"gpio6",
277 };
278 
279 static const char * const robosw_led1_groups[] = {
280 	"gpio7",
281 };
282 
283 static const char * const inet_led_groups[] = {
284 	"gpio8",
285 };
286 
287 static const char * const spi_cs2_groups[] = {
288 	"gpio9",
289 };
290 
291 static const char * const spi_cs3_groups[] = {
292 	"gpio10",
293 };
294 
295 static const char * const ntr_pulse_groups[] = {
296 	"gpio11",
297 };
298 
299 static const char * const uart1_scts_groups[] = {
300 	"gpio12",
301 };
302 
303 static const char * const uart1_srts_groups[] = {
304 	"gpio13",
305 };
306 
307 static const char * const uart1_sdin_groups[] = {
308 	"gpio14",
309 };
310 
311 static const char * const uart1_sdout_groups[] = {
312 	"gpio15",
313 };
314 
315 static const char * const adsl_spi_miso_groups[] = {
316 	"gpio16",
317 };
318 
319 static const char * const adsl_spi_mosi_groups[] = {
320 	"gpio17",
321 };
322 
323 static const char * const adsl_spi_clk_groups[] = {
324 	"gpio18",
325 };
326 
327 static const char * const adsl_spi_cs_groups[] = {
328 	"gpio19",
329 };
330 
331 static const char * const ephy0_led_groups[] = {
332 	"gpio20",
333 };
334 
335 static const char * const ephy1_led_groups[] = {
336 	"gpio21",
337 };
338 
339 static const char * const ephy2_led_groups[] = {
340 	"gpio22",
341 };
342 
343 static const char * const ephy3_led_groups[] = {
344 	"gpio23",
345 };
346 
347 static const char * const ext_irq0_groups[] = {
348 	"gpio24",
349 };
350 
351 static const char * const ext_irq1_groups[] = {
352 	"gpio25",
353 };
354 
355 static const char * const ext_irq2_groups[] = {
356 	"gpio26",
357 };
358 
359 static const char * const ext_irq3_groups[] = {
360 	"gpio27",
361 };
362 
363 static const char * const wifi_groups[] = {
364 	"gpio32",
365 	"gpio33",
366 	"gpio34",
367 	"gpio35",
368 	"gpio36",
369 	"gpio37",
370 	"gpio38",
371 	"gpio39",
372 	"gpio40",
373 	"gpio41",
374 	"gpio42",
375 	"gpio43",
376 	"gpio44",
377 	"gpio45",
378 	"gpio46",
379 	"gpio47",
380 };
381 
382 static const char * const nand_groups[] = {
383 	"nand_grp",
384 };
385 
386 #define BCM6362_LED_FUN(n)				\
387 	{						\
388 		.name = #n,				\
389 		.groups = n##_groups,			\
390 		.num_groups = ARRAY_SIZE(n##_groups),	\
391 		.reg = BCM6362_LEDCTRL,			\
392 	}
393 
394 #define BCM6362_MODE_FUN(n)				\
395 	{						\
396 		.name = #n,				\
397 		.groups = n##_groups,			\
398 		.num_groups = ARRAY_SIZE(n##_groups),	\
399 		.reg = BCM6362_MODE,			\
400 	}
401 
402 #define BCM6362_CTRL_FUN(n)				\
403 	{						\
404 		.name = #n,				\
405 		.groups = n##_groups,			\
406 		.num_groups = ARRAY_SIZE(n##_groups),	\
407 		.reg = BCM6362_CTRL,			\
408 	}
409 
410 #define BCM6362_BASEMODE_FUN(n, mask)			\
411 	{						\
412 		.name = #n,				\
413 		.groups = n##_groups,			\
414 		.num_groups = ARRAY_SIZE(n##_groups),	\
415 		.reg = BCM6362_BASEMODE,		\
416 		.basemode_mask = (mask),		\
417 	}
418 
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),
451 };
452 
453 static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
454 {
455 	return ARRAY_SIZE(bcm6362_groups);
456 }
457 
458 static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
459 						  unsigned group)
460 {
461 	return bcm6362_groups[group].name;
462 }
463 
464 static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
465 					  unsigned group, const unsigned **pins,
466 					  unsigned *num_pins)
467 {
468 	*pins = bcm6362_groups[group].pins;
469 	*num_pins = bcm6362_groups[group].num_pins;
470 
471 	return 0;
472 }
473 
474 static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
475 {
476 	return ARRAY_SIZE(bcm6362_funcs);
477 }
478 
479 static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
480 						 unsigned selector)
481 {
482 	return bcm6362_funcs[selector].name;
483 }
484 
485 static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev,
486 				      unsigned selector,
487 				      const char * const **groups,
488 				      unsigned * const num_groups)
489 {
490 	*groups = bcm6362_funcs[selector].groups;
491 	*num_groups = bcm6362_funcs[selector].num_groups;
492 
493 	return 0;
494 }
495 
496 static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
497 {
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);
501 
502 	if (basemode)
503 		regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, basemode, 0);
504 
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);
508 
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);
512 	} else {
513 		/* ctrl reg 0 => wifi function 1 => gpio */
514 		regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
515 	}
516 }
517 
518 static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
519 				   unsigned selector, unsigned group)
520 {
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];
524 	unsigned i;
525 	unsigned int reg;
526 	unsigned int val, mask;
527 
528 	for (i = 0; i < pg->num_pins; i++)
529 		bcm6362_set_gpio(pc, pg->pins[i]);
530 
531 	switch (f->reg) {
532 	case BCM6362_LEDCTRL:
533 		reg = BCM6362_LED_REG;
534 		mask = BIT(pg->pins[0]);
535 		val = BIT(pg->pins[0]);
536 		break;
537 	case BCM6362_MODE:
538 		reg = BCM6362_MODE_REG;
539 		mask = BIT(pg->pins[0]);
540 		val = BIT(pg->pins[0]);
541 		break;
542 	case BCM6362_CTRL:
543 		reg = BCM6362_CTRL_REG;
544 		mask = BIT(pg->pins[0]);
545 		val = 0;
546 		break;
547 	case BCM6362_BASEMODE:
548 		reg = BCM6362_BASEMODE_REG;
549 		mask = f->basemode_mask;
550 		val = f->basemode_mask;
551 		break;
552 	default:
553 		WARN_ON(1);
554 		return -EINVAL;
555 	}
556 
557 	regmap_update_bits(pc->regs, reg, mask, val);
558 
559 	return 0;
560 }
561 
562 static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
563 				       struct pinctrl_gpio_range *range,
564 				       unsigned offset)
565 {
566 	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
567 
568 	/* disable all functions using this pin */
569 	bcm6362_set_gpio(pc, offset);
570 
571 	return 0;
572 }
573 
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,
580 };
581 
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,
588 	.strict = true,
589 };
590 
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,
597 };
598 
599 static int bcm6362_pinctrl_probe(struct platform_device *pdev)
600 {
601 	return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
602 }
603 
604 static const struct of_device_id bcm6362_pinctrl_match[] = {
605 	{ .compatible = "brcm,bcm6362-pinctrl", },
606 	{ /* sentinel */ }
607 };
608 
609 static struct platform_driver bcm6362_pinctrl_driver = {
610 	.probe = bcm6362_pinctrl_probe,
611 	.driver = {
612 		.name = "bcm6362-pinctrl",
613 		.of_match_table = bcm6362_pinctrl_match,
614 	},
615 };
616 
617 builtin_platform_driver(bcm6362_pinctrl_driver);
618