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