Add driver model support for GPIOs. Since existing GPIO drivers do not use
driver model, this feature must be enabled by CONFIG_DM_GPIO. After all
GPO drivers are converted over we can perhaps remove this config.
Tests are provided for the sandbox implementation, and are a sufficient
sanity check for basic operation.
The GPIO uclass understands the concept of named banks of GPIOs, with each
GPIO device providing a single bank. Within each bank the GPIOs are numbered
using an offset from 0 to n-1. For example a bank named 'b' with 20
offsets will provide GPIOs named b0 to b19.
Anonymous GPIO banks are also supported, and are just numbered without any
prefix.
Each time a GPIO driver is added to the uclass, the GPIOs are renumbered
accordinging, so there is always a global GPIO numbering order.
Signed-off-by: Simon Glass s...@chromium.org
Signed-off-by: Marek Vasut ma...@denx.de
Signed-off-by: Pavel Herrmann morpheus.i...@gmail.com
Signed-off-by: Viktor Křivák viktor.kri...@gmail.com
Signed-off-by: Tomas Hlavacek tmshl...@gmail.com
---
Changes in v6:
- Rename platform_data to platdata
Changes in v5:
- Change to new SPDX license headers
Changes in v4: None
Changes in v3:
- Tidy up comments/documentation in GPIO module
- Update GPIO support to use new struct member names
Changes in v2: None
drivers/gpio/Makefile | 2 +
drivers/gpio/gpio-uclass.c | 266 +
include/asm-generic/gpio.h | 104 ++
test/dm/gpio.c | 111 +++
4 files changed, 483 insertions(+)
create mode 100644 drivers/gpio/gpio-uclass.c
create mode 100644 test/dm/gpio.c
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 1165793..eb1b1e7 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -5,6 +5,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
+obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
+
obj-$(CONFIG_AT91_GPIO)+= at91_gpio.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
obj-$(CONFIG_KIRKWOOD_GPIO)+= kw_gpio.o
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
new file mode 100644
index 000..56bfd11
--- /dev/null
+++ b/drivers/gpio/gpio-uclass.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2013 Google, Inc
+ *
+ * SPDX-License-Identifier:GPL-2.0+
+ */
+
+#include common.h
+#include dm.h
+#include errno.h
+#include asm/gpio.h
+
+/**
+ * gpio_to_device() - Convert global GPIO number to device, number
+ * gpio: The numeric representation of the GPIO
+ *
+ * Convert the GPIO number to an entry in the list of GPIOs
+ * or GPIO blocks registered with the GPIO controller. Returns
+ * entry on success, NULL on error.
+ */
+static int gpio_to_device(unsigned int gpio, struct device **devp,
+ unsigned int *offset)
+{
+ struct gpio_dev_priv *uc_priv;
+ struct device *dev;
+ int ret;
+
+ for (ret = uclass_first_device(UCLASS_GPIO, dev);
+dev;
+ret = uclass_next_device(dev)) {
+ uc_priv = dev-uclass_priv;
+ if (gpio = uc_priv-gpio_base
+ gpio uc_priv-gpio_base + uc_priv-gpio_count) {
+ *devp = dev;
+ *offset = gpio - uc_priv-gpio_base;
+ return 0;
+ }
+ }
+
+ /* No such GPIO */
+ return ret ? ret : -EINVAL;
+}
+
+int gpio_lookup_name(const char *name, struct device **devp,
+unsigned int *offsetp, unsigned int *gpiop)
+{
+ struct gpio_dev_priv *uc_priv;
+ struct device *dev;
+ int ret;
+
+ if (devp)
+ *devp = NULL;
+ for (ret = uclass_first_device(UCLASS_GPIO, dev);
+dev;
+ret = uclass_next_device(dev)) {
+ ulong offset;
+ int len;
+
+ uc_priv = dev-uclass_priv;
+ len = uc_priv-bank_name ? strlen(uc_priv-bank_name) : 0;
+
+ if (!strncmp(name, uc_priv-bank_name, len)) {
+ if (strict_strtoul(name + len, 10, offset))
+ continue;
+ if (devp)
+ *devp = dev;
+ if (offsetp)
+ *offsetp = offset;
+ if (gpiop)
+ *gpiop = uc_priv-gpio_base + offset;
+ return 0;
+ }
+ }
+
+ return ret ? ret : -EINVAL;
+}
+
+/**
+ * gpio_request() - [COMPAT] Request GPIO
+ * gpio: GPIO number
+ * label: Name for the requested GPIO
+ *
+ * This function implements the API that's compatible with current
+ * GPIO API used in U-Boot. The request is forwarded to particular
+ * GPIO driver. Returns 0 on success, negative value on error.
+ */
+int gpio_request(unsigned gpio, const char *label)
+{
+ unsigned int offset;
+ struct device *dev;
+ int ret;
+
+ ret