xref: /linux/drivers/pinctrl/bcm/pinctrl-bcm6318.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for BCM6318 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 BCM6318_NUM_GPIOS	50
22 #define BCM6318_NUM_MUX		48
23 
24 #define BCM6318_MODE_REG	0x18
25 #define BCM6318_MUX_REG		0x1c
26 #define  BCM6328_MUX_MASK	GENMASK(1, 0)
27 #define BCM6318_PAD_REG		0x54
28 #define  BCM6328_PAD_MASK	GENMASK(3, 0)
29 
30 struct bcm6318_pingroup {
31 	const char *name;
32 	const unsigned * const pins;
33 	const unsigned num_pins;
34 };
35 
36 struct bcm6318_function {
37 	const char *name;
38 	const char * const *groups;
39 	const unsigned num_groups;
40 
41 	unsigned mode_val:1;
42 	unsigned mux_val:2;
43 };
44 
45 static const struct pinctrl_pin_desc bcm6318_pins[] = {
46 	PINCTRL_PIN(0, "gpio0"),
47 	PINCTRL_PIN(1, "gpio1"),
48 	PINCTRL_PIN(2, "gpio2"),
49 	PINCTRL_PIN(3, "gpio3"),
50 	PINCTRL_PIN(4, "gpio4"),
51 	PINCTRL_PIN(5, "gpio5"),
52 	PINCTRL_PIN(6, "gpio6"),
53 	PINCTRL_PIN(7, "gpio7"),
54 	PINCTRL_PIN(8, "gpio8"),
55 	PINCTRL_PIN(9, "gpio9"),
56 	PINCTRL_PIN(10, "gpio10"),
57 	PINCTRL_PIN(11, "gpio11"),
58 	PINCTRL_PIN(12, "gpio12"),
59 	PINCTRL_PIN(13, "gpio13"),
60 	PINCTRL_PIN(14, "gpio14"),
61 	PINCTRL_PIN(15, "gpio15"),
62 	PINCTRL_PIN(16, "gpio16"),
63 	PINCTRL_PIN(17, "gpio17"),
64 	PINCTRL_PIN(18, "gpio18"),
65 	PINCTRL_PIN(19, "gpio19"),
66 	PINCTRL_PIN(20, "gpio20"),
67 	PINCTRL_PIN(21, "gpio21"),
68 	PINCTRL_PIN(22, "gpio22"),
69 	PINCTRL_PIN(23, "gpio23"),
70 	PINCTRL_PIN(24, "gpio24"),
71 	PINCTRL_PIN(25, "gpio25"),
72 	PINCTRL_PIN(26, "gpio26"),
73 	PINCTRL_PIN(27, "gpio27"),
74 	PINCTRL_PIN(28, "gpio28"),
75 	PINCTRL_PIN(29, "gpio29"),
76 	PINCTRL_PIN(30, "gpio30"),
77 	PINCTRL_PIN(31, "gpio31"),
78 	PINCTRL_PIN(32, "gpio32"),
79 	PINCTRL_PIN(33, "gpio33"),
80 	PINCTRL_PIN(34, "gpio34"),
81 	PINCTRL_PIN(35, "gpio35"),
82 	PINCTRL_PIN(36, "gpio36"),
83 	PINCTRL_PIN(37, "gpio37"),
84 	PINCTRL_PIN(38, "gpio38"),
85 	PINCTRL_PIN(39, "gpio39"),
86 	PINCTRL_PIN(40, "gpio40"),
87 	PINCTRL_PIN(41, "gpio41"),
88 	PINCTRL_PIN(42, "gpio42"),
89 	PINCTRL_PIN(43, "gpio43"),
90 	PINCTRL_PIN(44, "gpio44"),
91 	PINCTRL_PIN(45, "gpio45"),
92 	PINCTRL_PIN(46, "gpio46"),
93 	PINCTRL_PIN(47, "gpio47"),
94 	PINCTRL_PIN(48, "gpio48"),
95 	PINCTRL_PIN(49, "gpio49"),
96 };
97 
98 static unsigned gpio0_pins[] = { 0 };
99 static unsigned gpio1_pins[] = { 1 };
100 static unsigned gpio2_pins[] = { 2 };
101 static unsigned gpio3_pins[] = { 3 };
102 static unsigned gpio4_pins[] = { 4 };
103 static unsigned gpio5_pins[] = { 5 };
104 static unsigned gpio6_pins[] = { 6 };
105 static unsigned gpio7_pins[] = { 7 };
106 static unsigned gpio8_pins[] = { 8 };
107 static unsigned gpio9_pins[] = { 9 };
108 static unsigned gpio10_pins[] = { 10 };
109 static unsigned gpio11_pins[] = { 11 };
110 static unsigned gpio12_pins[] = { 12 };
111 static unsigned gpio13_pins[] = { 13 };
112 static unsigned gpio14_pins[] = { 14 };
113 static unsigned gpio15_pins[] = { 15 };
114 static unsigned gpio16_pins[] = { 16 };
115 static unsigned gpio17_pins[] = { 17 };
116 static unsigned gpio18_pins[] = { 18 };
117 static unsigned gpio19_pins[] = { 19 };
118 static unsigned gpio20_pins[] = { 20 };
119 static unsigned gpio21_pins[] = { 21 };
120 static unsigned gpio22_pins[] = { 22 };
121 static unsigned gpio23_pins[] = { 23 };
122 static unsigned gpio24_pins[] = { 24 };
123 static unsigned gpio25_pins[] = { 25 };
124 static unsigned gpio26_pins[] = { 26 };
125 static unsigned gpio27_pins[] = { 27 };
126 static unsigned gpio28_pins[] = { 28 };
127 static unsigned gpio29_pins[] = { 29 };
128 static unsigned gpio30_pins[] = { 30 };
129 static unsigned gpio31_pins[] = { 31 };
130 static unsigned gpio32_pins[] = { 32 };
131 static unsigned gpio33_pins[] = { 33 };
132 static unsigned gpio34_pins[] = { 34 };
133 static unsigned gpio35_pins[] = { 35 };
134 static unsigned gpio36_pins[] = { 36 };
135 static unsigned gpio37_pins[] = { 37 };
136 static unsigned gpio38_pins[] = { 38 };
137 static unsigned gpio39_pins[] = { 39 };
138 static unsigned gpio40_pins[] = { 40 };
139 static unsigned gpio41_pins[] = { 41 };
140 static unsigned gpio42_pins[] = { 42 };
141 static unsigned gpio43_pins[] = { 43 };
142 static unsigned gpio44_pins[] = { 44 };
143 static unsigned gpio45_pins[] = { 45 };
144 static unsigned gpio46_pins[] = { 46 };
145 static unsigned gpio47_pins[] = { 47 };
146 static unsigned gpio48_pins[] = { 48 };
147 static unsigned gpio49_pins[] = { 49 };
148 
149 #define BCM6318_GROUP(n)					\
150 	{							\
151 		.name = #n,					\
152 		.pins = n##_pins,				\
153 		.num_pins = ARRAY_SIZE(n##_pins),		\
154 	}
155 
156 static struct bcm6318_pingroup bcm6318_groups[] = {
157 	BCM6318_GROUP(gpio0),
158 	BCM6318_GROUP(gpio1),
159 	BCM6318_GROUP(gpio2),
160 	BCM6318_GROUP(gpio3),
161 	BCM6318_GROUP(gpio4),
162 	BCM6318_GROUP(gpio5),
163 	BCM6318_GROUP(gpio6),
164 	BCM6318_GROUP(gpio7),
165 	BCM6318_GROUP(gpio8),
166 	BCM6318_GROUP(gpio9),
167 	BCM6318_GROUP(gpio10),
168 	BCM6318_GROUP(gpio11),
169 	BCM6318_GROUP(gpio12),
170 	BCM6318_GROUP(gpio13),
171 	BCM6318_GROUP(gpio14),
172 	BCM6318_GROUP(gpio15),
173 	BCM6318_GROUP(gpio16),
174 	BCM6318_GROUP(gpio17),
175 	BCM6318_GROUP(gpio18),
176 	BCM6318_GROUP(gpio19),
177 	BCM6318_GROUP(gpio20),
178 	BCM6318_GROUP(gpio21),
179 	BCM6318_GROUP(gpio22),
180 	BCM6318_GROUP(gpio23),
181 	BCM6318_GROUP(gpio24),
182 	BCM6318_GROUP(gpio25),
183 	BCM6318_GROUP(gpio26),
184 	BCM6318_GROUP(gpio27),
185 	BCM6318_GROUP(gpio28),
186 	BCM6318_GROUP(gpio29),
187 	BCM6318_GROUP(gpio30),
188 	BCM6318_GROUP(gpio31),
189 	BCM6318_GROUP(gpio32),
190 	BCM6318_GROUP(gpio33),
191 	BCM6318_GROUP(gpio34),
192 	BCM6318_GROUP(gpio35),
193 	BCM6318_GROUP(gpio36),
194 	BCM6318_GROUP(gpio37),
195 	BCM6318_GROUP(gpio38),
196 	BCM6318_GROUP(gpio39),
197 	BCM6318_GROUP(gpio40),
198 	BCM6318_GROUP(gpio41),
199 	BCM6318_GROUP(gpio42),
200 	BCM6318_GROUP(gpio43),
201 	BCM6318_GROUP(gpio44),
202 	BCM6318_GROUP(gpio45),
203 	BCM6318_GROUP(gpio46),
204 	BCM6318_GROUP(gpio47),
205 	BCM6318_GROUP(gpio48),
206 	BCM6318_GROUP(gpio49),
207 };
208 
209 /* GPIO_MODE */
210 static const char * const led_groups[] = {
211 	"gpio0",
212 	"gpio1",
213 	"gpio2",
214 	"gpio3",
215 	"gpio4",
216 	"gpio5",
217 	"gpio6",
218 	"gpio7",
219 	"gpio8",
220 	"gpio9",
221 	"gpio10",
222 	"gpio11",
223 	"gpio12",
224 	"gpio13",
225 	"gpio14",
226 	"gpio15",
227 	"gpio16",
228 	"gpio17",
229 	"gpio18",
230 	"gpio19",
231 	"gpio20",
232 	"gpio21",
233 	"gpio22",
234 	"gpio23",
235 };
236 
237 /* PINMUX_SEL */
238 static const char * const ephy0_spd_led_groups[] = {
239 	"gpio0",
240 };
241 
242 static const char * const ephy1_spd_led_groups[] = {
243 	"gpio1",
244 };
245 
246 static const char * const ephy2_spd_led_groups[] = {
247 	"gpio2",
248 };
249 
250 static const char * const ephy3_spd_led_groups[] = {
251 	"gpio3",
252 };
253 
254 static const char * const ephy0_act_led_groups[] = {
255 	"gpio4",
256 };
257 
258 static const char * const ephy1_act_led_groups[] = {
259 	"gpio5",
260 };
261 
262 static const char * const ephy2_act_led_groups[] = {
263 	"gpio6",
264 };
265 
266 static const char * const ephy3_act_led_groups[] = {
267 	"gpio7",
268 };
269 
270 static const char * const serial_led_data_groups[] = {
271 	"gpio6",
272 };
273 
274 static const char * const serial_led_clk_groups[] = {
275 	"gpio7",
276 };
277 
278 static const char * const inet_act_led_groups[] = {
279 	"gpio8",
280 };
281 
282 static const char * const inet_fail_led_groups[] = {
283 	"gpio9",
284 };
285 
286 static const char * const dsl_led_groups[] = {
287 	"gpio10",
288 };
289 
290 static const char * const post_fail_led_groups[] = {
291 	"gpio11",
292 };
293 
294 static const char * const wlan_wps_led_groups[] = {
295 	"gpio12",
296 };
297 
298 static const char * const usb_pwron_groups[] = {
299 	"gpio13",
300 };
301 
302 static const char * const usb_device_led_groups[] = {
303 	"gpio13",
304 };
305 
306 static const char * const usb_active_groups[] = {
307 	"gpio40",
308 };
309 
310 #define BCM6318_MODE_FUN(n)				\
311 	{						\
312 		.name = #n,				\
313 		.groups = n##_groups,			\
314 		.num_groups = ARRAY_SIZE(n##_groups),	\
315 		.mode_val = 1,				\
316 	}
317 
318 #define BCM6318_MUX_FUN(n, mux)				\
319 	{						\
320 		.name = #n,				\
321 		.groups = n##_groups,			\
322 		.num_groups = ARRAY_SIZE(n##_groups),	\
323 		.mux_val = mux,				\
324 	}
325 
326 static const struct bcm6318_function bcm6318_funcs[] = {
327 	BCM6318_MODE_FUN(led),
328 	BCM6318_MUX_FUN(ephy0_spd_led, 1),
329 	BCM6318_MUX_FUN(ephy1_spd_led, 1),
330 	BCM6318_MUX_FUN(ephy2_spd_led, 1),
331 	BCM6318_MUX_FUN(ephy3_spd_led, 1),
332 	BCM6318_MUX_FUN(ephy0_act_led, 1),
333 	BCM6318_MUX_FUN(ephy1_act_led, 1),
334 	BCM6318_MUX_FUN(ephy2_act_led, 1),
335 	BCM6318_MUX_FUN(ephy3_act_led, 1),
336 	BCM6318_MUX_FUN(serial_led_data, 3),
337 	BCM6318_MUX_FUN(serial_led_clk, 3),
338 	BCM6318_MUX_FUN(inet_act_led, 1),
339 	BCM6318_MUX_FUN(inet_fail_led, 1),
340 	BCM6318_MUX_FUN(dsl_led, 1),
341 	BCM6318_MUX_FUN(post_fail_led, 1),
342 	BCM6318_MUX_FUN(wlan_wps_led, 1),
343 	BCM6318_MUX_FUN(usb_pwron, 1),
344 	BCM6318_MUX_FUN(usb_device_led, 2),
345 	BCM6318_MUX_FUN(usb_active, 2),
346 };
347 
348 static inline unsigned int bcm6318_mux_off(unsigned int pin)
349 {
350 	return BCM6318_MUX_REG + (pin / 16) * 4;
351 }
352 
353 static inline unsigned int bcm6318_pad_off(unsigned int pin)
354 {
355 	return BCM6318_PAD_REG + (pin / 8) * 4;
356 }
357 
358 static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
359 {
360 	return ARRAY_SIZE(bcm6318_groups);
361 }
362 
363 static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
364 						  unsigned group)
365 {
366 	return bcm6318_groups[group].name;
367 }
368 
369 static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
370 					  unsigned group, const unsigned **pins,
371 					  unsigned *num_pins)
372 {
373 	*pins = bcm6318_groups[group].pins;
374 	*num_pins = bcm6318_groups[group].num_pins;
375 
376 	return 0;
377 }
378 
379 static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
380 {
381 	return ARRAY_SIZE(bcm6318_funcs);
382 }
383 
384 static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
385 						 unsigned selector)
386 {
387 	return bcm6318_funcs[selector].name;
388 }
389 
390 static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
391 				      unsigned selector,
392 				      const char * const **groups,
393 				      unsigned * const num_groups)
394 {
395 	*groups = bcm6318_funcs[selector].groups;
396 	*num_groups = bcm6318_funcs[selector].num_groups;
397 
398 	return 0;
399 }
400 
401 static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
402 				   unsigned int mode, unsigned int mux)
403 {
404 	if (pin < BCM63XX_BANK_GPIOS)
405 		regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin),
406 				   mode ? BIT(pin) : 0);
407 
408 	if (pin < BCM6318_NUM_MUX)
409 		regmap_update_bits(pc->regs,
410 				   bcm6318_mux_off(pin),
411 				   BCM6328_MUX_MASK << ((pin % 16) * 2),
412 				   mux << ((pin % 16) * 2));
413 }
414 
415 static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin,
416 				   uint8_t val)
417 {
418 	regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
419 			   BCM6328_PAD_MASK << ((pin % 8) * 4),
420 			   val << ((pin % 8) * 4));
421 }
422 
423 static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
424 				   unsigned selector, unsigned group)
425 {
426 	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
427 	const struct bcm6318_pingroup *pg = &bcm6318_groups[group];
428 	const struct bcm6318_function *f = &bcm6318_funcs[selector];
429 
430 	bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
431 
432 	return 0;
433 }
434 
435 static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
436 				       struct pinctrl_gpio_range *range,
437 				       unsigned offset)
438 {
439 	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
440 
441 	/* disable all functions using this pin */
442 	if (offset < 13) {
443 		/* GPIOs 0-12 use mux 0 as GPIO function */
444 		bcm6318_rmw_mux(pc, offset, 0, 0);
445 	} else if (offset < 42) {
446 		/* GPIOs 13-41 use mux 3 as GPIO function */
447 		bcm6318_rmw_mux(pc, offset, 0, 3);
448 
449 		bcm6318_set_pad(pc, offset, 0);
450 	}
451 
452 	return 0;
453 }
454 
455 static const struct pinctrl_ops bcm6318_pctl_ops = {
456 	.dt_free_map = pinctrl_utils_free_map,
457 	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
458 	.get_group_name = bcm6318_pinctrl_get_group_name,
459 	.get_group_pins = bcm6318_pinctrl_get_group_pins,
460 	.get_groups_count = bcm6318_pinctrl_get_group_count,
461 };
462 
463 static const struct pinmux_ops bcm6318_pmx_ops = {
464 	.get_function_groups = bcm6318_pinctrl_get_groups,
465 	.get_function_name = bcm6318_pinctrl_get_func_name,
466 	.get_functions_count = bcm6318_pinctrl_get_func_count,
467 	.gpio_request_enable = bcm6318_gpio_request_enable,
468 	.set_mux = bcm6318_pinctrl_set_mux,
469 	.strict = true,
470 };
471 
472 static const struct bcm63xx_pinctrl_soc bcm6318_soc = {
473 	.ngpios = BCM6318_NUM_GPIOS,
474 	.npins = ARRAY_SIZE(bcm6318_pins),
475 	.pctl_ops = &bcm6318_pctl_ops,
476 	.pins = bcm6318_pins,
477 	.pmx_ops = &bcm6318_pmx_ops,
478 };
479 
480 static int bcm6318_pinctrl_probe(struct platform_device *pdev)
481 {
482 	return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL);
483 }
484 
485 static const struct of_device_id bcm6318_pinctrl_match[] = {
486 	{ .compatible = "brcm,bcm6318-pinctrl", },
487 	{ /* sentinel */ }
488 };
489 
490 static struct platform_driver bcm6318_pinctrl_driver = {
491 	.probe = bcm6318_pinctrl_probe,
492 	.driver = {
493 		.name = "bcm6318-pinctrl",
494 		.of_match_table = bcm6318_pinctrl_match,
495 	},
496 };
497 
498 builtin_platform_driver(bcm6318_pinctrl_driver);
499