blob: 48bdd0f6f5b3e79c6a9810c043ea20d3a2030eec [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);
298 if (offset < 0 || 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 Binacchi76d470d2021-04-11 09:39:49 +0200338 npins_in_reg = pdata->width / priv->bits_per_pin;
339 func = single_allocate_function(dev, count * npins_in_reg);
340 if (IS_ERR(func))
341 return PTR_ERR(func);
342
343 func->name = fname;
344 func->npins = 0;
Adam Ford159a8872019-06-10 13:15:55 -0500345 for (n = 0; n < count; n++, pins++) {
Dario Binacchi9b884e72021-04-11 09:39:41 +0200346 offset = fdt32_to_cpu(pins->reg);
347 if (offset < 0 || offset > pdata->offset) {
348 dev_dbg(dev, " invalid register offset 0x%x\n",
349 offset);
Adam Ford159a8872019-06-10 13:15:55 -0500350 continue;
351 }
Dario Binacchi9b884e72021-04-11 09:39:41 +0200352
353 reg = pdata->base + offset;
Adam Ford159a8872019-06-10 13:15:55 -0500354
Dario Binacchi76d470d2021-04-11 09:39:49 +0200355 pin = single_get_pin_by_offset(dev, offset);
356 if (pin < 0) {
357 dev_err(dev, " failed to get pin by offset 0x%pa\n",
358 &reg);
359 continue;
360 }
361
Adam Ford159a8872019-06-10 13:15:55 -0500362 mask = fdt32_to_cpu(pins->mask);
363 val = fdt32_to_cpu(pins->val) & mask;
Dario Binacchi180531f2021-04-11 09:39:46 +0200364 single_write(dev, (single_read(dev, reg) & ~mask) | val, reg);
Dario Binacchifcf6a2b2021-04-11 09:39:42 +0200365 dev_dbg(dev, " reg/val %pa/0x%08x\n", &reg, val);
Dario Binacchi76d470d2021-04-11 09:39:49 +0200366
367 while (mask) {
368 bit_pos = __ffs(mask);
369 pin_num_from_lsb = bit_pos / priv->bits_per_pin;
370 mask_pos = pdata->mask << bit_pos;
371 val_pos = val & mask_pos;
372 submask = mask & mask_pos;
373
374 if ((mask & mask_pos) == 0) {
375 dev_err(dev, "Invalid mask at 0x%x\n", offset);
376 break;
377 }
378
379 mask &= ~mask_pos;
380
381 if (submask != mask_pos) {
382 dev_warn(dev,
383 "Invalid submask 0x%x at 0x%x\n",
384 submask, offset);
385 continue;
386 }
387
388 func->pins[func->npins] = pin + pin_num_from_lsb;
389 func->npins++;
390 }
Adam Ford159a8872019-06-10 13:15:55 -0500391 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200392
393 qsort(func->pins, func->npins, sizeof(func->pins[0]),
394 single_pin_compare);
395 list_add(&func->node, &priv->functions);
Adam Ford159a8872019-06-10 13:15:55 -0500396 return 0;
397}
Felix Brack44d5c372017-03-22 11:26:44 +0100398static int single_set_state(struct udevice *dev,
399 struct udevice *config)
400{
Felix Brack44d5c372017-03-22 11:26:44 +0100401 const struct single_fdt_pin_cfg *prop;
Adam Ford159a8872019-06-10 13:15:55 -0500402 const struct single_fdt_bits_cfg *prop_bits;
Felix Brack44d5c372017-03-22 11:26:44 +0100403 int len;
404
Lokesh Vutladbfd9e02020-04-22 22:55:31 +0530405 prop = dev_read_prop(config, "pinctrl-single,pins", &len);
Adam Ford159a8872019-06-10 13:15:55 -0500406
Felix Brack44d5c372017-03-22 11:26:44 +0100407 if (prop) {
408 dev_dbg(dev, "configuring pins for %s\n", config->name);
409 if (len % sizeof(struct single_fdt_pin_cfg)) {
410 dev_dbg(dev, " invalid pin configuration in fdt\n");
411 return -FDT_ERR_BADSTRUCTURE;
412 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200413 single_configure_pins(dev, prop, len, config->name);
Adam Ford159a8872019-06-10 13:15:55 -0500414 return 0;
Felix Brack44d5c372017-03-22 11:26:44 +0100415 }
416
Adam Ford159a8872019-06-10 13:15:55 -0500417 /* pinctrl-single,pins not found so check for pinctrl-single,bits */
Lokesh Vutladbfd9e02020-04-22 22:55:31 +0530418 prop_bits = dev_read_prop(config, "pinctrl-single,bits", &len);
Adam Ford159a8872019-06-10 13:15:55 -0500419 if (prop_bits) {
420 dev_dbg(dev, "configuring pins for %s\n", config->name);
421 if (len % sizeof(struct single_fdt_bits_cfg)) {
422 dev_dbg(dev, " invalid bits configuration in fdt\n");
423 return -FDT_ERR_BADSTRUCTURE;
424 }
Dario Binacchi76d470d2021-04-11 09:39:49 +0200425 single_configure_bits(dev, prop_bits, len, config->name);
Adam Ford159a8872019-06-10 13:15:55 -0500426 return 0;
427 }
428
429 /* Neither 'pinctrl-single,pins' nor 'pinctrl-single,bits' were found */
Felix Brack44d5c372017-03-22 11:26:44 +0100430 return len;
431}
432
Dario Binacchi0b121622021-04-11 09:39:48 +0200433static const char *single_get_pin_name(struct udevice *dev,
434 unsigned int selector)
435{
436 struct single_priv *priv = dev_get_priv(dev);
437
438 if (selector >= priv->npins)
439 snprintf(priv->pin_name, PINNAME_SIZE, "Error");
440 else
441 snprintf(priv->pin_name, PINNAME_SIZE, "PIN%u", selector);
442
443 return priv->pin_name;
444}
445
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200446static int single_get_pins_count(struct udevice *dev)
447{
448 struct single_priv *priv = dev_get_priv(dev);
449
450 return priv->npins;
451}
452
453static int single_probe(struct udevice *dev)
454{
455 struct single_pdata *pdata = dev_get_plat(dev);
456 struct single_priv *priv = dev_get_priv(dev);
457 u32 size;
458
Dario Binacchi76d470d2021-04-11 09:39:49 +0200459 INIT_LIST_HEAD(&priv->functions);
460
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200461 size = pdata->offset + pdata->width / BITS_PER_BYTE;
Dario Binacchi55322622021-04-11 09:39:50 +0200462 #if (CONFIG_IS_ENABLED(SANDBOX))
463 priv->sandbox_regs =
464 devm_kzalloc(dev, size * sizeof(*priv->sandbox_regs),
465 GFP_KERNEL);
466 if (!priv->sandbox_regs)
467 return -ENOMEM;
468 #endif
469
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200470 priv->npins = size / (pdata->width / BITS_PER_BYTE);
471 if (pdata->bits_per_mux) {
472 priv->bits_per_pin = fls(pdata->mask);
473 priv->npins *= (pdata->width / priv->bits_per_pin);
474 }
475
476 dev_dbg(dev, "%d pins\n", priv->npins);
477 return 0;
478}
479
Simon Glassd1998a92020-12-03 16:55:21 -0700480static int single_of_to_plat(struct udevice *dev)
Felix Brack44d5c372017-03-22 11:26:44 +0100481{
482 fdt_addr_t addr;
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200483 fdt_size_t size;
Simon Glass0fd3d912020-12-22 19:30:28 -0700484 struct single_pdata *pdata = dev_get_plat(dev);
Dario Binacchi971c64a2021-04-11 09:39:44 +0200485 int ret;
Felix Brack44d5c372017-03-22 11:26:44 +0100486
Dario Binacchi971c64a2021-04-11 09:39:44 +0200487 ret = dev_read_u32(dev, "pinctrl-single,register-width", &pdata->width);
488 if (ret) {
489 dev_err(dev, "missing register width\n");
490 return ret;
491 }
Felix Brack44d5c372017-03-22 11:26:44 +0100492
Dario Binacchi180531f2021-04-11 09:39:46 +0200493 switch (pdata->width) {
494 case 8:
495 case 16:
496 case 32:
497 break;
498 default:
499 dev_err(dev, "wrong register width\n");
500 return -EINVAL;
501 }
502
Dario Binacchi9fd8a432021-04-11 09:39:43 +0200503 addr = dev_read_addr_size(dev, "reg", &size);
504 if (addr == FDT_ADDR_T_NONE) {
505 dev_err(dev, "failed to get base register size\n");
506 return -EINVAL;
507 }
508
509 pdata->offset = size - pdata->width / BITS_PER_BYTE;
Felix Brack44d5c372017-03-22 11:26:44 +0100510
Patrick Delaunay719cab62020-01-13 11:34:55 +0100511 addr = dev_read_addr(dev);
Felix Brack44d5c372017-03-22 11:26:44 +0100512 if (addr == FDT_ADDR_T_NONE) {
513 dev_dbg(dev, "no valid base register address\n");
514 return -EINVAL;
515 }
516 pdata->base = addr;
517
Dario Binacchid85b93e2021-04-11 09:39:45 +0200518 ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask);
519 if (ret) {
520 pdata->mask = 0;
521 dev_warn(dev, "missing function register mask\n");
522 }
523
Patrick Delaunay719cab62020-01-13 11:34:55 +0100524 pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux");
Adam Ford159a8872019-06-10 13:15:55 -0500525
Felix Brack44d5c372017-03-22 11:26:44 +0100526 return 0;
527}
528
529const struct pinctrl_ops single_pinctrl_ops = {
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200530 .get_pins_count = single_get_pins_count,
Dario Binacchi0b121622021-04-11 09:39:48 +0200531 .get_pin_name = single_get_pin_name,
Felix Brack44d5c372017-03-22 11:26:44 +0100532 .set_state = single_set_state,
Dario Binacchi76d470d2021-04-11 09:39:49 +0200533 .get_pin_muxing = single_get_pin_muxing,
Felix Brack44d5c372017-03-22 11:26:44 +0100534};
535
536static const struct udevice_id single_pinctrl_match[] = {
537 { .compatible = "pinctrl-single" },
538 { /* sentinel */ }
539};
540
541U_BOOT_DRIVER(single_pinctrl) = {
542 .name = "single-pinctrl",
543 .id = UCLASS_PINCTRL,
544 .of_match = single_pinctrl_match,
545 .ops = &single_pinctrl_ops,
Simon Glasscaa4daa2020-12-03 16:55:18 -0700546 .plat_auto = sizeof(struct single_pdata),
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200547 .priv_auto = sizeof(struct single_priv),
Simon Glassd1998a92020-12-03 16:55:21 -0700548 .of_to_plat = single_of_to_plat,
Dario Binacchi1dd7ae22021-04-11 09:39:47 +0200549 .probe = single_probe,
Felix Brack44d5c372017-03-22 11:26:44 +0100550};