blob: a3802d22d4f92cd644f6647de494c26c4207b1d1 [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
Matthias Schifferbb970d52023-09-27 15:33:33 +02007#include <mapmem.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 {
Matthias Schifferbb970d52023-09-27 15:33:33 +020027 void *base;
Dario Binacchi3b488022021-04-11 09:39:39 +020028 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
Matthias Schifferbb970d52023-09-27 15:33:33 +0200100static unsigned int single_read(struct udevice *dev, void *reg)
Dario Binacchi54dfe522021-04-11 09:39:46 +0200101{
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
Matthias Schifferbb970d52023-09-27 15:33:33 +0200116static void single_write(struct udevice *dev, unsigned int val, void *reg)
Dario Binacchi54dfe522021-04-11 09:39:46 +0200117{
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
Matthias Schifferbb970d52023-09-27 15:33:33 +0200134static unsigned int single_read(struct udevice *dev, void *reg)
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200135{
136 struct single_priv *priv = dev_get_priv(dev);
137
Matthias Schifferbb970d52023-09-27 15:33:33 +0200138 return priv->sandbox_regs[map_to_sysmem(reg)];
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200139}
140
Matthias Schifferbb970d52023-09-27 15:33:33 +0200141static void single_write(struct udevice *dev, unsigned int val, void *reg)
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200142{
143 struct single_priv *priv = dev_get_priv(dev);
144
Matthias Schifferbb970d52023-09-27 15:33:33 +0200145 priv->sandbox_regs[map_to_sysmem(reg)] = val;
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200146}
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);
Matthias Schifferbb970d52023-09-27 15:33:33 +0200217 phys_addr_t phys_reg;
218 void *reg;
Dario Binacchi596c5082021-04-11 09:39:49 +0200219 const char *fname;
220 unsigned int val;
221 int offset, pin_shift = 0;
222
223 offset = single_get_offset_by_pin(dev, pin);
224 if (offset < 0)
225 return offset;
226
227 reg = pdata->base + offset;
228 val = single_read(dev, reg);
229
Matthias Schifferbb970d52023-09-27 15:33:33 +0200230 phys_reg = map_to_sysmem(reg);
231
Dario Binacchi596c5082021-04-11 09:39:49 +0200232 if (pdata->bits_per_mux)
233 pin_shift = pin % (pdata->width / priv->bits_per_pin) *
234 priv->bits_per_pin;
235
236 val &= (pdata->mask << pin_shift);
237 fname = single_get_pin_function(dev, pin);
Matthias Schifferbb970d52023-09-27 15:33:33 +0200238 snprintf(buf, size, "%pa 0x%08x %s", &phys_reg, val,
Dario Binacchi596c5082021-04-11 09:39:49 +0200239 fname ? fname : "UNCLAIMED");
240 return 0;
241}
242
Bharat Gootyf02f9572021-08-24 15:46:32 +0530243static int single_request(struct udevice *dev, int pin, int flags)
244{
245 struct single_priv *priv = dev_get_priv(dev);
246 struct single_pdata *pdata = dev_get_plat(dev);
247 struct single_gpiofunc_range *frange = NULL;
248 struct list_head *pos, *tmp;
Matthias Schifferbb970d52023-09-27 15:33:33 +0200249 void *reg;
Bharat Gootyf02f9572021-08-24 15:46:32 +0530250 int mux_bytes = 0;
251 u32 data;
252
253 /* If function mask is null, needn't enable it. */
254 if (!pdata->mask)
255 return -ENOTSUPP;
256
257 list_for_each_safe(pos, tmp, &priv->gpiofuncs) {
258 frange = list_entry(pos, struct single_gpiofunc_range, node);
259 if ((pin >= frange->offset + frange->npins) ||
260 pin < frange->offset)
261 continue;
262
263 mux_bytes = pdata->width / BITS_PER_BYTE;
264 reg = pdata->base + pin * mux_bytes;
265
266 data = single_read(dev, reg);
267 data &= ~pdata->mask;
268 data |= frange->gpiofunc;
269 single_write(dev, data, reg);
270 break;
271 }
272
273 return 0;
274}
275
Dario Binacchi596c5082021-04-11 09:39:49 +0200276static struct single_func *single_allocate_function(struct udevice *dev,
277 unsigned int group_pins)
278{
279 struct single_func *func;
280
281 func = devm_kmalloc(dev, sizeof(*func), GFP_KERNEL);
282 if (!func)
283 return ERR_PTR(-ENOMEM);
284
285 func->pins = devm_kmalloc(dev, sizeof(unsigned int) * group_pins,
286 GFP_KERNEL);
287 if (!func->pins)
288 return ERR_PTR(-ENOMEM);
289
290 return func;
291}
292
293static int single_pin_compare(const void *s1, const void *s2)
294{
295 int pin1 = *(const unsigned int *)s1;
296 int pin2 = *(const unsigned int *)s2;
297
298 return pin1 - pin2;
Dario Binacchi54dfe522021-04-11 09:39:46 +0200299}
300
Felix Brack7bc23542017-03-22 11:26:44 +0100301/**
302 * single_configure_pins() - Configure pins based on FDT data
303 *
304 * @dev: Pointer to single pin configuration device which is the parent of
305 * the pins node holding the pin configuration data.
306 * @pins: Pointer to the first element of an array of register/value pairs
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000307 * of type 'u32'. Each such pair describes the pin to be configured
308 * and the value to be used for configuration.
309 * The value can either be a simple value if #pinctrl-cells = 1
310 * or a configuration value and a pin mux mode value if it is 2
Felix Brack7bc23542017-03-22 11:26:44 +0100311 * This pointer points to a 'pinctrl-single,pins' property in the
312 * device-tree.
313 * @size: Size of the 'pins' array in bytes.
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000314 * The number of cells in the array therefore equals to
315 * 'size / sizeof(u32)'.
Dario Binacchi596c5082021-04-11 09:39:49 +0200316 * @fname: Function name.
Felix Brack7bc23542017-03-22 11:26:44 +0100317 */
318static int single_configure_pins(struct udevice *dev,
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000319 const u32 *pins,
Dario Binacchi596c5082021-04-11 09:39:49 +0200320 int size, const char *fname)
Felix Brack7bc23542017-03-22 11:26:44 +0100321{
Simon Glass95588622020-12-22 19:30:28 -0700322 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi596c5082021-04-11 09:39:49 +0200323 struct single_priv *priv = dev_get_priv(dev);
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000324 int stride = pdata->args_count + 1;
325 int n, pin, count = size / sizeof(u32);
Dario Binacchi596c5082021-04-11 09:39:49 +0200326 struct single_func *func;
Matthias Schifferbb970d52023-09-27 15:33:33 +0200327 void *reg;
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000328 u32 offset, val, mux;
Felix Brack7bc23542017-03-22 11:26:44 +0100329
Dario Binacchi12f50452021-04-11 09:39:45 +0200330 /* If function mask is null, needn't enable it. */
331 if (!pdata->mask)
332 return 0;
333
Dario Binacchi596c5082021-04-11 09:39:49 +0200334 func = single_allocate_function(dev, count);
335 if (IS_ERR(func))
336 return PTR_ERR(func);
337
338 func->name = fname;
339 func->npins = 0;
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000340 for (n = 0; n < count; n += stride) {
341 offset = fdt32_to_cpu(pins[n]);
Dario Binacchia0cbd6a2021-04-22 22:28:56 +0200342 if (offset > pdata->offset) {
Dario Binacchi596c5082021-04-11 09:39:49 +0200343 dev_err(dev, " invalid register offset 0x%x\n",
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200344 offset);
Felix Brack7bc23542017-03-22 11:26:44 +0100345 continue;
346 }
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200347
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000348 /* if the pinctrl-cells is 2 then the second cell contains the mux */
349 if (stride == 3)
350 mux = fdt32_to_cpu(pins[n + 2]);
351 else
352 mux = 0;
353
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200354 reg = pdata->base + offset;
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000355 val = (fdt32_to_cpu(pins[n + 1]) | mux) & pdata->mask;
Dario Binacchi596c5082021-04-11 09:39:49 +0200356 pin = single_get_pin_by_offset(dev, offset);
357 if (pin < 0) {
358 dev_err(dev, " failed to get pin by offset %x\n",
359 offset);
360 continue;
361 }
362
Dario Binacchi54dfe522021-04-11 09:39:46 +0200363 single_write(dev, (single_read(dev, reg) & ~pdata->mask) | val,
364 reg);
Dario Binacchi35f4ac52021-04-11 09:39:42 +0200365 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi596c5082021-04-11 09:39:49 +0200366 func->pins[func->npins] = pin;
367 func->npins++;
Felix Brack7bc23542017-03-22 11:26:44 +0100368 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200369
370 qsort(func->pins, func->npins, sizeof(func->pins[0]),
371 single_pin_compare);
372 list_add(&func->node, &priv->functions);
Felix Brack7bc23542017-03-22 11:26:44 +0100373 return 0;
374}
375
Adam Ford6305a5c2019-06-10 13:15:55 -0500376static int single_configure_bits(struct udevice *dev,
377 const struct single_fdt_bits_cfg *pins,
Dario Binacchi596c5082021-04-11 09:39:49 +0200378 int size, const char *fname)
Adam Ford6305a5c2019-06-10 13:15:55 -0500379{
Simon Glass95588622020-12-22 19:30:28 -0700380 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi596c5082021-04-11 09:39:49 +0200381 struct single_priv *priv = dev_get_priv(dev);
382 int n, pin, count = size / sizeof(struct single_fdt_bits_cfg);
383 int npins_in_reg, pin_num_from_lsb;
384 struct single_func *func;
Matthias Schifferbb970d52023-09-27 15:33:33 +0200385 void *reg;
Dario Binacchi596c5082021-04-11 09:39:49 +0200386 u32 offset, val, mask, bit_pos, val_pos, mask_pos, submask;
Adam Ford6305a5c2019-06-10 13:15:55 -0500387
Dario Binacchi376daa82021-04-22 18:35:58 +0200388 /* If function mask is null, needn't enable it. */
389 if (!pdata->mask)
390 return 0;
391
Dario Binacchi596c5082021-04-11 09:39:49 +0200392 npins_in_reg = pdata->width / priv->bits_per_pin;
393 func = single_allocate_function(dev, count * npins_in_reg);
394 if (IS_ERR(func))
395 return PTR_ERR(func);
396
397 func->name = fname;
398 func->npins = 0;
Adam Ford6305a5c2019-06-10 13:15:55 -0500399 for (n = 0; n < count; n++, pins++) {
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200400 offset = fdt32_to_cpu(pins->reg);
Dario Binacchia0cbd6a2021-04-22 22:28:56 +0200401 if (offset > pdata->offset) {
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200402 dev_dbg(dev, " invalid register offset 0x%x\n",
403 offset);
Adam Ford6305a5c2019-06-10 13:15:55 -0500404 continue;
405 }
Dario Binacchic3ed31f2021-04-11 09:39:41 +0200406
407 reg = pdata->base + offset;
Adam Ford6305a5c2019-06-10 13:15:55 -0500408
Dario Binacchi596c5082021-04-11 09:39:49 +0200409 pin = single_get_pin_by_offset(dev, offset);
410 if (pin < 0) {
411 dev_err(dev, " failed to get pin by offset 0x%pa\n",
412 &reg);
413 continue;
414 }
415
Adam Ford6305a5c2019-06-10 13:15:55 -0500416 mask = fdt32_to_cpu(pins->mask);
417 val = fdt32_to_cpu(pins->val) & mask;
Dario Binacchi54dfe522021-04-11 09:39:46 +0200418 single_write(dev, (single_read(dev, reg) & ~mask) | val, reg);
Dario Binacchi35f4ac52021-04-11 09:39:42 +0200419 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi596c5082021-04-11 09:39:49 +0200420
421 while (mask) {
422 bit_pos = __ffs(mask);
423 pin_num_from_lsb = bit_pos / priv->bits_per_pin;
424 mask_pos = pdata->mask << bit_pos;
425 val_pos = val & mask_pos;
426 submask = mask & mask_pos;
427
428 if ((mask & mask_pos) == 0) {
429 dev_err(dev, "Invalid mask at 0x%x\n", offset);
430 break;
431 }
432
433 mask &= ~mask_pos;
434
435 if (submask != mask_pos) {
436 dev_warn(dev,
437 "Invalid submask 0x%x at 0x%x\n",
438 submask, offset);
439 continue;
440 }
441
442 func->pins[func->npins] = pin + pin_num_from_lsb;
443 func->npins++;
444 }
Adam Ford6305a5c2019-06-10 13:15:55 -0500445 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200446
447 qsort(func->pins, func->npins, sizeof(func->pins[0]),
448 single_pin_compare);
449 list_add(&func->node, &priv->functions);
Adam Ford6305a5c2019-06-10 13:15:55 -0500450 return 0;
451}
Felix Brack7bc23542017-03-22 11:26:44 +0100452static int single_set_state(struct udevice *dev,
453 struct udevice *config)
454{
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000455 const u32 *prop;
Adam Ford6305a5c2019-06-10 13:15:55 -0500456 const struct single_fdt_bits_cfg *prop_bits;
Felix Brack7bc23542017-03-22 11:26:44 +0100457 int len;
458
Lokesh Vutla0bef0262020-04-22 22:55:31 +0530459 prop = dev_read_prop(config, "pinctrl-single,pins", &len);
Adam Ford6305a5c2019-06-10 13:15:55 -0500460
Felix Brack7bc23542017-03-22 11:26:44 +0100461 if (prop) {
462 dev_dbg(dev, "configuring pins for %s\n", config->name);
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000463 if (len % sizeof(u32)) {
Felix Brack7bc23542017-03-22 11:26:44 +0100464 dev_dbg(dev, " invalid pin configuration in fdt\n");
465 return -FDT_ERR_BADSTRUCTURE;
466 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200467 single_configure_pins(dev, prop, len, config->name);
Adam Ford6305a5c2019-06-10 13:15:55 -0500468 return 0;
Felix Brack7bc23542017-03-22 11:26:44 +0100469 }
470
Adam Ford6305a5c2019-06-10 13:15:55 -0500471 /* pinctrl-single,pins not found so check for pinctrl-single,bits */
Lokesh Vutla0bef0262020-04-22 22:55:31 +0530472 prop_bits = dev_read_prop(config, "pinctrl-single,bits", &len);
Adam Ford6305a5c2019-06-10 13:15:55 -0500473 if (prop_bits) {
474 dev_dbg(dev, "configuring pins for %s\n", config->name);
475 if (len % sizeof(struct single_fdt_bits_cfg)) {
476 dev_dbg(dev, " invalid bits configuration in fdt\n");
477 return -FDT_ERR_BADSTRUCTURE;
478 }
Dario Binacchi596c5082021-04-11 09:39:49 +0200479 single_configure_bits(dev, prop_bits, len, config->name);
Adam Ford6305a5c2019-06-10 13:15:55 -0500480 return 0;
481 }
482
483 /* Neither 'pinctrl-single,pins' nor 'pinctrl-single,bits' were found */
Felix Brack7bc23542017-03-22 11:26:44 +0100484 return len;
485}
486
Dario Binacchif3ecbc12021-04-11 09:39:48 +0200487static const char *single_get_pin_name(struct udevice *dev,
488 unsigned int selector)
489{
490 struct single_priv *priv = dev_get_priv(dev);
491
492 if (selector >= priv->npins)
493 snprintf(priv->pin_name, PINNAME_SIZE, "Error");
494 else
495 snprintf(priv->pin_name, PINNAME_SIZE, "PIN%u", selector);
496
497 return priv->pin_name;
498}
499
Dario Binacchi235132c2021-04-11 09:39:47 +0200500static int single_get_pins_count(struct udevice *dev)
501{
502 struct single_priv *priv = dev_get_priv(dev);
503
504 return priv->npins;
505}
506
Bharat Gooty1063e102021-08-24 15:46:31 +0530507static int single_add_gpio_func(struct udevice *dev)
508{
509 struct single_priv *priv = dev_get_priv(dev);
510 const char *propname = "pinctrl-single,gpio-range";
511 const char *cellname = "#pinctrl-single,gpio-range-cells";
512 struct single_gpiofunc_range *range;
513 struct ofnode_phandle_args gpiospec;
514 int ret, i;
515
516 for (i = 0; ; i++) {
517 ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), propname,
518 cellname, 0, i, &gpiospec);
519 /* Do not treat it as error. Only treat it as end condition. */
520 if (ret) {
521 ret = 0;
522 break;
523 }
524 range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
525 if (!range) {
526 ret = -ENOMEM;
527 break;
528 }
529 range->offset = gpiospec.args[0];
530 range->npins = gpiospec.args[1];
531 range->gpiofunc = gpiospec.args[2];
532 list_add_tail(&range->node, &priv->gpiofuncs);
533 }
534 return ret;
535}
536
Dario Binacchi235132c2021-04-11 09:39:47 +0200537static int single_probe(struct udevice *dev)
538{
539 struct single_pdata *pdata = dev_get_plat(dev);
540 struct single_priv *priv = dev_get_priv(dev);
541 u32 size;
542
Dario Binacchi596c5082021-04-11 09:39:49 +0200543 INIT_LIST_HEAD(&priv->functions);
Bharat Gooty1063e102021-08-24 15:46:31 +0530544 INIT_LIST_HEAD(&priv->gpiofuncs);
Dario Binacchi596c5082021-04-11 09:39:49 +0200545
Dario Binacchi235132c2021-04-11 09:39:47 +0200546 size = pdata->offset + pdata->width / BITS_PER_BYTE;
Simon Glassb9dbc512023-02-05 15:40:42 -0700547 #if (IS_ENABLED(CONFIG_SANDBOX))
Dario Binacchi20dd9e12021-04-11 09:39:50 +0200548 priv->sandbox_regs =
549 devm_kzalloc(dev, size * sizeof(*priv->sandbox_regs),
550 GFP_KERNEL);
551 if (!priv->sandbox_regs)
552 return -ENOMEM;
553 #endif
554
Simon Glass43b82f52021-05-13 19:39:28 -0600555 /* looks like a possible divide by 0, but data->width avoids this */
Dario Binacchi235132c2021-04-11 09:39:47 +0200556 priv->npins = size / (pdata->width / BITS_PER_BYTE);
557 if (pdata->bits_per_mux) {
Dario Binacchi376daa82021-04-22 18:35:58 +0200558 if (!pdata->mask) {
559 dev_err(dev, "function mask needs to be non-zero\n");
560 return -EINVAL;
561 }
562
Dario Binacchi235132c2021-04-11 09:39:47 +0200563 priv->bits_per_pin = fls(pdata->mask);
564 priv->npins *= (pdata->width / priv->bits_per_pin);
565 }
566
Bharat Gooty1063e102021-08-24 15:46:31 +0530567 if (single_add_gpio_func(dev))
568 dev_dbg(dev, "gpio functions are not added\n");
569
Dario Binacchi235132c2021-04-11 09:39:47 +0200570 dev_dbg(dev, "%d pins\n", priv->npins);
571 return 0;
572}
573
Simon Glassaad29ae2020-12-03 16:55:21 -0700574static int single_of_to_plat(struct udevice *dev)
Felix Brack7bc23542017-03-22 11:26:44 +0100575{
Matthias Schifferbb970d52023-09-27 15:33:33 +0200576 void *addr;
Dario Binacchi22fb01d2021-04-11 09:39:43 +0200577 fdt_size_t size;
Simon Glass95588622020-12-22 19:30:28 -0700578 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi9e4051f2021-04-11 09:39:44 +0200579 int ret;
Felix Brack7bc23542017-03-22 11:26:44 +0100580
Dario Binacchi9e4051f2021-04-11 09:39:44 +0200581 ret = dev_read_u32(dev, "pinctrl-single,register-width", &pdata->width);
582 if (ret) {
583 dev_err(dev, "missing register width\n");
584 return ret;
585 }
Felix Brack7bc23542017-03-22 11:26:44 +0100586
Dario Binacchi54dfe522021-04-11 09:39:46 +0200587 switch (pdata->width) {
588 case 8:
589 case 16:
590 case 32:
591 break;
592 default:
593 dev_err(dev, "wrong register width\n");
594 return -EINVAL;
595 }
596
Matthias Schifferbb970d52023-09-27 15:33:33 +0200597 addr = dev_read_addr_size_index_ptr(dev, 0, &size);
598 if (!addr) {
Vignesh Raghavendrac074a182021-05-07 14:40:34 +0530599 dev_err(dev, "failed to get base register address\n");
Dario Binacchi22fb01d2021-04-11 09:39:43 +0200600 return -EINVAL;
601 }
602
603 pdata->offset = size - pdata->width / BITS_PER_BYTE;
Felix Brack7bc23542017-03-22 11:26:44 +0100604 pdata->base = addr;
605
Dario Binacchi12f50452021-04-11 09:39:45 +0200606 ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask);
607 if (ret) {
608 pdata->mask = 0;
609 dev_warn(dev, "missing function register mask\n");
610 }
611
Patrick Delaunayaf2fb742020-01-13 11:34:55 +0100612 pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
Adam Ford6305a5c2019-06-10 13:15:55 -0500613
AJ Bagwelle98e87a2021-12-03 15:18:53 +0000614 /* If no pinctrl-cells is present, default to old style of 2 cells with
615 * bits per mux and 1 cell otherwise.
616 */
617 ret = dev_read_u32(dev, "#pinctrl-cells", &pdata->args_count);
618 if (ret)
619 pdata->args_count = pdata->bits_per_mux ? 2 : 1;
620
Felix Brack7bc23542017-03-22 11:26:44 +0100621 return 0;
622}
623
624const struct pinctrl_ops single_pinctrl_ops = {
Dario Binacchi235132c2021-04-11 09:39:47 +0200625 .get_pins_count = single_get_pins_count,
Dario Binacchif3ecbc12021-04-11 09:39:48 +0200626 .get_pin_name = single_get_pin_name,
Felix Brack7bc23542017-03-22 11:26:44 +0100627 .set_state = single_set_state,
Dario Binacchi596c5082021-04-11 09:39:49 +0200628 .get_pin_muxing = single_get_pin_muxing,
Bharat Gootyf02f9572021-08-24 15:46:32 +0530629 .request = single_request,
Felix Brack7bc23542017-03-22 11:26:44 +0100630};
631
632static const struct udevice_id single_pinctrl_match[] = {
633 { .compatible = "pinctrl-single" },
634 { /* sentinel */ }
635};
636
637U_BOOT_DRIVER(single_pinctrl) = {
638 .name = "single-pinctrl",
639 .id = UCLASS_PINCTRL,
640 .of_match = single_pinctrl_match,
641 .ops = &single_pinctrl_ops,
Simon Glass71fa5b42020-12-03 16:55:18 -0700642 .plat_auto = sizeof(struct single_pdata),
Dario Binacchi235132c2021-04-11 09:39:47 +0200643 .priv_auto = sizeof(struct single_priv),
Simon Glassaad29ae2020-12-03 16:55:21 -0700644 .of_to_plat = single_of_to_plat,
Dario Binacchi235132c2021-04-11 09:39:47 +0200645 .probe = single_probe,
Felix Brack7bc23542017-03-22 11:26:44 +0100646};