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