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