bmips: backport accepted pinctrl patches
[openwrt/staging/chunkeey.git] / target / linux / bmips / patches-5.10 / 070-v5.13-pinctrl-add-a-pincontrol-driver-for-BCM63268.patch
1 From 155cca1b0794a8f541e7eaa45be70df0a49964f3 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
3 Date: Wed, 24 Mar 2021 09:19:20 +0100
4 Subject: [PATCH 19/22] 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 Co-developed-by: Jonas Gorski <jonas.gorski@gmail.com>
14 Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
15 Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
16 Link: https://lore.kernel.org/r/20210324081923.20379-20-noltari@gmail.com
17 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
18 ---
19 drivers/pinctrl/bcm/Kconfig | 8 +
20 drivers/pinctrl/bcm/Makefile | 1 +
21 drivers/pinctrl/bcm/pinctrl-bcm63268.c | 643 +++++++++++++++++++++++++
22 3 files changed, 652 insertions(+)
23 create mode 100644 drivers/pinctrl/bcm/pinctrl-bcm63268.c
24
25 --- a/drivers/pinctrl/bcm/Kconfig
26 +++ b/drivers/pinctrl/bcm/Kconfig
27 @@ -68,6 +68,14 @@ config PINCTRL_BCM6368
28 help
29 Say Y here to enable the Broadcom BCM6368 GPIO driver.
30
31 +config PINCTRL_BCM63268
32 + bool "Broadcom BCM63268 GPIO driver"
33 + depends on (BMIPS_GENERIC || COMPILE_TEST)
34 + select PINCTRL_BCM63XX
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 @@ -8,6 +8,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,643 @@
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/bits.h>
64 +#include <linux/gpio/driver.h>
65 +#include <linux/kernel.h>
66 +#include <linux/of.h>
67 +#include <linux/pinctrl/pinmux.h>
68 +#include <linux/platform_device.h>
69 +#include <linux/regmap.h>
70 +
71 +#include "../pinctrl-utils.h"
72 +
73 +#include "pinctrl-bcm63xx.h"
74 +
75 +#define BCM63268_NUM_GPIOS 52
76 +#define BCM63268_NUM_LEDS 24
77 +
78 +#define BCM63268_LED_REG 0x10
79 +#define BCM63268_MODE_REG 0x18
80 +#define BCM63268_CTRL_REG 0x1c
81 +#define BCM63268_BASEMODE_REG 0x38
82 +#define BCM63268_BASEMODE_NAND BIT(2) /* GPIOs 2-7, 24-31 */
83 +#define BCM63268_BASEMODE_GPIO35 BIT(4) /* GPIO 35 */
84 +#define BCM63268_BASEMODE_DECTPD BIT(5) /* GPIOs 8/9 */
85 +#define BCM63268_BASEMODE_VDSL_PHY_0 BIT(6) /* GPIOs 10/11 */
86 +#define BCM63268_BASEMODE_VDSL_PHY_1 BIT(7) /* GPIOs 12/13 */
87 +#define BCM63268_BASEMODE_VDSL_PHY_2 BIT(8) /* GPIOs 24/25 */
88 +#define BCM63268_BASEMODE_VDSL_PHY_3 BIT(9) /* GPIOs 26/27 */
89 +
90 +enum bcm63268_pinctrl_reg {
91 + BCM63268_LEDCTRL,
92 + BCM63268_MODE,
93 + BCM63268_CTRL,
94 + BCM63268_BASEMODE,
95 +};
96 +
97 +struct bcm63268_pingroup {
98 + const char *name;
99 + const unsigned * const pins;
100 + const unsigned num_pins;
101 +};
102 +
103 +struct bcm63268_function {
104 + const char *name;
105 + const char * const *groups;
106 + const unsigned num_groups;
107 +
108 + enum bcm63268_pinctrl_reg reg;
109 + uint32_t mask;
110 +};
111 +
112 +#define BCM63268_PIN(a, b, basemode) \
113 + { \
114 + .number = a, \
115 + .name = b, \
116 + .drv_data = (void *)(basemode) \
117 + }
118 +
119 +static const struct pinctrl_pin_desc bcm63268_pins[] = {
120 + PINCTRL_PIN(0, "gpio0"),
121 + PINCTRL_PIN(1, "gpio1"),
122 + BCM63268_PIN(2, "gpio2", BCM63268_BASEMODE_NAND),
123 + BCM63268_PIN(3, "gpio3", BCM63268_BASEMODE_NAND),
124 + BCM63268_PIN(4, "gpio4", BCM63268_BASEMODE_NAND),
125 + BCM63268_PIN(5, "gpio5", BCM63268_BASEMODE_NAND),
126 + BCM63268_PIN(6, "gpio6", BCM63268_BASEMODE_NAND),
127 + BCM63268_PIN(7, "gpio7", BCM63268_BASEMODE_NAND),
128 + BCM63268_PIN(8, "gpio8", BCM63268_BASEMODE_DECTPD),
129 + BCM63268_PIN(9, "gpio9", BCM63268_BASEMODE_DECTPD),
130 + BCM63268_PIN(10, "gpio10", BCM63268_BASEMODE_VDSL_PHY_0),
131 + BCM63268_PIN(11, "gpio11", BCM63268_BASEMODE_VDSL_PHY_0),
132 + BCM63268_PIN(12, "gpio12", BCM63268_BASEMODE_VDSL_PHY_1),
133 + BCM63268_PIN(13, "gpio13", BCM63268_BASEMODE_VDSL_PHY_1),
134 + PINCTRL_PIN(14, "gpio14"),
135 + PINCTRL_PIN(15, "gpio15"),
136 + PINCTRL_PIN(16, "gpio16"),
137 + PINCTRL_PIN(17, "gpio17"),
138 + PINCTRL_PIN(18, "gpio18"),
139 + PINCTRL_PIN(19, "gpio19"),
140 + PINCTRL_PIN(20, "gpio20"),
141 + PINCTRL_PIN(21, "gpio21"),
142 + PINCTRL_PIN(22, "gpio22"),
143 + PINCTRL_PIN(23, "gpio23"),
144 + BCM63268_PIN(24, "gpio24",
145 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
146 + BCM63268_PIN(25, "gpio25",
147 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_2),
148 + BCM63268_PIN(26, "gpio26",
149 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
150 + BCM63268_PIN(27, "gpio27",
151 + BCM63268_BASEMODE_NAND | BCM63268_BASEMODE_VDSL_PHY_3),
152 + BCM63268_PIN(28, "gpio28", BCM63268_BASEMODE_NAND),
153 + BCM63268_PIN(29, "gpio29", BCM63268_BASEMODE_NAND),
154 + BCM63268_PIN(30, "gpio30", BCM63268_BASEMODE_NAND),
155 + BCM63268_PIN(31, "gpio31", BCM63268_BASEMODE_NAND),
156 + PINCTRL_PIN(32, "gpio32"),
157 + PINCTRL_PIN(33, "gpio33"),
158 + PINCTRL_PIN(34, "gpio34"),
159 + PINCTRL_PIN(35, "gpio35"),
160 + PINCTRL_PIN(36, "gpio36"),
161 + PINCTRL_PIN(37, "gpio37"),
162 + PINCTRL_PIN(38, "gpio38"),
163 + PINCTRL_PIN(39, "gpio39"),
164 + PINCTRL_PIN(40, "gpio40"),
165 + PINCTRL_PIN(41, "gpio41"),
166 + PINCTRL_PIN(42, "gpio42"),
167 + PINCTRL_PIN(43, "gpio43"),
168 + PINCTRL_PIN(44, "gpio44"),
169 + PINCTRL_PIN(45, "gpio45"),
170 + PINCTRL_PIN(46, "gpio46"),
171 + PINCTRL_PIN(47, "gpio47"),
172 + PINCTRL_PIN(48, "gpio48"),
173 + PINCTRL_PIN(49, "gpio49"),
174 + PINCTRL_PIN(50, "gpio50"),
175 + PINCTRL_PIN(51, "gpio51"),
176 +};
177 +
178 +static unsigned gpio0_pins[] = { 0 };
179 +static unsigned gpio1_pins[] = { 1 };
180 +static unsigned gpio2_pins[] = { 2 };
181 +static unsigned gpio3_pins[] = { 3 };
182 +static unsigned gpio4_pins[] = { 4 };
183 +static unsigned gpio5_pins[] = { 5 };
184 +static unsigned gpio6_pins[] = { 6 };
185 +static unsigned gpio7_pins[] = { 7 };
186 +static unsigned gpio8_pins[] = { 8 };
187 +static unsigned gpio9_pins[] = { 9 };
188 +static unsigned gpio10_pins[] = { 10 };
189 +static unsigned gpio11_pins[] = { 11 };
190 +static unsigned gpio12_pins[] = { 12 };
191 +static unsigned gpio13_pins[] = { 13 };
192 +static unsigned gpio14_pins[] = { 14 };
193 +static unsigned gpio15_pins[] = { 15 };
194 +static unsigned gpio16_pins[] = { 16 };
195 +static unsigned gpio17_pins[] = { 17 };
196 +static unsigned gpio18_pins[] = { 18 };
197 +static unsigned gpio19_pins[] = { 19 };
198 +static unsigned gpio20_pins[] = { 20 };
199 +static unsigned gpio21_pins[] = { 21 };
200 +static unsigned gpio22_pins[] = { 22 };
201 +static unsigned gpio23_pins[] = { 23 };
202 +static unsigned gpio24_pins[] = { 24 };
203 +static unsigned gpio25_pins[] = { 25 };
204 +static unsigned gpio26_pins[] = { 26 };
205 +static unsigned gpio27_pins[] = { 27 };
206 +static unsigned gpio28_pins[] = { 28 };
207 +static unsigned gpio29_pins[] = { 29 };
208 +static unsigned gpio30_pins[] = { 30 };
209 +static unsigned gpio31_pins[] = { 31 };
210 +static unsigned gpio32_pins[] = { 32 };
211 +static unsigned gpio33_pins[] = { 33 };
212 +static unsigned gpio34_pins[] = { 34 };
213 +static unsigned gpio35_pins[] = { 35 };
214 +static unsigned gpio36_pins[] = { 36 };
215 +static unsigned gpio37_pins[] = { 37 };
216 +static unsigned gpio38_pins[] = { 38 };
217 +static unsigned gpio39_pins[] = { 39 };
218 +static unsigned gpio40_pins[] = { 40 };
219 +static unsigned gpio41_pins[] = { 41 };
220 +static unsigned gpio42_pins[] = { 42 };
221 +static unsigned gpio43_pins[] = { 43 };
222 +static unsigned gpio44_pins[] = { 44 };
223 +static unsigned gpio45_pins[] = { 45 };
224 +static unsigned gpio46_pins[] = { 46 };
225 +static unsigned gpio47_pins[] = { 47 };
226 +static unsigned gpio48_pins[] = { 48 };
227 +static unsigned gpio49_pins[] = { 49 };
228 +static unsigned gpio50_pins[] = { 50 };
229 +static unsigned gpio51_pins[] = { 51 };
230 +
231 +static unsigned nand_grp_pins[] = {
232 + 2, 3, 4, 5, 6, 7, 24,
233 + 25, 26, 27, 28, 29, 30, 31,
234 +};
235 +
236 +static unsigned dectpd_grp_pins[] = { 8, 9 };
237 +static unsigned vdsl_phy0_grp_pins[] = { 10, 11 };
238 +static unsigned vdsl_phy1_grp_pins[] = { 12, 13 };
239 +static unsigned vdsl_phy2_grp_pins[] = { 24, 25 };
240 +static unsigned vdsl_phy3_grp_pins[] = { 26, 27 };
241 +
242 +#define BCM63268_GROUP(n) \
243 + { \
244 + .name = #n, \
245 + .pins = n##_pins, \
246 + .num_pins = ARRAY_SIZE(n##_pins), \
247 + }
248 +
249 +static struct bcm63268_pingroup bcm63268_groups[] = {
250 + BCM63268_GROUP(gpio0),
251 + BCM63268_GROUP(gpio1),
252 + BCM63268_GROUP(gpio2),
253 + BCM63268_GROUP(gpio3),
254 + BCM63268_GROUP(gpio4),
255 + BCM63268_GROUP(gpio5),
256 + BCM63268_GROUP(gpio6),
257 + BCM63268_GROUP(gpio7),
258 + BCM63268_GROUP(gpio8),
259 + BCM63268_GROUP(gpio9),
260 + BCM63268_GROUP(gpio10),
261 + BCM63268_GROUP(gpio11),
262 + BCM63268_GROUP(gpio12),
263 + BCM63268_GROUP(gpio13),
264 + BCM63268_GROUP(gpio14),
265 + BCM63268_GROUP(gpio15),
266 + BCM63268_GROUP(gpio16),
267 + BCM63268_GROUP(gpio17),
268 + BCM63268_GROUP(gpio18),
269 + BCM63268_GROUP(gpio19),
270 + BCM63268_GROUP(gpio20),
271 + BCM63268_GROUP(gpio21),
272 + BCM63268_GROUP(gpio22),
273 + BCM63268_GROUP(gpio23),
274 + BCM63268_GROUP(gpio24),
275 + BCM63268_GROUP(gpio25),
276 + BCM63268_GROUP(gpio26),
277 + BCM63268_GROUP(gpio27),
278 + BCM63268_GROUP(gpio28),
279 + BCM63268_GROUP(gpio29),
280 + BCM63268_GROUP(gpio30),
281 + BCM63268_GROUP(gpio31),
282 + BCM63268_GROUP(gpio32),
283 + BCM63268_GROUP(gpio33),
284 + BCM63268_GROUP(gpio34),
285 + BCM63268_GROUP(gpio35),
286 + BCM63268_GROUP(gpio36),
287 + BCM63268_GROUP(gpio37),
288 + BCM63268_GROUP(gpio38),
289 + BCM63268_GROUP(gpio39),
290 + BCM63268_GROUP(gpio40),
291 + BCM63268_GROUP(gpio41),
292 + BCM63268_GROUP(gpio42),
293 + BCM63268_GROUP(gpio43),
294 + BCM63268_GROUP(gpio44),
295 + BCM63268_GROUP(gpio45),
296 + BCM63268_GROUP(gpio46),
297 + BCM63268_GROUP(gpio47),
298 + BCM63268_GROUP(gpio48),
299 + BCM63268_GROUP(gpio49),
300 + BCM63268_GROUP(gpio50),
301 + BCM63268_GROUP(gpio51),
302 +
303 + /* multi pin groups */
304 + BCM63268_GROUP(nand_grp),
305 + BCM63268_GROUP(dectpd_grp),
306 + BCM63268_GROUP(vdsl_phy0_grp),
307 + BCM63268_GROUP(vdsl_phy1_grp),
308 + BCM63268_GROUP(vdsl_phy2_grp),
309 + BCM63268_GROUP(vdsl_phy3_grp),
310 +};
311 +
312 +static const char * const led_groups[] = {
313 + "gpio0",
314 + "gpio1",
315 + "gpio2",
316 + "gpio3",
317 + "gpio4",
318 + "gpio5",
319 + "gpio6",
320 + "gpio7",
321 + "gpio8",
322 + "gpio9",
323 + "gpio10",
324 + "gpio11",
325 + "gpio12",
326 + "gpio13",
327 + "gpio14",
328 + "gpio15",
329 + "gpio16",
330 + "gpio17",
331 + "gpio18",
332 + "gpio19",
333 + "gpio20",
334 + "gpio21",
335 + "gpio22",
336 + "gpio23",
337 +};
338 +
339 +static const char * const serial_led_clk_groups[] = {
340 + "gpio0",
341 +};
342 +
343 +static const char * const serial_led_data_groups[] = {
344 + "gpio1",
345 +};
346 +
347 +static const char * const hsspi_cs4_groups[] = {
348 + "gpio16",
349 +};
350 +
351 +static const char * const hsspi_cs5_groups[] = {
352 + "gpio17",
353 +};
354 +
355 +static const char * const hsspi_cs6_groups[] = {
356 + "gpio8",
357 +};
358 +
359 +static const char * const hsspi_cs7_groups[] = {
360 + "gpio9",
361 +};
362 +
363 +static const char * const uart1_scts_groups[] = {
364 + "gpio10",
365 + "gpio24",
366 +};
367 +
368 +static const char * const uart1_srts_groups[] = {
369 + "gpio11",
370 + "gpio25",
371 +};
372 +
373 +static const char * const uart1_sdin_groups[] = {
374 + "gpio12",
375 + "gpio26",
376 +};
377 +
378 +static const char * const uart1_sdout_groups[] = {
379 + "gpio13",
380 + "gpio27",
381 +};
382 +
383 +static const char * const ntr_pulse_in_groups[] = {
384 + "gpio14",
385 + "gpio28",
386 +};
387 +
388 +static const char * const dsl_ntr_pulse_out_groups[] = {
389 + "gpio15",
390 + "gpio29",
391 +};
392 +
393 +static const char * const adsl_spi_miso_groups[] = {
394 + "gpio18",
395 +};
396 +
397 +static const char * const adsl_spi_mosi_groups[] = {
398 + "gpio19",
399 +};
400 +
401 +static const char * const vreg_clk_groups[] = {
402 + "gpio22",
403 +};
404 +
405 +static const char * const pcie_clkreq_b_groups[] = {
406 + "gpio23",
407 +};
408 +
409 +static const char * const switch_led_clk_groups[] = {
410 + "gpio30",
411 +};
412 +
413 +static const char * const switch_led_data_groups[] = {
414 + "gpio31",
415 +};
416 +
417 +static const char * const wifi_groups[] = {
418 + "gpio32",
419 + "gpio33",
420 + "gpio34",
421 + "gpio35",
422 + "gpio36",
423 + "gpio37",
424 + "gpio38",
425 + "gpio39",
426 + "gpio40",
427 + "gpio41",
428 + "gpio42",
429 + "gpio43",
430 + "gpio44",
431 + "gpio45",
432 + "gpio46",
433 + "gpio47",
434 + "gpio48",
435 + "gpio49",
436 + "gpio50",
437 + "gpio51",
438 +};
439 +
440 +static const char * const nand_groups[] = {
441 + "nand_grp",
442 +};
443 +
444 +static const char * const dectpd_groups[] = {
445 + "dectpd_grp",
446 +};
447 +
448 +static const char * const vdsl_phy_override_0_groups[] = {
449 + "vdsl_phy_override_0_grp",
450 +};
451 +
452 +static const char * const vdsl_phy_override_1_groups[] = {
453 + "vdsl_phy_override_1_grp",
454 +};
455 +
456 +static const char * const vdsl_phy_override_2_groups[] = {
457 + "vdsl_phy_override_2_grp",
458 +};
459 +
460 +static const char * const vdsl_phy_override_3_groups[] = {
461 + "vdsl_phy_override_3_grp",
462 +};
463 +
464 +#define BCM63268_LED_FUN(n) \
465 + { \
466 + .name = #n, \
467 + .groups = n##_groups, \
468 + .num_groups = ARRAY_SIZE(n##_groups), \
469 + .reg = BCM63268_LEDCTRL, \
470 + }
471 +
472 +#define BCM63268_MODE_FUN(n) \
473 + { \
474 + .name = #n, \
475 + .groups = n##_groups, \
476 + .num_groups = ARRAY_SIZE(n##_groups), \
477 + .reg = BCM63268_MODE, \
478 + }
479 +
480 +#define BCM63268_CTRL_FUN(n) \
481 + { \
482 + .name = #n, \
483 + .groups = n##_groups, \
484 + .num_groups = ARRAY_SIZE(n##_groups), \
485 + .reg = BCM63268_CTRL, \
486 + }
487 +
488 +#define BCM63268_BASEMODE_FUN(n, val) \
489 + { \
490 + .name = #n, \
491 + .groups = n##_groups, \
492 + .num_groups = ARRAY_SIZE(n##_groups), \
493 + .reg = BCM63268_BASEMODE, \
494 + .mask = val, \
495 + }
496 +
497 +static const struct bcm63268_function bcm63268_funcs[] = {
498 + BCM63268_LED_FUN(led),
499 + BCM63268_MODE_FUN(serial_led_clk),
500 + BCM63268_MODE_FUN(serial_led_data),
501 + BCM63268_MODE_FUN(hsspi_cs6),
502 + BCM63268_MODE_FUN(hsspi_cs7),
503 + BCM63268_MODE_FUN(uart1_scts),
504 + BCM63268_MODE_FUN(uart1_srts),
505 + BCM63268_MODE_FUN(uart1_sdin),
506 + BCM63268_MODE_FUN(uart1_sdout),
507 + BCM63268_MODE_FUN(ntr_pulse_in),
508 + BCM63268_MODE_FUN(dsl_ntr_pulse_out),
509 + BCM63268_MODE_FUN(hsspi_cs4),
510 + BCM63268_MODE_FUN(hsspi_cs5),
511 + BCM63268_MODE_FUN(adsl_spi_miso),
512 + BCM63268_MODE_FUN(adsl_spi_mosi),
513 + BCM63268_MODE_FUN(vreg_clk),
514 + BCM63268_MODE_FUN(pcie_clkreq_b),
515 + BCM63268_MODE_FUN(switch_led_clk),
516 + BCM63268_MODE_FUN(switch_led_data),
517 + BCM63268_CTRL_FUN(wifi),
518 + BCM63268_BASEMODE_FUN(nand, BCM63268_BASEMODE_NAND),
519 + BCM63268_BASEMODE_FUN(dectpd, BCM63268_BASEMODE_DECTPD),
520 + BCM63268_BASEMODE_FUN(vdsl_phy_override_0,
521 + BCM63268_BASEMODE_VDSL_PHY_0),
522 + BCM63268_BASEMODE_FUN(vdsl_phy_override_1,
523 + BCM63268_BASEMODE_VDSL_PHY_1),
524 + BCM63268_BASEMODE_FUN(vdsl_phy_override_2,
525 + BCM63268_BASEMODE_VDSL_PHY_2),
526 + BCM63268_BASEMODE_FUN(vdsl_phy_override_3,
527 + BCM63268_BASEMODE_VDSL_PHY_3),
528 +};
529 +
530 +static int bcm63268_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
531 +{
532 + return ARRAY_SIZE(bcm63268_groups);
533 +}
534 +
535 +static const char *bcm63268_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
536 + unsigned group)
537 +{
538 + return bcm63268_groups[group].name;
539 +}
540 +
541 +static int bcm63268_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
542 + unsigned group,
543 + const unsigned **pins,
544 + unsigned *num_pins)
545 +{
546 + *pins = bcm63268_groups[group].pins;
547 + *num_pins = bcm63268_groups[group].num_pins;
548 +
549 + return 0;
550 +}
551 +
552 +static int bcm63268_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
553 +{
554 + return ARRAY_SIZE(bcm63268_funcs);
555 +}
556 +
557 +static const char *bcm63268_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
558 + unsigned selector)
559 +{
560 + return bcm63268_funcs[selector].name;
561 +}
562 +
563 +static int bcm63268_pinctrl_get_groups(struct pinctrl_dev *pctldev,
564 + unsigned selector,
565 + const char * const **groups,
566 + unsigned * const num_groups)
567 +{
568 + *groups = bcm63268_funcs[selector].groups;
569 + *num_groups = bcm63268_funcs[selector].num_groups;
570 +
571 + return 0;
572 +}
573 +
574 +static void bcm63268_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
575 +{
576 + const struct pinctrl_pin_desc *desc = &bcm63268_pins[pin];
577 + unsigned int basemode = (unsigned long) desc->drv_data;
578 + unsigned int mask = BIT(bcm63xx_bank_pin(pin));
579 +
580 + if (basemode)
581 + regmap_update_bits(pc->regs, BCM63268_BASEMODE_REG, basemode,
582 + 0);
583 +
584 + if (pin < BCM63XX_BANK_GPIOS) {
585 + /* base mode: 0 => gpio, 1 => mux function */
586 + regmap_update_bits(pc->regs, BCM63268_MODE_REG, mask, 0);
587 +
588 + /* pins 0-23 might be muxed to led */
589 + if (pin < BCM63268_NUM_LEDS)
590 + regmap_update_bits(pc->regs, BCM63268_LED_REG, mask,
591 + 0);
592 + } else if (pin < BCM63268_NUM_GPIOS) {
593 + /* ctrl reg: 0 => wifi function, 1 => gpio */
594 + regmap_update_bits(pc->regs, BCM63268_CTRL_REG, mask, mask);
595 + }
596 +}
597 +
598 +static int bcm63268_pinctrl_set_mux(struct pinctrl_dev *pctldev,
599 + unsigned selector, unsigned group)
600 +{
601 + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
602 + const struct bcm63268_pingroup *pg = &bcm63268_groups[group];
603 + const struct bcm63268_function *f = &bcm63268_funcs[selector];
604 + unsigned i;
605 + unsigned int reg;
606 + unsigned int val, mask;
607 +
608 + for (i = 0; i < pg->num_pins; i++)
609 + bcm63268_set_gpio(pc, pg->pins[i]);
610 +
611 + switch (f->reg) {
612 + case BCM63268_LEDCTRL:
613 + reg = BCM63268_LED_REG;
614 + mask = BIT(pg->pins[0]);
615 + val = BIT(pg->pins[0]);
616 + break;
617 + case BCM63268_MODE:
618 + reg = BCM63268_MODE_REG;
619 + mask = BIT(pg->pins[0]);
620 + val = BIT(pg->pins[0]);
621 + break;
622 + case BCM63268_CTRL:
623 + reg = BCM63268_CTRL_REG;
624 + mask = BIT(pg->pins[0]);
625 + val = 0;
626 + break;
627 + case BCM63268_BASEMODE:
628 + reg = BCM63268_BASEMODE_REG;
629 + mask = f->mask;
630 + val = f->mask;
631 + break;
632 + default:
633 + WARN_ON(1);
634 + return -EINVAL;
635 + }
636 +
637 + regmap_update_bits(pc->regs, reg, mask, val);
638 +
639 + return 0;
640 +}
641 +
642 +static int bcm63268_gpio_request_enable(struct pinctrl_dev *pctldev,
643 + struct pinctrl_gpio_range *range,
644 + unsigned offset)
645 +{
646 + struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
647 +
648 + /* disable all functions using this pin */
649 + bcm63268_set_gpio(pc, offset);
650 +
651 + return 0;
652 +}
653 +
654 +static struct pinctrl_ops bcm63268_pctl_ops = {
655 + .dt_free_map = pinctrl_utils_free_map,
656 + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
657 + .get_group_name = bcm63268_pinctrl_get_group_name,
658 + .get_group_pins = bcm63268_pinctrl_get_group_pins,
659 + .get_groups_count = bcm63268_pinctrl_get_group_count,
660 +};
661 +
662 +static struct pinmux_ops bcm63268_pmx_ops = {
663 + .get_function_groups = bcm63268_pinctrl_get_groups,
664 + .get_function_name = bcm63268_pinctrl_get_func_name,
665 + .get_functions_count = bcm63268_pinctrl_get_func_count,
666 + .gpio_request_enable = bcm63268_gpio_request_enable,
667 + .set_mux = bcm63268_pinctrl_set_mux,
668 + .strict = true,
669 +};
670 +
671 +static const struct bcm63xx_pinctrl_soc bcm63268_soc = {
672 + .ngpios = BCM63268_NUM_GPIOS,
673 + .npins = ARRAY_SIZE(bcm63268_pins),
674 + .pctl_ops = &bcm63268_pctl_ops,
675 + .pins = bcm63268_pins,
676 + .pmx_ops = &bcm63268_pmx_ops,
677 +};
678 +
679 +static int bcm63268_pinctrl_probe(struct platform_device *pdev)
680 +{
681 + return bcm63xx_pinctrl_probe(pdev, &bcm63268_soc, NULL);
682 +}
683 +
684 +static const struct of_device_id bcm63268_pinctrl_match[] = {
685 + { .compatible = "brcm,bcm63268-pinctrl", },
686 + { /* sentinel */ }
687 +};
688 +
689 +static struct platform_driver bcm63268_pinctrl_driver = {
690 + .probe = bcm63268_pinctrl_probe,
691 + .driver = {
692 + .name = "bcm63268-pinctrl",
693 + .of_match_table = bcm63268_pinctrl_match,
694 + },
695 +};
696 +
697 +builtin_platform_driver(bcm63268_pinctrl_driver);