diff options
-rw-r--r-- | arch/arm/imx-common/iomux-v3.c | 19 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-vf610/gpio.h | 24 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-vf610/imx-regs.h | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/imx-common/iomux-v3.h | 2 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/vybrid_gpio.c | 84 |
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, ®s->gpio_psor); + else + writel(mask, ®s->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(®s->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; +} |