1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Marvell MVEBU pinctrl core driver
4 *
5 * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
6 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
7 */
8
9#include <linux/err.h>
10#include <linux/gpio/driver.h>
11#include <linux/io.h>
12#include <linux/mfd/syscon.h>
13#include <linux/of.h>
14#include <linux/platform_device.h>
15#include <linux/regmap.h>
16#include <linux/seq_file.h>
17#include <linux/slab.h>
18
19#include <linux/pinctrl/machine.h>
20#include <linux/pinctrl/pinconf.h>
21#include <linux/pinctrl/pinctrl.h>
22#include <linux/pinctrl/pinmux.h>
23
24#include "pinctrl-mvebu.h"
25
26#define MPPS_PER_REG 8
27#define MPP_BITS 4
28#define MPP_MASK 0xf
29
30struct mvebu_pinctrl_function {
31 const char *name;
32 const char **groups;
33 unsigned num_groups;
34};
35
36struct mvebu_pinctrl_group {
37 const char *name;
38 const struct mvebu_mpp_ctrl *ctrl;
39 struct mvebu_mpp_ctrl_data *data;
40 struct mvebu_mpp_ctrl_setting *settings;
41 unsigned num_settings;
42 unsigned gid;
43 unsigned *pins;
44 unsigned npins;
45};
46
47struct mvebu_pinctrl {
48 struct device *dev;
49 struct pinctrl_dev *pctldev;
50 struct pinctrl_desc desc;
51 struct mvebu_pinctrl_group *groups;
52 unsigned num_groups;
53 struct mvebu_pinctrl_function *functions;
54 unsigned num_functions;
55 u8 variant;
56};
57
58int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
59 unsigned int pid, unsigned long *config)
60{
61 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
62 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
63
64 *config = (readl(addr: data->base + off) >> shift) & MVEBU_MPP_MASK;
65
66 return 0;
67}
68
69int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
70 unsigned int pid, unsigned long config)
71{
72 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
73 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
74 unsigned long reg;
75
76 reg = readl(addr: data->base + off) & ~(MVEBU_MPP_MASK << shift);
77 writel(val: reg | (config << shift), addr: data->base + off);
78
79 return 0;
80}
81
82static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
83 struct mvebu_pinctrl *pctl, unsigned pid)
84{
85 unsigned n;
86 for (n = 0; n < pctl->num_groups; n++) {
87 if (pid >= pctl->groups[n].pins[0] &&
88 pid < pctl->groups[n].pins[0] +
89 pctl->groups[n].npins)
90 return &pctl->groups[n];
91 }
92 return NULL;
93}
94
95static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name(
96 struct mvebu_pinctrl *pctl, const char *name)
97{
98 unsigned n;
99
100 for (n = 0; n < pctl->num_groups; n++) {
101 if (strcmp(name, pctl->groups[n].name) == 0)
102 return &pctl->groups[n];
103 }
104
105 return NULL;
106}
107
108static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val(
109 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
110 unsigned long config)
111{
112 unsigned n;
113
114 for (n = 0; n < grp->num_settings; n++) {
115 if (config == grp->settings[n].val) {
116 if (!pctl->variant || (pctl->variant &
117 grp->settings[n].variant))
118 return &grp->settings[n];
119 }
120 }
121
122 return NULL;
123}
124
125static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name(
126 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp,
127 const char *name)
128{
129 unsigned n;
130
131 for (n = 0; n < grp->num_settings; n++) {
132 if (strcmp(name, grp->settings[n].name) == 0) {
133 if (!pctl->variant || (pctl->variant &
134 grp->settings[n].variant))
135 return &grp->settings[n];
136 }
137 }
138
139 return NULL;
140}
141
142static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting(
143 struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp)
144{
145 unsigned n;
146
147 for (n = 0; n < grp->num_settings; n++) {
148 if (grp->settings[n].flags &
149 (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
150 if (!pctl->variant || (pctl->variant &
151 grp->settings[n].variant))
152 return &grp->settings[n];
153 }
154 }
155
156 return NULL;
157}
158
159static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
160 struct mvebu_pinctrl *pctl, const char *name)
161{
162 unsigned n;
163
164 for (n = 0; n < pctl->num_functions; n++) {
165 if (strcmp(name, pctl->functions[n].name) == 0)
166 return &pctl->functions[n];
167 }
168
169 return NULL;
170}
171
172static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
173 unsigned gid, unsigned long *config)
174{
175 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
176 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
177
178 if (!grp->ctrl)
179 return -EINVAL;
180
181 return grp->ctrl->mpp_get(grp->data, grp->pins[0], config);
182}
183
184static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
185 unsigned gid, unsigned long *configs,
186 unsigned num_configs)
187{
188 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
189 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
190 int i, ret;
191
192 if (!grp->ctrl)
193 return -EINVAL;
194
195 for (i = 0; i < num_configs; i++) {
196 ret = grp->ctrl->mpp_set(grp->data, grp->pins[0], configs[i]);
197 if (ret)
198 return ret;
199 } /* for each config */
200
201 return 0;
202}
203
204static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
205 struct seq_file *s, unsigned gid)
206{
207 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
208 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
209 struct mvebu_mpp_ctrl_setting *curr;
210 unsigned long config;
211 unsigned n;
212
213 if (mvebu_pinconf_group_get(pctldev, gid, config: &config))
214 return;
215
216 curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config);
217
218 if (curr) {
219 seq_printf(m: s, fmt: "current: %s", curr->name);
220 if (curr->subname)
221 seq_printf(m: s, fmt: "(%s)", curr->subname);
222 if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
223 seq_putc(m: s, c: '(');
224 if (curr->flags & MVEBU_SETTING_GPI)
225 seq_putc(m: s, c: 'i');
226 if (curr->flags & MVEBU_SETTING_GPO)
227 seq_putc(m: s, c: 'o');
228 seq_putc(m: s, c: ')');
229 }
230 } else {
231 seq_puts(m: s, s: "current: UNKNOWN");
232 }
233
234 if (grp->num_settings > 1) {
235 seq_puts(m: s, s: ", available = [");
236 for (n = 0; n < grp->num_settings; n++) {
237 if (curr == &grp->settings[n])
238 continue;
239
240 /* skip unsupported settings for this variant */
241 if (pctl->variant &&
242 !(pctl->variant & grp->settings[n].variant))
243 continue;
244
245 seq_printf(m: s, fmt: " %s", grp->settings[n].name);
246 if (grp->settings[n].subname)
247 seq_printf(m: s, fmt: "(%s)", grp->settings[n].subname);
248 if (grp->settings[n].flags &
249 (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) {
250 seq_putc(m: s, c: '(');
251 if (grp->settings[n].flags & MVEBU_SETTING_GPI)
252 seq_putc(m: s, c: 'i');
253 if (grp->settings[n].flags & MVEBU_SETTING_GPO)
254 seq_putc(m: s, c: 'o');
255 seq_putc(m: s, c: ')');
256 }
257 }
258 seq_puts(m: s, s: " ]");
259 }
260}
261
262static const struct pinconf_ops mvebu_pinconf_ops = {
263 .pin_config_group_get = mvebu_pinconf_group_get,
264 .pin_config_group_set = mvebu_pinconf_group_set,
265 .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show,
266};
267
268static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev)
269{
270 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
271
272 return pctl->num_functions;
273}
274
275static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev,
276 unsigned fid)
277{
278 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
279
280 return pctl->functions[fid].name;
281}
282
283static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid,
284 const char * const **groups,
285 unsigned * const num_groups)
286{
287 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
288
289 *groups = pctl->functions[fid].groups;
290 *num_groups = pctl->functions[fid].num_groups;
291 return 0;
292}
293
294static int mvebu_pinmux_set(struct pinctrl_dev *pctldev, unsigned fid,
295 unsigned gid)
296{
297 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
298 struct mvebu_pinctrl_function *func = &pctl->functions[fid];
299 struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
300 struct mvebu_mpp_ctrl_setting *setting;
301 int ret;
302 unsigned long config;
303
304 setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
305 name: func->name);
306 if (!setting) {
307 dev_err(pctl->dev,
308 "unable to find setting %s in group %s\n",
309 func->name, func->groups[gid]);
310 return -EINVAL;
311 }
312
313 config = setting->val;
314 ret = mvebu_pinconf_group_set(pctldev, gid: grp->gid, configs: &config, num_configs: 1);
315 if (ret) {
316 dev_err(pctl->dev, "cannot set group %s to %s\n",
317 func->groups[gid], func->name);
318 return ret;
319 }
320
321 return 0;
322}
323
324static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
325 struct pinctrl_gpio_range *range, unsigned offset)
326{
327 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
328 struct mvebu_pinctrl_group *grp;
329 struct mvebu_mpp_ctrl_setting *setting;
330 unsigned long config;
331
332 grp = mvebu_pinctrl_find_group_by_pid(pctl, pid: offset);
333 if (!grp)
334 return -EINVAL;
335
336 if (grp->ctrl->mpp_gpio_req)
337 return grp->ctrl->mpp_gpio_req(grp->data, offset);
338
339 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
340 if (!setting)
341 return -ENOTSUPP;
342
343 config = setting->val;
344
345 return mvebu_pinconf_group_set(pctldev, gid: grp->gid, configs: &config, num_configs: 1);
346}
347
348static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
349 struct pinctrl_gpio_range *range, unsigned offset, bool input)
350{
351 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
352 struct mvebu_pinctrl_group *grp;
353 struct mvebu_mpp_ctrl_setting *setting;
354
355 grp = mvebu_pinctrl_find_group_by_pid(pctl, pid: offset);
356 if (!grp)
357 return -EINVAL;
358
359 if (grp->ctrl->mpp_gpio_dir)
360 return grp->ctrl->mpp_gpio_dir(grp->data, offset, input);
361
362 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
363 if (!setting)
364 return -ENOTSUPP;
365
366 if ((input && (setting->flags & MVEBU_SETTING_GPI)) ||
367 (!input && (setting->flags & MVEBU_SETTING_GPO)))
368 return 0;
369
370 return -ENOTSUPP;
371}
372
373static const struct pinmux_ops mvebu_pinmux_ops = {
374 .get_functions_count = mvebu_pinmux_get_funcs_count,
375 .get_function_name = mvebu_pinmux_get_func_name,
376 .get_function_groups = mvebu_pinmux_get_groups,
377 .gpio_request_enable = mvebu_pinmux_gpio_request_enable,
378 .gpio_set_direction = mvebu_pinmux_gpio_set_direction,
379 .set_mux = mvebu_pinmux_set,
380};
381
382static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
383{
384 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
385 return pctl->num_groups;
386}
387
388static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
389 unsigned gid)
390{
391 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
392 return pctl->groups[gid].name;
393}
394
395static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
396 unsigned gid, const unsigned **pins,
397 unsigned *num_pins)
398{
399 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
400 *pins = pctl->groups[gid].pins;
401 *num_pins = pctl->groups[gid].npins;
402 return 0;
403}
404
405static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
406 struct device_node *np,
407 struct pinctrl_map **map,
408 unsigned *num_maps)
409{
410 struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
411 struct property *prop;
412 const char *function;
413 const char *group;
414 int ret, nmaps, n;
415
416 *map = NULL;
417 *num_maps = 0;
418
419 ret = of_property_read_string(np, propname: "marvell,function", out_string: &function);
420 if (ret) {
421 dev_err(pctl->dev,
422 "missing marvell,function in node %pOFn\n", np);
423 return 0;
424 }
425
426 nmaps = of_property_count_strings(np, propname: "marvell,pins");
427 if (nmaps < 0) {
428 dev_err(pctl->dev,
429 "missing marvell,pins in node %pOFn\n", np);
430 return 0;
431 }
432
433 *map = kmalloc_array(n: nmaps, size: sizeof(**map), GFP_KERNEL);
434 if (!*map)
435 return -ENOMEM;
436
437 n = 0;
438 of_property_for_each_string(np, "marvell,pins", prop, group) {
439 struct mvebu_pinctrl_group *grp =
440 mvebu_pinctrl_find_group_by_name(pctl, name: group);
441
442 if (!grp) {
443 dev_err(pctl->dev, "unknown pin %s", group);
444 continue;
445 }
446
447 if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, name: function)) {
448 dev_err(pctl->dev, "unsupported function %s on pin %s",
449 function, group);
450 continue;
451 }
452
453 (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP;
454 (*map)[n].data.mux.group = group;
455 (*map)[n].data.mux.function = function;
456 n++;
457 }
458
459 *num_maps = nmaps;
460
461 return 0;
462}
463
464static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
465 struct pinctrl_map *map, unsigned num_maps)
466{
467 kfree(objp: map);
468}
469
470static const struct pinctrl_ops mvebu_pinctrl_ops = {
471 .get_groups_count = mvebu_pinctrl_get_groups_count,
472 .get_group_name = mvebu_pinctrl_get_group_name,
473 .get_group_pins = mvebu_pinctrl_get_group_pins,
474 .dt_node_to_map = mvebu_pinctrl_dt_node_to_map,
475 .dt_free_map = mvebu_pinctrl_dt_free_map,
476};
477
478static int _add_function(struct mvebu_pinctrl_function *funcs, int *funcsize,
479 const char *name)
480{
481 if (*funcsize <= 0)
482 return -EOVERFLOW;
483
484 while (funcs->num_groups) {
485 /* function already there */
486 if (strcmp(funcs->name, name) == 0) {
487 funcs->num_groups++;
488 return -EEXIST;
489 }
490 funcs++;
491 }
492
493 /* append new unique function */
494 funcs->name = name;
495 funcs->num_groups = 1;
496 (*funcsize)--;
497
498 return 0;
499}
500
501static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
502 struct mvebu_pinctrl *pctl)
503{
504 struct mvebu_pinctrl_function *funcs;
505 int num = 0, funcsize = pctl->desc.npins;
506 int n, s;
507
508 /* we allocate functions for number of pins and hope
509 * there are fewer unique functions than pins available */
510 funcs = devm_kcalloc(dev: &pdev->dev,
511 n: funcsize, size: sizeof(struct mvebu_pinctrl_function),
512 GFP_KERNEL);
513 if (!funcs)
514 return -ENOMEM;
515
516 for (n = 0; n < pctl->num_groups; n++) {
517 struct mvebu_pinctrl_group *grp = &pctl->groups[n];
518 for (s = 0; s < grp->num_settings; s++) {
519 int ret;
520
521 /* skip unsupported settings on this variant */
522 if (pctl->variant &&
523 !(pctl->variant & grp->settings[s].variant))
524 continue;
525
526 /* check for unique functions and count groups */
527 ret = _add_function(funcs, funcsize: &funcsize,
528 name: grp->settings[s].name);
529 if (ret == -EOVERFLOW)
530 dev_err(&pdev->dev,
531 "More functions than pins(%d)\n",
532 pctl->desc.npins);
533 if (ret < 0)
534 continue;
535
536 num++;
537 }
538 }
539
540 pctl->num_functions = num;
541 pctl->functions = funcs;
542
543 for (n = 0; n < pctl->num_groups; n++) {
544 struct mvebu_pinctrl_group *grp = &pctl->groups[n];
545 for (s = 0; s < grp->num_settings; s++) {
546 struct mvebu_pinctrl_function *f;
547 const char **groups;
548
549 /* skip unsupported settings on this variant */
550 if (pctl->variant &&
551 !(pctl->variant & grp->settings[s].variant))
552 continue;
553
554 f = mvebu_pinctrl_find_function_by_name(pctl,
555 name: grp->settings[s].name);
556
557 /* allocate group name array if not done already */
558 if (!f->groups) {
559 f->groups = devm_kcalloc(dev: &pdev->dev,
560 n: f->num_groups,
561 size: sizeof(char *),
562 GFP_KERNEL);
563 if (!f->groups)
564 return -ENOMEM;
565 }
566
567 /* find next free group name and assign current name */
568 groups = f->groups;
569 while (*groups)
570 groups++;
571 *groups = grp->name;
572 }
573 }
574
575 return 0;
576}
577
578int mvebu_pinctrl_probe(struct platform_device *pdev)
579{
580 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(dev: &pdev->dev);
581 struct mvebu_pinctrl *pctl;
582 struct pinctrl_pin_desc *pdesc;
583 unsigned gid, n, k;
584 unsigned size, noname = 0;
585 char *noname_buf;
586 void *p;
587 int ret;
588
589 if (!soc || !soc->controls || !soc->modes) {
590 dev_err(&pdev->dev, "wrong pinctrl soc info\n");
591 return -EINVAL;
592 }
593
594 pctl = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct mvebu_pinctrl),
595 GFP_KERNEL);
596 if (!pctl)
597 return -ENOMEM;
598
599 pctl->desc.name = dev_name(dev: &pdev->dev);
600 pctl->desc.owner = THIS_MODULE;
601 pctl->desc.pctlops = &mvebu_pinctrl_ops;
602 pctl->desc.pmxops = &mvebu_pinmux_ops;
603 pctl->desc.confops = &mvebu_pinconf_ops;
604 pctl->variant = soc->variant;
605 pctl->dev = &pdev->dev;
606 platform_set_drvdata(pdev, data: pctl);
607
608 /* count controls and create names for mvebu generic
609 register controls; also does sanity checks */
610 pctl->num_groups = 0;
611 pctl->desc.npins = 0;
612 for (n = 0; n < soc->ncontrols; n++) {
613 const struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
614
615 pctl->desc.npins += ctrl->npins;
616 /* initialize control's pins[] array */
617 for (k = 0; k < ctrl->npins; k++)
618 ctrl->pins[k] = ctrl->pid + k;
619
620 /*
621 * We allow to pass controls with NULL name that we treat
622 * as a range of one-pin groups with generic mvebu register
623 * controls.
624 */
625 if (!ctrl->name) {
626 pctl->num_groups += ctrl->npins;
627 noname += ctrl->npins;
628 } else {
629 pctl->num_groups += 1;
630 }
631 }
632
633 pdesc = devm_kcalloc(dev: &pdev->dev,
634 n: pctl->desc.npins,
635 size: sizeof(struct pinctrl_pin_desc),
636 GFP_KERNEL);
637 if (!pdesc)
638 return -ENOMEM;
639
640 for (n = 0; n < pctl->desc.npins; n++)
641 pdesc[n].number = n;
642 pctl->desc.pins = pdesc;
643
644 /*
645 * allocate groups and name buffers for unnamed groups.
646 */
647 size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
648 p = devm_kzalloc(dev: &pdev->dev, size, GFP_KERNEL);
649 if (!p)
650 return -ENOMEM;
651
652 pctl->groups = p;
653 noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);
654
655 /* assign mpp controls to groups */
656 gid = 0;
657 for (n = 0; n < soc->ncontrols; n++) {
658 const struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
659 struct mvebu_mpp_ctrl_data *data = soc->control_data ?
660 &soc->control_data[n] : NULL;
661
662 pctl->groups[gid].gid = gid;
663 pctl->groups[gid].ctrl = ctrl;
664 pctl->groups[gid].data = data;
665 pctl->groups[gid].name = ctrl->name;
666 pctl->groups[gid].pins = ctrl->pins;
667 pctl->groups[gid].npins = ctrl->npins;
668
669 /*
670 * We treat unnamed controls as a range of one-pin groups
671 * with generic mvebu register controls. Use one group for
672 * each in this range and assign a default group name.
673 */
674 if (!ctrl->name) {
675 pctl->groups[gid].name = noname_buf;
676 pctl->groups[gid].npins = 1;
677 sprintf(buf: noname_buf, fmt: "mpp%d", ctrl->pid+0);
678 noname_buf += 8;
679
680 for (k = 1; k < ctrl->npins; k++) {
681 gid++;
682 pctl->groups[gid].gid = gid;
683 pctl->groups[gid].ctrl = ctrl;
684 pctl->groups[gid].data = data;
685 pctl->groups[gid].name = noname_buf;
686 pctl->groups[gid].pins = &ctrl->pins[k];
687 pctl->groups[gid].npins = 1;
688 sprintf(buf: noname_buf, fmt: "mpp%d", ctrl->pid+k);
689 noname_buf += 8;
690 }
691 }
692 gid++;
693 }
694
695 /* assign mpp modes to groups */
696 for (n = 0; n < soc->nmodes; n++) {
697 struct mvebu_mpp_mode *mode = &soc->modes[n];
698 struct mvebu_mpp_ctrl_setting *set = &mode->settings[0];
699 struct mvebu_pinctrl_group *grp;
700 unsigned num_settings;
701 unsigned supp_settings;
702
703 for (num_settings = 0, supp_settings = 0; ; set++) {
704 if (!set->name)
705 break;
706
707 num_settings++;
708
709 /* skip unsupported settings for this variant */
710 if (pctl->variant && !(pctl->variant & set->variant))
711 continue;
712
713 supp_settings++;
714
715 /* find gpio/gpo/gpi settings */
716 if (strcmp(set->name, "gpio") == 0)
717 set->flags = MVEBU_SETTING_GPI |
718 MVEBU_SETTING_GPO;
719 else if (strcmp(set->name, "gpo") == 0)
720 set->flags = MVEBU_SETTING_GPO;
721 else if (strcmp(set->name, "gpi") == 0)
722 set->flags = MVEBU_SETTING_GPI;
723 }
724
725 /* skip modes with no settings for this variant */
726 if (!supp_settings)
727 continue;
728
729 grp = mvebu_pinctrl_find_group_by_pid(pctl, pid: mode->pid);
730 if (!grp) {
731 dev_warn(&pdev->dev, "unknown pinctrl group %d\n",
732 mode->pid);
733 continue;
734 }
735
736 grp->settings = mode->settings;
737 grp->num_settings = num_settings;
738 }
739
740 ret = mvebu_pinctrl_build_functions(pdev, pctl);
741 if (ret) {
742 dev_err(&pdev->dev, "unable to build functions\n");
743 return ret;
744 }
745
746 pctl->pctldev = devm_pinctrl_register(dev: &pdev->dev, pctldesc: &pctl->desc, driver_data: pctl);
747 if (IS_ERR(ptr: pctl->pctldev)) {
748 dev_err(&pdev->dev, "unable to register pinctrl driver\n");
749 return PTR_ERR(ptr: pctl->pctldev);
750 }
751
752 dev_info(&pdev->dev, "registered pinctrl driver\n");
753
754 /* register gpio ranges */
755 for (n = 0; n < soc->ngpioranges; n++)
756 pinctrl_add_gpio_range(pctldev: pctl->pctldev, range: &soc->gpioranges[n]);
757
758 return 0;
759}
760
761/*
762 * mvebu_pinctrl_simple_mmio_probe - probe a simple mmio pinctrl
763 * @pdev: platform device (with platform data already attached)
764 *
765 * Initialise a simple (single base address) mmio pinctrl driver,
766 * assigning the MMIO base address to all mvebu mpp ctrl instances.
767 */
768int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev)
769{
770 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(dev: &pdev->dev);
771 struct mvebu_mpp_ctrl_data *mpp_data;
772 void __iomem *base;
773 int i;
774
775 base = devm_platform_ioremap_resource(pdev, index: 0);
776 if (IS_ERR(ptr: base))
777 return PTR_ERR(ptr: base);
778
779 mpp_data = devm_kcalloc(dev: &pdev->dev, n: soc->ncontrols, size: sizeof(*mpp_data),
780 GFP_KERNEL);
781 if (!mpp_data)
782 return -ENOMEM;
783
784 for (i = 0; i < soc->ncontrols; i++)
785 mpp_data[i].base = base;
786
787 soc->control_data = mpp_data;
788
789 return mvebu_pinctrl_probe(pdev);
790}
791
792int mvebu_regmap_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
793 unsigned int pid, unsigned long *config)
794{
795 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
796 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
797 unsigned int val;
798 int err;
799
800 err = regmap_read(map: data->regmap.map, reg: data->regmap.offset + off, val: &val);
801 if (err)
802 return err;
803
804 *config = (val >> shift) & MVEBU_MPP_MASK;
805
806 return 0;
807}
808
809int mvebu_regmap_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
810 unsigned int pid, unsigned long config)
811{
812 unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
813 unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
814
815 return regmap_update_bits(map: data->regmap.map, reg: data->regmap.offset + off,
816 MVEBU_MPP_MASK << shift, val: config << shift);
817}
818
819int mvebu_pinctrl_simple_regmap_probe(struct platform_device *pdev,
820 struct device *syscon_dev, u32 offset)
821{
822 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(dev: &pdev->dev);
823 struct mvebu_mpp_ctrl_data *mpp_data;
824 struct regmap *regmap;
825 int i;
826
827 regmap = syscon_node_to_regmap(np: syscon_dev->of_node);
828 if (IS_ERR(ptr: regmap))
829 return PTR_ERR(ptr: regmap);
830
831 mpp_data = devm_kcalloc(dev: &pdev->dev, n: soc->ncontrols, size: sizeof(*mpp_data),
832 GFP_KERNEL);
833 if (!mpp_data)
834 return -ENOMEM;
835
836 for (i = 0; i < soc->ncontrols; i++) {
837 mpp_data[i].regmap.map = regmap;
838 mpp_data[i].regmap.offset = offset;
839 }
840
841 soc->control_data = mpp_data;
842
843 return mvebu_pinctrl_probe(pdev);
844}
845

source code of linux/drivers/pinctrl/mvebu/pinctrl-mvebu.c