blob: 7af6c5f0b0371cdbd0b580f6ad46a0fe91db19d6 [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>
Felix Brack44d5c372017-03-22 11:26:44 +010011#include <dm/pinctrl.h>
Masahiro Yamadab08c8c42018-03-05 01:20:11 +090012#include <linux/libfdt.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020013#include <linux/list.h>
Felix Brack44d5c372017-03-22 11:26:44 +010014#include <asm/io.h>
Dario Binacchi76d470d2021-04-11 09:39:49 +020015#include <sort.h>
Felix Brack44d5c372017-03-22 11:26:44 +010016
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020017/**
18 * struct single_pdata - platform data
19 * @base: first configuration register
20 * @offset: index of last configuration register
21 * @mask: configuration-value mask bits
22 * @width: configuration register bit width
23 * @bits_per_mux: true if one register controls more than one pin
24 */
Felix Brack44d5c372017-03-22 11:26:44 +010025struct single_pdata {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020026 fdt_addr_t base;
27 int offset;
28 u32 mask;
Dario Binacchi971c64a2021-04-11 09:39:44 +020029 u32 width;
Adam Ford159a8872019-06-10 13:15:55 -050030 bool bits_per_mux;
Felix Brack44d5c372017-03-22 11:26:44 +010031};
32
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020033/**
Dario Binacchi76d470d2021-04-11 09:39:49 +020034 * struct single_func - pinctrl function
35 * @node: list node
36 * @name: pinctrl function name
37 * @npins: number of entries in pins array
38 * @pins: pins array
39 */
40struct single_func {
41 struct list_head node;
42 const char *name;
43 unsigned int npins;
44 unsigned int *pins;
45};
46
47/**
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020048 * struct single_priv - private data
49 * @bits_per_pin: number of bits per pin
50 * @npins: number of selectable pins
Dario Binacchi0b121622021-04-11 09:39:48 +020051 * @pin_name: temporary buffer to store the pin name
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020052 */
53struct single_priv {
Dario Binacchi55322622021-04-11 09:39:50 +020054#if (IS_ENABLED(CONFIG_SANDBOX))
55 u32 *sandbox_regs;
56#endif
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020057 unsigned int bits_per_pin;
58 unsigned int npins;
Dario Binacchi0b121622021-04-11 09:39:48 +020059 char pin_name[PINNAME_SIZE];
Dario Binacchi76d470d2021-04-11 09:39:49 +020060 struct list_head functions;
Dario Binacchi1dd7ae22021-04-11 09:39:47 +020061};
62
63/**
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020064 * struct single_fdt_pin_cfg - pin configuration
65 *
66 * This structure is used for the pin configuration parameters in case
67 * the register controls only one pin.
68 *
69 * @reg: configuration register offset
70 * @val: configuration register value
71 */
Felix Brack44d5c372017-03-22 11:26:44 +010072struct single_fdt_pin_cfg {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020073 fdt32_t reg;
74 fdt32_t val;
Felix Brack44d5c372017-03-22 11:26:44 +010075};
76
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020077/**
78 * struct single_fdt_bits_cfg - pin configuration
79 *
80 * This structure is used for the pin configuration parameters in case
81 * the register controls more than one pin.
82 *
83 * @reg: configuration register offset
84 * @val: configuration register value
85 * @mask: configuration register mask
86 */
Adam Ford159a8872019-06-10 13:15:55 -050087struct single_fdt_bits_cfg {
Dario Binacchi4ace4fa2021-04-11 09:39:39 +020088 fdt32_t reg;
89 fdt32_t val;
90 fdt32_t mask;
Adam Ford159a8872019-06-10 13:15:55 -050091};
92
Dario Binacchi55322622021-04-11 09:39:50 +020093#if (!IS_ENABLED(CONFIG_SANDBOX))
94
Dario Binacchi180531f2021-04-11 09:39:46 +020095static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
96{
97 struct single_pdata *pdata = dev_get_plat(dev);
98
99 switch (pdata->width) {
100 case 8:
101 return readb(reg);
102 case 16:
103 return readw(reg);
104 default: /* 32 bits */
105 return readl(reg);
106 }
107
108 return readb(reg);
109}
110
111static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
112{
113 struct single_pdata *pdata = dev_get_plat(dev);
114
115 switch (pdata->width) {
116 case 8:
117 writeb(val, reg);
118 break;
119 case 16:
120 writew(val, reg);
121 break;
122 default: /* 32 bits */
123 writel(val, reg);
124 }
125}
126
Dario Binacchi55322622021-04-11 09:39:50 +0200127#else /* CONFIG_SANDBOX */
128
129static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
130{
131 struct single_priv *priv = dev_get_priv(dev);
132
133 return priv->sandbox_regs[reg];
134}
135
136static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
137{
138 struct single_priv *priv = dev_get_priv(dev);
139
140 priv->sandbox_regs[reg] = val;
141}
142
143#endif /* CONFIG_SANDBOX */
144
Felix Brack44d5c372017-03-22 11:26:44 +0100145/**
Dario Binacchi76d470d2021-04-11 09:39:49 +0200146 * single_get_pin_by_offset() - get a pin based on the register offset
147 * @dev: single driver instance
148 * @offset: register offset from the base
149 */
150static int single_get_pin_by_offset(struct udevice *dev, unsigned int offset)
151{
152 struct single_pdata *pdata = dev_get_plat(dev);
153 struct single_priv *priv = dev_get_priv(dev);
154
155 if (offset > pdata->offset) {
156 dev_err(dev, "mux offset out of range: 0x%x (0x%x)\n",
157 offset, pdata->offset);
158 return -EINVAL;
159 }
160
161 if (pdata->bits_per_mux)
162 return (offset * BITS_PER_BYTE) / priv->bits_per_pin;
163
164 return offset / (pdata->width / BITS_PER_BYTE);
165}
166
167static int single_get_offset_by_pin(struct udevice *dev, unsigned int pin)
168{
169 struct single_pdata *pdata = dev_get_plat(dev);
170 struct single_priv *priv = dev_get_priv(dev);
171 unsigned int mux_bytes;
172
173 if (pin >= priv->npins)
174 return -EINVAL;
175
176 mux_bytes = pdata->width / BITS_PER_BYTE;
177 if (pdata->bits_per_mux) {
178 int byte_num;
179
180 byte_num = (priv->bits_per_pin * pin) / BITS_PER_BYTE;
181 return (byte_num / mux_bytes) * mux_bytes;
182 }
183
184 return pin * mux_bytes;
185}
186
187static const char *single_get_pin_function(struct udevice *dev,
188 unsigned int pin)
189{
190 struct single_priv *priv = dev_get_priv(dev);
191 struct single_func *func;
192 int i;
193
194 list_for_each_entry(func, &priv->functions, node) {
195 for (i = 0; i < func->npins; i++) {
196 if (pin == func->pins[i])
197 return func->name;
198
199 if (pin < func->pins[i])
200 break;
201 }
202 }
203
204 return NULL;
205}
206
207static int single_get_pin_muxing(struct udevice *dev, unsigned int pin,
208 char *buf, int size)
209{
210 struct single_pdata *pdata = dev_get_plat(dev);
211 struct single_priv *priv = dev_get_priv(dev);
212 fdt_addr_t reg;
213 const char *fname;
214 unsigned int val;
215 int offset, pin_shift = 0;
216
217 offset = single_get_offset_by_pin(dev, pin);
218 if (offset < 0)
219 return offset;
220
221 reg = pdata->base + offset;
222 val = single_read(dev, reg);
223
224 if (pdata->bits_per_mux)
225 pin_shift = pin % (pdata->width / priv->bits_per_pin) *
226 priv->bits_per_pin;
227
228 val &= (pdata->mask << pin_shift);
229 fname = single_get_pin_function(dev, pin);
230 snprintf(buf, size, "%pa 0x%08x %s", &reg, val,
231 fname ? fname : "UNCLAIMED");
232 return 0;
233}
234
235static struct single_func *single_allocate_function(struct udevice *dev,
236 unsigned int group_pins)
237{
238 struct single_func *func;
239
240 func = devm_kmalloc(dev, sizeof(*func), GFP_KERNEL);
241 if (!func)
242 return ERR_PTR(-ENOMEM);
243
244 func->pins = devm_kmalloc(dev, sizeof(unsigned int) * group_pins,
245 GFP_KERNEL);
246 if (!func->pins)
247 return ERR_PTR(-ENOMEM);
248
249 return func;
250}
251
252static int single_pin_compare(const void *s1, const void *s2)
253{
254 int pin1 = *(const unsigned int *)s1;
255 int pin2 = *(const unsigned int *)s2;
256
257 return pin1 - pin2;
258}
259
260/**
Felix Brack44d5c372017-03-22 11:26:44 +0100261 * single_configure_pins() - Configure pins based on FDT data
262 *
263 * @dev: Pointer to single pin configuration device which is the parent of
264 * the pins node holding the pin configuration data.
265 * @pins: Pointer to the first element of an array of register/value pairs
266 * of type 'struct single_fdt_pin_cfg'. Each such pair describes the
267 * the pin to be configured and the value to be used for configuration.
268 * This pointer points to a 'pinctrl-single,pins' property in the
269 * device-tree.
270 * @size: Size of the 'pins' array in bytes.
271 * The number of register/value pairs in the 'pins' array therefore
272 * equals to 'size / sizeof(struct single_fdt_pin_cfg)'.
Dario Binacchi76d470d2021-04-11 09:39:49 +0200273 * @fname: Function name.
Felix Brack44d5c372017-03-22 11:26:44 +0100274 */
275static int single_configure_pins(struct udevice *dev,
276 const struct single_fdt_pin_cfg *pins,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200277 int size, const char *fname)
Felix Brack44d5c372017-03-22 11:26:44 +0100278{
Simon Glass0fd3d912020-12-22 19:30:28 -0700279 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200280 struct single_priv *priv = dev_get_priv(dev);
281 int n, pin, count = size / sizeof(struct single_fdt_pin_cfg);
282 struct single_func *func;
Dario Binacchi67192942021-04-11 09:39:40 +0200283 phys_addr_t reg;
Dario Binacchi9b884e72021-04-11 09:39:41 +0200284 u32 offset, val;
Felix Brack44d5c372017-03-22 11:26:44 +0100285
Dario Binacchid85b93e2021-04-11 09:39:45 +0200286 /* If function mask is null, needn't enable it. */
287 if (!pdata->mask)
288 return 0;
289
Dario Binacchi76d470d2021-04-11 09:39:49 +0200290 func = single_allocate_function(dev, count);
291 if (IS_ERR(func))
292 return PTR_ERR(func);
293
294 func->name = fname;
295 func->npins = 0;
James Balean46f51dc2017-04-18 21:06:35 -0500296 for (n = 0; n < count; n++, pins++) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200297 offset = fdt32_to_cpu(pins->reg);
Dario Binacchi230bc622021-04-22 22:28:56 +0200298 if (offset > pdata->offset) {
Dario Binacchi76d470d2021-04-11 09:39:49 +0200299 dev_err(dev, " invalid register offset 0x%x\n",
Dario Binacchi9b884e72021-04-11 09:39:41 +0200300 offset);
Felix Brack44d5c372017-03-22 11:26:44 +0100301 continue;
302 }
Dario Binacchi9b884e72021-04-11 09:39:41 +0200303
304 reg = pdata->base + offset;
James Balean46f51dc2017-04-18 21:06:35 -0500305 val = fdt32_to_cpu(pins->val) & pdata->mask;
Dario Binacchi76d470d2021-04-11 09:39:49 +0200306 pin = single_get_pin_by_offset(dev, offset);
307 if (pin < 0) {
308 dev_err(dev, " failed to get pin by offset %x\n",
309 offset);
310 continue;
311 }
312
Dario Binacchi180531f2021-04-11 09:39:46 +0200313 single_write(dev, (single_read(dev, reg) & ~pdata->mask) | val,
314 reg);
Dario Binacchifcf6a2b2021-04-11 09:39:42 +0200315 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200316 func->pins[func->npins] = pin;
317 func->npins++;
Felix Brack44d5c372017-03-22 11:26:44 +0100318 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200319
320 qsort(func->pins, func->npins, sizeof(func->pins[0]),
321 single_pin_compare);
322 list_add(&func->node, &priv->functions);
Felix Brack44d5c372017-03-22 11:26:44 +0100323 return 0;
324}
325
Adam Ford159a8872019-06-10 13:15:55 -0500326static int single_configure_bits(struct udevice *dev,
327 const struct single_fdt_bits_cfg *pins,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200328 int size, const char *fname)
Adam Ford159a8872019-06-10 13:15:55 -0500329{
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_bits_cfg);
333 int npins_in_reg, pin_num_from_lsb;
334 struct single_func *func;
Dario Binacchi67192942021-04-11 09:39:40 +0200335 phys_addr_t reg;
Dario Binacchi76d470d2021-04-11 09:39:49 +0200336 u32 offset, val, mask, bit_pos, val_pos, mask_pos, submask;
Adam Ford159a8872019-06-10 13:15:55 -0500337
Dario Binacchi69414d82021-04-22 18:35:58 +0200338 /* If function mask is null, needn't enable it. */
339 if (!pdata->mask)
340 return 0;
341
Dario Binacchi76d470d2021-04-11 09:39:49 +0200342 npins_in_reg = pdata->width / priv->bits_per_pin;
343 func = single_allocate_function(dev, count * npins_in_reg);
344 if (IS_ERR(func))
345 return PTR_ERR(func);
346
347 func->name = fname;
348 func->npins = 0;
Adam Ford159a8872019-06-10 13:15:55 -0500349 for (n = 0; n < count; n++, pins++) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200350 offset = fdt32_to_cpu(pins->reg);
Dario Binacchi230bc622021-04-22 22:28:56 +0200351 if (offset > pdata->offset) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200352 dev_dbg(dev, " invalid register offset 0x%x\n",
353 offset);
Adam Ford159a8872019-06-10 13:15:55 -0500354 continue;
355 }
Dario Binacchi9b884e72021-04-11 09:39:41 +0200356
357 reg = pdata->base + offset;
Adam Ford159a8872019-06-10 13:15:55 -0500358
Dario Binacchi76d470d2021-04-11 09:39:49 +0200359 pin = single_get_pin_by_offset(dev, offset);
360 if (pin < 0) {
361 dev_err(dev, " failed to get pin by offset 0x%pa\n",
362 &reg);
363 continue;
364 }
365
Adam Ford159a8872019-06-10 13:15:55 -0500366 mask = fdt32_to_cpu(pins->mask);
367 val = fdt32_to_cpu(pins->val) & mask;
Dario Binacchi180531f2021-04-11 09:39:46 +0200368 single_write(dev, (single_read(dev, reg) & ~mask) | val, reg);
Dario Binacchifcf6a2b2021-04-11 09:39:42 +0200369 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200370
371 while (mask) {
372 bit_pos = __ffs(mask);
373 pin_num_from_lsb = bit_pos / priv->bits_per_pin;
374 mask_pos = pdata->mask << bit_pos;
375 val_pos = val & mask_pos;
376 submask = mask & mask_pos;
377
378 if ((mask & mask_pos) == 0) {
379 dev_err(dev, "Invalid mask at 0x%x\n", offset);
380 break;
381 }
382
383 mask &= ~mask_pos;
384
385 if (submask != mask_pos) {
386 dev_warn(dev,
387 "Invalid submask 0x%x at 0x%x\n",
388 submask, offset);
389 continue;
390 }
391
392 func->pins[func->npins] = pin + pin_num_from_lsb;
393 func->npins++;
394 }
Adam Ford159a8872019-06-10 13:15:55 -0500395 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200396
397 qsort(func->pins, func->npins, sizeof(func->pins[0]),
398 single_pin_compare);
399 list_add(&func->node, &priv->functions);
Adam Ford159a8872019-06-10 13:15:55 -0500400 return 0;
401}
Felix Brack44d5c372017-03-22 11:26:44 +0100402static int single_set_state(struct udevice *dev,
403 struct udevice *config)
404{
Felix Brack44d5c372017-03-22 11:26:44 +0100405 const struct single_fdt_pin_cfg *prop;
Adam Ford159a8872019-06-10 13:15:55 -0500406 const struct single_fdt_bits_cfg *prop_bits;
Felix Brack44d5c372017-03-22 11:26:44 +0100407 int len;
408
Lokesh Vutladbfd9e02020-04-22 22:55:31 +0530409 prop = dev_read_prop(config, "pinctrl-single,pins", &len);
Adam Ford159a8872019-06-10 13:15:55 -0500410
Felix Brack44d5c372017-03-22 11:26:44 +0100411 if (prop) {
412 dev_dbg(dev, "configuring pins for %s\n", config->name);
413 if (len % sizeof(struct single_fdt_pin_cfg)) {
414 dev_dbg(dev, " invalid pin configuration in fdt\n");
415 return -FDT_ERR_BADSTRUCTURE;
416 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200417 single_configure_pins(dev, prop, len, config->name);
Adam Ford159a8872019-06-10 13:15:55 -0500418 return 0;
Felix Brack44d5c372017-03-22 11:26:44 +0100419 }
420
Adam Ford159a8872019-06-10 13:15:55 -0500421 /* pinctrl-single,pins not found so check for pinctrl-single,bits */
Lokesh Vutladbfd9e02020-04-22 22:55:31 +0530422 prop_bits = dev_read_prop(config, "pinctrl-single,bits", &len);
Adam Ford159a8872019-06-10 13:15:55 -0500423 if (prop_bits) {
424 dev_dbg(dev, "configuring pins for %s\n", config->name);
425 if (len % sizeof(struct single_fdt_bits_cfg)) {
426 dev_dbg(dev, " invalid bits configuration in fdt\n");
427 return -FDT_ERR_BADSTRUCTURE;
428 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200429 single_configure_bits(dev, prop_bits, len, config->name);
Adam Ford159a8872019-06-10 13:15:55 -0500430 return 0;
431 }
432
433 /* Neither 'pinctrl-single,pins' nor 'pinctrl-single,bits' were found */
Felix Brack44d5c372017-03-22 11:26:44 +0100434 return len;
435}
436
Dario Binacchi0b121622021-04-11 09:39:48 +0200437static const char *single_get_pin_name(struct udevice *dev,
438 unsigned int selector)
439{
440 struct single_priv *priv = dev_get_priv(dev);
441
442 if (selector >= priv->npins)
443 snprintf(priv->pin_name, PINNAME_SIZE, "Error");
444 else
445 snprintf(priv->pin_name, PINNAME_SIZE, "PIN%u", selector);
446
447 return priv->pin_name;
448}
449
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200450static int single_get_pins_count(struct udevice *dev)
451{
452 struct single_priv *priv = dev_get_priv(dev);
453
454 return priv->npins;
455}
456
457static int single_probe(struct udevice *dev)
458{
459 struct single_pdata *pdata = dev_get_plat(dev);
460 struct single_priv *priv = dev_get_priv(dev);
461 u32 size;
462
Dario Binacchi76d470d2021-04-11 09:39:49 +0200463 INIT_LIST_HEAD(&priv->functions);
464
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200465 size = pdata->offset + pdata->width / BITS_PER_BYTE;
Dario Binacchi55322622021-04-11 09:39:50 +0200466 #if (CONFIG_IS_ENABLED(SANDBOX))
467 priv->sandbox_regs =
468 devm_kzalloc(dev, size * sizeof(*priv->sandbox_regs),
469 GFP_KERNEL);
470 if (!priv->sandbox_regs)
471 return -ENOMEM;
472 #endif
473
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200474 priv->npins = size / (pdata->width / BITS_PER_BYTE);
475 if (pdata->bits_per_mux) {
Dario Binacchi69414d82021-04-22 18:35:58 +0200476 if (!pdata->mask) {
477 dev_err(dev, "function mask needs to be non-zero\n");
478 return -EINVAL;
479 }
480
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200481 priv->bits_per_pin = fls(pdata->mask);
482 priv->npins *= (pdata->width / priv->bits_per_pin);
483 }
484
485 dev_dbg(dev, "%d pins\n", priv->npins);
486 return 0;
487}
488
Simon Glassd1998a92020-12-03 16:55:21 -0700489static int single_of_to_plat(struct udevice *dev)
Felix Brack44d5c372017-03-22 11:26:44 +0100490{
491 fdt_addr_t addr;
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200492 fdt_size_t size;
Simon Glass0fd3d912020-12-22 19:30:28 -0700493 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi971c64a2021-04-11 09:39:44 +0200494 int ret;
Felix Brack44d5c372017-03-22 11:26:44 +0100495
Dario Binacchi971c64a2021-04-11 09:39:44 +0200496 ret = dev_read_u32(dev, "pinctrl-single,register-width", &pdata->width);
497 if (ret) {
498 dev_err(dev, "missing register width\n");
499 return ret;
500 }
Felix Brack44d5c372017-03-22 11:26:44 +0100501
Dario Binacchi180531f2021-04-11 09:39:46 +0200502 switch (pdata->width) {
503 case 8:
504 case 16:
505 case 32:
506 break;
507 default:
508 dev_err(dev, "wrong register width\n");
509 return -EINVAL;
510 }
511
Vignesh Raghavendra1e787902021-05-07 14:40:34 +0530512 addr = dev_read_addr_size_index(dev, 0, &size);
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200513 if (addr == FDT_ADDR_T_NONE) {
Vignesh Raghavendra1e787902021-05-07 14:40:34 +0530514 dev_err(dev, "failed to get base register address\n");
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200515 return -EINVAL;
516 }
517
518 pdata->offset = size - pdata->width / BITS_PER_BYTE;
Felix Brack44d5c372017-03-22 11:26:44 +0100519 pdata->base = addr;
520
Dario Binacchid85b93e2021-04-11 09:39:45 +0200521 ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask);
522 if (ret) {
523 pdata->mask = 0;
524 dev_warn(dev, "missing function register mask\n");
525 }
526
Patrick Delaunay719cab62020-01-13 11:34:55 +0100527 pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
Adam Ford159a8872019-06-10 13:15:55 -0500528
Felix Brack44d5c372017-03-22 11:26:44 +0100529 return 0;
530}
531
532const struct pinctrl_ops single_pinctrl_ops = {
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200533 .get_pins_count = single_get_pins_count,
Dario Binacchi0b121622021-04-11 09:39:48 +0200534 .get_pin_name = single_get_pin_name,
Felix Brack44d5c372017-03-22 11:26:44 +0100535 .set_state = single_set_state,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200536 .get_pin_muxing = single_get_pin_muxing,
Felix Brack44d5c372017-03-22 11:26:44 +0100537};
538
539static const struct udevice_id single_pinctrl_match[] = {
540 { .compatible = "pinctrl-single" },
541 { /* sentinel */ }
542};
543
544U_BOOT_DRIVER(single_pinctrl) = {
545 .name = "single-pinctrl",
546 .id = UCLASS_PINCTRL,
547 .of_match = single_pinctrl_match,
548 .ops = &single_pinctrl_ops,
Simon Glasscaa4daa2020-12-03 16:55:18 -0700549 .plat_auto = sizeof(struct single_pdata),
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200550 .priv_auto = sizeof(struct single_priv),
Simon Glassd1998a92020-12-03 16:55:21 -0700551 .of_to_plat = single_of_to_plat,
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200552 .probe = single_probe,
Felix Brack44d5c372017-03-22 11:26:44 +0100553};