summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhuvanchandra DV <bhuvanchandra.dv@toradex.com>2015-03-18 16:26:39 +0530
committerStefan Agner <stefan.agner@toradex.com>2015-03-18 13:06:13 +0100
commitbd1dde7fcc7b560cdf59ea18f6188935a221a655 (patch)
treecbecd716b4fcfe0085463adf7679d750bdd46ab5
parent8206224e0373658d5ecdc71756150fcbfc77f013 (diff)
gpio: vf610: Add gpio support
Add GPIO support to Freescale VF610 Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
-rw-r--r--arch/arm/imx-common/iomux-v3.c19
-rw-r--r--arch/arm/include/asm/arch-vf610/gpio.h24
-rw-r--r--arch/arm/include/asm/arch-vf610/imx-regs.h6
-rw-r--r--arch/arm/include/asm/imx-common/iomux-v3.h2
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/vybrid_gpio.c84
6 files changed, 135 insertions, 1 deletions
diff --git a/arch/arm/imx-common/iomux-v3.c b/arch/arm/imx-common/iomux-v3.c
index 22cd11aa04..91225ab61a 100644
--- a/arch/arm/imx-common/iomux-v3.c
+++ b/arch/arm/imx-common/iomux-v3.c
@@ -77,3 +77,22 @@ void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
p += stride;
}
}
+
+#ifdef CONFIG_IOMUX_SHARE_CONF_REG
+void imx_iomux_gpio_set_direction(unsigned int gpio,
+ unsigned int direction)
+{
+ u32 reg;
+ /*
+ * Only on Vybrid the input/output buffer enable flags
+ * are part of the shared mux/conf register.
+ */
+ reg = readl(base + (gpio << 2));
+ if (direction)
+ reg |= 0x2;
+ else
+ reg &= ~0x2;
+
+ writel(reg, (base + (gpio << 2)));
+}
+#endif
diff --git a/arch/arm/include/asm/arch-vf610/gpio.h b/arch/arm/include/asm/arch-vf610/gpio.h
new file mode 100644
index 0000000000..98897ef289
--- /dev/null
+++ b/arch/arm/include/asm/arch-vf610/gpio.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014
+ * Bhuvanchandra DV, Toradex, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ASM_ARCH_VF610_GPIO_H
+#define __ASM_ARCH_VF610_GPIO_H
+
+#define GPIO_TO_PORT(n) (n >> 5)
+#define VF610_GPIO_DIRECTION_IN 0x0
+#define VF610_GPIO_DIRECTION_OUT 0x1
+
+/* GPIO registers */
+struct gpio_regs {
+ u32 gpio_pdor;
+ u32 gpio_psor;
+ u32 gpio_pcor;
+ u32 gpio_ptor;
+ u32 gpio_pdir;
+};
+
+#endif /* __ASM_ARCH_VF610_GPIO_H */
diff --git a/arch/arm/include/asm/arch-vf610/imx-regs.h b/arch/arm/include/asm/arch-vf610/imx-regs.h
index 68b97bbd39..b21cc72c43 100644
--- a/arch/arm/include/asm/arch-vf610/imx-regs.h
+++ b/arch/arm/include/asm/arch-vf610/imx-regs.h
@@ -81,6 +81,11 @@
#define VREG_DIG_BASE_ADDR (AIPS0_BASE_ADDR + 0x0006D000)
#define SRC_BASE_ADDR (AIPS0_BASE_ADDR + 0x0006E000)
#define CMU_BASE_ADDR (AIPS0_BASE_ADDR + 0x0006F000)
+#define GPIO0_BASE_ADDR (AIPS0_BASE_ADDR + 0x000FF000)
+#define GPIO1_BASE_ADDR (AIPS0_BASE_ADDR + 0x000FF040)
+#define GPIO2_BASE_ADDR (AIPS0_BASE_ADDR + 0x000FF080)
+#define GPIO3_BASE_ADDR (AIPS0_BASE_ADDR + 0x000FF0C0)
+#define GPIO4_BASE_ADDR (AIPS0_BASE_ADDR + 0x000FF100)
/* AIPS 1 */
#define OCOTP_BASE_ADDR (AIPS1_BASE_ADDR + 0x00025000)
@@ -479,7 +484,6 @@ struct scsc_reg {
u32 sirc_ctr;
u32 sosc_ctr;
};
-
#endif /* __ASSEMBLER__*/
#endif /* __ASM_ARCH_IMX_REGS_H__ */
diff --git a/arch/arm/include/asm/imx-common/iomux-v3.h b/arch/arm/include/asm/imx-common/iomux-v3.h
index a8ca49c343..4509f17431 100644
--- a/arch/arm/include/asm/imx-common/iomux-v3.h
+++ b/arch/arm/include/asm/imx-common/iomux-v3.h
@@ -182,6 +182,8 @@ typedef u64 iomux_v3_cfg_t;
void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
unsigned count);
+void imx_iomux_gpio_set_direction(unsigned int gpio,
+ unsigned int direction);
/* macros for declaring and using pinmux array */
#if defined(CONFIG_MX6QDL)
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index aa11f15423..88e8a58720 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o
obj-$(CONFIG_TCA642X) += tca642x.o
oby-$(CONFIG_SX151X) += sx151x.o
obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o
+obj-$(CONFIG_VYBRID_GPIO) += vybrid_gpio.o
diff --git a/drivers/gpio/vybrid_gpio.c b/drivers/gpio/vybrid_gpio.c
new file mode 100644
index 0000000000..a508397e17
--- /dev/null
+++ b/drivers/gpio/vybrid_gpio.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015
+ * Bhuvanchandra DV, Toradex, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/iomux-v3.h>
+
+static unsigned long gpio_ports[] = {
+ [0] = GPIO0_BASE_ADDR,
+ [1] = GPIO1_BASE_ADDR,
+ [2] = GPIO2_BASE_ADDR,
+ [3] = GPIO3_BASE_ADDR,
+ [4] = GPIO4_BASE_ADDR,
+};
+
+int gpio_set_value(unsigned gpio, int value)
+{
+ unsigned int port = GPIO_TO_PORT(gpio);
+ struct gpio_regs *regs;
+ u32 mask = (1 << (gpio & GPIO_PIN_MASK));
+
+ if (port >= ARRAY_SIZE(gpio_ports))
+ return -1;
+
+ regs = (struct gpio_regs *)gpio_ports[port];
+
+ if (value)
+ writel(mask, &regs->gpio_psor);
+ else
+ writel(mask, &regs->gpio_pcor);
+
+ return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ unsigned int port = GPIO_TO_PORT(gpio);
+ struct gpio_regs *regs;
+ u32 mask = (1 << (gpio & GPIO_PIN_MASK));
+
+ if (port >= ARRAY_SIZE(gpio_ports))
+ return -1;
+
+ regs = (struct gpio_regs *)gpio_ports[port];
+
+ return ((readl(&regs->gpio_pdir) & mask)) ? 1 : 0;
+}
+
+int gpio_request(unsigned gpio, const char *label)
+{
+ unsigned int port = GPIO_TO_PORT(gpio);
+
+ if (port >= ARRAY_SIZE(gpio_ports))
+ return -1;
+
+ return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+ return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+ imx_iomux_gpio_set_direction(gpio, VF610_GPIO_DIRECTION_IN);
+
+ return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ gpio_set_value(gpio, value);
+
+ imx_iomux_gpio_set_direction(gpio, VF610_GPIO_DIRECTION_OUT);
+
+ return 0;
+}