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