bmips: vr-3032u: fix gpio keys
[openwrt/staging/chunkeey.git] / target / linux / bmips / patches-5.10 / 409-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
1 From 8ec959299a6e4bbdc65d62180aa952ae04cdcf07 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
3 Date: Fri, 24 Jun 2016 22:19:12 +0200
4 Subject: [PATCH 10/12] pinctrl: add a pincontrol driver for BCM63268
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Add a pincontrol driver for BCM63268. BCM63268 allows muxing GPIOs
10 to different functions. Depending on the mux, these are either single
11 pin configurations or whole pin groups.
12
13 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
14 Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
15 ---
16 drivers/pinctrl/bcm/Kconfig | 11 +
17 drivers/pinctrl/bcm/Makefile | 1 +
18 drivers/pinctrl/bcm/pinctrl-bcm63268.c | 821 +++++++++++++++++++++++++
19 3 files changed, 833 insertions(+)
20 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c
21
22 --- a/drivers/pinctrl/bcm/Kconfig
23 +++ b/drivers/pinctrl/bcm/Kconfig
24 @@ -73,6 +73,17 @@ config PINCTRL_BCM6368
25 help
26 Say Y here to enable the Broadcom BCM6368 GPIO driver.
27
28 +config PINCTRL_BCM63268
29 + bool "Broadcom BCM63268 GPIO driver"
30 + depends on OF_GPIO && (BMIPS_GENERIC || COMPILE_TEST)
31 + select PINMUX
32 + select PINCONF
33 + select GENERIC_PINCONF
34 + select MFD_SYSCON
35 + default BMIPS_GENERIC
36 + help
37 + Say Y here to enable the Broadcom BCM63268 GPIO driver.
38 +
39 config PINCTRL_IPROC_GPIO
40 bool "Broadcom iProc GPIO (with PINCONF) driver"
41 depends on OF_GPIO && (ARCH_BCM_IPROC || COMPILE_TEST)
42 --- a/drivers/pinctrl/bcm/Makefile
43 +++ b/drivers/pinctrl/bcm/Makefile
44 @@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_BCM6328) += pinctr
45 obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o
46 obj-$(CONFIG_PINCTRL_BCM6362) += pinctrl-bcm6362.o
47 obj-$(CONFIG_PINCTRL_BCM6368) += pinctrl-bcm6368.o
48 +obj-$(CONFIG_PINCTRL_BCM63268) += pinctrl-bcm63268.o
49 obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o
50 obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o
51 obj-$(CONFIG_PINCTRL_NS) += pinctrl-ns.o
52 --- /dev/null
53 +++ b/drivers/pinctrl/bcm/pinctrl-bcm63268.c
54 @@ -0,0 +1,821 @@
55 +// SPDX-License-Identifier: GPL-2.0+
56 +/*
57 + * Driver for BCM63268 GPIO unit (pinctrl + GPIO)
58 + *
59 + * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
60 + * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
61 + */
62 +
63 +#include <linux/bitops.h>
64 +#include <linux/gpio.h>
65 +#include <linux/kernel.h>
66 +#include <linux/mfd/syscon.h>
67 +#include <linux/of.h>
68 +#include <linux/of_gpio.h>
69 +#include <linux/of_irq.h>
70 +#include <linux/platform_device.h>
71 +#include <linux/regmap.h>
72 +
73 +#include <linux/pinctrl/machine.h>
74 +#include <linux/pinctrl/pinconf.h>
75 +#include <linux/pinctrl/pinconf-generic.h>
76 +#include <linux/pinctrl/pinmux.h>
77 +
78 +#include "../core.h"
79 +#include "../pinctrl-utils.h"
80 +
81 +#define MODULE_NAME "bcm63268-pinctrl"
82 +#define BCM63268_NUM_GPIOS 52
83 +#define BCM63268_NUM_LEDS 24
84 +
85 +#define BANK_SIZE sizeof(uint32_t)
86 +#define PINS_PER_BANK (BANK_SIZE * BITS_PER_BYTE)
87 +
88 +#define BCM63268_DIROUT_REG 0x04
89 +#define BCM63268_DATA_REG 0x0c
90 +#define BCM63268_LED_REG 0x10
91 +#define BCM63268_MODE_REG 0x18
92 +#define BCM63268_CTRL_REG 0x1c
93 +#define BCM63268_BASEMODE_REG 0x38
94 +#define BCM63268_BASEMODE_NAND BIT(2) /* GPIOs 2-7, 24-31 */
95 +#define BCM63268_BASEMODE_GPIO35 BIT(4) /* GPIO 35 */
96 +#define BCM63268_BASEMODE_DECTPD BIT(5) /* GPIOs 8/9 */
97 +#define BCM63268_BASEMODE_VDSL_PHY_0 BIT(6) /* GPIOs 10/11 */
98 +#define BCM63268_BASEMODE_VDSL_PHY_1 BIT(7) /* GPIOs 12/13 */
99 +#define BCM63268_BASEMODE_VDSL_PHY_2 BIT(8) /* GPIOs 24/25 */
100 +#define BCM63268_BASEMODE_VDSL_PHY_3 BIT(9) /* GPIOs 26/27 */
101 +
102 +enum bcm63268_pinctrl_reg {
103 + BCM63268_LEDCTRL,
104 + BCM63268_MODE,
105 + BCM63268_CTRL,
106 + BCM63268_BASEMODE,
107 +};
108 +
109 +struct bcm63268_pingroup {
110 + const char *name;
111 + const unsigned * const pins;
112 + const unsigned num_pins;
113 +};
114 +
115 +struct bcm63268_function {
116 + const char *name;
117 + const char * const *groups;
118 + const unsigned num_groups;
119 +
120 + enum bcm63268_pinctrl_reg reg;
121 + uint32_t mask;
122 +};
123 +
124 +struct bcm63268_pinctrl {
125 + struct device *dev;
126 + struct regmap *regs;
127 +
128 + struct pinctrl_dev *pctl_dev;
129 + struct gpio_chip gpio_chip;
130 + struct pinctrl_desc pctl_desc;
131 + struct pinctrl_gpio_range gpio_range;
132 +};
133 +
134 +#define BCM63268_PIN(a, b, basemode) \
135 + { \
136 + .number = a, \
137 + .name = b, \
138 + .drv_data = (void *)(basemode) \
139 + }
140 +
141 +static const struct pinctrl_pin_desc bcm63268_pins[] = {
142 + PINCTRL_PIN(0, "gpio0"),
143 + PINCTRL_PIN(1, "gpio1"),
144 + BCM63268_PIN(2, "gpio2", BCM63268_BASEMODE_NAND),
145 + BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND),
146 + BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND),
147 + BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND),
148 + BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND),
149 + BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND),
150 + BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD),
151 + BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD),
152 + BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0),
153 + BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0),
154 + BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1),
155 + BCM63268_PIN(13, "gpio13", BCM63268_BASEMODE_VDSL_PHY_1),
156 + PINCTRL_PIN(14, "gpio14"),
157 + PINCTRL_PIN(15, "gpio15"),
158 + PINCTRL_PIN(16, "gpio16"),
159 + PINCTRL_PIN(17, "gpio17"),
160 + PINCTRL_PIN(18, "gpio18"),
161 + PINCTRL_PIN(19, "gpio19"),
162 + PINCTRL_PIN(20, "gpio20"),
163 + PINCTRL_PIN(21, "gpio21"),
164 + PINCTRL_PIN(22, "gpio22"),
165 + PINCTRL_PIN(23, "gpio23"),
166 + BCM63268_PIN(24, "gpio24",
167 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
168 + BCM63268_PIN(25, "gpio25",
169 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
170 + BCM63268_PIN(26, "gpio26",
171 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
172 + BCM63268_PIN(27, "gpio27",
173 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
174 + BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND),
175 + BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND),
176 + BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND),
177 + BCM63268_PIN(31, "gpio31", BCM63268_BASEMODE_NAND),
178 + PINCTRL_PIN(32, "gpio32"),
179 + PINCTRL_PIN(33, "gpio33"),
180 + PINCTRL_PIN(34, "gpio34"),
181 + PINCTRL_PIN(35, "gpio35"),
182 + PINCTRL_PIN(36, "gpio36"),
183 + PINCTRL_PIN(37, "gpio37"),
184 + PINCTRL_PIN(38, "gpio38"),
185 + PINCTRL_PIN(39, "gpio39"),
186 + PINCTRL_PIN(40, "gpio40"),
187 + PINCTRL_PIN(41, "gpio41"),
188 + PINCTRL_PIN(42, "gpio42"),
189 + PINCTRL_PIN(43, "gpio43"),
190 + PINCTRL_PIN(44, "gpio44"),
191 + PINCTRL_PIN(45, "gpio45"),
192 + PINCTRL_PIN(46, "gpio46"),
193 + PINCTRL_PIN(47, "gpio47"),
194 + PINCTRL_PIN(48, "gpio48"),
195 + PINCTRL_PIN(49, "gpio49"),
196 + PINCTRL_PIN(50, "gpio50"),
197 + PINCTRL_PIN(51, "gpio51"),
198 +};
199 +
200 +static unsigned gpio0_pins[] = { 0 };
201 +static unsigned gpio1_pins[] = { 1 };
202 +static unsigned gpio2_pins[] = { 2 };
203 +static unsigned gpio3_pins[] = { 3 };
204 +static unsigned gpio4_pins[] = { 4 };
205 +static unsigned gpio5_pins[] = { 5 };
206 +static unsigned gpio6_pins[] = { 6 };
207 +static unsigned gpio7_pins[] = { 7 };
208 +static unsigned gpio8_pins[] = { 8 };
209 +static unsigned gpio9_pins[] = { 9 };
210 +static unsigned gpio10_pins[] = { 10 };
211 +static unsigned gpio11_pins[] = { 11 };
212 +static unsigned gpio12_pins[] = { 12 };
213 +static unsigned gpio13_pins[] = { 13 };
214 +static unsigned gpio14_pins[] = { 14 };
215 +static unsigned gpio15_pins[] = { 15 };
216 +static unsigned gpio16_pins[] = { 16 };
217 +static unsigned gpio17_pins[] = { 17 };
218 +static unsigned gpio18_pins[] = { 18 };
219 +static unsigned gpio19_pins[] = { 19 };
220 +static unsigned gpio20_pins[] = { 20 };
221 +static unsigned gpio21_pins[] = { 21 };
222 +static unsigned gpio22_pins[] = { 22 };
223 +static unsigned gpio23_pins[] = { 23 };
224 +static unsigned gpio24_pins[] = { 24 };
225 +static unsigned gpio25_pins[] = { 25 };
226 +static unsigned gpio26_pins[] = { 26 };
227 +static unsigned gpio27_pins[] = { 27 };
228 +static unsigned gpio28_pins[] = { 28 };
229 +static unsigned gpio29_pins[] = { 29 };
230 +static unsigned gpio30_pins[] = { 30 };
231 +static unsigned gpio31_pins[] = { 31 };
232 +static unsigned gpio32_pins[] = { 32 };
233 +static unsigned gpio33_pins[] = { 33 };
234 +static unsigned gpio34_pins[] = { 34 };
235 +static unsigned gpio35_pins[] = { 35 };
236 +static unsigned gpio36_pins[] = { 36 };
237 +static unsigned gpio37_pins[] = { 37 };
238 +static unsigned gpio38_pins[] = { 38 };
239 +static unsigned gpio39_pins[] = { 39 };
240 +static unsigned gpio40_pins[] = { 40 };
241 +static unsigned gpio41_pins[] = { 41 };
242 +static unsigned gpio42_pins[] = { 42 };
243 +static unsigned gpio43_pins[] = { 43 };
244 +static unsigned gpio44_pins[] = { 44 };
245 +static unsigned gpio45_pins[] = { 45 };
246 +static unsigned gpio46_pins[] = { 46 };
247 +static unsigned gpio47_pins[] = { 47 };
248 +static unsigned gpio48_pins[] = { 48 };
249 +static unsigned gpio49_pins[] = { 49 };
250 +static unsigned gpio50_pins[] = { 50 };
251 +static unsigned gpio51_pins[] = { 51 };
252 +
253 +static unsigned nand_grp_pins[] = {
254 + 2, 3, 4, 5, 6, 7, 24,
255 + 25, 26, 27, 28, 29, 30, 31,
256 +};
257 +
258 +static unsigned dectpd_grp_pins[] = { 8, 9 };
259 +static unsigned vdsl_phy0_grp_pins[] = { 10, 11 };
260 +static unsigned vdsl_phy1_grp_pins[] = { 12, 13 };
261 +static unsigned vdsl_phy2_grp_pins[] = { 24, 25 };
262 +static unsigned vdsl_phy3_grp_pins[] = { 26, 27 };
263 +
264 +#define BCM63268_GROUP(n) \
265 + { \
266 + .name = #n, \
267 + .pins = n##_pins, \
268 + .num_pins = ARRAY_SIZE(n##_pins), \
269 + }
270 +
271 +static struct bcm63268_pingroup bcm63268_groups[] = {
272 + BCM63268_GROUP(gpio0),
273 + BCM63268_GROUP(gpio1),
274 + BCM63268_GROUP(gpio2),
275 + BCM63268_GROUP(gpio3),
276 + BCM63268_GROUP(gpio4),
277 + BCM63268_GROUP(gpio5),
278 + BCM63268_GROUP(gpio6),
279 + BCM63268_GROUP(gpio7),
280 + BCM63268_GROUP(gpio8),
281 + BCM63268_GROUP(gpio9),
282 + BCM63268_GROUP(gpio10),
283 + BCM63268_GROUP(gpio11),
284 + BCM63268_GROUP(gpio12),
285 + BCM63268_GROUP(gpio13),
286 + BCM63268_GROUP(gpio14),
287 + BCM63268_GROUP(gpio15),
288 + BCM63268_GROUP(gpio16),
289 + BCM63268_GROUP(gpio17),
290 + BCM63268_GROUP(gpio18),
291 + BCM63268_GROUP(gpio19),
292 + BCM63268_GROUP(gpio20),
293 + BCM63268_GROUP(gpio21),
294 + BCM63268_GROUP(gpio22),
295 + BCM63268_GROUP(gpio23),
296 + BCM63268_GROUP(gpio24),
297 + BCM63268_GROUP(gpio25),
298 + BCM63268_GROUP(gpio26),
299 + BCM63268_GROUP(gpio27),
300 + BCM63268_GROUP(gpio28),
301 + BCM63268_GROUP(gpio29),
302 + BCM63268_GROUP(gpio30),
303 + BCM63268_GROUP(gpio31),
304 + BCM63268_GROUP(gpio32),
305 + BCM63268_GROUP(gpio33),
306 + BCM63268_GROUP(gpio34),
307 + BCM63268_GROUP(gpio35),
308 + BCM63268_GROUP(gpio36),
309 + BCM63268_GROUP(gpio37),
310 + BCM63268_GROUP(gpio38),
311 + BCM63268_GROUP(gpio39),
312 + BCM63268_GROUP(gpio40),
313 + BCM63268_GROUP(gpio41),
314 + BCM63268_GROUP(gpio42),
315 + BCM63268_GROUP(gpio43),
316 + BCM63268_GROUP(gpio44),
317 + BCM63268_GROUP(gpio45),
318 + BCM63268_GROUP(gpio46),
319 + BCM63268_GROUP(gpio47),
320 + BCM63268_GROUP(gpio48),
321 + BCM63268_GROUP(gpio49),
322 + BCM63268_GROUP(gpio50),
323 + BCM63268_GROUP(gpio51),
324 +
325 + /* multi pin groups */
326 + BCM63268_GROUP(nand_grp),
327 + BCM63268_GROUP(dectpd_grp),
328 + BCM63268_GROUP(vdsl_phy0_grp),
329 + BCM63268_GROUP(vdsl_phy1_grp),
330 + BCM63268_GROUP(vdsl_phy2_grp),
331 + BCM63268_GROUP(vdsl_phy3_grp),
332 +};
333 +
334 +static const char * const led_groups[] = {
335 + "gpio0",
336 + "gpio1",
337 + "gpio2",
338 + "gpio3",
339 + "gpio4",
340 + "gpio5",
341 + "gpio6",
342 + "gpio7",
343 + "gpio8",
344 + "gpio9",
345 + "gpio10",
346 + "gpio11",
347 + "gpio12",
348 + "gpio13",
349 + "gpio14",
350 + "gpio15",
351 + "gpio16",
352 + "gpio17",
353 + "gpio18",
354 + "gpio19",
355 + "gpio20",
356 + "gpio21",
357 + "gpio22",
358 + "gpio23",
359 +};
360 +
361 +static const char * const serial_led_clk_groups[] = {
362 + "gpio0",
363 +};
364 +
365 +static const char * const serial_led_data_groups[] = {
366 + "gpio1",
367 +};
368 +
369 +static const char * const hsspi_cs4_groups[] = {
370 + "gpio16",
371 +};
372 +
373 +static const char * const hsspi_cs5_groups[] = {
374 + "gpio17",
375 +};
376 +
377 +static const char * const hsspi_cs6_groups[] = {
378 + "gpio8",
379 +};
380 +
381 +static const char * const hsspi_cs7_groups[] = {
382 + "gpio9",
383 +};
384 +
385 +static const char * const uart1_scts_groups[] = {
386 + "gpio10",
387 + "gpio24",
388 +};
389 +
390 +static const char * const uart1_srts_groups[] = {
391 + "gpio11",
392 + "gpio25",
393 +};
394 +
395 +static const char * const uart1_sdin_groups[] = {
396 + "gpio12",
397 + "gpio26",
398 +};
399 +
400 +static const char * const uart1_sdout_groups[] = {
401 + "gpio13",
402 + "gpio27",
403 +};
404 +
405 +static const char * const ntr_pulse_in_groups[] = {
406 + "gpio14",
407 + "gpio28",
408 +};
409 +
410 +static const char * const dsl_ntr_pulse_out_groups[] = {
411 + "gpio15",
412 + "gpio29",
413 +};
414 +
415 +static const char * const adsl_spi_miso_groups[] = {
416 + "gpio18",
417 +};
418 +
419 +static const char * const adsl_spi_mosi_groups[] = {
420 + "gpio19",
421 +};
422 +
423 +static const char * const vreg_clk_groups[] = {
424 + "gpio22",
425 +};
426 +
427 +static const char * const pcie_clkreq_b_groups[] = {
428 + "gpio23",
429 +};
430 +
431 +static const char * const switch_led_clk_groups[] = {
432 + "gpio30",
433 +};
434 +
435 +static const char * const switch_led_data_groups[] = {
436 + "gpio31",
437 +};
438 +
439 +static const char * const wifi_groups[] = {
440 + "gpio32",
441 + "gpio33",
442 + "gpio34",
443 + "gpio35",
444 + "gpio36",
445 + "gpio37",
446 + "gpio38",
447 + "gpio39",
448 + "gpio40",
449 + "gpio41",
450 + "gpio42",
451 + "gpio43",
452 + "gpio44",
453 + "gpio45",
454 + "gpio46",
455 + "gpio47",
456 + "gpio48",
457 + "gpio49",
458 + "gpio50",
459 + "gpio51",
460 +};
461 +
462 +static const char * const nand_groups[] = {
463 + "nand_grp",
464 +};
465 +
466 +static const char * const dectpd_groups[] = {
467 + "dectpd_grp",
468 +};
469 +
470 +static const char * const vdsl_phy_override_0_groups[] = {
471 + "vdsl_phy_override_0_grp",
472 +};
473 +
474 +static const char * const vdsl_phy_override_1_groups[] = {
475 + "vdsl_phy_override_1_grp",
476 +};
477 +
478 +static const char * const vdsl_phy_override_2_groups[] = {
479 + "vdsl_phy_override_2_grp",
480 +};
481 +
482 +static const char * const vdsl_phy_override_3_groups[] = {
483 + "vdsl_phy_override_3_grp",
484 +};
485 +
486 +#define BCM63268_LED_FUN(n) \
487 + { \
488 + .name = #n, \
489 + .groups = n##_groups, \
490 + .num_groups = ARRAY_SIZE(n##_groups), \
491 + .reg = BCM63268_LEDCTRL, \
492 + }
493 +
494 +#define BCM63268_MODE_FUN(n) \
495 + { \
496 + .name = #n, \
497 + .groups = n##_groups, \
498 + .num_groups = ARRAY_SIZE(n##_groups), \
499 + .reg = BCM63268_MODE, \
500 + }
501 +
502 +#define BCM63268_CTRL_FUN(n) \
503 + { \
504 + .name = #n, \
505 + .groups = n##_groups, \
506 + .num_groups = ARRAY_SIZE(n##_groups), \
507 + .reg = BCM63268_CTRL, \
508 + }
509 +
510 +#define BCM63268_BASEMODE_FUN(n, val) \
511 + { \
512 + .name = #n, \
513 + .groups = n##_groups, \
514 + .num_groups = ARRAY_SIZE(n##_groups), \
515 + .reg = BCM63268_BASEMODE, \
516 + .mask = val, \
517 + }
518 +
519 +static const struct bcm63268_function bcm63268_funcs[] = {
520 + BCM63268_LED_FUN(led),
521 + BCM63268_MODE_FUN(serial_led_clk),
522 + BCM63268_MODE_FUN(serial_led_data),
523 + BCM63268_MODE_FUN(hsspi_cs6),
524 + BCM63268_MODE_FUN(hsspi_cs7),
525 + BCM63268_MODE_FUN(uart1_scts),
526 + BCM63268_MODE_FUN(uart1_srts),
527 + BCM63268_MODE_FUN(uart1_sdin),
528 + BCM63268_MODE_FUN(uart1_sdout),
529 + BCM63268_MODE_FUN(ntr_pulse_in),
530 + BCM63268_MODE_FUN(dsl_ntr_pulse_out),
531 + BCM63268_MODE_FUN(hsspi_cs4),
532 + BCM63268_MODE_FUN(hsspi_cs5),
533 + BCM63268_MODE_FUN(adsl_spi_miso),
534 + BCM63268_MODE_FUN(adsl_spi_mosi),
535 + BCM63268_MODE_FUN(vreg_clk),
536 + BCM63268_MODE_FUN(pcie_clkreq_b),
537 + BCM63268_MODE_FUN(switch_led_clk),
538 + BCM63268_MODE_FUN(switch_led_data),
539 + BCM63268_CTRL_FUN(wifi),
540 + BCM63268_BASEMODE_FUN(nand, BCM63268_BASEMODE_NAND),
541 + BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD),
542 + BCM63268_BASEMODE_FUN(vdsl_phy_override_0,
543 + BCM63268_BASEMODE_VDSL_PHY_0),
544 + BCM63268_BASEMODE_FUN(vdsl_phy_override_1,
545 + BCM63268_BASEMODE_VDSL_PHY_1),
546 + BCM63268_BASEMODE_FUN(vdsl_phy_override_2,
547 + BCM63268_BASEMODE_VDSL_PHY_2),
548 + BCM63268_BASEMODE_FUN(vdsl_phy_override_3,
549 + BCM63268_BASEMODE_VDSL_PHY_3),
550 +};
551 +
552 +static inline unsigned int bcm63268_bank_pin(unsigned int pin)
553 +{
554 + return pin % PINS_PER_BANK;
555 +}
556 +
557 +static inline unsigned int bcm63268_reg_off(unsigned int reg, unsigned int pin)
558 +{
559 + return reg - (pin / PINS_PER_BANK) * BANK_SIZE;
560 +}
561 +
562 +static int bcm63268_gpio_direction_input(struct gpio_chip *chip,
563 + unsigned int pin)
564 +{
565 + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
566 + unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin);
567 + unsigned int bank_pin = bcm63268_bank_pin(pin);
568 + int ret;
569 +
570 + /*
571 + * Check with the pinctrl driver whether this pin is usable as
572 + * an input GPIO
573 + */
574 + ret = pinctrl_gpio_direction_input(chip->base + pin);
575 + if (ret)
576 + return ret;
577 +
578 + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), 0);
579 +
580 + return 0;
581 +}
582 +
583 +static int bcm63268_gpio_direction_output(struct gpio_chip *chip,
584 + unsigned int pin, int value)
585 +{
586 + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
587 + unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin);
588 + unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin);
589 + unsigned int bank_pin = bcm63268_bank_pin(pin);
590 + unsigned int val = value ? BIT(bank_pin) : 0;
591 + int ret;
592 +
593 + /*
594 + * Check with the pinctrl driver whether this pin is usable as
595 + * an output GPIO
596 + */
597 + ret = pinctrl_gpio_direction_output(chip->base + pin);
598 + if (ret)
599 + return ret;
600 +
601 + regmap_update_bits(pc->regs, dirout, BIT(bank_pin), BIT(bank_pin));
602 + regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
603 +
604 + return 0;
605 +}
606 +
607 +static int bcm63268_gpio_get(struct gpio_chip *chip, unsigned int pin)
608 +{
609 + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
610 + unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin);
611 + unsigned int bank_pin = bcm63268_bank_pin(pin);
612 + unsigned int val;
613 +
614 + regmap_read(pc->regs, data, &val);
615 +
616 + return !!(val & BIT(bank_pin));
617 +}
618 +
619 +static int bcm63268_gpio_get_direction(struct gpio_chip *chip, unsigned int pin)
620 +{
621 + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
622 + unsigned int dirout = bcm63268_reg_off(BCM63268_DIROUT_REG, pin);
623 + unsigned int bank_pin = bcm63268_bank_pin(pin);
624 + unsigned int val;
625 +
626 + regmap_read(pc->regs, dirout, &val);
627 +
628 + if (val & BIT(bank_pin))
629 + return GPIO_LINE_DIRECTION_OUT;
630 +
631 + return GPIO_LINE_DIRECTION_IN;
632 +}
633 +
634 +static void bcm63268_gpio_set(struct gpio_chip *chip, unsigned int pin,
635 + int value)
636 +{
637 + struct bcm63268_pinctrl *pc = gpiochip_get_data(chip);
638 + unsigned int data = bcm63268_reg_off(BCM63268_DATA_REG, pin);
639 + unsigned int bank_pin = bcm63268_bank_pin(pin);
640 + unsigned int val = value ? BIT(bank_pin) : 0;
641 +
642 + regmap_update_bits(pc->regs, data, BIT(bank_pin), val);
643 +}
644 +
645 +static int bcm63268_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
646 +{
647 + char irq_name[7];
648 +
649 + sprintf(irq_name, "gpio%d", gpio);
650 +
651 + return of_irq_get_byname(chip->of_node, irq_name);
652 +}
653 +
654 +static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
655 +{
656 + return ARRAY_SIZE(bcm63268_groups);
657 +}
658 +
659 +static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
660 + unsigned group)
661 +{
662 + return bcm63268_groups[group].name;
663 +}
664 +
665 +static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
666 + unsigned group,
667 + const unsigned **pins,
668 + unsigned *num_pins)
669 +{
670 + *pins = bcm63268_groups[group].pins;
671 + *num_pins = bcm63268_groups[group].num_pins;
672 +
673 + return 0;
674 +}
675 +
676 +static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
677 +{
678 + return ARRAY_SIZE(bcm63268_funcs);
679 +}
680 +
681 +static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
682 + unsigned selector)
683 +{
684 + return bcm63268_funcs[selector].name;
685 +}
686 +
687 +static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev,
688 + unsigned selector,
689 + const char * const **groups,
690 + unsigned * const num_groups)
691 +{
692 + *groups = bcm63268_funcs[selector].groups;
693 + *num_groups = bcm63268_funcs[selector].num_groups;
694 +
695 + return 0;
696 +}
697 +
698 +static void bcm63268_set_gpio(struct bcm63268_pinctrl *pc, unsigned pin)
699 +{
700 + const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
701 + unsigned int basemode = (unsigned long) desc->drv_data;
702 + unsigned int mask = BIT(bcm63268_bank_pin(pin));
703 +
704 + if (basemode)
705 + regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode,
706 + 0);
707 +
708 + if (pin < PINS_PER_BANK) {
709 + /* base mode: 0 => gpio, 1 => mux function */
710 + regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0);
711 +
712 + /* pins 0-23 might be muxed to led */
713 + if (pin < BCM63268_NUM_LEDS)
714 + regmap_update_bits(pc->regs, BCM63268_LED_REG, mask,
715 + 0);
716 + } else if (pin < BCM63268_NUM_GPIOS) {
717 + /* ctrl reg: 0 => wifi function, 1 => gpio */
718 + regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask);
719 + }
720 +}
721 +
722 +static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
723 + unsigned selector, unsigned group)
724 +{
725 + struct bcm63268_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
726 + const struct bcm63268_pingroup *pg = &bcm63268_groups[group];
727 + const struct bcm63268_function *f = &bcm63268_funcs[selector];
728 + unsigned i;
729 + unsigned int reg;
730 + unsigned int val, mask;
731 +
732 + for (i = 0; i < pg->num_pins; i++)
733 + bcm63268_set_gpio(pc, pg->pins[i]);
734 +
735 + switch (f->reg) {
736 + case BCM63268_LEDCTRL:
737 + reg = BCM63268_LED_REG;
738 + mask = BIT(pg->pins[0]);
739 + val = BIT(pg->pins[0]);
740 + break;
741 + case BCM63268_MODE:
742 + reg = BCM63268_MODE_REG;
743 + mask = BIT(pg->pins[0]);
744 + val = BIT(pg->pins[0]);
745 + break;
746 + case BCM63268_CTRL:
747 + reg = BCM63268_CTRL_REG;
748 + mask = BIT(pg->pins[0]);
749 + val = 0;
750 + break;
751 + case BCM63268_BASEMODE:
752 + reg = BCM63268_BASEMODE_REG;
753 + mask = f->mask;
754 + val = f->mask;
755 + break;
756 + default:
757 + WARN_ON(1);
758 + return -EINVAL;
759 + }
760 +
761 + regmap_update_bits(pc->regs, reg, mask, val);
762 +
763 + return 0;
764 +}
765 +
766 +static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev,
767 + struct pinctrl_gpio_range *range,
768 + unsigned offset)
769 +{
770 + struct bcm63268_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
771 +
772 + /* disable all functions using this pin */
773 + bcm63268_set_gpio(pc, offset);
774 +
775 + return 0;
776 +}
777 +
778 +static struct pinctrl_ops bcm63268_pctl_ops = {
779 + .get_groups_count = bcm63268_pinctrl_get_group_count,
780 + .get_group_name = bcm63268_pinctrl_get_group_name,
781 + .get_group_pins = bcm63268_pinctrl_get_group_pins,
782 + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
783 + .dt_free_map = pinctrl_utils_free_map,
784 +};
785 +
786 +static struct pinmux_ops bcm63268_pmx_ops = {
787 + .get_functions_count = bcm63268_pinctrl_get_func_count,
788 + .get_function_name = bcm63268_pinctrl_get_func_name,
789 + .get_function_groups = bcm63268_pinctrl_get_groups,
790 + .set_mux = bcm63268_pinctrl_set_mux,
791 + .gpio_request_enable = bcm63268_gpio_request_enable,
792 + .strict = true,
793 +};
794 +
795 +static int bcm63268_pinctrl_probe(struct platform_device *pdev)
796 +{
797 + struct device *dev = &pdev->dev;
798 + struct device_node *np = dev->of_node;
799 + struct bcm63268_pinctrl *pc;
800 + int err;
801 +
802 + pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
803 + if (!pc)
804 + return -ENOMEM;
805 +
806 + platform_set_drvdata(pdev, pc);
807 + pc->dev = dev;
808 +
809 + pc->regs = syscon_node_to_regmap(dev->parent->of_node);
810 + if (IS_ERR(pc->regs))
811 + return PTR_ERR(pc->regs);
812 +
813 + pc->gpio_chip.label = MODULE_NAME;
814 + pc->gpio_chip.owner = THIS_MODULE;
815 + pc->gpio_chip.request = gpiochip_generic_request;
816 + pc->gpio_chip.free = gpiochip_generic_free;
817 + pc->gpio_chip.direction_input = bcm63268_gpio_direction_input;
818 + pc->gpio_chip.direction_output = bcm63268_gpio_direction_output;
819 + pc->gpio_chip.get_direction = bcm63268_gpio_get_direction;
820 + pc->gpio_chip.get = bcm63268_gpio_get;
821 + pc->gpio_chip.set = bcm63268_gpio_set;
822 + pc->gpio_chip.set_config = gpiochip_generic_config;
823 + pc->gpio_chip.base = -1;
824 + pc->gpio_chip.ngpio = BCM63268_NUM_GPIOS;
825 + pc->gpio_chip.can_sleep = false;
826 + pc->gpio_chip.parent = dev;
827 + pc->gpio_chip.of_node = np;
828 +
829 + if (of_get_property(np, "interrupt-names", NULL))
830 + pc->gpio_chip.to_irq = bcm63268_gpio_to_irq;
831 +
832 + err = gpiochip_add_data(&pc->gpio_chip, pc);
833 + if (err) {
834 + dev_err(dev, "could not add GPIO chip\n");
835 + return err;
836 + }
837 +
838 + pc->pctl_desc.name = MODULE_NAME,
839 + pc->pctl_desc.pins = bcm63268_pins,
840 + pc->pctl_desc.npins = ARRAY_SIZE(bcm63268_pins),
841 + pc->pctl_desc.pctlops = &bcm63268_pctl_ops,
842 + pc->pctl_desc.pmxops = &bcm63268_pmx_ops,
843 + pc->pctl_desc.owner = THIS_MODULE,
844 +
845 + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
846 + if (IS_ERR(pc->pctl_dev)) {
847 + gpiochip_remove(&pc->gpio_chip);
848 + return PTR_ERR(pc->pctl_dev);
849 + }
850 +
851 + pc->gpio_range.name = MODULE_NAME;
852 + pc->gpio_range.npins = BCM63268_NUM_GPIOS;
853 + pc->gpio_range.base = pc->gpio_chip.base;
854 + pc->gpio_range.gc = &pc->gpio_chip;
855 + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
856 +
857 + dev_info(dev, "registered\n");
858 +
859 + return 0;
860 +}
861 +
862 +static const struct of_device_id bcm63268_pinctrl_match[] = {
863 + { .compatible = "brcm,bcm63268-pinctrl", },
864 + { },
865 +};
866 +
867 +static struct platform_driver bcm63268_pinctrl_driver = {
868 + .probe = bcm63268_pinctrl_probe,
869 + .driver = {
870 + .name = MODULE_NAME,
871 + .of_match_table = bcm63268_pinctrl_match,
872 + },
873 +};
874 +
875 +builtin_platform_driver(bcm63268_pinctrl_driver);