1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2011 The Chromium OS Authors.
11 #include <acpi/acpi_device.h>
14 #include <dm/device-internal.h>
15 #include <dm/device_compat.h>
18 #include <dm/pinctrl.h>
19 #include <dt-bindings/gpio/gpio.h>
20 #include <dt-bindings/gpio/sandbox-gpio.h>
24 const char *label; /* label given by requester */
25 ulong flags; /* flags (GPIOD_...) */
28 /* Access routines for GPIO info */
29 static struct gpio_state *get_gpio_state(struct udevice *dev, uint offset)
31 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
32 struct gpio_state *state = dev_get_priv(dev);
34 if (offset >= uc_priv->gpio_count) {
35 printf("sandbox_gpio: error: invalid gpio %u\n", offset);
39 return &state[offset];
42 /* Access routines for GPIO flags */
43 static ulong *get_gpio_flags(struct udevice *dev, unsigned int offset)
45 struct gpio_state *state = get_gpio_state(dev, offset);
54 static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
56 return (*get_gpio_flags(dev, offset) & flag) != 0;
59 static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
62 struct gpio_state *state = get_gpio_state(dev, offset);
67 state->flags &= ~flag;
73 * Back-channel sandbox-internal-only access to GPIO state
76 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
78 struct gpio_state *state = get_gpio_state(dev, offset);
81 if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
82 debug("sandbox_gpio: get_value on output gpio %u\n", offset);
84 if (state->flags & GPIOD_EXT_DRIVEN)
85 val = state->flags & GPIOD_EXT_HIGH;
92 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
94 set_gpio_flag(dev, offset, GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
99 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
101 return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
104 int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
106 set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
107 set_gpio_flag(dev, offset, GPIOD_IS_IN, !output);
112 ulong sandbox_gpio_get_flags(struct udevice *dev, uint offset)
114 ulong flags = *get_gpio_flags(dev, offset);
116 return flags & ~GPIOD_SANDBOX_MASK;
119 int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags)
121 struct gpio_state *state = get_gpio_state(dev, offset);
123 state->flags = flags;
129 * These functions implement the public interface within U-Boot
132 /* set GPIO port 'offset' as an input */
133 static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
135 debug("%s: offset:%u\n", __func__, offset);
137 return sandbox_gpio_set_direction(dev, offset, 0);
140 /* set GPIO port 'offset' as an output, with polarity 'value' */
141 static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
146 debug("%s: offset:%u, value = %d\n", __func__, offset, value);
148 ret = sandbox_gpio_set_direction(dev, offset, 1);
151 ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
152 GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
159 /* read GPIO IN value of port 'offset' */
160 static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
162 debug("%s: offset:%u\n", __func__, offset);
164 return sandbox_gpio_get_value(dev, offset);
167 /* write GPIO OUT value to port 'offset' */
168 static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
172 debug("%s: offset:%u, value = %d\n", __func__, offset, value);
174 if (!sandbox_gpio_get_direction(dev, offset)) {
175 printf("sandbox_gpio: error: set_value on input gpio %u\n",
180 ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
181 GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
188 static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
190 if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
192 if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
195 return GPIOF_INPUT; /*GPIO is not configurated */
198 static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
199 struct ofnode_phandle_args *args)
201 desc->offset = args->args[0];
202 if (args->args_count < 2)
204 /* treat generic binding with gpio uclass */
205 gpio_xlate_offs_flags(dev, desc, args);
207 /* sandbox test specific, not defined in gpio.h */
208 if (args->args[1] & GPIO_IN)
209 desc->flags |= GPIOD_IS_IN;
211 if (args->args[1] & GPIO_OUT)
212 desc->flags |= GPIOD_IS_OUT;
214 if (args->args[1] & GPIO_OUT_ACTIVE)
215 desc->flags |= GPIOD_IS_OUT_ACTIVE;
220 static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
223 debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags);
224 struct gpio_state *state = get_gpio_state(dev, offset);
226 if (flags & GPIOD_IS_OUT) {
227 flags |= GPIOD_EXT_DRIVEN;
228 if (flags & GPIOD_IS_OUT_ACTIVE)
229 flags |= GPIOD_EXT_HIGH;
231 flags &= ~GPIOD_EXT_HIGH;
233 flags |= state->flags & GPIOD_SANDBOX_MASK;
235 state->flags = flags;
240 static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp)
242 debug("%s: offset:%u\n", __func__, offset);
243 *flagsp = *get_gpio_flags(dev, offset) & ~GPIOD_SANDBOX_MASK;
248 #if CONFIG_IS_ENABLED(ACPIGEN)
249 static int sb_gpio_get_acpi(const struct gpio_desc *desc,
250 struct acpi_gpio *gpio)
254 /* Note that gpio_get_acpi() zeroes *gpio before calling here */
256 gpio->pins[0] = desc->offset;
257 ret = acpi_device_scope(desc->dev, gpio->resource,
258 sizeof(gpio->resource));
262 /* All of these values are just used for testing */
263 if (desc->flags & GPIOD_ACTIVE_LOW) {
264 gpio->pin0_addr = 0x80012 + desc->offset;
265 gpio->type = ACPI_GPIO_TYPE_INTERRUPT;
266 gpio->pull = ACPI_GPIO_PULL_DOWN;
267 gpio->interrupt_debounce_timeout = 4321;
269 /* We use the GpioInt part */
270 gpio->irq.pin = desc->offset;
271 gpio->irq.polarity = ACPI_IRQ_ACTIVE_BOTH;
272 gpio->irq.shared = ACPI_IRQ_SHARED;
273 gpio->irq.wake = ACPI_IRQ_WAKE;
275 /* The GpioIo part is only used for testing */
276 gpio->polarity = ACPI_GPIO_ACTIVE_LOW;
278 gpio->pin0_addr = 0xc00dc + desc->offset;
279 gpio->type = ACPI_GPIO_TYPE_IO;
280 gpio->pull = ACPI_GPIO_PULL_UP;
281 gpio->interrupt_debounce_timeout = 0;
283 /* The GpioInt part is not used */
285 /* We use the GpioIo part */
286 gpio->output_drive_strength = 1234;
287 gpio->io_shared = true;
288 gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_INPUT;
295 static int sb_gpio_get_name(const struct udevice *dev, char *out_name)
297 return acpi_copy_name(out_name, "GPIO");
300 struct acpi_ops gpio_sandbox_acpi_ops = {
301 .get_name = sb_gpio_get_name,
305 static const struct dm_gpio_ops gpio_sandbox_ops = {
306 .direction_input = sb_gpio_direction_input,
307 .direction_output = sb_gpio_direction_output,
308 .get_value = sb_gpio_get_value,
309 .set_value = sb_gpio_set_value,
310 .get_function = sb_gpio_get_function,
311 .xlate = sb_gpio_xlate,
312 .set_flags = sb_gpio_set_flags,
313 .get_flags = sb_gpio_get_flags,
314 #if CONFIG_IS_ENABLED(ACPIGEN)
315 .get_acpi = sb_gpio_get_acpi,
319 static int sandbox_gpio_of_to_plat(struct udevice *dev)
321 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
323 uc_priv->gpio_count = dev_read_u32_default(dev, "sandbox,gpio-count",
325 uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
330 static int gpio_sandbox_probe(struct udevice *dev)
332 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
334 if (!dev_has_ofnode(dev))
335 /* Tell the uclass how many GPIOs we have */
336 uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
339 calloc(sizeof(struct gpio_state), uc_priv->gpio_count));
344 static int gpio_sandbox_remove(struct udevice *dev)
346 free(dev_get_priv(dev));
351 static const struct udevice_id sandbox_gpio_ids[] = {
352 { .compatible = "sandbox,gpio" },
356 U_BOOT_DRIVER(sandbox_gpio) = {
357 .name = "sandbox_gpio",
359 .of_match = sandbox_gpio_ids,
360 .of_to_plat = sandbox_gpio_of_to_plat,
361 .probe = gpio_sandbox_probe,
362 .remove = gpio_sandbox_remove,
363 .ops = &gpio_sandbox_ops,
364 ACPI_OPS_PTR(&gpio_sandbox_acpi_ops)
367 DM_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
369 /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
371 struct sb_pinctrl_priv {
373 struct list_head gpio_dev;
376 struct sb_gpio_bank {
377 struct udevice *gpio_dev;
378 struct list_head list;
381 static int sb_populate_gpio_dev_list(struct udevice *dev)
383 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
384 struct udevice *gpio_dev;
385 struct udevice *child;
386 struct sb_gpio_bank *gpio_bank;
390 * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
391 * a list with all gpio device reference which belongs to the
392 * current pin-controller. This list is used to find pin_name and
395 list_for_each_entry(child, &dev->child_head, sibling_node) {
396 ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
401 gpio_bank = malloc(sizeof(*gpio_bank));
403 dev_err(dev, "Not enough memory\n");
407 gpio_bank->gpio_dev = gpio_dev;
408 list_add_tail(&gpio_bank->list, &priv->gpio_dev);
414 static int sb_pinctrl_get_pins_count(struct udevice *dev)
416 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
417 struct gpio_dev_priv *uc_priv;
418 struct sb_gpio_bank *gpio_bank;
421 * if get_pins_count has already been executed once on this
422 * pin-controller, no need to run it again
424 if (priv->pinctrl_ngpios)
425 return priv->pinctrl_ngpios;
427 if (list_empty(&priv->gpio_dev))
428 sb_populate_gpio_dev_list(dev);
430 * walk through all banks to retrieve the pin-controller
433 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
434 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
436 priv->pinctrl_ngpios += uc_priv->gpio_count;
439 return priv->pinctrl_ngpios;
442 static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
443 unsigned int selector,
446 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
447 struct sb_gpio_bank *gpio_bank;
448 struct gpio_dev_priv *uc_priv;
451 if (list_empty(&priv->gpio_dev))
452 sb_populate_gpio_dev_list(dev);
454 /* look up for the bank which owns the requested pin */
455 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
456 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
458 if (selector < (pin_count + uc_priv->gpio_count)) {
460 * we found the bank, convert pin selector to
463 *idx = selector - pin_count;
465 return gpio_bank->gpio_dev;
467 pin_count += uc_priv->gpio_count;
473 static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
474 unsigned int selector)
476 struct gpio_dev_priv *uc_priv;
477 struct udevice *gpio_dev;
478 unsigned int gpio_idx;
479 static char pin_name[PINNAME_SIZE];
481 /* look up for the bank which owns the requested pin */
482 gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
484 snprintf(pin_name, PINNAME_SIZE, "Error");
486 uc_priv = dev_get_uclass_priv(gpio_dev);
488 snprintf(pin_name, PINNAME_SIZE, "%s%d",
496 static char *get_flags_string(ulong flags)
498 if (flags & GPIOD_OPEN_DRAIN)
499 return "drive-open-drain";
500 if (flags & GPIOD_OPEN_SOURCE)
501 return "drive-open-source";
502 if (flags & GPIOD_PULL_UP)
503 return "bias-pull-up";
504 if (flags & GPIOD_PULL_DOWN)
505 return "bias-pull-down";
509 static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
510 unsigned int selector,
513 struct udevice *gpio_dev;
514 unsigned int gpio_idx;
518 /* look up for the bank which owns the requested pin */
519 gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
521 snprintf(buf, size, "Error");
523 function = sb_gpio_get_function(gpio_dev, gpio_idx);
524 flags = *get_gpio_flags(gpio_dev, gpio_idx);
526 snprintf(buf, size, "gpio %s %s",
527 function == GPIOF_OUTPUT ? "output" : "input",
528 get_flags_string(flags));
534 #if CONFIG_IS_ENABLED(ACPIGEN)
535 static int sb_pinctrl_get_name(const struct udevice *dev, char *out_name)
537 return acpi_copy_name(out_name, "PINC");
541 static int sandbox_pinctrl_probe(struct udevice *dev)
543 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
545 INIT_LIST_HEAD(&priv->gpio_dev);
550 static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
551 .get_pin_name = sb_pinctrl_get_pin_name,
552 .get_pins_count = sb_pinctrl_get_pins_count,
553 .get_pin_muxing = sb_pinctrl_get_pin_muxing,
556 #if CONFIG_IS_ENABLED(ACPIGEN)
557 struct acpi_ops pinctrl_sandbox_acpi_ops = {
558 .get_name = sb_pinctrl_get_name,
562 static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
563 { .compatible = "sandbox,pinctrl-gpio" },
567 U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
568 .name = "sandbox_pinctrl_gpio",
569 .id = UCLASS_PINCTRL,
570 .of_match = sandbox_pinctrl_gpio_match,
571 .ops = &sandbox_pinctrl_gpio_ops,
572 .bind = dm_scan_fdt_dev,
573 .probe = sandbox_pinctrl_probe,
574 .priv_auto = sizeof(struct sb_pinctrl_priv),
575 ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)