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_compat.h>
17 #include <dm/pinctrl.h>
18 #include <dt-bindings/gpio/gpio.h>
19 #include <dt-bindings/gpio/sandbox-gpio.h>
23 const char *label; /* label given by requester */
24 ulong dir_flags; /* dir_flags (GPIOD_...) */
27 /* Access routines for GPIO dir flags */
28 static ulong *get_gpio_dir_flags(struct udevice *dev, unsigned int offset)
30 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
31 struct gpio_state *state = dev_get_priv(dev);
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;
39 return &state[offset].dir_flags;
43 static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
45 return (*get_gpio_dir_flags(dev, offset) & flag) != 0;
48 static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
51 ulong *gpio = get_gpio_dir_flags(dev, offset);
62 * Back-channel sandbox-internal-only access to GPIO state
65 int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
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);
72 int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
74 return set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE, value);
77 int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
79 return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
82 int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
84 set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
85 set_gpio_flag(dev, offset, GPIOD_IS_IN, !(output));
90 ulong sandbox_gpio_get_dir_flags(struct udevice *dev, unsigned int offset)
92 return *get_gpio_dir_flags(dev, offset);
95 int sandbox_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
98 *get_gpio_dir_flags(dev, offset) = flags;
104 * These functions implement the public interface within U-Boot
107 /* set GPIO port 'offset' as an input */
108 static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
110 debug("%s: offset:%u\n", __func__, offset);
112 return sandbox_gpio_set_direction(dev, offset, 0);
115 /* set GPIO port 'offset' as an output, with polarity 'value' */
116 static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
119 debug("%s: offset:%u, value = %d\n", __func__, offset, value);
121 return sandbox_gpio_set_direction(dev, offset, 1) |
122 sandbox_gpio_set_value(dev, offset, value);
125 /* read GPIO IN value of port 'offset' */
126 static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
128 debug("%s: offset:%u\n", __func__, offset);
130 return sandbox_gpio_get_value(dev, offset);
133 /* write GPIO OUT value to port 'offset' */
134 static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
136 debug("%s: offset:%u, value = %d\n", __func__, offset, value);
138 if (!sandbox_gpio_get_direction(dev, offset)) {
139 printf("sandbox_gpio: error: set_value on input gpio %u\n",
144 return sandbox_gpio_set_value(dev, offset, value);
147 static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
149 if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
151 if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
154 return GPIOF_INPUT; /*GPIO is not configurated */
157 static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
158 struct ofnode_phandle_args *args)
160 desc->offset = args->args[0];
161 if (args->args_count < 2)
163 /* treat generic binding with gpio uclass */
164 gpio_xlate_offs_flags(dev, desc, args);
166 /* sandbox test specific, not defined in gpio.h */
167 if (args->args[1] & GPIO_IN)
168 desc->flags |= GPIOD_IS_IN;
170 if (args->args[1] & GPIO_OUT)
171 desc->flags |= GPIOD_IS_OUT;
173 if (args->args[1] & GPIO_OUT_ACTIVE)
174 desc->flags |= GPIOD_IS_OUT_ACTIVE;
179 static int sb_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
184 debug("%s: offset:%u, dir_flags = %lx\n", __func__, offset, flags);
186 dir_flags = get_gpio_dir_flags(dev, offset);
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.
192 if (flags & GPIOD_IS_IN)
193 *dir_flags = (flags & ~GPIOD_IS_OUT_ACTIVE) |
194 (*dir_flags & GPIOD_IS_OUT_ACTIVE);
201 static int sb_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
204 debug("%s: offset:%u\n", __func__, offset);
205 *flags = *get_gpio_dir_flags(dev, offset);
210 #if CONFIG_IS_ENABLED(ACPIGEN)
211 static int sb_gpio_get_acpi(const struct gpio_desc *desc,
212 struct acpi_gpio *gpio)
216 /* Note that gpio_get_acpi() zeroes *gpio before calling here */
218 gpio->pins[0] = desc->offset;
219 ret = acpi_device_scope(desc->dev, gpio->resource,
220 sizeof(gpio->resource));
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;
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;
237 /* The GpioIo part is only used for testing */
238 gpio->polarity = ACPI_GPIO_ACTIVE_LOW;
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;
245 /* The GpioInt part is not used */
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;
257 static int sb_gpio_get_name(const struct udevice *dev, char *out_name)
259 return acpi_copy_name(out_name, "GPIO");
262 struct acpi_ops gpio_sandbox_acpi_ops = {
263 .get_name = sb_gpio_get_name,
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,
281 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
283 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
285 uc_priv->gpio_count = dev_read_u32_default(dev, "sandbox,gpio-count",
287 uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
292 static int gpio_sandbox_probe(struct udevice *dev)
294 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
296 if (!dev_of_valid(dev))
297 /* Tell the uclass how many GPIOs we have */
298 uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
300 dev->priv = calloc(sizeof(struct gpio_state), uc_priv->gpio_count);
305 static int gpio_sandbox_remove(struct udevice *dev)
312 static const struct udevice_id sandbox_gpio_ids[] = {
313 { .compatible = "sandbox,gpio" },
317 U_BOOT_DRIVER(sandbox_gpio) = {
318 .name = "sandbox_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)
328 U_BOOT_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
330 /* pincontrol: used only to check GPIO pin configuration (pinmux command) */
332 struct sb_pinctrl_priv {
334 struct list_head gpio_dev;
337 struct sb_gpio_bank {
338 struct udevice *gpio_dev;
339 struct list_head list;
342 static int sb_populate_gpio_dev_list(struct udevice *dev)
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;
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
356 list_for_each_entry(child, &dev->child_head, sibling_node) {
357 ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
362 gpio_bank = malloc(sizeof(*gpio_bank));
364 dev_err(dev, "Not enough memory\n");
368 gpio_bank->gpio_dev = gpio_dev;
369 list_add_tail(&gpio_bank->list, &priv->gpio_dev);
375 static int sb_pinctrl_get_pins_count(struct udevice *dev)
377 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
378 struct gpio_dev_priv *uc_priv;
379 struct sb_gpio_bank *gpio_bank;
382 * if get_pins_count has already been executed once on this
383 * pin-controller, no need to run it again
385 if (priv->pinctrl_ngpios)
386 return priv->pinctrl_ngpios;
388 if (list_empty(&priv->gpio_dev))
389 sb_populate_gpio_dev_list(dev);
391 * walk through all banks to retrieve the pin-controller
394 list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
395 uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
397 priv->pinctrl_ngpios += uc_priv->gpio_count;
400 return priv->pinctrl_ngpios;
403 static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
404 unsigned int selector,
407 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
408 struct sb_gpio_bank *gpio_bank;
409 struct gpio_dev_priv *uc_priv;
412 if (list_empty(&priv->gpio_dev))
413 sb_populate_gpio_dev_list(dev);
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);
419 if (selector < (pin_count + uc_priv->gpio_count)) {
421 * we found the bank, convert pin selector to
424 *idx = selector - pin_count;
426 return gpio_bank->gpio_dev;
428 pin_count += uc_priv->gpio_count;
434 static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
435 unsigned int selector)
437 struct gpio_dev_priv *uc_priv;
438 struct udevice *gpio_dev;
439 unsigned int gpio_idx;
440 static char pin_name[PINNAME_SIZE];
442 /* look up for the bank which owns the requested pin */
443 gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
445 snprintf(pin_name, PINNAME_SIZE, "Error");
447 uc_priv = dev_get_uclass_priv(gpio_dev);
449 snprintf(pin_name, PINNAME_SIZE, "%s%d",
457 static char *get_dir_flags_string(ulong flags)
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";
470 static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
471 unsigned int selector,
474 struct udevice *gpio_dev;
475 unsigned int gpio_idx;
479 /* look up for the bank which owns the requested pin */
480 gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
482 snprintf(buf, size, "Error");
484 function = sb_gpio_get_function(gpio_dev, gpio_idx);
485 dir_flags = *get_gpio_dir_flags(gpio_dev, gpio_idx);
487 snprintf(buf, size, "gpio %s %s",
488 function == GPIOF_OUTPUT ? "output" : "input",
489 get_dir_flags_string(dir_flags));
495 #if CONFIG_IS_ENABLED(ACPIGEN)
496 static int sb_pinctrl_get_name(const struct udevice *dev, char *out_name)
498 return acpi_copy_name(out_name, "PINC");
502 static int sandbox_pinctrl_probe(struct udevice *dev)
504 struct sb_pinctrl_priv *priv = dev_get_priv(dev);
506 INIT_LIST_HEAD(&priv->gpio_dev);
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,
517 #if CONFIG_IS_ENABLED(ACPIGEN)
518 struct acpi_ops pinctrl_sandbox_acpi_ops = {
519 .get_name = sb_pinctrl_get_name,
523 static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
524 { .compatible = "sandbox,pinctrl-gpio" },
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_alloc_size = sizeof(struct sb_pinctrl_priv),
536 ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)