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