blob: bc9c17bce848f481bd47ec0cdc356c2484bb4858 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Felix Brack7bc23542017-03-22 11:26:44 +01002/*
3 * Copyright (C) EETS GmbH, 2017, Felix Brack <f.brack@eets.ch>
Dario Binacchi596c5082021-04-11 09:39:49 +02004 * Copyright (C) 2021 Dario Binacchi <dariobin@libero.it>
Felix Brack7bc23542017-03-22 11:26:44 +01005 */
6
7#include <common.h>
Simon Glass11c89f32017-05-17 17:18:03 -06008#include <dm.h>
Simon Glass9bc15642020-02-03 07:36:16 -07009#include <dm/device_compat.h>
Dario Binacchi596c5082021-04-11 09:39:49 +020010#include <dm/devres.h>
Bharat Gooty1063e102021-08-24 15:46:31 +053011#include <dm/of_access.h>
Felix Brack7bc23542017-03-22 11:26:44 +010012#include <dm/pinctrl.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090013#include <linux/libfdt.h>
Dario Binacchi596c5082021-04-11 09:39:49 +020014#include <linux/list.h>
Felix Brack7bc23542017-03-22 11:26:44 +010015#include <asm/io.h>
Dario Binacchi596c5082021-04-11 09:39:49 +020016#include <sort.h>
Felix Brack7bc23542017-03-22 11:26:44 +010017
Dario Binacchi3b488022021-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 Brack7bc23542017-03-22 11:26:44 +010026struct single_pdata {
Dario Binacchi3b488022021-04-11 09:39:39 +020027 fdt_addr_t base;
28 int offset;
29 u32 mask;
Dario Binacchi9e4051f2021-04-11 09:39:44 +020030 u32 width;
AJ Bagwelle98e87a2021-12-03 15:18:53 +000031 u32 args_count;
Adam Ford6305a5c2019-06-10 13:15:55 -050032 bool bits_per_mux;
Felix Brack7bc23542017-03-22 11:26:44 +010033};
34
Dario Binacchi3b488022021-04-11 09:39:39 +020035/**
Dario Binacchi596c5082021-04-11 09:39:49 +020036 * struct single_func - pinctrl function
37 * @node: list node
38 * @name: pinctrl function name
39 * @npins: number of entries in pins array
40 * @pins: pins array
41 */
42struct single_func {
43 struct list_head node;
44 const char *name;
45 unsigned int npins;
46 unsigned int *pins;
47};
48
49/**
Bharat Gooty1063e102021-08-24 15:46:31 +053050 * struct single_gpiofunc_range - pin ranges with same mux value of gpio fun
51 * @offset: offset base of pins
52 * @npins: number pins with the same mux value of gpio function
53 * @gpiofunc: mux value of gpio function
54 * @node: list node
55 */
56struct single_gpiofunc_range {
57 u32 offset;
58 u32 npins;
59 u32 gpiofunc;
60 struct list_head node;
61};
62
63/**
Dario Binacchi235132c2021-04-11 09:39:47 +020064 * struct single_priv - private data
65 * @bits_per_pin: number of bits per pin
66 * @npins: number of selectable pins
Dario Binacchif3ecbc12021-04-11 09:39:48 +020067 * @pin_name: temporary buffer to store the pin name
Bharat Gooty1063e102021-08-24 15:46:31 +053068 * @functions: list pin functions
69 * @gpiofuncs: list gpio functions
Dario Binacchi235132c2021-04-11 09:39:47 +020070 */
71struct single_priv {
Dario Binacchi20dd9e12021-04-11 09:39:50 +020072#if (IS_ENABLED(CONFIG_SANDBOX))
73 u32 *sandbox_regs;
74#endif
Dario Binacchi235132c2021-04-11 09:39:47 +020075 unsigned int bits_per_pin;
76 unsigned int npins;
Dario Binacchif3ecbc12021-04-11 09:39:48 +020077 char pin_name[PINNAME_SIZE];
Dario Binacchi596c5082021-04-11 09:39:49 +020078 struct list_head functions;
Bharat Gooty1063e102021-08-24 15:46:31 +053079 struct list_head gpiofuncs;
Dario Binacchi235132c2021-04-11 09:39:47 +020080};
81
82/**
Dario Binacchi3b488022021-04-11 09:39:39 +020083 * struct single_fdt_bits_cfg - pin configuration
84 *
85 * This structure is used for the pin configuration parameters in case
86 * the register controls more than one pin.
87 *
88 * @reg: configuration register offset
89 * @val: configuration register value
90 * @mask: configuration register mask
91 */
Adam Ford6305a5c2019-06-10 13:15:55 -050092struct single_fdt_bits_cfg {
Dario Binacchi3b488022021-04-11 09:39:39 +020093 fdt32_t reg;
94 fdt32_t val;
95 fdt32_t mask;
Adam Ford6305a5c2019-06-10 13:15:55 -050096};
97
Dario Binacchi20dd9e12021-04-11 09:39:50 +020098#if (!IS_ENABLED(CONFIG_SANDBOX))
99
Dario Binacchi54dfe522021-04-11 09:39:46 +0200100static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
101{
102 struct single_pdata *pdata = dev_get_plat(dev);
103
104 switch (pdata->width) {
105 case 8:
106 return readb(reg);
107 case 16:
108 return readw(reg);
109 default: /* 32 bits */
110 return readl(reg);
111 }
112
113 return readb(reg);
114}
115
116static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
117{
118 struct single_pdata *pdata = dev_get_plat(dev);
119
120 switch (pdata->width) {
121 case 8:
122 writeb(val, reg);
123 break;
124 case 16:
125 writew(val, reg);
126 break;
127 default: /* 32 bits */
128 writel(val, reg);
129 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200130}
131
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200132#else /* CONFIG_SANDBOX */
133
134static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
135{
136 struct single_priv *priv = dev_get_priv(dev);
137
138 return priv->sandbox_regs[reg];
139}
140
141static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
142{
143 struct single_priv *priv = dev_get_priv(dev);
144
145 priv->sandbox_regs[reg] = val;
146}
147
148#endif /* CONFIG_SANDBOX */
149
Dario Binacchi596c5082021-04-11 09:39:49 +0200150/**
151 * single_get_pin_by_offset() - get a pin based on the register offset
152 * @dev: single driver instance
153 * @offset: register offset from the base
154 */
155static int single_get_pin_by_offset(struct udevice *dev, unsigned int offset)
156{
157 struct single_pdata *pdata = dev_get_plat(dev);
158 struct single_priv *priv = dev_get_priv(dev);
159
160 if (offset > pdata->offset) {
161 dev_err(dev, "mux offset out of range: 0x%x (0x%x)\n",
162 offset, pdata->offset);
163 return -EINVAL;
164 }
165
166 if (pdata->bits_per_mux)
167 return (offset * BITS_PER_BYTE) / priv->bits_per_pin;
168
169 return offset / (pdata->width / BITS_PER_BYTE);
170}
171
172static int single_get_offset_by_pin(struct udevice *dev, unsigned int pin)
173{
174 struct single_pdata *pdata = dev_get_plat(dev);
175 struct single_priv *priv = dev_get_priv(dev);
176 unsigned int mux_bytes;
177
178 if (pin >= priv->npins)
179 return -EINVAL;
180
181 mux_bytes = pdata->width / BITS_PER_BYTE;
182 if (pdata->bits_per_mux) {
183 int byte_num;
184
185 byte_num = (priv->bits_per_pin * pin) / BITS_PER_BYTE;
186 return (byte_num / mux_bytes) * mux_bytes;
187 }
188
189 return pin * mux_bytes;
190}
191
192static const char *single_get_pin_function(struct udevice *dev,
193 unsigned int pin)
194{
195 struct single_priv *priv = dev_get_priv(dev);
196 struct single_func *func;
197 int i;
198
199 list_for_each_entry(func, &priv->functions, node) {
200 for (i = 0; i < func->npins; i++) {
201 if (pin == func->pins[i])
202 return func->name;
203
204 if (pin < func->pins[i])
205 break;
206 }
207 }
208
209 return NULL;
210}
211
212static int single_get_pin_muxing(struct udevice *dev, unsigned int pin,
213 char *buf, int size)
214{
215 struct single_pdata *pdata = dev_get_plat(dev);
216 struct single_priv *priv = dev_get_priv(dev);
217 fdt_addr_t reg;
218 const char *fname;
219 unsigned int val;
220 int offset, pin_shift = 0;
221
222 offset = single_get_offset_by_pin(dev, pin);
223 if (offset < 0)
224 return offset;
225
226 reg = pdata->base + offset;
227 val = single_read(dev, reg);
228
229 if (pdata->bits_per_mux)
230 pin_shift = pin % (pdata->width / priv->bits_per_pin) *
231 priv->bits_per_pin;
232
233 val &= (pdata->mask << pin_shift);
234 fname = single_get_pin_function(dev, pin);
235 snprintf(buf, size, "%pa 0x%08x %s", &reg, val,
236 fname ? fname : "UNCLAIMED");
237 return 0;
238}
239
Bharat Gootyf02f9572021-08-24 15:46:32 +0530240static int single_request(struct udevice *dev, int pin, int flags)
241{
242 struct single_priv *priv = dev_get_priv(dev);
243 struct single_pdata *pdata = dev_get_plat(dev);
244 struct single_gpiofunc_range *frange = NULL;
245 struct list_head *pos, *tmp;
246 phys_addr_t reg;
247 int mux_bytes = 0;
248 u32 data;
249
250 /* If function mask is null, needn't enable it. */
251 if (!pdata->mask)
252 return -ENOTSUPP;
253
254 list_for_each_safe(pos, tmp, &priv->gpiofuncs) {
255 frange = list_entry(pos, struct single_gpiofunc_range, node);
256 if ((pin >= frange->offset + frange->npins) ||
257 pin < frange->offset)
258 continue;
259
260 mux_bytes = pdata->width / BITS_PER_BYTE;
261 reg = pdata->base + pin * mux_bytes;
262
263 data = single_read(dev, reg);
264 data &= ~pdata->mask;
265 data |= frange->gpiofunc;
266 single_write(dev, data, reg);
267 break;
268 }
269
270 return 0;
271}
272
Dario Binacchi596c5082021-04-11 09:39:49 +0200273static struct single_func *single_allocate_function(struct udevice *dev,
274 unsigned int group_pins)
275{
276 struct single_func *func;
277
278 func = devm_kmalloc(dev, sizeof(*func), GFP_KERNEL);
279 if (!func)
280 return ERR_PTR(-ENOMEM);
281
282 func->pins = devm_kmalloc(dev, sizeof(unsigned int) * group_pins,
283 GFP_KERNEL);
284 if (!func->pins)
285 return ERR_PTR(-ENOMEM);
286
287 return func;
288}
289
290static int single_pin_compare(const void *s1, const void *s2)
291{
292 int pin1 = *(const unsigned int *)s1;
293 int pin2 = *(const unsigned int *)s2;
294
295 return pin1 - pin2;
Dario Binacchi54dfe522021-04-11 09:39:46 +0200296}
297
Felix Brack7bc23542017-03-22 11:26:44 +0100298/**
299 * single_configure_pins() - Configure pins based on FDT data
300 *
301 * @dev: Pointer to single pin configuration device which is the parent of
302 * the pins node holding the pin configuration data.
303 * @pins: Pointer to the first element of an array of register/value pairs
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000304 * of type 'u32'. Each such pair describes the pin to be configured
305 * and the value to be used for configuration.
306 * The value can either be a simple value if #pinctrl-cells = 1
307 * or a configuration value and a pin mux mode value if it is 2
Felix Brack7bc23542017-03-22 11:26:44 +0100308 * This pointer points to a 'pinctrl-single,pins' property in the
309 * device-tree.
310 * @size: Size of the 'pins' array in bytes.
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000311 * The number of cells in the array therefore equals to
312 * 'size / sizeof(u32)'.
Dario Binacchi596c5082021-04-11 09:39:49 +0200313 * @fname: Function name.
Felix Brack7bc23542017-03-22 11:26:44 +0100314 */
315static int single_configure_pins(struct udevice *dev,
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000316 const u32 *pins,
Dario Binacchi596c5082021-04-11 09:39:49 +0200317 int size, const char *fname)
Felix Brack7bc23542017-03-22 11:26:44 +0100318{
Simon Glass95588622020-12-22 19:30:28 -0700319 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi596c5082021-04-11 09:39:49 +0200320 struct single_priv *priv = dev_get_priv(dev);
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000321 int stride = pdata->args_count + 1;
322 int n, pin, count = size / sizeof(u32);
Dario Binacchi596c5082021-04-11 09:39:49 +0200323 struct single_func *func;
Dario Binacchie02eea32021-04-11 09:39:40 +0200324 phys_addr_t reg;
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000325 u32 offset, val, mux;
Felix Brack7bc23542017-03-22 11:26:44 +0100326
Dario Binacchi12f50452021-04-11 09:39:45 +0200327 /* If function mask is null, needn't enable it. */
328 if (!pdata->mask)
329 return 0;
330
Dario Binacchi596c5082021-04-11 09:39:49 +0200331 func = single_allocate_function(dev, count);
332 if (IS_ERR(func))
333 return PTR_ERR(func);
334
335 func->name = fname;
336 func->npins = 0;
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000337 for (n = 0; n < count; n += stride) {
338 offset = fdt32_to_cpu(pins[n]);
Dario Binacchia0cbd6a2021-04-22 22:28:56 +0200339 if (offset > pdata->offset) {
Dario Binacchi596c5082021-04-11 09:39:49 +0200340 dev_err(dev, " invalid register offset 0x%x\n",
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200341 offset);
Felix Brack7bc23542017-03-22 11:26:44 +0100342 continue;
343 }
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200344
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000345 /* if the pinctrl-cells is 2 then the second cell contains the mux */
346 if (stride == 3)
347 mux = fdt32_to_cpu(pins[n + 2]);
348 else
349 mux = 0;
350
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200351 reg = pdata->base + offset;
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000352 val = (fdt32_to_cpu(pins[n + 1]) | mux) & pdata->mask;
Dario Binacchi596c5082021-04-11 09:39:49 +0200353 pin = single_get_pin_by_offset(dev, offset);
354 if (pin < 0) {
355 dev_err(dev, " failed to get pin by offset %x\n",
356 offset);
357 continue;
358 }
359
Dario Binacchi54dfe522021-04-11 09:39:46 +0200360 single_write(dev, (single_read(dev, reg) & ~pdata->mask) | val,
361 reg);
Dario Binacchi35f4ac52021-04-11 09:39:42 +0200362 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi596c5082021-04-11 09:39:49 +0200363 func->pins[func->npins] = pin;
364 func->npins++;
Felix Brack7bc23542017-03-22 11:26:44 +0100365 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200366
367 qsort(func->pins, func->npins, sizeof(func->pins[0]),
368 single_pin_compare);
369 list_add(&func->node, &priv->functions);
Felix Brack7bc23542017-03-22 11:26:44 +0100370 return 0;
371}
372
Adam Ford6305a5c2019-06-10 13:15:55 -0500373static int single_configure_bits(struct udevice *dev,
374 const struct single_fdt_bits_cfg *pins,
Dario Binacchi596c5082021-04-11 09:39:49 +0200375 int size, const char *fname)
Adam Ford6305a5c2019-06-10 13:15:55 -0500376{
Simon Glass95588622020-12-22 19:30:28 -0700377 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi596c5082021-04-11 09:39:49 +0200378 struct single_priv *priv = dev_get_priv(dev);
379 int n, pin, count = size / sizeof(struct single_fdt_bits_cfg);
380 int npins_in_reg, pin_num_from_lsb;
381 struct single_func *func;
Dario Binacchie02eea32021-04-11 09:39:40 +0200382 phys_addr_t reg;
Dario Binacchi596c5082021-04-11 09:39:49 +0200383 u32 offset, val, mask, bit_pos, val_pos, mask_pos, submask;
Adam Ford6305a5c2019-06-10 13:15:55 -0500384
Dario Binacchi376daa82021-04-22 18:35:58 +0200385 /* If function mask is null, needn't enable it. */
386 if (!pdata->mask)
387 return 0;
388
Dario Binacchi596c5082021-04-11 09:39:49 +0200389 npins_in_reg = pdata->width / priv->bits_per_pin;
390 func = single_allocate_function(dev, count * npins_in_reg);
391 if (IS_ERR(func))
392 return PTR_ERR(func);
393
394 func->name = fname;
395 func->npins = 0;
Adam Ford6305a5c2019-06-10 13:15:55 -0500396 for (n = 0; n < count; n++, pins++) {
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200397 offset = fdt32_to_cpu(pins->reg);
Dario Binacchia0cbd6a2021-04-22 22:28:56 +0200398 if (offset > pdata->offset) {
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200399 dev_dbg(dev, " invalid register offset 0x%x\n",
400 offset);
Adam Ford6305a5c2019-06-10 13:15:55 -0500401 continue;
402 }
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200403
404 reg = pdata->base + offset;
Adam Ford6305a5c2019-06-10 13:15:55 -0500405
Dario Binacchi596c5082021-04-11 09:39:49 +0200406 pin = single_get_pin_by_offset(dev, offset);
407 if (pin < 0) {
408 dev_err(dev, " failed to get pin by offset 0x%pa\n",
409 &reg);
410 continue;
411 }
412
Adam Ford6305a5c2019-06-10 13:15:55 -0500413 mask = fdt32_to_cpu(pins->mask);
414 val = fdt32_to_cpu(pins->val) & mask;
Dario Binacchi54dfe522021-04-11 09:39:46 +0200415 single_write(dev, (single_read(dev, reg) & ~mask) | val, reg);
Dario Binacchi35f4ac52021-04-11 09:39:42 +0200416 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi596c5082021-04-11 09:39:49 +0200417
418 while (mask) {
419 bit_pos = __ffs(mask);
420 pin_num_from_lsb = bit_pos / priv->bits_per_pin;
421 mask_pos = pdata->mask << bit_pos;
422 val_pos = val & mask_pos;
423 submask = mask & mask_pos;
424
425 if ((mask & mask_pos) == 0) {
426 dev_err(dev, "Invalid mask at 0x%x\n", offset);
427 break;
428 }
429
430 mask &= ~mask_pos;
431
432 if (submask != mask_pos) {
433 dev_warn(dev,
434 "Invalid submask 0x%x at 0x%x\n",
435 submask, offset);
436 continue;
437 }
438
439 func->pins[func->npins] = pin + pin_num_from_lsb;
440 func->npins++;
441 }
Adam Ford6305a5c2019-06-10 13:15:55 -0500442 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200443
444 qsort(func->pins, func->npins, sizeof(func->pins[0]),
445 single_pin_compare);
446 list_add(&func->node, &priv->functions);
Adam Ford6305a5c2019-06-10 13:15:55 -0500447 return 0;
448}
Felix Brack7bc23542017-03-22 11:26:44 +0100449static int single_set_state(struct udevice *dev,
450 struct udevice *config)
451{
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000452 const u32 *prop;
Adam Ford6305a5c2019-06-10 13:15:55 -0500453 const struct single_fdt_bits_cfg *prop_bits;
Felix Brack7bc23542017-03-22 11:26:44 +0100454 int len;
455
Lokesh Vutla0bef0262020-04-22 22:55:31 +0530456 prop = dev_read_prop(config, "pinctrl-single,pins", &len);
Adam Ford6305a5c2019-06-10 13:15:55 -0500457
Felix Brack7bc23542017-03-22 11:26:44 +0100458 if (prop) {
459 dev_dbg(dev, "configuring pins for %s\n", config->name);
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000460 if (len % sizeof(u32)) {
Felix Brack7bc23542017-03-22 11:26:44 +0100461 dev_dbg(dev, " invalid pin configuration in fdt\n");
462 return -FDT_ERR_BADSTRUCTURE;
463 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200464 single_configure_pins(dev, prop, len, config->name);
Adam Ford6305a5c2019-06-10 13:15:55 -0500465 return 0;
Felix Brack7bc23542017-03-22 11:26:44 +0100466 }
467
Adam Ford6305a5c2019-06-10 13:15:55 -0500468 /* pinctrl-single,pins not found so check for pinctrl-single,bits */
Lokesh Vutla0bef0262020-04-22 22:55:31 +0530469 prop_bits = dev_read_prop(config, "pinctrl-single,bits", &len);
Adam Ford6305a5c2019-06-10 13:15:55 -0500470 if (prop_bits) {
471 dev_dbg(dev, "configuring pins for %s\n", config->name);
472 if (len % sizeof(struct single_fdt_bits_cfg)) {
473 dev_dbg(dev, " invalid bits configuration in fdt\n");
474 return -FDT_ERR_BADSTRUCTURE;
475 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200476 single_configure_bits(dev, prop_bits, len, config->name);
Adam Ford6305a5c2019-06-10 13:15:55 -0500477 return 0;
478 }
479
480 /* Neither 'pinctrl-single,pins' nor 'pinctrl-single,bits' were found */
Felix Brack7bc23542017-03-22 11:26:44 +0100481 return len;
482}
483
Dario Binacchif3ecbc12021-04-11 09:39:48 +0200484static const char *single_get_pin_name(struct udevice *dev,
485 unsigned int selector)
486{
487 struct single_priv *priv = dev_get_priv(dev);
488
489 if (selector >= priv->npins)
490 snprintf(priv->pin_name, PINNAME_SIZE, "Error");
491 else
492 snprintf(priv->pin_name, PINNAME_SIZE, "PIN%u", selector);
493
494 return priv->pin_name;
495}
496
Dario Binacchi235132c2021-04-11 09:39:47 +0200497static int single_get_pins_count(struct udevice *dev)
498{
499 struct single_priv *priv = dev_get_priv(dev);
500
501 return priv->npins;
502}
503
Bharat Gooty1063e102021-08-24 15:46:31 +0530504static int single_add_gpio_func(struct udevice *dev)
505{
506 struct single_priv *priv = dev_get_priv(dev);
507 const char *propname = "pinctrl-single,gpio-range";
508 const char *cellname = "#pinctrl-single,gpio-range-cells";
509 struct single_gpiofunc_range *range;
510 struct ofnode_phandle_args gpiospec;
511 int ret, i;
512
513 for (i = 0; ; i++) {
514 ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), propname,
515 cellname, 0, i, &gpiospec);
516 /* Do not treat it as error. Only treat it as end condition. */
517 if (ret) {
518 ret = 0;
519 break;
520 }
521 range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
522 if (!range) {
523 ret = -ENOMEM;
524 break;
525 }
526 range->offset = gpiospec.args[0];
527 range->npins = gpiospec.args[1];
528 range->gpiofunc = gpiospec.args[2];
529 list_add_tail(&range->node, &priv->gpiofuncs);
530 }
531 return ret;
532}
533
Dario Binacchi235132c2021-04-11 09:39:47 +0200534static int single_probe(struct udevice *dev)
535{
536 struct single_pdata *pdata = dev_get_plat(dev);
537 struct single_priv *priv = dev_get_priv(dev);
538 u32 size;
539
Dario Binacchi596c5082021-04-11 09:39:49 +0200540 INIT_LIST_HEAD(&priv->functions);
Bharat Gooty1063e102021-08-24 15:46:31 +0530541 INIT_LIST_HEAD(&priv->gpiofuncs);
Dario Binacchi596c5082021-04-11 09:39:49 +0200542
Dario Binacchi235132c2021-04-11 09:39:47 +0200543 size = pdata->offset + pdata->width / BITS_PER_BYTE;
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200544 #if (CONFIG_IS_ENABLED(SANDBOX))
545 priv->sandbox_regs =
546 devm_kzalloc(dev, size * sizeof(*priv->sandbox_regs),
547 GFP_KERNEL);
548 if (!priv->sandbox_regs)
549 return -ENOMEM;
550 #endif
551
Simon Glass43b82f52021-05-13 19:39:28 -0600552 /* looks like a possible divide by 0, but data->width avoids this */
Dario Binacchi235132c2021-04-11 09:39:47 +0200553 priv->npins = size / (pdata->width / BITS_PER_BYTE);
554 if (pdata->bits_per_mux) {
Dario Binacchi376daa82021-04-22 18:35:58 +0200555 if (!pdata->mask) {
556 dev_err(dev, "function mask needs to be non-zero\n");
557 return -EINVAL;
558 }
559
Dario Binacchi235132c2021-04-11 09:39:47 +0200560 priv->bits_per_pin = fls(pdata->mask);
561 priv->npins *= (pdata->width / priv->bits_per_pin);
562 }
563
Bharat Gooty1063e102021-08-24 15:46:31 +0530564 if (single_add_gpio_func(dev))
565 dev_dbg(dev, "gpio functions are not added\n");
566
Dario Binacchi235132c2021-04-11 09:39:47 +0200567 dev_dbg(dev, "%d pins\n", priv->npins);
568 return 0;
569}
570
Simon Glassaad29ae2020-12-03 16:55:21 -0700571static int single_of_to_plat(struct udevice *dev)
Felix Brack7bc23542017-03-22 11:26:44 +0100572{
573 fdt_addr_t addr;
Dario Binacchi22fb01d2021-04-11 09:39:43 +0200574 fdt_size_t size;
Simon Glass95588622020-12-22 19:30:28 -0700575 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi9e4051f2021-04-11 09:39:44 +0200576 int ret;
Felix Brack7bc23542017-03-22 11:26:44 +0100577
Dario Binacchi9e4051f2021-04-11 09:39:44 +0200578 ret = dev_read_u32(dev, "pinctrl-single,register-width", &pdata->width);
579 if (ret) {
580 dev_err(dev, "missing register width\n");
581 return ret;
582 }
Felix Brack7bc23542017-03-22 11:26:44 +0100583
Dario Binacchi54dfe522021-04-11 09:39:46 +0200584 switch (pdata->width) {
585 case 8:
586 case 16:
587 case 32:
588 break;
589 default:
590 dev_err(dev, "wrong register width\n");
591 return -EINVAL;
592 }
593
Vignesh Raghavendrac074a182021-05-07 14:40:34 +0530594 addr = dev_read_addr_size_index(dev, 0, &size);
Dario Binacchi22fb01d2021-04-11 09:39:43 +0200595 if (addr == FDT_ADDR_T_NONE) {
Vignesh Raghavendrac074a182021-05-07 14:40:34 +0530596 dev_err(dev, "failed to get base register address\n");
Dario Binacchi22fb01d2021-04-11 09:39:43 +0200597 return -EINVAL;
598 }
599
600 pdata->offset = size - pdata->width / BITS_PER_BYTE;
Felix Brack7bc23542017-03-22 11:26:44 +0100601 pdata->base = addr;
602
Dario Binacchi12f50452021-04-11 09:39:45 +0200603 ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask);
604 if (ret) {
605 pdata->mask = 0;
606 dev_warn(dev, "missing function register mask\n");
607 }
608
Patrick Delaunayaf2fb742020-01-13 11:34:55 +0100609 pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
Adam Ford6305a5c2019-06-10 13:15:55 -0500610
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000611 /* If no pinctrl-cells is present, default to old style of 2 cells with
612 * bits per mux and 1 cell otherwise.
613 */
614 ret = dev_read_u32(dev, "#pinctrl-cells", &pdata->args_count);
615 if (ret)
616 pdata->args_count = pdata->bits_per_mux ? 2 : 1;
617
Felix Brack7bc23542017-03-22 11:26:44 +0100618 return 0;
619}
620
621const struct pinctrl_ops single_pinctrl_ops = {
Dario Binacchi235132c2021-04-11 09:39:47 +0200622 .get_pins_count = single_get_pins_count,
Dario Binacchif3ecbc12021-04-11 09:39:48 +0200623 .get_pin_name = single_get_pin_name,
Felix Brack7bc23542017-03-22 11:26:44 +0100624 .set_state = single_set_state,
Dario Binacchi596c5082021-04-11 09:39:49 +0200625 .get_pin_muxing = single_get_pin_muxing,
Bharat Gootyf02f9572021-08-24 15:46:32 +0530626 .request = single_request,
Felix Brack7bc23542017-03-22 11:26:44 +0100627};
628
629static const struct udevice_id single_pinctrl_match[] = {
630 { .compatible = "pinctrl-single" },
631 { /* sentinel */ }
632};
633
634U_BOOT_DRIVER(single_pinctrl) = {
635 .name = "single-pinctrl",
636 .id = UCLASS_PINCTRL,
637 .of_match = single_pinctrl_match,
638 .ops = &single_pinctrl_ops,
Simon Glass71fa5b42020-12-03 16:55:18 -0700639 .plat_auto = sizeof(struct single_pdata),
Dario Binacchi235132c2021-04-11 09:39:47 +0200640 .priv_auto = sizeof(struct single_priv),
Simon Glassaad29ae2020-12-03 16:55:21 -0700641 .of_to_plat = single_of_to_plat,
Dario Binacchi235132c2021-04-11 09:39:47 +0200642 .probe = single_probe,
Felix Brack7bc23542017-03-22 11:26:44 +0100643};