blob: 8fc07e34986cb926f52ef0906ceec6a023704150 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Felix Brack44d5c372017-03-22 11:26:44 +01002/*
3 * Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch>
Dario Binacchi76d470d2021-04-11 09:39:49 +02004 * Copyright (C) 2021 Dario Binacchi <dariobin@libero.it>
Felix Brack44d5c372017-03-22 11:26:44 +01005 */
6
7#include <common.h>
Simon Glass9d922452017-05-17 17:18:03 -06008#include <dm.h>
Simon Glass336d4612020-02-03 07:36:16 -07009#include <dm/device_compat.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020010#include <dm/devres.h>
Bharat Gooty62f86c62021-08-24 15:46:31 +053011#include <dm/of_access.h>
Felix Brack44d5c372017-03-22 11:26:44 +010012#include <dm/pinctrl.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +090013#include <linux/libfdt.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020014#include <linux/list.h>
Felix Brack44d5c372017-03-22 11:26:44 +010015#include <asm/io.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020016#include <sort.h>
Felix Brack44d5c372017-03-22 11:26:44 +010017
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020018/**
19 * struct single_pdata - platform data
20 * @base: first configuration register
21 * @offset: index of last configuration register
22 * @mask: configuration-value mask bits
23 * @width: configuration register bit width
24 * @bits_per_mux: true if one register controls more than one pin
25 */
Felix Brack44d5c372017-03-22 11:26:44 +010026struct single_pdata {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020027 fdt_addr_t base;
28 int offset;
29 u32 mask;
Dario Binacchi971c64a2021-04-11 09:39:44 +020030 u32 width;
Adam Ford159a8872019-06-10 13:15:55 -050031 bool bits_per_mux;
Felix Brack44d5c372017-03-22 11:26:44 +010032};
33
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020034/**
Dario Binacchi76d470d2021-04-11 09:39:49 +020035 * struct single_func - pinctrl function
36 * @node: list node
37 * @name: pinctrl function name
38 * @npins: number of entries in pins array
39 * @pins: pins array
40 */
41struct single_func {
42 struct list_head node;
43 const char *name;
44 unsigned int npins;
45 unsigned int *pins;
46};
47
48/**
Bharat Gooty62f86c62021-08-24 15:46:31 +053049 * struct single_gpiofunc_range - pin ranges with same mux value of gpio fun
50 * @offset: offset base of pins
51 * @npins: number pins with the same mux value of gpio function
52 * @gpiofunc: mux value of gpio function
53 * @node: list node
54 */
55struct single_gpiofunc_range {
56 u32 offset;
57 u32 npins;
58 u32 gpiofunc;
59 struct list_head node;
60};
61
62/**
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020063 * struct single_priv - private data
64 * @bits_per_pin: number of bits per pin
65 * @npins: number of selectable pins
Dario Binacchi0b121622021-04-11 09:39:48 +020066 * @pin_name: temporary buffer to store the pin name
Bharat Gooty62f86c62021-08-24 15:46:31 +053067 * @functions: list pin functions
68 * @gpiofuncs: list gpio functions
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020069 */
70struct single_priv {
Dario Binacchi55322622021-04-11 09:39:50 +020071#if (IS_ENABLED(CONFIG_SANDBOX))
72 u32 *sandbox_regs;
73#endif
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020074 unsigned int bits_per_pin;
75 unsigned int npins;
Dario Binacchi0b121622021-04-11 09:39:48 +020076 char pin_name[PINNAME_SIZE];
Dario Binacchi76d470d2021-04-11 09:39:49 +020077 struct list_head functions;
Bharat Gooty62f86c62021-08-24 15:46:31 +053078 struct list_head gpiofuncs;
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020079};
80
81/**
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020082 * struct single_fdt_pin_cfg - pin configuration
83 *
84 * This structure is used for the pin configuration parameters in case
85 * the register controls only one pin.
86 *
87 * @reg: configuration register offset
88 * @val: configuration register value
89 */
Felix Brack44d5c372017-03-22 11:26:44 +010090struct single_fdt_pin_cfg {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020091 fdt32_t reg;
92 fdt32_t val;
Felix Brack44d5c372017-03-22 11:26:44 +010093};
94
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020095/**
96 * struct single_fdt_bits_cfg - pin configuration
97 *
98 * This structure is used for the pin configuration parameters in case
99 * the register controls more than one pin.
100 *
101 * @reg: configuration register offset
102 * @val: configuration register value
103 * @mask: configuration register mask
104 */
Adam Ford159a8872019-06-10 13:15:55 -0500105struct single_fdt_bits_cfg {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +0200106 fdt32_t reg;
107 fdt32_t val;
108 fdt32_t mask;
Adam Ford159a8872019-06-10 13:15:55 -0500109};
110
Dario Binacchi55322622021-04-11 09:39:50 +0200111#if (!IS_ENABLED(CONFIG_SANDBOX))
112
Dario Binacchi180531f2021-04-11 09:39:46 +0200113static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
114{
115 struct single_pdata *pdata = dev_get_plat(dev);
116
117 switch (pdata->width) {
118 case 8:
119 return readb(reg);
120 case 16:
121 return readw(reg);
122 default: /* 32 bits */
123 return readl(reg);
124 }
125
126 return readb(reg);
127}
128
129static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
130{
131 struct single_pdata *pdata = dev_get_plat(dev);
132
133 switch (pdata->width) {
134 case 8:
135 writeb(val, reg);
136 break;
137 case 16:
138 writew(val, reg);
139 break;
140 default: /* 32 bits */
141 writel(val, reg);
142 }
143}
144
Dario Binacchi55322622021-04-11 09:39:50 +0200145#else /* CONFIG_SANDBOX */
146
147static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
148{
149 struct single_priv *priv = dev_get_priv(dev);
150
151 return priv->sandbox_regs[reg];
152}
153
154static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
155{
156 struct single_priv *priv = dev_get_priv(dev);
157
158 priv->sandbox_regs[reg] = val;
159}
160
161#endif /* CONFIG_SANDBOX */
162
Felix Brack44d5c372017-03-22 11:26:44 +0100163/**
Dario Binacchi76d470d2021-04-11 09:39:49 +0200164 * single_get_pin_by_offset() - get a pin based on the register offset
165 * @dev: single driver instance
166 * @offset: register offset from the base
167 */
168static int single_get_pin_by_offset(struct udevice *dev, unsigned int offset)
169{
170 struct single_pdata *pdata = dev_get_plat(dev);
171 struct single_priv *priv = dev_get_priv(dev);
172
173 if (offset > pdata->offset) {
174 dev_err(dev, "mux offset out of range: 0x%x (0x%x)\n",
175 offset, pdata->offset);
176 return -EINVAL;
177 }
178
179 if (pdata->bits_per_mux)
180 return (offset * BITS_PER_BYTE) / priv->bits_per_pin;
181
182 return offset / (pdata->width / BITS_PER_BYTE);
183}
184
185static int single_get_offset_by_pin(struct udevice *dev, unsigned int pin)
186{
187 struct single_pdata *pdata = dev_get_plat(dev);
188 struct single_priv *priv = dev_get_priv(dev);
189 unsigned int mux_bytes;
190
191 if (pin >= priv->npins)
192 return -EINVAL;
193
194 mux_bytes = pdata->width / BITS_PER_BYTE;
195 if (pdata->bits_per_mux) {
196 int byte_num;
197
198 byte_num = (priv->bits_per_pin * pin) / BITS_PER_BYTE;
199 return (byte_num / mux_bytes) * mux_bytes;
200 }
201
202 return pin * mux_bytes;
203}
204
205static const char *single_get_pin_function(struct udevice *dev,
206 unsigned int pin)
207{
208 struct single_priv *priv = dev_get_priv(dev);
209 struct single_func *func;
210 int i;
211
212 list_for_each_entry(func, &priv->functions, node) {
213 for (i = 0; i < func->npins; i++) {
214 if (pin == func->pins[i])
215 return func->name;
216
217 if (pin < func->pins[i])
218 break;
219 }
220 }
221
222 return NULL;
223}
224
225static int single_get_pin_muxing(struct udevice *dev, unsigned int pin,
226 char *buf, int size)
227{
228 struct single_pdata *pdata = dev_get_plat(dev);
229 struct single_priv *priv = dev_get_priv(dev);
230 fdt_addr_t reg;
231 const char *fname;
232 unsigned int val;
233 int offset, pin_shift = 0;
234
235 offset = single_get_offset_by_pin(dev, pin);
236 if (offset < 0)
237 return offset;
238
239 reg = pdata->base + offset;
240 val = single_read(dev, reg);
241
242 if (pdata->bits_per_mux)
243 pin_shift = pin % (pdata->width / priv->bits_per_pin) *
244 priv->bits_per_pin;
245
246 val &= (pdata->mask << pin_shift);
247 fname = single_get_pin_function(dev, pin);
248 snprintf(buf, size, "%pa 0x%08x %s", &reg, val,
249 fname ? fname : "UNCLAIMED");
250 return 0;
251}
252
Bharat Gootyfd921d22021-08-24 15:46:32 +0530253static int single_request(struct udevice *dev, int pin, int flags)
254{
255 struct single_priv *priv = dev_get_priv(dev);
256 struct single_pdata *pdata = dev_get_plat(dev);
257 struct single_gpiofunc_range *frange = NULL;
258 struct list_head *pos, *tmp;
259 phys_addr_t reg;
260 int mux_bytes = 0;
261 u32 data;
262
263 /* If function mask is null, needn't enable it. */
264 if (!pdata->mask)
265 return -ENOTSUPP;
266
267 list_for_each_safe(pos, tmp, &priv->gpiofuncs) {
268 frange = list_entry(pos, struct single_gpiofunc_range, node);
269 if ((pin >= frange->offset + frange->npins) ||
270 pin < frange->offset)
271 continue;
272
273 mux_bytes = pdata->width / BITS_PER_BYTE;
274 reg = pdata->base + pin * mux_bytes;
275
276 data = single_read(dev, reg);
277 data &= ~pdata->mask;
278 data |= frange->gpiofunc;
279 single_write(dev, data, reg);
280 break;
281 }
282
283 return 0;
284}
285
Dario Binacchi76d470d2021-04-11 09:39:49 +0200286static struct single_func *single_allocate_function(struct udevice *dev,
287 unsigned int group_pins)
288{
289 struct single_func *func;
290
291 func = devm_kmalloc(dev, sizeof(*func), GFP_KERNEL);
292 if (!func)
293 return ERR_PTR(-ENOMEM);
294
295 func->pins = devm_kmalloc(dev, sizeof(unsigned int) * group_pins,
296 GFP_KERNEL);
297 if (!func->pins)
298 return ERR_PTR(-ENOMEM);
299
300 return func;
301}
302
303static int single_pin_compare(const void *s1, const void *s2)
304{
305 int pin1 = *(const unsigned int *)s1;
306 int pin2 = *(const unsigned int *)s2;
307
308 return pin1 - pin2;
309}
310
311/**
Felix Brack44d5c372017-03-22 11:26:44 +0100312 * single_configure_pins() - Configure pins based on FDT data
313 *
314 * @dev: Pointer to single pin configuration device which is the parent of
315 * the pins node holding the pin configuration data.
316 * @pins: Pointer to the first element of an array of register/value pairs
317 * of type 'struct single_fdt_pin_cfg'. Each such pair describes the
318 * the pin to be configured and the value to be used for configuration.
319 * This pointer points to a 'pinctrl-single,pins' property in the
320 * device-tree.
321 * @size: Size of the 'pins' array in bytes.
322 * The number of register/value pairs in the 'pins' array therefore
323 * equals to 'size / sizeof(struct single_fdt_pin_cfg)'.
Dario Binacchi76d470d2021-04-11 09:39:49 +0200324 * @fname: Function name.
Felix Brack44d5c372017-03-22 11:26:44 +0100325 */
326static int single_configure_pins(struct udevice *dev,
327 const struct single_fdt_pin_cfg *pins,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200328 int size, const char *fname)
Felix Brack44d5c372017-03-22 11:26:44 +0100329{
Simon Glass0fd3d912020-12-22 19:30:28 -0700330 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200331 struct single_priv *priv = dev_get_priv(dev);
332 int n, pin, count = size / sizeof(struct single_fdt_pin_cfg);
333 struct single_func *func;
Dario Binacchi67192942021-04-11 09:39:40 +0200334 phys_addr_t reg;
Dario Binacchi9b884e72021-04-11 09:39:41 +0200335 u32 offset, val;
Felix Brack44d5c372017-03-22 11:26:44 +0100336
Dario Binacchid85b93e2021-04-11 09:39:45 +0200337 /* If function mask is null, needn't enable it. */
338 if (!pdata->mask)
339 return 0;
340
Dario Binacchi76d470d2021-04-11 09:39:49 +0200341 func = single_allocate_function(dev, count);
342 if (IS_ERR(func))
343 return PTR_ERR(func);
344
345 func->name = fname;
346 func->npins = 0;
James Balean46f51dc2017-04-18 21:06:35 -0500347 for (n = 0; n < count; n++, pins++) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200348 offset = fdt32_to_cpu(pins->reg);
Dario Binacchi230bc622021-04-22 22:28:56 +0200349 if (offset > pdata->offset) {
Dario Binacchi76d470d2021-04-11 09:39:49 +0200350 dev_err(dev, " invalid register offset 0x%x\n",
Dario Binacchi9b884e72021-04-11 09:39:41 +0200351 offset);
Felix Brack44d5c372017-03-22 11:26:44 +0100352 continue;
353 }
Dario Binacchi9b884e72021-04-11 09:39:41 +0200354
355 reg = pdata->base + offset;
James Balean46f51dc2017-04-18 21:06:35 -0500356 val = fdt32_to_cpu(pins->val) & pdata->mask;
Dario Binacchi76d470d2021-04-11 09:39:49 +0200357 pin = single_get_pin_by_offset(dev, offset);
358 if (pin < 0) {
359 dev_err(dev, " failed to get pin by offset %x\n",
360 offset);
361 continue;
362 }
363
Dario Binacchi180531f2021-04-11 09:39:46 +0200364 single_write(dev, (single_read(dev, reg) & ~pdata->mask) | val,
365 reg);
Dario Binacchifcf6a2b2021-04-11 09:39:42 +0200366 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200367 func->pins[func->npins] = pin;
368 func->npins++;
Felix Brack44d5c372017-03-22 11:26:44 +0100369 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200370
371 qsort(func->pins, func->npins, sizeof(func->pins[0]),
372 single_pin_compare);
373 list_add(&func->node, &priv->functions);
Felix Brack44d5c372017-03-22 11:26:44 +0100374 return 0;
375}
376
Adam Ford159a8872019-06-10 13:15:55 -0500377static int single_configure_bits(struct udevice *dev,
378 const struct single_fdt_bits_cfg *pins,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200379 int size, const char *fname)
Adam Ford159a8872019-06-10 13:15:55 -0500380{
Simon Glass0fd3d912020-12-22 19:30:28 -0700381 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200382 struct single_priv *priv = dev_get_priv(dev);
383 int n, pin, count = size / sizeof(struct single_fdt_bits_cfg);
384 int npins_in_reg, pin_num_from_lsb;
385 struct single_func *func;
Dario Binacchi67192942021-04-11 09:39:40 +0200386 phys_addr_t reg;
Dario Binacchi76d470d2021-04-11 09:39:49 +0200387 u32 offset, val, mask, bit_pos, val_pos, mask_pos, submask;
Adam Ford159a8872019-06-10 13:15:55 -0500388
Dario Binacchi69414d82021-04-22 18:35:58 +0200389 /* If function mask is null, needn't enable it. */
390 if (!pdata->mask)
391 return 0;
392
Dario Binacchi76d470d2021-04-11 09:39:49 +0200393 npins_in_reg = pdata->width / priv->bits_per_pin;
394 func = single_allocate_function(dev, count * npins_in_reg);
395 if (IS_ERR(func))
396 return PTR_ERR(func);
397
398 func->name = fname;
399 func->npins = 0;
Adam Ford159a8872019-06-10 13:15:55 -0500400 for (n = 0; n < count; n++, pins++) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200401 offset = fdt32_to_cpu(pins->reg);
Dario Binacchi230bc622021-04-22 22:28:56 +0200402 if (offset > pdata->offset) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200403 dev_dbg(dev, " invalid register offset 0x%x\n",
404 offset);
Adam Ford159a8872019-06-10 13:15:55 -0500405 continue;
406 }
Dario Binacchi9b884e72021-04-11 09:39:41 +0200407
408 reg = pdata->base + offset;
Adam Ford159a8872019-06-10 13:15:55 -0500409
Dario Binacchi76d470d2021-04-11 09:39:49 +0200410 pin = single_get_pin_by_offset(dev, offset);
411 if (pin < 0) {
412 dev_err(dev, " failed to get pin by offset 0x%pa\n",
413 &reg);
414 continue;
415 }
416
Adam Ford159a8872019-06-10 13:15:55 -0500417 mask = fdt32_to_cpu(pins->mask);
418 val = fdt32_to_cpu(pins->val) & mask;
Dario Binacchi180531f2021-04-11 09:39:46 +0200419 single_write(dev, (single_read(dev, reg) & ~mask) | val, reg);
Dario Binacchifcf6a2b2021-04-11 09:39:42 +0200420 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200421
422 while (mask) {
423 bit_pos = __ffs(mask);
424 pin_num_from_lsb = bit_pos / priv->bits_per_pin;
425 mask_pos = pdata->mask << bit_pos;
426 val_pos = val & mask_pos;
427 submask = mask & mask_pos;
428
429 if ((mask & mask_pos) == 0) {
430 dev_err(dev, "Invalid mask at 0x%x\n", offset);
431 break;
432 }
433
434 mask &= ~mask_pos;
435
436 if (submask != mask_pos) {
437 dev_warn(dev,
438 "Invalid submask 0x%x at 0x%x\n",
439 submask, offset);
440 continue;
441 }
442
443 func->pins[func->npins] = pin + pin_num_from_lsb;
444 func->npins++;
445 }
Adam Ford159a8872019-06-10 13:15:55 -0500446 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200447
448 qsort(func->pins, func->npins, sizeof(func->pins[0]),
449 single_pin_compare);
450 list_add(&func->node, &priv->functions);
Adam Ford159a8872019-06-10 13:15:55 -0500451 return 0;
452}
Felix Brack44d5c372017-03-22 11:26:44 +0100453static int single_set_state(struct udevice *dev,
454 struct udevice *config)
455{
Felix Brack44d5c372017-03-22 11:26:44 +0100456 const struct single_fdt_pin_cfg *prop;
Adam Ford159a8872019-06-10 13:15:55 -0500457 const struct single_fdt_bits_cfg *prop_bits;
Felix Brack44d5c372017-03-22 11:26:44 +0100458 int len;
459
Lokesh Vutladbfd9e02020-04-22 22:55:31 +0530460 prop = dev_read_prop(config, "pinctrl-single,pins", &len);
Adam Ford159a8872019-06-10 13:15:55 -0500461
Felix Brack44d5c372017-03-22 11:26:44 +0100462 if (prop) {
463 dev_dbg(dev, "configuring pins for %s\n", config->name);
464 if (len % sizeof(struct single_fdt_pin_cfg)) {
465 dev_dbg(dev, " invalid pin configuration in fdt\n");
466 return -FDT_ERR_BADSTRUCTURE;
467 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200468 single_configure_pins(dev, prop, len, config->name);
Adam Ford159a8872019-06-10 13:15:55 -0500469 return 0;
Felix Brack44d5c372017-03-22 11:26:44 +0100470 }
471
Adam Ford159a8872019-06-10 13:15:55 -0500472 /* pinctrl-single,pins not found so check for pinctrl-single,bits */
Lokesh Vutladbfd9e02020-04-22 22:55:31 +0530473 prop_bits = dev_read_prop(config, "pinctrl-single,bits", &len);
Adam Ford159a8872019-06-10 13:15:55 -0500474 if (prop_bits) {
475 dev_dbg(dev, "configuring pins for %s\n", config->name);
476 if (len % sizeof(struct single_fdt_bits_cfg)) {
477 dev_dbg(dev, " invalid bits configuration in fdt\n");
478 return -FDT_ERR_BADSTRUCTURE;
479 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200480 single_configure_bits(dev, prop_bits, len, config->name);
Adam Ford159a8872019-06-10 13:15:55 -0500481 return 0;
482 }
483
484 /* Neither 'pinctrl-single,pins' nor 'pinctrl-single,bits' were found */
Felix Brack44d5c372017-03-22 11:26:44 +0100485 return len;
486}
487
Dario Binacchi0b121622021-04-11 09:39:48 +0200488static const char *single_get_pin_name(struct udevice *dev,
489 unsigned int selector)
490{
491 struct single_priv *priv = dev_get_priv(dev);
492
493 if (selector >= priv->npins)
494 snprintf(priv->pin_name, PINNAME_SIZE, "Error");
495 else
496 snprintf(priv->pin_name, PINNAME_SIZE, "PIN%u", selector);
497
498 return priv->pin_name;
499}
500
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200501static int single_get_pins_count(struct udevice *dev)
502{
503 struct single_priv *priv = dev_get_priv(dev);
504
505 return priv->npins;
506}
507
Bharat Gooty62f86c62021-08-24 15:46:31 +0530508static int single_add_gpio_func(struct udevice *dev)
509{
510 struct single_priv *priv = dev_get_priv(dev);
511 const char *propname = "pinctrl-single,gpio-range";
512 const char *cellname = "#pinctrl-single,gpio-range-cells";
513 struct single_gpiofunc_range *range;
514 struct ofnode_phandle_args gpiospec;
515 int ret, i;
516
517 for (i = 0; ; i++) {
518 ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), propname,
519 cellname, 0, i, &gpiospec);
520 /* Do not treat it as error. Only treat it as end condition. */
521 if (ret) {
522 ret = 0;
523 break;
524 }
525 range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
526 if (!range) {
527 ret = -ENOMEM;
528 break;
529 }
530 range->offset = gpiospec.args[0];
531 range->npins = gpiospec.args[1];
532 range->gpiofunc = gpiospec.args[2];
533 list_add_tail(&range->node, &priv->gpiofuncs);
534 }
535 return ret;
536}
537
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200538static int single_probe(struct udevice *dev)
539{
540 struct single_pdata *pdata = dev_get_plat(dev);
541 struct single_priv *priv = dev_get_priv(dev);
542 u32 size;
543
Dario Binacchi76d470d2021-04-11 09:39:49 +0200544 INIT_LIST_HEAD(&priv->functions);
Bharat Gooty62f86c62021-08-24 15:46:31 +0530545 INIT_LIST_HEAD(&priv->gpiofuncs);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200546
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200547 size = pdata->offset + pdata->width / BITS_PER_BYTE;
Dario Binacchi55322622021-04-11 09:39:50 +0200548 #if (CONFIG_IS_ENABLED(SANDBOX))
549 priv->sandbox_regs =
550 devm_kzalloc(dev, size * sizeof(*priv->sandbox_regs),
551 GFP_KERNEL);
552 if (!priv->sandbox_regs)
553 return -ENOMEM;
554 #endif
555
Simon Glass4d159b62021-05-13 19:39:28 -0600556 /* looks like a possible divide by 0, but data->width avoids this */
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200557 priv->npins = size / (pdata->width / BITS_PER_BYTE);
558 if (pdata->bits_per_mux) {
Dario Binacchi69414d82021-04-22 18:35:58 +0200559 if (!pdata->mask) {
560 dev_err(dev, "function mask needs to be non-zero\n");
561 return -EINVAL;
562 }
563
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200564 priv->bits_per_pin = fls(pdata->mask);
565 priv->npins *= (pdata->width / priv->bits_per_pin);
566 }
567
Bharat Gooty62f86c62021-08-24 15:46:31 +0530568 if (single_add_gpio_func(dev))
569 dev_dbg(dev, "gpio functions are not added\n");
570
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200571 dev_dbg(dev, "%d pins\n", priv->npins);
572 return 0;
573}
574
Simon Glassd1998a92020-12-03 16:55:21 -0700575static int single_of_to_plat(struct udevice *dev)
Felix Brack44d5c372017-03-22 11:26:44 +0100576{
577 fdt_addr_t addr;
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200578 fdt_size_t size;
Simon Glass0fd3d912020-12-22 19:30:28 -0700579 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi971c64a2021-04-11 09:39:44 +0200580 int ret;
Felix Brack44d5c372017-03-22 11:26:44 +0100581
Dario Binacchi971c64a2021-04-11 09:39:44 +0200582 ret = dev_read_u32(dev, "pinctrl-single,register-width", &pdata->width);
583 if (ret) {
584 dev_err(dev, "missing register width\n");
585 return ret;
586 }
Felix Brack44d5c372017-03-22 11:26:44 +0100587
Dario Binacchi180531f2021-04-11 09:39:46 +0200588 switch (pdata->width) {
589 case 8:
590 case 16:
591 case 32:
592 break;
593 default:
594 dev_err(dev, "wrong register width\n");
595 return -EINVAL;
596 }
597
Vignesh Raghavendra1e787902021-05-07 14:40:34 +0530598 addr = dev_read_addr_size_index(dev, 0, &size);
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200599 if (addr == FDT_ADDR_T_NONE) {
Vignesh Raghavendra1e787902021-05-07 14:40:34 +0530600 dev_err(dev, "failed to get base register address\n");
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200601 return -EINVAL;
602 }
603
604 pdata->offset = size - pdata->width / BITS_PER_BYTE;
Felix Brack44d5c372017-03-22 11:26:44 +0100605 pdata->base = addr;
606
Dario Binacchid85b93e2021-04-11 09:39:45 +0200607 ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask);
608 if (ret) {
609 pdata->mask = 0;
610 dev_warn(dev, "missing function register mask\n");
611 }
612
Patrick Delaunay719cab62020-01-13 11:34:55 +0100613 pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
Adam Ford159a8872019-06-10 13:15:55 -0500614
Felix Brack44d5c372017-03-22 11:26:44 +0100615 return 0;
616}
617
618const struct pinctrl_ops single_pinctrl_ops = {
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200619 .get_pins_count = single_get_pins_count,
Dario Binacchi0b121622021-04-11 09:39:48 +0200620 .get_pin_name = single_get_pin_name,
Felix Brack44d5c372017-03-22 11:26:44 +0100621 .set_state = single_set_state,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200622 .get_pin_muxing = single_get_pin_muxing,
Bharat Gootyfd921d22021-08-24 15:46:32 +0530623 .request = single_request,
Felix Brack44d5c372017-03-22 11:26:44 +0100624};
625
626static const struct udevice_id single_pinctrl_match[] = {
627 { .compatible = "pinctrl-single" },
628 { /* sentinel */ }
629};
630
631U_BOOT_DRIVER(single_pinctrl) = {
632 .name = "single-pinctrl",
633 .id = UCLASS_PINCTRL,
634 .of_match = single_pinctrl_match,
635 .ops = &single_pinctrl_ops,
Simon Glasscaa4daa2020-12-03 16:55:18 -0700636 .plat_auto = sizeof(struct single_pdata),
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200637 .priv_auto = sizeof(struct single_priv),
Simon Glassd1998a92020-12-03 16:55:21 -0700638 .of_to_plat = single_of_to_plat,
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200639 .probe = single_probe,
Felix Brack44d5c372017-03-22 11:26:44 +0100640};