summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2015-04-23 17:19:58 +0200
committerStefan Agner <stefan.agner@toradex.com>2015-04-23 17:19:58 +0200
commit769c0f8d9c7a98d77855aa7efd8ec21a2f125924 (patch)
treec81bfe80a1e201f9f38587278594ad638e65da1d /drivers
parentf51c0c368c45a55f3eb41b1fa4206b87165f8661 (diff)
parent60f63388e38a305ae60d5502e20b9f16d1f78f83 (diff)
Merge branch '2015.04-toradex-next-gpio' into 2015.04-toradex-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-uclass.c1
-rw-r--r--drivers/gpio/vybrid_gpio.c122
3 files changed, 124 insertions, 0 deletions
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 85f71c5d4a7..62c73042b76 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_TCA642X) += tca642x.o
oby-$(CONFIG_SX151X) += sx151x.o
obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o
obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o
+obj-$(CONFIG_VYBRID_GPIO) += vybrid_gpio.o
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index a69bbd2002e..27778b4fccc 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -717,6 +717,7 @@ static int gpio_pre_remove(struct udevice *dev)
UCLASS_DRIVER(gpio) = {
.id = UCLASS_GPIO,
.name = "gpio",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
.post_probe = gpio_post_probe,
.pre_remove = gpio_pre_remove,
.per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
diff --git a/drivers/gpio/vybrid_gpio.c b/drivers/gpio/vybrid_gpio.c
new file mode 100644
index 00000000000..9fa0762b7cc
--- /dev/null
+++ b/drivers/gpio/vybrid_gpio.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015
+ * Bhuvanchandra DV, Toradex, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/io.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct vybrid_gpios {
+ unsigned int chip;
+ struct vybrid_gpio_regs *reg;
+};
+
+static int vybrid_gpio_direction_input(struct udevice *dev, unsigned gpio)
+{
+ const struct vybrid_gpios *gpios = dev_get_priv(dev);
+
+ gpio = gpio + (gpios->chip * VYBRID_GPIO_COUNT);
+ imx_iomux_gpio_set_direction(gpio, VF610_GPIO_DIRECTION_IN);
+
+ return 0;
+}
+
+static int vybrid_gpio_direction_output(struct udevice *dev, unsigned gpio,
+ int value)
+{
+ const struct vybrid_gpios *gpios = dev_get_priv(dev);
+
+ gpio = gpio + (gpios->chip * VYBRID_GPIO_COUNT);
+ gpio_set_value(gpio, value);
+ imx_iomux_gpio_set_direction(gpio, VF610_GPIO_DIRECTION_OUT);
+
+ return 0;
+}
+
+static int vybrid_gpio_get_value(struct udevice *dev, unsigned gpio)
+{
+ const struct vybrid_gpios *gpios = dev_get_priv(dev);
+
+ return ((readl(&gpios->reg->gpio_pdir) & (1 << gpio))) ? 1 : 0;
+}
+
+static int vybrid_gpio_set_value(struct udevice *dev, unsigned gpio,
+ int value)
+{
+ const struct vybrid_gpios *gpios = dev_get_priv(dev);
+ if (value)
+ writel((1 << gpio), &gpios->reg->gpio_psor);
+ else
+ writel((1 << gpio), &gpios->reg->gpio_pcor);
+
+ return 0;
+}
+
+static const struct dm_gpio_ops gpio_vybrid_ops = {
+ .direction_input = vybrid_gpio_direction_input,
+ .direction_output = vybrid_gpio_direction_output,
+ .get_value = vybrid_gpio_get_value,
+ .set_value = vybrid_gpio_set_value,
+};
+
+static int vybrid_gpio_probe(struct udevice *dev)
+{
+ struct vybrid_gpios *gpios = dev_get_priv(dev);
+ struct vybrid_gpio_platdata *plat = dev_get_platdata(dev);
+ struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+
+ uc_priv->bank_name = "GPIO";
+ uc_priv->gpio_count = VYBRID_GPIO_COUNT;
+ gpios->reg = (struct vybrid_gpio_regs *)plat->base;
+ gpios->chip = plat->chip;
+
+ return 0;
+}
+
+static int vybrid_gpio_bind(struct udevice *dev)
+{
+ struct vybrid_gpio_platdata *plat = dev->platdata;
+ fdt_addr_t base_addr;
+
+ if (plat)
+ return 0;
+
+ base_addr = dev_get_addr(dev);
+ if (base_addr == FDT_ADDR_T_NONE)
+ return -ENODEV;
+
+ plat = calloc(1, sizeof(*plat));
+ if (!plat)
+ return -ENOMEM;
+
+ plat->base = base_addr;
+ plat->chip = dev->req_seq;
+ dev->platdata = plat;
+
+ return 0;
+}
+
+static const struct udevice_id vybrid_gpio_ids[] = {
+ { .compatible = "fsl,vf610-gpio" },
+ { }
+};
+
+U_BOOT_DRIVER(gpio_vybrid) = {
+ .name = "gpio_vybrid",
+ .id = UCLASS_GPIO,
+ .ops = &gpio_vybrid_ops,
+ .probe = vybrid_gpio_probe,
+ .priv_auto_alloc_size = sizeof(struct vybrid_gpios),
+ .of_match = vybrid_gpio_ids,
+ .bind = vybrid_gpio_bind,
+};