blob: e76ef153e60414cdc20a3c46cf2d00ba15d915c9 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Gregory CLEMENTa2490a22017-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 CLEMENTa2490a22017-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 Glass9bc15642020-02-03 07:36:16 -070022#include <malloc.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060023#include <asm/global_data.h>
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +020024#include <dm/device-internal.h>
Simon Glass9bc15642020-02-03 07:36:16 -070025#include <dm/device_compat.h>
Simon Glassd66c5f72020-02-03 07:36:15 -070026#include <dm/devres.h>
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +020027#include <dm/lists.h>
Gregory CLEMENTa2490a22017-05-09 13:36:21 +020028#include <dm/pinctrl.h>
29#include <dm/root.h>
30#include <errno.h>
31#include <fdtdec.h>
32#include <regmap.h>
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +020033#include <asm/gpio.h>
Gregory CLEMENTa2490a22017-05-09 13:36:21 +020034#include <asm/system.h>
35#include <asm/io.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060036#include <linux/bitops.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060037#include <linux/libfdt.h>
Gregory CLEMENTa2490a22017-05-09 13:36:21 +020038
39DECLARE_GLOBAL_DATA_PTR;
40
41#define OUTPUT_EN 0x0
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +020042#define INPUT_VAL 0x10
43#define OUTPUT_VAL 0x18
Gregory CLEMENTa2490a22017-05-09 13:36:21 +020044#define OUTPUT_CTL 0x20
45#define SELECTION 0x30
46
47#define IRQ_EN 0x0
48#define IRQ_POL 0x08
49#define IRQ_STATUS 0x10
50#define IRQ_WKUP 0x18
51
Ken Mab28aedb2018-03-26 15:56:01 +080052#define NB_FUNCS 3
Gregory CLEMENTa2490a22017-05-09 13:36:21 +020053#define GPIO_PER_REG 32
54
55/**
56 * struct armada_37xx_pin_group: represents group of pins of a pinmux function.
57 * The pins of a pinmux groups are composed of one or two groups of contiguous
58 * pins.
59 * @name: Name of the pin group, used to lookup the group.
60 * @start_pins: Index of the first pin of the main range of pins belonging to
61 * the group
62 * @npins: Number of pins included in the first range
63 * @reg_mask: Bit mask matching the group in the selection register
64 * @extra_pins: Index of the first pin of the optional second range of pins
65 * belonging to the group
66 * @npins: Number of pins included in the second optional range
67 * @funcs: A list of pinmux functions that can be selected for this group.
68 * @pins: List of the pins included in the group
69 */
70struct armada_37xx_pin_group {
71 const char *name;
72 unsigned int start_pin;
73 unsigned int npins;
74 u32 reg_mask;
75 u32 val[NB_FUNCS];
76 unsigned int extra_pin;
77 unsigned int extra_npins;
78 const char *funcs[NB_FUNCS];
79 unsigned int *pins;
80};
81
82struct armada_37xx_pin_data {
83 u8 nr_pins;
84 char *name;
85 struct armada_37xx_pin_group *groups;
86 int ngroups;
87};
88
89struct armada_37xx_pmx_func {
90 const char *name;
91 const char **groups;
92 unsigned int ngroups;
93};
94
95struct armada_37xx_pinctrl {
96 void __iomem *base;
97 const struct armada_37xx_pin_data *data;
98 struct udevice *dev;
99 struct pinctrl_dev *pctl_dev;
100 struct armada_37xx_pin_group *groups;
101 unsigned int ngroups;
102 struct armada_37xx_pmx_func *funcs;
103 unsigned int nfuncs;
104};
105
106#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \
107 { \
108 .name = _name, \
109 .start_pin = _start, \
110 .npins = _nr, \
111 .reg_mask = _mask, \
112 .val = {0, _mask}, \
113 .funcs = {_func1, _func2} \
114 }
115
116#define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \
117 { \
118 .name = _name, \
119 .start_pin = _start, \
120 .npins = _nr, \
121 .reg_mask = _mask, \
122 .val = {0, _mask}, \
123 .funcs = {_func1, "gpio"} \
124 }
125
126#define PIN_GRP_GPIO_2(_name, _start, _nr, _mask, _val1, _val2, _func1) \
127 { \
128 .name = _name, \
129 .start_pin = _start, \
130 .npins = _nr, \
131 .reg_mask = _mask, \
132 .val = {_val1, _val2}, \
133 .funcs = {_func1, "gpio"} \
134 }
135
Ken Mab28aedb2018-03-26 15:56:01 +0800136#define PIN_GRP_GPIO_3(_name, _start, _nr, _mask, _v1, _v2, _v3, _f1, _f2) \
137 { \
138 .name = _name, \
139 .start_pin = _start, \
140 .npins = _nr, \
141 .reg_mask = _mask, \
142 .val = {_v1, _v2, _v3}, \
143 .funcs = {_f1, _f2, "gpio"} \
144 }
145
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200146#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
147 _f1, _f2) \
148 { \
149 .name = _name, \
150 .start_pin = _start, \
151 .npins = _nr, \
152 .reg_mask = _mask, \
153 .val = {_v1, _v2}, \
154 .extra_pin = _start2, \
155 .extra_npins = _nr2, \
156 .funcs = {_f1, _f2} \
157 }
158
159static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
160 PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
161 PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
162 PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
Marek Behún9eaf20b2021-07-23 19:57:11 +0200163 PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3),
164 "pwm", "led"),
Marek Behún54021602022-02-28 15:59:37 +0100165 PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4),
Marek Behún9eaf20b2021-07-23 19:57:11 +0200166 "pwm", "led"),
Marek Behún54021602022-02-28 15:59:37 +0100167 PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5),
Marek Behún9eaf20b2021-07-23 19:57:11 +0200168 "pwm", "led"),
Marek Behún54021602022-02-28 15:59:37 +0100169 PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6),
Marek Behún9eaf20b2021-07-23 19:57:11 +0200170 "pwm", "led"),
Ken Ma3cdd35b2018-03-26 15:56:03 +0800171 PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"),
172 PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"),
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200173 PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
174 PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
175 PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
176 PIN_GRP_GPIO_2("spi_cs2", 18, 1, BIT(13) | BIT(19), 0, BIT(13), "spi"),
177 PIN_GRP_GPIO_2("spi_cs3", 19, 1, BIT(14) | BIT(19), 0, BIT(14), "spi"),
178 PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
179 PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
180 PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
Ken Maa12d6372017-06-22 17:13:35 +0800181 PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19),
182 BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19),
183 18, 2, "gpio", "uart"),
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200184};
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 Ma3cdd35b2018-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 CLEMENTa2490a22017-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 Mab28aedb2018-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 CLEMENTa2490a22017-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 Maa1d81602018-03-26 15:55:59 +0800208 .nr_pins = 30,
Gregory CLEMENTa2490a22017-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 CLEMENT7ca5e2b2017-05-17 17:05:25 +0200214static inline void armada_37xx_update_reg(unsigned int *reg,
Ken Maf72c5292018-03-26 15:56:02 +0800215 unsigned int *offset)
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200216{
217 /* We never have more than 2 registers */
Ken Maf72c5292018-03-26 15:56:02 +0800218 if (*offset >= GPIO_PER_REG) {
219 *offset -= GPIO_PER_REG;
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200220 *reg += sizeof(u32);
221 }
222}
223
Gregory CLEMENTa2490a22017-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 Mab28aedb2018-03-26 15:56:01 +0800229 for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++)
Gregory CLEMENTa2490a22017-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 Mab28aedb2018-03-26 15:56:01 +0800371 for (f = 0; (f < NB_FUNCS) && grp->funcs[f]; f++) {
Gregory CLEMENTa2490a22017-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 Mab28aedb2018-03-26 15:56:01 +0800423 for (f = 0; (f < NB_FUNCS) && gp->funcs[f]; f++) {
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200424 if (strcmp(gp->funcs[f], name) == 0) {
425 *groups = gp->name;
426 groups++;
427 }
428 }
429 }
430 }
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200431 return 0;
432}
433
434static 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 Maf72c5292018-03-26 15:56:02 +0800440 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENT7ca5e2b2017-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 Maf72c5292018-03-26 15:56:02 +0800455 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENT7ca5e2b2017-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 Maf72c5292018-03-26 15:56:02 +0800471 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENT7ca5e2b2017-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 Maf72c5292018-03-26 15:56:02 +0800488 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENT7ca5e2b2017-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 Maf72c5292018-03-26 15:56:02 +0800503 armada_37xx_update_reg(&reg, &offset);
Gregory CLEMENT7ca5e2b2017-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
Simon Glass6996c662020-11-28 17:50:03 -0700550 /* FIXME: Should not need to lookup GPIO uclass */
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200551 drv = lists_uclass_lookup(UCLASS_GPIO);
552 if (!drv) {
553 puts("Cannot find GPIO driver\n");
554 return -ENOENT;
555 }
556
Simon Glass6996c662020-11-28 17:50:03 -0700557 /* FIXME: Use livtree and check the result of device_bind() below */
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200558 fdt_for_each_subnode(subnode, blob, node) {
Ken Mafeb93c62017-06-22 17:13:36 +0800559 if (fdtdec_get_bool(blob, subnode, "gpio-controller")) {
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200560 ret = 0;
561 break;
562 }
563 };
564 if (ret)
565 return ret;
566
567 name = calloc(1, 32);
568 sprintf(name, "armada-37xx-gpio");
569
570 /* Create child device UCLASS_GPIO and bind it */
Simon Glass6996c662020-11-28 17:50:03 -0700571 device_bind(parent, &armada_37xx_gpio_driver, name, NULL,
572 offset_to_ofnode(subnode), &dev);
Gregory CLEMENT7ca5e2b2017-05-17 17:05:25 +0200573
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200574 return 0;
575}
576
577const 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
Masahiro Yamada1096ae12020-07-17 14:36:46 +0900595 info->base = dev_read_addr_ptr(dev);
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200596 if (!info->base) {
Masahiro Yamada81e10422017-09-16 14:10:41 +0900597 pr_err("unable to find regmap\n");
Gregory CLEMENTa2490a22017-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 CLEMENT7ca5e2b2017-05-17 17:05:25 +0200622 ret = armada_37xx_gpiochip_register(dev, info);
623 if (ret)
624 return ret;
625
Gregory CLEMENTa2490a22017-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,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700646 .priv_auto = sizeof(struct armada_37xx_pinctrl),
Gregory CLEMENTa2490a22017-05-09 13:36:21 +0200647 .ops = &armada_37xx_pinctrl_ops,
648};