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