dm: treewide: Rename auto_alloc_size members to be shorter
[platform/kernel/u-boot.git] / drivers / gpio / sandbox.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2011 The Chromium OS Authors.
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <fdtdec.h>
9 #include <log.h>
10 #include <malloc.h>
11 #include <acpi/acpi_device.h>
12 #include <asm/gpio.h>
13 #include <dm/acpi.h>
14 #include <dm/device_compat.h>
15 #include <dm/lists.h>
16 #include <dm/of.h>
17 #include <dm/pinctrl.h>
18 #include <dt-bindings/gpio/gpio.h>
19 #include <dt-bindings/gpio/sandbox-gpio.h>
20
21
22 struct gpio_state {
23         const char *label;      /* label given by requester */
24         ulong dir_flags;        /* dir_flags (GPIOD_...) */
25 };
26
27 /* Access routines for GPIO dir flags */
28 static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
29 {
30         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
31         struct gpio_state *state = dev_get_priv(dev);
32
33         if (offset >= uc_priv->gpio_count) {
34                 static ulong invalid_dir_flags;
35                 printf("sandbox_gpio: error: invalid gpio %u\n", offset);
36                 return &invalid_dir_flags;
37         }
38
39         return &state[offset].dir_flags;
40
41 }
42
43 static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
44 {
45         return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
46 }
47
48 static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
49                          int value)
50 {
51         ulong *gpio = get_gpio_dir_flags(dev, offset);
52
53         if (value)
54                 *gpio |= flag;
55         else
56                 *gpio &= ~flag;
57
58         return 0;
59 }
60
61 /*
62  * Back-channel sandbox-internal-only access to GPIO state
63  */
64
65 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
66 {
67         if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
68                 debug("sandbox_gpio: get_value on output gpio %u\n", offset);
69         return get_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE);
70 }
71
72 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
73 {
74         return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
75 }
76
77 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
78 {
79         return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
80 }
81
82 int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
83 {
84         set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
85         set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
86
87         return 0;
88 }
89
90 ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
91 {
92         return *get_gpio_dir_flags(dev, offset);
93 }
94
95 int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
96                                ulong flags)
97 {
98         *get_gpio_dir_flags(dev, offset) = flags;
99
100         return 0;
101 }
102
103 /*
104  * These functions implement the public interface within U-Boot
105  */
106
107 /* set GPIO port 'offset' as an input */
108 static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
109 {
110         debug("%s: offset:%u\n", __func__, offset);
111
112         return sandbox_gpio_set_direction(dev, offset, 0);
113 }
114
115 /* set GPIO port 'offset' as an output, with polarity 'value' */
116 static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
117                                     int value)
118 {
119         debug("%s: offset:%u, value = %d\n", __func__, offset, value);
120
121         return sandbox_gpio_set_direction(dev, offset, 1) |
122                 sandbox_gpio_set_value(dev, offset, value);
123 }
124
125 /* read GPIO IN value of port 'offset' */
126 static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
127 {
128         debug("%s: offset:%u\n", __func__, offset);
129
130         return sandbox_gpio_get_value(dev, offset);
131 }
132
133 /* write GPIO OUT value to port 'offset' */
134 static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
135 {
136         debug("%s: offset:%u, value = %d\n", __func__, offset, value);
137
138         if (!sandbox_gpio_get_direction(dev, offset)) {
139                 printf("sandbox_gpio: error: set_value on input gpio %u\n",
140                        offset);
141                 return -1;
142         }
143
144         return sandbox_gpio_set_value(dev, offset, value);
145 }
146
147 static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
148 {
149         if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
150                 return GPIOF_OUTPUT;
151         if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
152                 return GPIOF_INPUT;
153
154         return GPIOF_INPUT; /*GPIO is not configurated */
155 }
156
157 static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
158                          struct ofnode_phandle_args *args)
159 {
160         desc->offset = args->args[0];
161         if (args->args_count < 2)
162                 return 0;
163         /* treat generic binding with gpio uclass */
164         gpio_xlate_offs_flags(dev, desc, args);
165
166         /* sandbox test specific, not defined in gpio.h */
167         if (args->args[1] & GPIO_IN)
168                 desc->flags |= GPIOD_IS_IN;
169
170         if (args->args[1] & GPIO_OUT)
171                 desc->flags |= GPIOD_IS_OUT;
172
173         if (args->args[1] & GPIO_OUT_ACTIVE)
174                 desc->flags |= GPIOD_IS_OUT_ACTIVE;
175
176         return 0;
177 }
178
179 static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
180                                  ulong flags)
181 {
182         ulong *dir_flags;
183
184         debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
185
186         dir_flags = get_gpio_dir_flags(dev, offset);
187
188         /*
189          * For testing purposes keep the output value when switching to input.
190          * This allows us to manipulate the input value via the gpio command.
191          */
192         if (flags & GPIOD_IS_IN)
193                 *dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
194                              (*dir_flags & GPIOD_IS_OUT_ACTIVE);
195         else
196                 *dir_flags = flags;
197
198         return 0;
199 }
200
201 static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
202                                  ulong *flags)
203 {
204         debug("%s: offset:%u\n", __func__, offset);
205         *flags = *get_gpio_dir_flags(dev, offset);
206
207         return 0;
208 }
209
210 #if CONFIG_IS_ENABLED(ACPIGEN)
211 static int sb_gpio_get_acpi(const struct gpio_desc *desc,
212                             struct acpi_gpio *gpio)
213 {
214         int ret;
215
216         /* Note that gpio_get_acpi() zeroes *gpio before calling here */
217         gpio->pin_count = 1;
218         gpio->pins[0] = desc->offset;
219         ret = acpi_device_scope(desc->dev, gpio->resource,
220                                 sizeof(gpio->resource));
221         if (ret)
222                 return log_ret(ret);
223
224         /* All of these values are just used for testing */
225         if (desc->flags & GPIOD_ACTIVE_LOW) {
226                 gpio->pin0_addr = 0x80012 + desc->offset;
227                 gpio->type = ACPI_GPIO_TYPE_INTERRUPT;
228                 gpio->pull = ACPI_GPIO_PULL_DOWN;
229                 gpio->interrupt_debounce_timeout = 4321;
230
231                 /* We use the GpioInt part */
232                 gpio->irq.pin = desc->offset;
233                 gpio->irq.polarity = ACPI_IRQ_ACTIVE_BOTH;
234                 gpio->irq.shared = ACPI_IRQ_SHARED;
235                 gpio->irq.wake = ACPI_IRQ_WAKE;
236
237                 /* The GpioIo part is only used for testing */
238                 gpio->polarity = ACPI_GPIO_ACTIVE_LOW;
239         } else {
240                 gpio->pin0_addr = 0xc00dc + desc->offset;
241                 gpio->type = ACPI_GPIO_TYPE_IO;
242                 gpio->pull = ACPI_GPIO_PULL_UP;
243                 gpio->interrupt_debounce_timeout = 0;
244
245                 /* The GpioInt part is not used */
246
247                 /* We use the GpioIo part */
248                 gpio->output_drive_strength = 1234;
249                 gpio->io_shared = true;
250                 gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_INPUT;
251                 gpio->polarity = 0;
252         }
253
254         return 0;
255 }
256
257 static int sb_gpio_get_name(const struct udevice *dev, char *out_name)
258 {
259         return acpi_copy_name(out_name, "GPIO");
260 }
261
262 struct acpi_ops gpio_sandbox_acpi_ops = {
263         .get_name       = sb_gpio_get_name,
264 };
265 #endif /* ACPIGEN */
266
267 static const struct dm_gpio_ops gpio_sandbox_ops = {
268         .direction_input        = sb_gpio_direction_input,
269         .direction_output       = sb_gpio_direction_output,
270         .get_value              = sb_gpio_get_value,
271         .set_value              = sb_gpio_set_value,
272         .get_function           = sb_gpio_get_function,
273         .xlate                  = sb_gpio_xlate,
274         .set_dir_flags          = sb_gpio_set_dir_flags,
275         .get_dir_flags          = sb_gpio_get_dir_flags,
276 #if CONFIG_IS_ENABLED(ACPIGEN)
277         .get_acpi               = sb_gpio_get_acpi,
278 #endif
279 };
280
281 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
282 {
283         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
284
285         uc_priv->gpio_count = dev_read_u32_default(dev, "sandbox,gpio-count",
286                                                    0);
287         uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
288
289         return 0;
290 }
291
292 static int gpio_sandbox_probe(struct udevice *dev)
293 {
294         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
295
296         if (!dev_of_valid(dev))
297                 /* Tell the uclass how many GPIOs we have */
298                 uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
299
300         dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
301
302         return 0;
303 }
304
305 static int gpio_sandbox_remove(struct udevice *dev)
306 {
307         free(dev->priv);
308
309         return 0;
310 }
311
312 static const struct udevice_id sandbox_gpio_ids[] = {
313         { .compatible = "sandbox,gpio" },
314         { }
315 };
316
317 U_BOOT_DRIVER(sandbox_gpio) = {
318         .name   = "sandbox_gpio",
319         .id     = UCLASS_GPIO,
320         .of_match = sandbox_gpio_ids,
321         .ofdata_to_platdata = sandbox_gpio_ofdata_to_platdata,
322         .probe  = gpio_sandbox_probe,
323         .remove = gpio_sandbox_remove,
324         .ops    = &gpio_sandbox_ops,
325         ACPI_OPS_PTR(&gpio_sandbox_acpi_ops)
326 };
327
328 U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
329
330 /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
331
332 struct sb_pinctrl_priv {
333         int pinctrl_ngpios;
334         struct list_head gpio_dev;
335 };
336
337 struct sb_gpio_bank {
338         struct udevice *gpio_dev;
339         struct list_head list;
340 };
341
342 static int sb_populate_gpio_dev_list(struct udevice *dev)
343 {
344         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
345         struct udevice *gpio_dev;
346         struct udevice *child;
347         struct sb_gpio_bank *gpio_bank;
348         int ret;
349
350         /*
351          * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
352          * a list with all gpio device reference which belongs to the
353          * current pin-controller. This list is used to find pin_name and
354          * pin muxing
355          */
356         list_for_each_entry(child, &dev->child_head, sibling_node) {
357                 ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
358                                                 &gpio_dev);
359                 if (ret < 0)
360                         continue;
361
362                 gpio_bank = malloc(sizeof(*gpio_bank));
363                 if (!gpio_bank) {
364                         dev_err(dev, "Not enough memory\n");
365                         return -ENOMEM;
366                 }
367
368                 gpio_bank->gpio_dev = gpio_dev;
369                 list_add_tail(&gpio_bank->list, &priv->gpio_dev);
370         }
371
372         return 0;
373 }
374
375 static int sb_pinctrl_get_pins_count(struct udevice *dev)
376 {
377         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
378         struct gpio_dev_priv *uc_priv;
379         struct sb_gpio_bank *gpio_bank;
380
381         /*
382          * if get_pins_count has already been executed once on this
383          * pin-controller, no need to run it again
384          */
385         if (priv->pinctrl_ngpios)
386                 return priv->pinctrl_ngpios;
387
388         if (list_empty(&priv->gpio_dev))
389                 sb_populate_gpio_dev_list(dev);
390         /*
391          * walk through all banks to retrieve the pin-controller
392          * pins number
393          */
394         list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
395                 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
396
397                 priv->pinctrl_ngpios += uc_priv->gpio_count;
398         }
399
400         return priv->pinctrl_ngpios;
401 }
402
403 static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
404                                                unsigned int selector,
405                                                unsigned int *idx)
406 {
407         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
408         struct sb_gpio_bank *gpio_bank;
409         struct gpio_dev_priv *uc_priv;
410         int pin_count = 0;
411
412         if (list_empty(&priv->gpio_dev))
413                 sb_populate_gpio_dev_list(dev);
414
415         /* look up for the bank which owns the requested pin */
416         list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
417                 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
418
419                 if (selector < (pin_count + uc_priv->gpio_count)) {
420                         /*
421                          * we found the bank, convert pin selector to
422                          * gpio bank index
423                          */
424                         *idx = selector - pin_count;
425
426                         return gpio_bank->gpio_dev;
427                 }
428                 pin_count += uc_priv->gpio_count;
429         }
430
431         return NULL;
432 }
433
434 static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
435                                            unsigned int selector)
436 {
437         struct gpio_dev_priv *uc_priv;
438         struct udevice *gpio_dev;
439         unsigned int gpio_idx;
440         static char pin_name[PINNAME_SIZE];
441
442         /* look up for the bank which owns the requested pin */
443         gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
444         if (!gpio_dev) {
445                 snprintf(pin_name, PINNAME_SIZE, "Error");
446         } else {
447                 uc_priv = dev_get_uclass_priv(gpio_dev);
448
449                 snprintf(pin_name, PINNAME_SIZE, "%s%d",
450                          uc_priv->bank_name,
451                          gpio_idx);
452         }
453
454         return pin_name;
455 }
456
457 static char *get_dir_flags_string(ulong flags)
458 {
459         if (flags & GPIOD_OPEN_DRAIN)
460                 return "drive-open-drain";
461         if (flags & GPIOD_OPEN_SOURCE)
462                 return "drive-open-source";
463         if (flags & GPIOD_PULL_UP)
464                 return "bias-pull-up";
465         if (flags & GPIOD_PULL_DOWN)
466                 return "bias-pull-down";
467         return ".";
468 }
469
470 static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
471                                      unsigned int selector,
472                                      char *buf, int size)
473 {
474         struct udevice *gpio_dev;
475         unsigned int gpio_idx;
476         ulong dir_flags;
477         int function;
478
479         /* look up for the bank which owns the requested pin */
480         gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
481         if (!gpio_dev) {
482                 snprintf(buf, size, "Error");
483         } else {
484                 function = sb_gpio_get_function(gpio_dev, gpio_idx);
485                 dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
486
487                 snprintf(buf, size, "gpio %s %s",
488                          function == GPIOF_OUTPUT ? "output" : "input",
489                          get_dir_flags_string(dir_flags));
490         }
491
492         return 0;
493 }
494
495 #if CONFIG_IS_ENABLED(ACPIGEN)
496 static int sb_pinctrl_get_name(const struct udevice *dev, char *out_name)
497 {
498         return acpi_copy_name(out_name, "PINC");
499 }
500 #endif
501
502 static int sandbox_pinctrl_probe(struct udevice *dev)
503 {
504         struct sb_pinctrl_priv *priv = dev_get_priv(dev);
505
506         INIT_LIST_HEAD(&priv->gpio_dev);
507
508         return 0;
509 }
510
511 static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
512         .get_pin_name           = sb_pinctrl_get_pin_name,
513         .get_pins_count         = sb_pinctrl_get_pins_count,
514         .get_pin_muxing         = sb_pinctrl_get_pin_muxing,
515 };
516
517 #if CONFIG_IS_ENABLED(ACPIGEN)
518 struct acpi_ops pinctrl_sandbox_acpi_ops = {
519         .get_name       = sb_pinctrl_get_name,
520 };
521 #endif
522
523 static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
524         { .compatible = "sandbox,pinctrl-gpio" },
525         { /* sentinel */ }
526 };
527
528 U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
529         .name = "sandbox_pinctrl_gpio",
530         .id = UCLASS_PINCTRL,
531         .of_match = sandbox_pinctrl_gpio_match,
532         .ops = &sandbox_pinctrl_gpio_ops,
533         .bind = dm_scan_fdt_dev,
534         .probe = sandbox_pinctrl_probe,
535         .priv_auto      = sizeof(struct sb_pinctrl_priv),
536         ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)
537 };