blob: 2dee79af17ebaf1cae4424b34ffd381ecf68093a [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Gregory CLEMENT08718062017-05-09 13:36:21 +02002/*
3 * U-Boot Marvell 37xx SoC pinctrl driver
4 *
5 * Copyright (C) 2017 Stefan Roese <sr@denx.de>
6 *
7 * This driver is based on the Linux driver version, which is:
8 * Copyright (C) 2017 Marvell
9 * Gregory CLEMENT <gregory.clement@free-electrons.com>
10 *
11 * Additionally parts are derived from the Meson U-Boot pinctrl driver,
12 * which is:
13 * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
14 * Based on code from Linux kernel:
15 * Copyright (C) 2016 Endless Mobile, Inc.
Gregory CLEMENT08718062017-05-09 13:36:21 +020016 * https://spdx.org/licenses
17 */
18
19#include <common.h>
20#include <config.h>
21#include <dm.h>
Simon Glass336d4612020-02-03 07:36:16 -070022#include <malloc.h>
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +020023#include <dm/device-internal.h>
Simon Glass336d4612020-02-03 07:36:16 -070024#include <dm/device_compat.h>
Simon Glass61b29b82020-02-03 07:36:15 -070025#include <dm/devres.h>
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +020026#include <dm/lists.h>
Gregory CLEMENT08718062017-05-09 13:36:21 +020027#include <dm/pinctrl.h>
28#include <dm/root.h>
29#include <errno.h>
30#include <fdtdec.h>
31#include <regmap.h>
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +020032#include <asm/gpio.h>
Gregory CLEMENT08718062017-05-09 13:36:21 +020033#include <asm/system.h>
34#include <asm/io.h>
Simon Glasscd93d622020-05-10 11:40:13 -060035#include <linux/bitops.h>
Simon Glass4d72caa2020-05-10 11:40:01 -060036#include <linux/libfdt.h>
Gregory CLEMENT08718062017-05-09 13:36:21 +020037
38DECLARE_GLOBAL_DATA_PTR;
39
40#define OUTPUT_EN 0x0
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +020041#define INPUT_VAL 0x10
42#define OUTPUT_VAL 0x18
Gregory CLEMENT08718062017-05-09 13:36:21 +020043#define OUTPUT_CTL 0x20
44#define SELECTION 0x30
45
46#define IRQ_EN 0x0
47#define IRQ_POL 0x08
48#define IRQ_STATUS 0x10
49#define IRQ_WKUP 0x18
50
Ken Ma23626ca2018-03-26 15:56:01 +080051#define NB_FUNCS 3
Gregory CLEMENT08718062017-05-09 13:36:21 +020052#define GPIO_PER_REG 32
53
54/**
55 * struct armada_37xx_pin_group: represents group of pins of a pinmux function.
56 * The pins of a pinmux groups are composed of one or two groups of contiguous
57 * pins.
58 * @name: Name of the pin group, used to lookup the group.
59 * @start_pins: Index of the first pin of the main range of pins belonging to
60 * the group
61 * @npins: Number of pins included in the first range
62 * @reg_mask: Bit mask matching the group in the selection register
63 * @extra_pins: Index of the first pin of the optional second range of pins
64 * belonging to the group
65 * @npins: Number of pins included in the second optional range
66 * @funcs: A list of pinmux functions that can be selected for this group.
67 * @pins: List of the pins included in the group
68 */
69struct armada_37xx_pin_group {
70 const char *name;
71 unsigned int start_pin;
72 unsigned int npins;
73 u32 reg_mask;
74 u32 val[NB_FUNCS];
75 unsigned int extra_pin;
76 unsigned int extra_npins;
77 const char *funcs[NB_FUNCS];
78 unsigned int *pins;
79};
80
81struct armada_37xx_pin_data {
82 u8 nr_pins;
83 char *name;
84 struct armada_37xx_pin_group *groups;
85 int ngroups;
86};
87
88struct armada_37xx_pmx_func {
89 const char *name;
90 const char **groups;
91 unsigned int ngroups;
92};
93
94struct armada_37xx_pinctrl {
95 void __iomem *base;
96 const struct armada_37xx_pin_data *data;
97 struct udevice *dev;
98 struct pinctrl_dev *pctl_dev;
99 struct armada_37xx_pin_group *groups;
100 unsigned int ngroups;
101 struct armada_37xx_pmx_func *funcs;
102 unsigned int nfuncs;
103};
104
105#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \
106 { \
107 .name = _name, \
108 .start_pin = _start, \
109 .npins = _nr, \
110 .reg_mask = _mask, \
111 .val = {0, _mask}, \
112 .funcs = {_func1, _func2} \
113 }
114
115#define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \
116 { \
117 .name = _name, \
118 .start_pin = _start, \
119 .npins = _nr, \
120 .reg_mask = _mask, \
121 .val = {0, _mask}, \
122 .funcs = {_func1, "gpio"} \
123 }
124
125#define PIN_GRP_GPIO_2(_name, _start, _nr, _mask, _val1, _val2, _func1) \
126 { \
127 .name = _name, \
128 .start_pin = _start, \
129 .npins = _nr, \
130 .reg_mask = _mask, \
131 .val = {_val1, _val2}, \
132 .funcs = {_func1, "gpio"} \
133 }
134
Ken Ma23626ca2018-03-26 15:56:01 +0800135#define PIN_GRP_GPIO_3(_name, _start, _nr, _mask, _v1, _v2, _v3, _f1, _f2) \
136 { \
137 .name = _name, \
138 .start_pin = _start, \
139 .npins = _nr, \
140 .reg_mask = _mask, \
141 .val = {_v1, _v2, _v3}, \
142 .funcs = {_f1, _f2, "gpio"} \
143 }
144
Gregory CLEMENT08718062017-05-09 13:36:21 +0200145#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
146 _f1, _f2) \
147 { \
148 .name = _name, \
149 .start_pin = _start, \
150 .npins = _nr, \
151 .reg_mask = _mask, \
152 .val = {_v1, _v2}, \
153 .extra_pin = _start2, \
154 .extra_npins = _nr2, \
155 .funcs = {_f1, _f2} \
156 }
157
158static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
159 PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
160 PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
161 PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
162 PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"),
163 PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
164 PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
165 PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
Ken Madc362352018-03-26 15:56:03 +0800166 PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"),
167 PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"),
Gregory CLEMENT08718062017-05-09 13:36:21 +0200168 PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
169 PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
170 PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
171 PIN_GRP_GPIO_2("spi_cs2", 18, 1, BIT(13) | BIT(19), 0, BIT(13), "spi"),
172 PIN_GRP_GPIO_2("spi_cs3", 19, 1, BIT(14) | BIT(19), 0, BIT(14), "spi"),
173 PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
174 PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
175 PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
Ken Mab5a6c942017-06-22 17:13:35 +0800176 PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19),
177 BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19),
178 18, 2, "gpio", "uart"),
Gregory CLEMENT08718062017-05-09 13:36:21 +0200179 PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
180 PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
181 PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
182 PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"),
183
184};
185
186static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
187 PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
188 PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
Ken Madc362352018-03-26 15:56:03 +0800189 PIN_GRP_GPIO("sdio_sb", 24, 6, BIT(2), "sdio"),
190 PIN_GRP_GPIO("rgmii", 6, 12, BIT(3), "mii"),
191 PIN_GRP_GPIO("smi", 18, 2, BIT(4), "smi"),
192 PIN_GRP_GPIO("pcie1", 3, 3, BIT(5) | BIT(9) | BIT(10), "pcie"),
193 PIN_GRP_GPIO("ptp", 20, 3, BIT(11) | BIT(12) | BIT(13), "ptp"),
Gregory CLEMENT08718062017-05-09 13:36:21 +0200194 PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
195 PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
Ken Ma23626ca2018-03-26 15:56:01 +0800196 PIN_GRP_GPIO_3("mii_col", 23, 1, BIT(8) | BIT(14), 0, BIT(8), BIT(14),
197 "mii", "mii_err"),
Gregory CLEMENT08718062017-05-09 13:36:21 +0200198};
199
200const struct armada_37xx_pin_data armada_37xx_pin_nb = {
201 .nr_pins = 36,
202 .name = "GPIO1",
203 .groups = armada_37xx_nb_groups,
204 .ngroups = ARRAY_SIZE(armada_37xx_nb_groups),
205};
206
207const struct armada_37xx_pin_data armada_37xx_pin_sb = {
Ken Ma44ac7472018-03-26 15:55:59 +0800208 .nr_pins = 30,
Gregory CLEMENT08718062017-05-09 13:36:21 +0200209 .name = "GPIO2",
210 .groups = armada_37xx_sb_groups,
211 .ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
212};
213
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200214static inline void armada_37xx_update_reg(unsigned int *reg,
Ken Ma02374482018-03-26 15:56:02 +0800215 unsigned int *offset)
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200216{
217 /* We never have more than 2 registers */
Ken Ma02374482018-03-26 15:56:02 +0800218 if (*offset >= GPIO_PER_REG) {
219 *offset -= GPIO_PER_REG;
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200220 *reg += sizeof(u32);
221 }
222}
223
Gregory CLEMENT08718062017-05-09 13:36:21 +0200224static int armada_37xx_get_func_reg(struct armada_37xx_pin_group *grp,
225 const char *func)
226{
227 int f;
228
Ken Ma23626ca2018-03-26 15:56:01 +0800229 for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++)
Gregory CLEMENT08718062017-05-09 13:36:21 +0200230 if (!strcmp(grp->funcs[f], func))
231 return f;
232
233 return -ENOTSUPP;
234}
235
236static int armada_37xx_pmx_get_groups_count(struct udevice *dev)
237{
238 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
239
240 return info->ngroups;
241}
242
243static const char *armada_37xx_pmx_dummy_name = "_dummy";
244
245static const char *armada_37xx_pmx_get_group_name(struct udevice *dev,
246 unsigned selector)
247{
248 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
249
250 if (!info->groups[selector].name)
251 return armada_37xx_pmx_dummy_name;
252
253 return info->groups[selector].name;
254}
255
256static int armada_37xx_pmx_get_funcs_count(struct udevice *dev)
257{
258 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
259
260 return info->nfuncs;
261}
262
263static const char *armada_37xx_pmx_get_func_name(struct udevice *dev,
264 unsigned selector)
265{
266 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
267
268 return info->funcs[selector].name;
269}
270
271static int armada_37xx_pmx_set_by_name(struct udevice *dev,
272 const char *name,
273 struct armada_37xx_pin_group *grp)
274{
275 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
276 unsigned int reg = SELECTION;
277 unsigned int mask = grp->reg_mask;
278 int func, val;
279
280 dev_dbg(info->dev, "enable function %s group %s\n",
281 name, grp->name);
282
283 func = armada_37xx_get_func_reg(grp, name);
284
285 if (func < 0)
286 return func;
287
288 val = grp->val[func];
289
290 clrsetbits_le32(info->base + reg, mask, val);
291
292 return 0;
293}
294
295static int armada_37xx_pmx_group_set(struct udevice *dev,
296 unsigned group_selector,
297 unsigned func_selector)
298{
299 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
300 struct armada_37xx_pin_group *grp = &info->groups[group_selector];
301 const char *name = info->funcs[func_selector].name;
302
303 return armada_37xx_pmx_set_by_name(dev, name, grp);
304}
305
306/**
307 * armada_37xx_add_function() - Add a new function to the list
308 * @funcs: array of function to add the new one
309 * @funcsize: size of the remaining space for the function
310 * @name: name of the function to add
311 *
312 * If it is a new function then create it by adding its name else
313 * increment the number of group associated to this function.
314 */
315static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
316 int *funcsize, const char *name)
317{
318 int i = 0;
319
320 if (*funcsize <= 0)
321 return -EOVERFLOW;
322
323 while (funcs->ngroups) {
324 /* function already there */
325 if (strcmp(funcs->name, name) == 0) {
326 funcs->ngroups++;
327
328 return -EEXIST;
329 }
330 funcs++;
331 i++;
332 }
333
334 /* append new unique function */
335 funcs->name = name;
336 funcs->ngroups = 1;
337 (*funcsize)--;
338
339 return 0;
340}
341
342/**
343 * armada_37xx_fill_group() - complete the group array
344 * @info: info driver instance
345 *
346 * Based on the data available from the armada_37xx_pin_group array
347 * completes the last member of the struct for each function: the list
348 * of the groups associated to this function.
349 *
350 */
351static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
352{
353 int n, num = 0, funcsize = info->data->nr_pins;
354
355 for (n = 0; n < info->ngroups; n++) {
356 struct armada_37xx_pin_group *grp = &info->groups[n];
357 int i, j, f;
358
359 grp->pins = devm_kzalloc(info->dev,
360 (grp->npins + grp->extra_npins) *
361 sizeof(*grp->pins), GFP_KERNEL);
362 if (!grp->pins)
363 return -ENOMEM;
364
365 for (i = 0; i < grp->npins; i++)
366 grp->pins[i] = grp->start_pin + i;
367
368 for (j = 0; j < grp->extra_npins; j++)
369 grp->pins[i+j] = grp->extra_pin + j;
370
Ken Ma23626ca2018-03-26 15:56:01 +0800371 for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++) {
Gregory CLEMENT08718062017-05-09 13:36:21 +0200372 int ret;
373 /* check for unique functions and count groups */
374 ret = armada_37xx_add_function(info->funcs, &funcsize,
375 grp->funcs[f]);
376 if (ret == -EOVERFLOW)
377 dev_err(info->dev,
378 "More functions than pins(%d)\n",
379 info->data->nr_pins);
380 if (ret < 0)
381 continue;
382 num++;
383 }
384 }
385
386 info->nfuncs = num;
387
388 return 0;
389}
390
391/**
392 * armada_37xx_fill_funcs() - complete the funcs array
393 * @info: info driver instance
394 *
395 * Based on the data available from the armada_37xx_pin_group array
396 * completes the last two member of the struct for each group:
397 * - the list of the pins included in the group
398 * - the list of pinmux functions that can be selected for this group
399 *
400 */
401static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
402{
403 struct armada_37xx_pmx_func *funcs = info->funcs;
404 int n;
405
406 for (n = 0; n < info->nfuncs; n++) {
407 const char *name = funcs[n].name;
408 const char **groups;
409 int g;
410
411 funcs[n].groups = devm_kzalloc(info->dev, funcs[n].ngroups *
412 sizeof(*(funcs[n].groups)),
413 GFP_KERNEL);
414 if (!funcs[n].groups)
415 return -ENOMEM;
416
417 groups = funcs[n].groups;
418
419 for (g = 0; g < info->ngroups; g++) {
420 struct armada_37xx_pin_group *gp = &info->groups[g];
421 int f;
422
Ken Ma23626ca2018-03-26 15:56:01 +0800423 for (f = 0; (f < NB_FUNCS) && gp->funcs[f]; f++) {
Gregory CLEMENT08718062017-05-09 13:36:21 +0200424 if (strcmp(gp->funcs[f], name) == 0) {
425 *groups = gp->name;
426 groups++;
427 }
428 }
429 }
430 }
431 return 0;
432}
433
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200434static int armada_37xx_gpio_get(struct udevice *dev, unsigned int offset)
435{
436 struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
437 unsigned int reg = INPUT_VAL;
438 unsigned int val, mask;
439
Ken Ma02374482018-03-26 15:56:02 +0800440 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200441 mask = BIT(offset);
442
443 val = readl(info->base + reg);
444
445 return (val & mask) != 0;
446}
447
448static int armada_37xx_gpio_set(struct udevice *dev, unsigned int offset,
449 int value)
450{
451 struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
452 unsigned int reg = OUTPUT_VAL;
453 unsigned int mask, val;
454
Ken Ma02374482018-03-26 15:56:02 +0800455 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200456 mask = BIT(offset);
457 val = value ? mask : 0;
458
459 clrsetbits_le32(info->base + reg, mask, val);
460
461 return 0;
462}
463
464static int armada_37xx_gpio_get_direction(struct udevice *dev,
465 unsigned int offset)
466{
467 struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
468 unsigned int reg = OUTPUT_EN;
469 unsigned int val, mask;
470
Ken Ma02374482018-03-26 15:56:02 +0800471 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200472 mask = BIT(offset);
473 val = readl(info->base + reg);
474
475 if (val & mask)
476 return GPIOF_OUTPUT;
477 else
478 return GPIOF_INPUT;
479}
480
481static int armada_37xx_gpio_direction_input(struct udevice *dev,
482 unsigned int offset)
483{
484 struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
485 unsigned int reg = OUTPUT_EN;
486 unsigned int mask;
487
Ken Ma02374482018-03-26 15:56:02 +0800488 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200489 mask = BIT(offset);
490
491 clrbits_le32(info->base + reg, mask);
492
493 return 0;
494}
495
496static int armada_37xx_gpio_direction_output(struct udevice *dev,
497 unsigned int offset, int value)
498{
499 struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
500 unsigned int reg = OUTPUT_EN;
501 unsigned int mask;
502
Ken Ma02374482018-03-26 15:56:02 +0800503 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200504 mask = BIT(offset);
505
506 setbits_le32(info->base + reg, mask);
507
508 /* And set the requested value */
509 return armada_37xx_gpio_set(dev, offset, value);
510}
511
512static int armada_37xx_gpio_probe(struct udevice *dev)
513{
514 struct armada_37xx_pinctrl *info = dev_get_priv(dev->parent);
515 struct gpio_dev_priv *uc_priv;
516
517 uc_priv = dev_get_uclass_priv(dev);
518 uc_priv->bank_name = info->data->name;
519 uc_priv->gpio_count = info->data->nr_pins;
520
521 return 0;
522}
523
524static const struct dm_gpio_ops armada_37xx_gpio_ops = {
525 .set_value = armada_37xx_gpio_set,
526 .get_value = armada_37xx_gpio_get,
527 .get_function = armada_37xx_gpio_get_direction,
528 .direction_input = armada_37xx_gpio_direction_input,
529 .direction_output = armada_37xx_gpio_direction_output,
530};
531
532static struct driver armada_37xx_gpio_driver = {
533 .name = "armada-37xx-gpio",
534 .id = UCLASS_GPIO,
535 .probe = armada_37xx_gpio_probe,
536 .ops = &armada_37xx_gpio_ops,
537};
538
539static int armada_37xx_gpiochip_register(struct udevice *parent,
540 struct armada_37xx_pinctrl *info)
541{
542 const void *blob = gd->fdt_blob;
543 int node = dev_of_offset(parent);
544 struct uclass_driver *drv;
545 struct udevice *dev;
546 int ret = -ENODEV;
547 int subnode;
548 char *name;
549
550 /* Lookup GPIO driver */
551 drv = lists_uclass_lookup(UCLASS_GPIO);
552 if (!drv) {
553 puts("Cannot find GPIO driver\n");
554 return -ENOENT;
555 }
556
557 fdt_for_each_subnode(subnode, blob, node) {
Ken Maae118b62017-06-22 17:13:36 +0800558 if (fdtdec_get_bool(blob, subnode, "gpio-controller")) {
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200559 ret = 0;
560 break;
561 }
562 };
563 if (ret)
564 return ret;
565
566 name = calloc(1, 32);
567 sprintf(name, "armada-37xx-gpio");
568
569 /* Create child device UCLASS_GPIO and bind it */
570 device_bind(parent, &armada_37xx_gpio_driver, name, NULL, subnode,
571 &dev);
572 dev_set_of_offset(dev, subnode);
573
574 return 0;
575}
576
Gregory CLEMENT08718062017-05-09 13:36:21 +0200577const struct pinctrl_ops armada_37xx_pinctrl_ops = {
578 .get_groups_count = armada_37xx_pmx_get_groups_count,
579 .get_group_name = armada_37xx_pmx_get_group_name,
580 .get_functions_count = armada_37xx_pmx_get_funcs_count,
581 .get_function_name = armada_37xx_pmx_get_func_name,
582 .pinmux_group_set = armada_37xx_pmx_group_set,
583 .set_state = pinctrl_generic_set_state,
584};
585
586int armada_37xx_pinctrl_probe(struct udevice *dev)
587{
588 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
589 const struct armada_37xx_pin_data *pin_data;
590 int ret;
591
592 info->data = (struct armada_37xx_pin_data *)dev_get_driver_data(dev);
593 pin_data = info->data;
594
Simon Glassa821c4a2017-05-17 17:18:05 -0600595 info->base = (void __iomem *)devfdt_get_addr(dev);
Gregory CLEMENT08718062017-05-09 13:36:21 +0200596 if (!info->base) {
Masahiro Yamada9b643e32017-09-16 14:10:41 +0900597 pr_err("unable to find regmap\n");
Gregory CLEMENT08718062017-05-09 13:36:21 +0200598 return -ENODEV;
599 }
600
601 info->groups = pin_data->groups;
602 info->ngroups = pin_data->ngroups;
603
604 /*
605 * we allocate functions for number of pins and hope there are
606 * fewer unique functions than pins available
607 */
608 info->funcs = devm_kzalloc(info->dev, pin_data->nr_pins *
609 sizeof(struct armada_37xx_pmx_func), GFP_KERNEL);
610 if (!info->funcs)
611 return -ENOMEM;
612
613
614 ret = armada_37xx_fill_group(info);
615 if (ret)
616 return ret;
617
618 ret = armada_37xx_fill_func(info);
619 if (ret)
620 return ret;
621
Gregory CLEMENTd2d92bd2017-05-17 17:05:25 +0200622 ret = armada_37xx_gpiochip_register(dev, info);
623 if (ret)
624 return ret;
625
Gregory CLEMENT08718062017-05-09 13:36:21 +0200626 return 0;
627}
628
629static const struct udevice_id armada_37xx_pinctrl_of_match[] = {
630 {
631 .compatible = "marvell,armada3710-sb-pinctrl",
632 .data = (ulong)&armada_37xx_pin_sb,
633 },
634 {
635 .compatible = "marvell,armada3710-nb-pinctrl",
636 .data = (ulong)&armada_37xx_pin_nb,
637 },
638 { /* sentinel */ }
639};
640
641U_BOOT_DRIVER(armada_37xx_pinctrl) = {
642 .name = "armada-37xx-pinctrl",
643 .id = UCLASS_PINCTRL,
644 .of_match = of_match_ptr(armada_37xx_pinctrl_of_match),
645 .probe = armada_37xx_pinctrl_probe,
646 .priv_auto_alloc_size = sizeof(struct armada_37xx_pinctrl),
647 .ops = &armada_37xx_pinctrl_ops,
648};