blob: d1db377c13799655a2a789bad24040f8c804095d [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>
Matthias Schiffer7f18fb82023-09-27 15:33:33 +02008#include <mapmem.h>
Simon Glass9d922452017-05-17 17:18:03 -06009#include <dm.h>
Simon Glass336d4612020-02-03 07:36:16 -070010#include <dm/device_compat.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020011#include <dm/devres.h>
Bharat Gooty62f86c62021-08-24 15:46:31 +053012#include <dm/of_access.h>
Felix Brack44d5c372017-03-22 11:26:44 +010013#include <dm/pinctrl.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +090014#include <linux/libfdt.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020015#include <linux/list.h>
Felix Brack44d5c372017-03-22 11:26:44 +010016#include <asm/io.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020017#include <sort.h>
Felix Brack44d5c372017-03-22 11:26:44 +010018
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020019/**
20 * struct single_pdata - platform data
21 * @base: first configuration register
22 * @offset: index of last configuration register
23 * @mask: configuration-value mask bits
24 * @width: configuration register bit width
25 * @bits_per_mux: true if one register controls more than one pin
26 */
Felix Brack44d5c372017-03-22 11:26:44 +010027struct single_pdata {
Matthias Schiffer7f18fb82023-09-27 15:33:33 +020028 void *base;
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020029 int offset;
30 u32 mask;
Dario Binacchi971c64a2021-04-11 09:39:44 +020031 u32 width;
AJ Bagwell1041eae2021-12-03 15:18:53 +000032 u32 args_count;
Adam Ford159a8872019-06-10 13:15:55 -050033 bool bits_per_mux;
Felix Brack44d5c372017-03-22 11:26:44 +010034};
35
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020036/**
Dario Binacchi76d470d2021-04-11 09:39:49 +020037 * struct single_func - pinctrl function
38 * @node: list node
39 * @name: pinctrl function name
40 * @npins: number of entries in pins array
41 * @pins: pins array
42 */
43struct single_func {
44 struct list_head node;
45 const char *name;
46 unsigned int npins;
47 unsigned int *pins;
48};
49
50/**
Bharat Gooty62f86c62021-08-24 15:46:31 +053051 * struct single_gpiofunc_range - pin ranges with same mux value of gpio fun
52 * @offset: offset base of pins
53 * @npins: number pins with the same mux value of gpio function
54 * @gpiofunc: mux value of gpio function
55 * @node: list node
56 */
57struct single_gpiofunc_range {
58 u32 offset;
59 u32 npins;
60 u32 gpiofunc;
61 struct list_head node;
62};
63
64/**
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020065 * struct single_priv - private data
66 * @bits_per_pin: number of bits per pin
67 * @npins: number of selectable pins
Dario Binacchi0b121622021-04-11 09:39:48 +020068 * @pin_name: temporary buffer to store the pin name
Bharat Gooty62f86c62021-08-24 15:46:31 +053069 * @functions: list pin functions
70 * @gpiofuncs: list gpio functions
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020071 */
72struct single_priv {
Dario Binacchi55322622021-04-11 09:39:50 +020073#if (IS_ENABLED(CONFIG_SANDBOX))
74 u32 *sandbox_regs;
75#endif
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020076 unsigned int bits_per_pin;
77 unsigned int npins;
Dario Binacchi0b121622021-04-11 09:39:48 +020078 char pin_name[PINNAME_SIZE];
Dario Binacchi76d470d2021-04-11 09:39:49 +020079 struct list_head functions;
Bharat Gooty62f86c62021-08-24 15:46:31 +053080 struct list_head gpiofuncs;
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020081};
82
83/**
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020084 * struct single_fdt_bits_cfg - pin configuration
85 *
86 * This structure is used for the pin configuration parameters in case
87 * the register controls more than one pin.
88 *
89 * @reg: configuration register offset
90 * @val: configuration register value
91 * @mask: configuration register mask
92 */
Adam Ford159a8872019-06-10 13:15:55 -050093struct single_fdt_bits_cfg {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020094 fdt32_t reg;
95 fdt32_t val;
96 fdt32_t mask;
Adam Ford159a8872019-06-10 13:15:55 -050097};
98
Dario Binacchi55322622021-04-11 09:39:50 +020099#if (!IS_ENABLED(CONFIG_SANDBOX))
100
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200101static unsigned int single_read(struct udevice *dev, void *reg)
Dario Binacchi180531f2021-04-11 09:39:46 +0200102{
103 struct single_pdata *pdata = dev_get_plat(dev);
104
105 switch (pdata->width) {
106 case 8:
107 return readb(reg);
108 case 16:
109 return readw(reg);
110 default: /* 32 bits */
111 return readl(reg);
112 }
113
114 return readb(reg);
115}
116
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200117static void single_write(struct udevice *dev, unsigned int val, void *reg)
Dario Binacchi180531f2021-04-11 09:39:46 +0200118{
119 struct single_pdata *pdata = dev_get_plat(dev);
120
121 switch (pdata->width) {
122 case 8:
123 writeb(val, reg);
124 break;
125 case 16:
126 writew(val, reg);
127 break;
128 default: /* 32 bits */
129 writel(val, reg);
130 }
131}
132
Dario Binacchi55322622021-04-11 09:39:50 +0200133#else /* CONFIG_SANDBOX */
134
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200135static unsigned int single_read(struct udevice *dev, void *reg)
Dario Binacchi55322622021-04-11 09:39:50 +0200136{
137 struct single_priv *priv = dev_get_priv(dev);
138
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200139 return priv->sandbox_regs[map_to_sysmem(reg)];
Dario Binacchi55322622021-04-11 09:39:50 +0200140}
141
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200142static void single_write(struct udevice *dev, unsigned int val, void *reg)
Dario Binacchi55322622021-04-11 09:39:50 +0200143{
144 struct single_priv *priv = dev_get_priv(dev);
145
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200146 priv->sandbox_regs[map_to_sysmem(reg)] = val;
Dario Binacchi55322622021-04-11 09:39:50 +0200147}
148
149#endif /* CONFIG_SANDBOX */
150
Felix Brack44d5c372017-03-22 11:26:44 +0100151/**
Dario Binacchi76d470d2021-04-11 09:39:49 +0200152 * single_get_pin_by_offset() - get a pin based on the register offset
153 * @dev: single driver instance
154 * @offset: register offset from the base
155 */
156static int single_get_pin_by_offset(struct udevice *dev, unsigned int offset)
157{
158 struct single_pdata *pdata = dev_get_plat(dev);
159 struct single_priv *priv = dev_get_priv(dev);
160
161 if (offset > pdata->offset) {
162 dev_err(dev, "mux offset out of range: 0x%x (0x%x)\n",
163 offset, pdata->offset);
164 return -EINVAL;
165 }
166
167 if (pdata->bits_per_mux)
168 return (offset * BITS_PER_BYTE) / priv->bits_per_pin;
169
170 return offset / (pdata->width / BITS_PER_BYTE);
171}
172
173static int single_get_offset_by_pin(struct udevice *dev, unsigned int pin)
174{
175 struct single_pdata *pdata = dev_get_plat(dev);
176 struct single_priv *priv = dev_get_priv(dev);
177 unsigned int mux_bytes;
178
179 if (pin >= priv->npins)
180 return -EINVAL;
181
182 mux_bytes = pdata->width / BITS_PER_BYTE;
183 if (pdata->bits_per_mux) {
184 int byte_num;
185
186 byte_num = (priv->bits_per_pin * pin) / BITS_PER_BYTE;
187 return (byte_num / mux_bytes) * mux_bytes;
188 }
189
190 return pin * mux_bytes;
191}
192
193static const char *single_get_pin_function(struct udevice *dev,
194 unsigned int pin)
195{
196 struct single_priv *priv = dev_get_priv(dev);
197 struct single_func *func;
198 int i;
199
200 list_for_each_entry(func, &priv->functions, node) {
201 for (i = 0; i < func->npins; i++) {
202 if (pin == func->pins[i])
203 return func->name;
204
205 if (pin < func->pins[i])
206 break;
207 }
208 }
209
210 return NULL;
211}
212
213static int single_get_pin_muxing(struct udevice *dev, unsigned int pin,
214 char *buf, int size)
215{
216 struct single_pdata *pdata = dev_get_plat(dev);
217 struct single_priv *priv = dev_get_priv(dev);
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200218 phys_addr_t phys_reg;
219 void *reg;
Dario Binacchi76d470d2021-04-11 09:39:49 +0200220 const char *fname;
221 unsigned int val;
222 int offset, pin_shift = 0;
223
224 offset = single_get_offset_by_pin(dev, pin);
225 if (offset < 0)
226 return offset;
227
228 reg = pdata->base + offset;
229 val = single_read(dev, reg);
230
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200231 phys_reg = map_to_sysmem(reg);
232
Dario Binacchi76d470d2021-04-11 09:39:49 +0200233 if (pdata->bits_per_mux)
234 pin_shift = pin % (pdata->width / priv->bits_per_pin) *
235 priv->bits_per_pin;
236
237 val &= (pdata->mask << pin_shift);
238 fname = single_get_pin_function(dev, pin);
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200239 snprintf(buf, size, "%pa 0x%08x %s", &phys_reg, val,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200240 fname ? fname : "UNCLAIMED");
241 return 0;
242}
243
Bharat Gootyfd921d22021-08-24 15:46:32 +0530244static int single_request(struct udevice *dev, int pin, int flags)
245{
246 struct single_priv *priv = dev_get_priv(dev);
247 struct single_pdata *pdata = dev_get_plat(dev);
248 struct single_gpiofunc_range *frange = NULL;
249 struct list_head *pos, *tmp;
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200250 void *reg;
Bharat Gootyfd921d22021-08-24 15:46:32 +0530251 int mux_bytes = 0;
252 u32 data;
253
254 /* If function mask is null, needn't enable it. */
255 if (!pdata->mask)
256 return -ENOTSUPP;
257
258 list_for_each_safe(pos, tmp, &priv->gpiofuncs) {
259 frange = list_entry(pos, struct single_gpiofunc_range, node);
260 if ((pin >= frange->offset + frange->npins) ||
261 pin < frange->offset)
262 continue;
263
264 mux_bytes = pdata->width / BITS_PER_BYTE;
265 reg = pdata->base + pin * mux_bytes;
266
267 data = single_read(dev, reg);
268 data &= ~pdata->mask;
269 data |= frange->gpiofunc;
270 single_write(dev, data, reg);
271 break;
272 }
273
274 return 0;
275}
276
Dario Binacchi76d470d2021-04-11 09:39:49 +0200277static struct single_func *single_allocate_function(struct udevice *dev,
278 unsigned int group_pins)
279{
280 struct single_func *func;
281
282 func = devm_kmalloc(dev, sizeof(*func), GFP_KERNEL);
283 if (!func)
284 return ERR_PTR(-ENOMEM);
285
286 func->pins = devm_kmalloc(dev, sizeof(unsigned int) * group_pins,
287 GFP_KERNEL);
288 if (!func->pins)
289 return ERR_PTR(-ENOMEM);
290
291 return func;
292}
293
294static int single_pin_compare(const void *s1, const void *s2)
295{
296 int pin1 = *(const unsigned int *)s1;
297 int pin2 = *(const unsigned int *)s2;
298
299 return pin1 - pin2;
300}
301
302/**
Felix Brack44d5c372017-03-22 11:26:44 +0100303 * single_configure_pins() - Configure pins based on FDT data
304 *
305 * @dev: Pointer to single pin configuration device which is the parent of
306 * the pins node holding the pin configuration data.
307 * @pins: Pointer to the first element of an array of register/value pairs
AJ Bagwell1041eae2021-12-03 15:18:53 +0000308 * of type 'u32'. Each such pair describes the pin to be configured
309 * and the value to be used for configuration.
310 * The value can either be a simple value if #pinctrl-cells = 1
311 * or a configuration value and a pin mux mode value if it is 2
Felix Brack44d5c372017-03-22 11:26:44 +0100312 * This pointer points to a 'pinctrl-single,pins' property in the
313 * device-tree.
314 * @size: Size of the 'pins' array in bytes.
AJ Bagwell1041eae2021-12-03 15:18:53 +0000315 * The number of cells in the array therefore equals to
316 * 'size / sizeof(u32)'.
Dario Binacchi76d470d2021-04-11 09:39:49 +0200317 * @fname: Function name.
Felix Brack44d5c372017-03-22 11:26:44 +0100318 */
319static int single_configure_pins(struct udevice *dev,
AJ Bagwell1041eae2021-12-03 15:18:53 +0000320 const u32 *pins,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200321 int size, const char *fname)
Felix Brack44d5c372017-03-22 11:26:44 +0100322{
Simon Glass0fd3d912020-12-22 19:30:28 -0700323 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200324 struct single_priv *priv = dev_get_priv(dev);
AJ Bagwell1041eae2021-12-03 15:18:53 +0000325 int stride = pdata->args_count + 1;
326 int n, pin, count = size / sizeof(u32);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200327 struct single_func *func;
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200328 void *reg;
AJ Bagwell1041eae2021-12-03 15:18:53 +0000329 u32 offset, val, mux;
Felix Brack44d5c372017-03-22 11:26:44 +0100330
Dario Binacchid85b93e2021-04-11 09:39:45 +0200331 /* If function mask is null, needn't enable it. */
332 if (!pdata->mask)
333 return 0;
334
Dario Binacchi76d470d2021-04-11 09:39:49 +0200335 func = single_allocate_function(dev, count);
336 if (IS_ERR(func))
337 return PTR_ERR(func);
338
339 func->name = fname;
340 func->npins = 0;
AJ Bagwell1041eae2021-12-03 15:18:53 +0000341 for (n = 0; n < count; n += stride) {
342 offset = fdt32_to_cpu(pins[n]);
Dario Binacchi230bc622021-04-22 22:28:56 +0200343 if (offset > pdata->offset) {
Dario Binacchi76d470d2021-04-11 09:39:49 +0200344 dev_err(dev, " invalid register offset 0x%x\n",
Dario Binacchi9b884e72021-04-11 09:39:41 +0200345 offset);
Felix Brack44d5c372017-03-22 11:26:44 +0100346 continue;
347 }
Dario Binacchi9b884e72021-04-11 09:39:41 +0200348
AJ Bagwell1041eae2021-12-03 15:18:53 +0000349 /* if the pinctrl-cells is 2 then the second cell contains the mux */
350 if (stride == 3)
351 mux = fdt32_to_cpu(pins[n + 2]);
352 else
353 mux = 0;
354
Dario Binacchi9b884e72021-04-11 09:39:41 +0200355 reg = pdata->base + offset;
AJ Bagwell1041eae2021-12-03 15:18:53 +0000356 val = (fdt32_to_cpu(pins[n + 1]) | mux) & 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;
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200386 void *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{
AJ Bagwell1041eae2021-12-03 15:18:53 +0000456 const u32 *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);
AJ Bagwell1041eae2021-12-03 15:18:53 +0000464 if (len % sizeof(u32)) {
Felix Brack44d5c372017-03-22 11:26:44 +0100465 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;
Simon Glassef746bf2023-02-05 15:40:42 -0700548 #if (IS_ENABLED(CONFIG_SANDBOX))
Dario Binacchi55322622021-04-11 09:39:50 +0200549 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{
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200577 void *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
Matthias Schiffer7f18fb82023-09-27 15:33:33 +0200598 addr = dev_read_addr_size_index_ptr(dev, 0, &size);
599 if (!addr) {
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
AJ Bagwell1041eae2021-12-03 15:18:53 +0000615 /* If no pinctrl-cells is present, default to old style of 2 cells with
616 * bits per mux and 1 cell otherwise.
617 */
618 ret = dev_read_u32(dev, "#pinctrl-cells", &pdata->args_count);
619 if (ret)
620 pdata->args_count = pdata->bits_per_mux ? 2 : 1;
621
Felix Brack44d5c372017-03-22 11:26:44 +0100622 return 0;
623}
624
625const struct pinctrl_ops single_pinctrl_ops = {
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200626 .get_pins_count = single_get_pins_count,
Dario Binacchi0b121622021-04-11 09:39:48 +0200627 .get_pin_name = single_get_pin_name,
Felix Brack44d5c372017-03-22 11:26:44 +0100628 .set_state = single_set_state,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200629 .get_pin_muxing = single_get_pin_muxing,
Bharat Gootyfd921d22021-08-24 15:46:32 +0530630 .request = single_request,
Felix Brack44d5c372017-03-22 11:26:44 +0100631};
632
633static const struct udevice_id single_pinctrl_match[] = {
634 { .compatible = "pinctrl-single" },
635 { /* sentinel */ }
636};
637
638U_BOOT_DRIVER(single_pinctrl) = {
639 .name = "single-pinctrl",
640 .id = UCLASS_PINCTRL,
641 .of_match = single_pinctrl_match,
642 .ops = &single_pinctrl_ops,
Simon Glasscaa4daa2020-12-03 16:55:18 -0700643 .plat_auto = sizeof(struct single_pdata),
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200644 .priv_auto = sizeof(struct single_priv),
Simon Glassd1998a92020-12-03 16:55:21 -0700645 .of_to_plat = single_of_to_plat,
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200646 .probe = single_probe,
Felix Brack44d5c372017-03-22 11:26:44 +0100647};