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