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