]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
pinctrl: armada-37xx: Add pin controller support for Armada 37xx
[mirror_ubuntu-jammy-kernel.git] / drivers / pinctrl / mvebu / pinctrl-armada-37xx.c
CommitLineData
87466ccd
GC
1/*
2 * Marvell 37xx SoC pinctrl driver
3 *
4 * Copyright (C) 2017 Marvell
5 *
6 * Gregory CLEMENT <gregory.clement@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2 or later. This program is licensed "as is"
10 * without any warranty of any kind, whether express or implied.
11 */
12
13#include <linux/mfd/syscon.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/pinctrl/pinconf-generic.h>
17#include <linux/pinctrl/pinconf.h>
18#include <linux/pinctrl/pinctrl.h>
19#include <linux/pinctrl/pinmux.h>
20#include <linux/platform_device.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23
24#include "../pinctrl-utils.h"
25
26#define OUTPUT_EN 0x0
27#define OUTPUT_CTL 0x20
28#define SELECTION 0x30
29
30#define NB_FUNCS 2
31#define GPIO_PER_REG 32
32
33/**
34 * struct armada_37xx_pin_group: represents group of pins of a pinmux function.
35 * The pins of a pinmux groups are composed of one or two groups of contiguous
36 * pins.
37 * @name: Name of the pin group, used to lookup the group.
38 * @start_pins: Index of the first pin of the main range of pins belonging to
39 * the group
40 * @npins: Number of pins included in the first range
41 * @reg_mask: Bit mask matching the group in the selection register
42 * @extra_pins: Index of the first pin of the optional second range of pins
43 * belonging to the group
44 * @npins: Number of pins included in the second optional range
45 * @funcs: A list of pinmux functions that can be selected for this group.
46 * @pins: List of the pins included in the group
47 */
48struct armada_37xx_pin_group {
49 const char *name;
50 unsigned int start_pin;
51 unsigned int npins;
52 u32 reg_mask;
53 u32 val[NB_FUNCS];
54 unsigned int extra_pin;
55 unsigned int extra_npins;
56 const char *funcs[NB_FUNCS];
57 unsigned int *pins;
58};
59
60struct armada_37xx_pin_data {
61 u8 nr_pins;
62 char *name;
63 struct armada_37xx_pin_group *groups;
64 int ngroups;
65};
66
67struct armada_37xx_pmx_func {
68 const char *name;
69 const char **groups;
70 unsigned int ngroups;
71};
72
73struct armada_37xx_pinctrl {
74 struct regmap *regmap;
75 const struct armada_37xx_pin_data *data;
76 struct device *dev;
77 struct pinctrl_desc pctl;
78 struct pinctrl_dev *pctl_dev;
79 struct armada_37xx_pin_group *groups;
80 unsigned int ngroups;
81 struct armada_37xx_pmx_func *funcs;
82 unsigned int nfuncs;
83};
84
85#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \
86 { \
87 .name = _name, \
88 .start_pin = _start, \
89 .npins = _nr, \
90 .reg_mask = _mask, \
91 .val = {0, _mask}, \
92 .funcs = {_func1, _func2} \
93 }
94
95#define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \
96 { \
97 .name = _name, \
98 .start_pin = _start, \
99 .npins = _nr, \
100 .reg_mask = _mask, \
101 .val = {0, _mask}, \
102 .funcs = {_func1, "gpio"} \
103 }
104
105#define PIN_GRP_GPIO_2(_name, _start, _nr, _mask, _val1, _val2, _func1) \
106 { \
107 .name = _name, \
108 .start_pin = _start, \
109 .npins = _nr, \
110 .reg_mask = _mask, \
111 .val = {_val1, _val2}, \
112 .funcs = {_func1, "gpio"} \
113 }
114
115#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
116 _f1, _f2) \
117 { \
118 .name = _name, \
119 .start_pin = _start, \
120 .npins = _nr, \
121 .reg_mask = _mask, \
122 .val = {_v1, _v2}, \
123 .extra_pin = _start2, \
124 .extra_npins = _nr2, \
125 .funcs = {_f1, _f2} \
126 }
127
128static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
129 PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
130 PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
131 PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
132 PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"),
133 PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
134 PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
135 PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
136 PIN_GRP_GPIO("pmic1", 17, 1, BIT(7), "pmic"),
137 PIN_GRP_GPIO("pmic0", 16, 1, BIT(8), "pmic"),
138 PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
139 PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
140 PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
141 PIN_GRP_GPIO_2("spi_cs2", 18, 1, BIT(13) | BIT(19), 0, BIT(13), "spi"),
142 PIN_GRP_GPIO_2("spi_cs3", 19, 1, BIT(14) | BIT(19), 0, BIT(14), "spi"),
143 PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
144 PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
145 PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
146 PIN_GRP_EXTRA("uart2", 9, 2, BIT(13) | BIT(14) | BIT(19),
147 BIT(13) | BIT(14), BIT(19), 18, 2, "gpio", "uart"),
148 PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
149 PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
150 PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
151 PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"),
152
153};
154
155static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
156 PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
157 PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
158 PIN_GRP_GPIO("sdio_sb", 24, 5, BIT(2), "sdio"),
159 PIN_GRP_EXTRA("rgmii", 6, 14, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
160 PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
161 PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
162 PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
163 PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
164 PIN_GRP("mii_col", 23, 1, BIT(8), "mii", "mii_err"),
165};
166
167const struct armada_37xx_pin_data armada_37xx_pin_nb = {
168 .nr_pins = 36,
169 .name = "GPIO1",
170 .groups = armada_37xx_nb_groups,
171 .ngroups = ARRAY_SIZE(armada_37xx_nb_groups),
172};
173
174const struct armada_37xx_pin_data armada_37xx_pin_sb = {
175 .nr_pins = 29,
176 .name = "GPIO2",
177 .groups = armada_37xx_sb_groups,
178 .ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
179};
180
181static int armada_37xx_get_func_reg(struct armada_37xx_pin_group *grp,
182 const char *func)
183{
184 int f;
185
186 for (f = 0; f < NB_FUNCS; f++)
187 if (!strcmp(grp->funcs[f], func))
188 return f;
189
190 return -ENOTSUPP;
191}
192
193static struct armada_37xx_pin_group *armada_37xx_find_next_grp_by_pin(
194 struct armada_37xx_pinctrl *info, int pin, int *grp)
195{
196 while (*grp < info->ngroups) {
197 struct armada_37xx_pin_group *group = &info->groups[*grp];
198 int j;
199
200 *grp = *grp + 1;
201 for (j = 0; j < (group->npins + group->extra_npins); j++)
202 if (group->pins[j] == pin)
203 return group;
204 }
205 return NULL;
206}
207
208static int armada_37xx_pin_config_group_get(struct pinctrl_dev *pctldev,
209 unsigned int selector, unsigned long *config)
210{
211 return -ENOTSUPP;
212}
213
214static int armada_37xx_pin_config_group_set(struct pinctrl_dev *pctldev,
215 unsigned int selector, unsigned long *configs,
216 unsigned int num_configs)
217{
218 return -ENOTSUPP;
219}
220
221static struct pinconf_ops armada_37xx_pinconf_ops = {
222 .is_generic = true,
223 .pin_config_group_get = armada_37xx_pin_config_group_get,
224 .pin_config_group_set = armada_37xx_pin_config_group_set,
225};
226
227static int armada_37xx_get_groups_count(struct pinctrl_dev *pctldev)
228{
229 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
230
231 return info->ngroups;
232}
233
234static const char *armada_37xx_get_group_name(struct pinctrl_dev *pctldev,
235 unsigned int group)
236{
237 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
238
239 return info->groups[group].name;
240}
241
242static int armada_37xx_get_group_pins(struct pinctrl_dev *pctldev,
243 unsigned int selector,
244 const unsigned int **pins,
245 unsigned int *npins)
246{
247 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
248
249 if (selector >= info->ngroups)
250 return -EINVAL;
251
252 *pins = info->groups[selector].pins;
253 *npins = info->groups[selector].npins +
254 info->groups[selector].extra_npins;
255
256 return 0;
257}
258
259static const struct pinctrl_ops armada_37xx_pctrl_ops = {
260 .get_groups_count = armada_37xx_get_groups_count,
261 .get_group_name = armada_37xx_get_group_name,
262 .get_group_pins = armada_37xx_get_group_pins,
263 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
264 .dt_free_map = pinctrl_utils_free_map,
265};
266
267/*
268 * Pinmux_ops handling
269 */
270
271static int armada_37xx_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
272{
273 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
274
275 return info->nfuncs;
276}
277
278static const char *armada_37xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
279 unsigned int selector)
280{
281 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
282
283 return info->funcs[selector].name;
284}
285
286static int armada_37xx_pmx_get_groups(struct pinctrl_dev *pctldev,
287 unsigned int selector,
288 const char * const **groups,
289 unsigned int * const num_groups)
290{
291 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
292
293 *groups = info->funcs[selector].groups;
294 *num_groups = info->funcs[selector].ngroups;
295
296 return 0;
297}
298
299static int armada_37xx_pmx_set_by_name(struct pinctrl_dev *pctldev,
300 const char *name,
301 struct armada_37xx_pin_group *grp)
302{
303 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
304 unsigned int reg = SELECTION;
305 unsigned int mask = grp->reg_mask;
306 int func, val;
307
308 dev_dbg(info->dev, "enable function %s group %s\n",
309 name, grp->name);
310
311 func = armada_37xx_get_func_reg(grp, name);
312
313 if (func < 0)
314 return func;
315
316 val = grp->val[func];
317
318 regmap_update_bits(info->regmap, reg, mask, val);
319
320 return 0;
321}
322
323static int armada_37xx_pmx_set(struct pinctrl_dev *pctldev,
324 unsigned int selector,
325 unsigned int group)
326{
327
328 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
329 struct armada_37xx_pin_group *grp = &info->groups[group];
330 const char *name = info->funcs[selector].name;
331
332 return armada_37xx_pmx_set_by_name(pctldev, name, grp);
333}
334
335static int armada_37xx_pmx_direction_input(struct armada_37xx_pinctrl *info,
336 unsigned int offset)
337{
338 unsigned int reg = OUTPUT_EN;
339 unsigned int mask;
340
341 if (offset >= GPIO_PER_REG) {
342 offset -= GPIO_PER_REG;
343 reg += sizeof(u32);
344 }
345 mask = BIT(offset);
346
347 return regmap_update_bits(info->regmap, reg, mask, 0);
348}
349
350static int armada_37xx_pmx_direction_output(struct armada_37xx_pinctrl *info,
351 unsigned int offset, int value)
352{
353 unsigned int reg = OUTPUT_EN;
354 unsigned int mask;
355
356 if (offset >= GPIO_PER_REG) {
357 offset -= GPIO_PER_REG;
358 reg += sizeof(u32);
359 }
360 mask = BIT(offset);
361
362 return regmap_update_bits(info->regmap, reg, mask, mask);
363}
364
365static int armada_37xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
366 struct pinctrl_gpio_range *range,
367 unsigned int offset, bool input)
368{
369 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
370
371 dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
372 offset, range->name, offset, input ? "input" : "output");
373
374 if (input)
375 armada_37xx_pmx_direction_input(info, offset);
376 else
377 armada_37xx_pmx_direction_output(info, offset, 0);
378
379 return 0;
380}
381
382static int armada_37xx_gpio_request_enable(struct pinctrl_dev *pctldev,
383 struct pinctrl_gpio_range *range,
384 unsigned int offset)
385{
386 struct armada_37xx_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
387 struct armada_37xx_pin_group *group;
388 int grp = 0;
389
390 dev_dbg(info->dev, "requesting gpio %d\n", offset);
391
392 while ((group = armada_37xx_find_next_grp_by_pin(info, offset, &grp)))
393 armada_37xx_pmx_set_by_name(pctldev, "gpio", group);
394
395 return 0;
396}
397
398static const struct pinmux_ops armada_37xx_pmx_ops = {
399 .get_functions_count = armada_37xx_pmx_get_funcs_count,
400 .get_function_name = armada_37xx_pmx_get_func_name,
401 .get_function_groups = armada_37xx_pmx_get_groups,
402 .set_mux = armada_37xx_pmx_set,
403 .gpio_request_enable = armada_37xx_gpio_request_enable,
404 .gpio_set_direction = armada_37xx_pmx_gpio_set_direction,
405};
406
407/**
408 * armada_37xx_add_function() - Add a new function to the list
409 * @funcs: array of function to add the new one
410 * @funcsize: size of the remaining space for the function
411 * @name: name of the function to add
412 *
413 * If it is a new function then create it by adding its name else
414 * increment the number of group associated to this function.
415 */
416static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
417 int *funcsize, const char *name)
418{
419 int i = 0;
420
421 if (*funcsize <= 0)
422 return -EOVERFLOW;
423
424 while (funcs->ngroups) {
425 /* function already there */
426 if (strcmp(funcs->name, name) == 0) {
427 funcs->ngroups++;
428
429 return -EEXIST;
430 }
431 funcs++;
432 i++;
433 }
434
435 /* append new unique function */
436 funcs->name = name;
437 funcs->ngroups = 1;
438 (*funcsize)--;
439
440 return 0;
441}
442
443/**
444 * armada_37xx_fill_group() - complete the group array
445 * @info: info driver instance
446 *
447 * Based on the data available from the armada_37xx_pin_group array
448 * completes the last member of the struct for each function: the list
449 * of the groups associated to this function.
450 *
451 */
452static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
453{
454 int n, num = 0, funcsize = info->data->nr_pins;
455
456 for (n = 0; n < info->ngroups; n++) {
457 struct armada_37xx_pin_group *grp = &info->groups[n];
458 int i, j, f;
459
460 grp->pins = devm_kzalloc(info->dev,
461 (grp->npins + grp->extra_npins) *
462 sizeof(*grp->pins), GFP_KERNEL);
463 if (!grp->pins)
464 return -ENOMEM;
465
466 for (i = 0; i < grp->npins; i++)
467 grp->pins[i] = grp->start_pin + i;
468
469 for (j = 0; j < grp->extra_npins; j++)
470 grp->pins[i+j] = grp->extra_pin + j;
471
472 for (f = 0; f < NB_FUNCS; f++) {
473 int ret;
474 /* check for unique functions and count groups */
475 ret = armada_37xx_add_function(info->funcs, &funcsize,
476 grp->funcs[f]);
477 if (ret == -EOVERFLOW)
478 dev_err(info->dev,
479 "More functions than pins(%d)\n",
480 info->data->nr_pins);
481 if (ret < 0)
482 continue;
483 num++;
484 }
485 }
486
487 info->nfuncs = num;
488
489 return 0;
490}
491
492/**
493 * armada_37xx_fill_funcs() - complete the funcs array
494 * @info: info driver instance
495 *
496 * Based on the data available from the armada_37xx_pin_group array
497 * completes the last two member of the struct for each group:
498 * - the list of the pins included in the group
499 * - the list of pinmux functions that can be selected for this group
500 *
501 */
502static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
503{
504 struct armada_37xx_pmx_func *funcs = info->funcs;
505 int n;
506
507 for (n = 0; n < info->nfuncs; n++) {
508 const char *name = funcs[n].name;
509 const char **groups;
510 int g;
511
512 funcs[n].groups = devm_kzalloc(info->dev, funcs[n].ngroups *
513 sizeof(*(funcs[n].groups)),
514 GFP_KERNEL);
515 if (!funcs[n].groups)
516 return -ENOMEM;
517
518 groups = funcs[n].groups;
519
520 for (g = 0; g < info->ngroups; g++) {
521 struct armada_37xx_pin_group *gp = &info->groups[g];
522 int f;
523
524 for (f = 0; f < NB_FUNCS; f++) {
525 if (strcmp(gp->funcs[f], name) == 0) {
526 *groups = gp->name;
527 groups++;
528 }
529 }
530 }
531 }
532 return 0;
533}
534
535static int armada_37xx_pinctrl_register(struct platform_device *pdev,
536 struct armada_37xx_pinctrl *info)
537{
538 const struct armada_37xx_pin_data *pin_data = info->data;
539 struct pinctrl_desc *ctrldesc = &info->pctl;
540 struct pinctrl_pin_desc *pindesc, *pdesc;
541 int pin, ret;
542
543 info->groups = pin_data->groups;
544 info->ngroups = pin_data->ngroups;
545
546 ctrldesc->name = "armada_37xx-pinctrl";
547 ctrldesc->owner = THIS_MODULE;
548 ctrldesc->pctlops = &armada_37xx_pctrl_ops;
549 ctrldesc->pmxops = &armada_37xx_pmx_ops;
550 ctrldesc->confops = &armada_37xx_pinconf_ops;
551
552 pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
553 pin_data->nr_pins, GFP_KERNEL);
554 if (!pindesc)
555 return -ENOMEM;
556
557 ctrldesc->pins = pindesc;
558 ctrldesc->npins = pin_data->nr_pins;
559
560 pdesc = pindesc;
561 for (pin = 0; pin < pin_data->nr_pins; pin++) {
562 pdesc->number = pin;
563 pdesc->name = kasprintf(GFP_KERNEL, "%s-%d",
564 pin_data->name, pin);
565 pdesc++;
566 }
567
568 /*
569 * we allocate functions for number of pins and hope there are
570 * fewer unique functions than pins available
571 */
572 info->funcs = devm_kzalloc(&pdev->dev, pin_data->nr_pins *
573 sizeof(struct armada_37xx_pmx_func), GFP_KERNEL);
574 if (!info->funcs)
575 return -ENOMEM;
576
577
578 ret = armada_37xx_fill_group(info);
579 if (ret)
580 return ret;
581
582 ret = armada_37xx_fill_func(info);
583 if (ret)
584 return ret;
585
586 info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info);
587 if (IS_ERR(info->pctl_dev)) {
588 dev_err(&pdev->dev, "could not register pinctrl driver\n");
589 return PTR_ERR(info->pctl_dev);
590 }
591
592 return 0;
593}
594
595static const struct of_device_id armada_37xx_pinctrl_of_match[] = {
596 {
597 .compatible = "marvell,armada3710-sb-pinctrl",
598 .data = (void *)&armada_37xx_pin_sb,
599 },
600 {
601 .compatible = "marvell,armada3710-nb-pinctrl",
602 .data = (void *)&armada_37xx_pin_nb,
603 },
604 { },
605};
606
607static int __init armada_37xx_pinctrl_probe(struct platform_device *pdev)
608{
609 struct armada_37xx_pinctrl *info;
610 struct device *dev = &pdev->dev;
611 struct device_node *np = dev->of_node;
612 struct regmap *regmap;
613 int ret;
614
615 info = devm_kzalloc(dev, sizeof(struct armada_37xx_pinctrl),
616 GFP_KERNEL);
617 if (!info)
618 return -ENOMEM;
619
620 info->dev = dev;
621
622 regmap = syscon_node_to_regmap(np);
623 if (IS_ERR(regmap)) {
624 dev_err(&pdev->dev, "cannot get regmap\n");
625 return PTR_ERR(regmap);
626 }
627 info->regmap = regmap;
628
629 info->data = of_device_get_match_data(dev);
630
631 ret = armada_37xx_pinctrl_register(pdev, info);
632 if (ret)
633 return ret;
634
635 platform_set_drvdata(pdev, info);
636
637 return 0;
638}
639
640static struct platform_driver armada_37xx_pinctrl_driver = {
641 .driver = {
642 .name = "armada-37xx-pinctrl",
643 .of_match_table = armada_37xx_pinctrl_of_match,
644 },
645};
646
647builtin_platform_driver_probe(armada_37xx_pinctrl_driver,
648 armada_37xx_pinctrl_probe);