diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2015-04-23 17:19:58 +0200 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2015-04-23 17:19:58 +0200 |
commit | 769c0f8d9c7a98d77855aa7efd8ec21a2f125924 (patch) | |
tree | c81bfe80a1e201f9f38587278594ad638e65da1d | |
parent | f51c0c368c45a55f3eb41b1fa4206b87165f8661 (diff) | |
parent | 60f63388e38a305ae60d5502e20b9f16d1f78f83 (diff) |
Merge branch '2015.04-toradex-next-gpio' into 2015.04-toradex-next
-rw-r--r-- | arch/arm/imx-common/iomux-v3.c | 19 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-vf610/gpio.h | 28 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-vf610/imx-regs.h | 5 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-vf610/iomux-vf610.h | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/imx-common/iomux-v3.h | 2 | ||||
-rw-r--r-- | board/toradex/colibri_vf/colibri_vf.c | 44 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-uclass.c | 1 | ||||
-rw-r--r-- | drivers/gpio/vybrid_gpio.c | 122 | ||||
-rw-r--r-- | include/configs/colibri_vf.h | 8 |
10 files changed, 243 insertions, 0 deletions
diff --git a/arch/arm/imx-common/iomux-v3.c b/arch/arm/imx-common/iomux-v3.c index e88e6e2a98..22c536e0c3 100644 --- a/arch/arm/imx-common/iomux-v3.c +++ b/arch/arm/imx-common/iomux-v3.c @@ -92,3 +92,22 @@ void imx_iomux_set_gpr_register(int group, int start_bit, reg |= (value << start_bit); writel(reg, base + group * 4); } + +#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..57d50c3b01 --- /dev/null +++ b/arch/arm/include/asm/arch-vf610/gpio.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 + * Bhuvanchandra DV, Toradex, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __ASM_ARCH_VF610_GPIO_H +#define __ASM_ARCH_VF610_GPIO_H + +#define VYBRID_GPIO_COUNT 32 +#define VF610_GPIO_DIRECTION_IN 0x0 +#define VF610_GPIO_DIRECTION_OUT 0x1 + +/* GPIO registers */ +struct vybrid_gpio_regs { + u32 gpio_pdor; + u32 gpio_psor; + u32 gpio_pcor; + u32 gpio_ptor; + u32 gpio_pdir; +}; + +struct vybrid_gpio_platdata { + unsigned int chip; + u32 base; +}; +#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 512bc1fdb5..5ca3abba58 100644 --- a/arch/arm/include/asm/arch-vf610/imx-regs.h +++ b/arch/arm/include/asm/arch-vf610/imx-regs.h @@ -82,6 +82,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) diff --git a/arch/arm/include/asm/arch-vf610/iomux-vf610.h b/arch/arm/include/asm/arch-vf610/iomux-vf610.h index 6d0f817f12..d9257ae599 100644 --- a/arch/arm/include/asm/arch-vf610/iomux-vf610.h +++ b/arch/arm/include/asm/arch-vf610/iomux-vf610.h @@ -35,13 +35,26 @@ #define VF610_DCU_PAD_CTRL (PAD_CTL_SPEED_MED | PAD_CTL_SRE | \ PAD_CTL_DSE_37ohm | PAD_CTL_OBE_ENABLE) +#define VF610_GPIO_PAD_CTRL (PAD_CTL_SPEED_MED | PAD_CTL_DSE_50ohm | \ + PAD_CTL_PUS_47K_UP | PAD_CTL_IBE_ENABLE) + enum { VF610_PAD_PTA6__RMII0_CLKIN = IOMUX_PAD(0x0000, 0x0000, 2, __NA_, 0, VF610_ENET_PAD_CTRL), VF610_PAD_PTA6__RMII0_CLKOUT = IOMUX_PAD(0x0000, 0x0000, 1, __NA_, 0, VF610_ENET_PAD_CTRL), + VF610_PAD_PTA17__GPIO_7 = IOMUX_PAD(0x001c, 0x001c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTA20__GPIO_10 = IOMUX_PAD(0x0028, 0x0028, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTA21__GPIO_11 = IOMUX_PAD(0x002c, 0x002c, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTA30__GPIO_20 = IOMUX_PAD(0x0050, 0x0050, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTA31__GPIO_21 = IOMUX_PAD(0x0054, 0x0054, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTB0__GPIO_22 = IOMUX_PAD(0x0058, 0x0058, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTB1__GPIO_23 = IOMUX_PAD(0x005C, 0x005C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), VF610_PAD_PTB4__UART1_TX = IOMUX_PAD(0x0068, 0x0068, 2, 0x0380, 0, VF610_UART_PAD_CTRL), VF610_PAD_PTB5__UART1_RX = IOMUX_PAD(0x006c, 0x006c, 2, 0x037c, 0, VF610_UART_PAD_CTRL), + VF610_PAD_PTB8__GPIO_30 = IOMUX_PAD(0x0078, 0x0078, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), + VF610_PAD_PTB9__GPIO_31 = IOMUX_PAD(0x007C, 0x007C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), VF610_PAD_PTB10__UART0_TX = IOMUX_PAD(0x0080, 0x0080, 1, __NA_, 0, VF610_UART_PAD_CTRL), VF610_PAD_PTB11__UART0_RX = IOMUX_PAD(0x0084, 0x0084, 1, __NA_, 0, VF610_UART_PAD_CTRL), + VF610_PAD_PTC0__GPIO_45 = IOMUX_PAD(0x00b4, 0x00b4, 0, __NA_, 0, VF610_GPIO_PAD_CTRL), VF610_PAD_PTC1__RMII0_MDIO = IOMUX_PAD(0x00b8, 0x00b8, 1, __NA_, 0, VF610_ENET_PAD_CTRL), VF610_PAD_PTC0__RMII0_MDC = IOMUX_PAD(0x00b4, 0x00b4, 1, __NA_, 0, VF610_ENET_PAD_CTRL), VF610_PAD_PTC2__RMII0_CRS_DV = IOMUX_PAD(0x00bc, 0x00bc, 1, __NA_, 0, VF610_ENET_PAD_CTRL), diff --git a/arch/arm/include/asm/imx-common/iomux-v3.h b/arch/arm/include/asm/imx-common/iomux-v3.h index 5f161bb5f1..a817b0cc03 100644 --- a/arch/arm/include/asm/imx-common/iomux-v3.h +++ b/arch/arm/include/asm/imx-common/iomux-v3.h @@ -190,6 +190,8 @@ void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list, */ void imx_iomux_set_gpr_register(int group, int start_bit, int num_bits, int value); +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/board/toradex/colibri_vf/colibri_vf.c b/board/toradex/colibri_vf/colibri_vf.c index 0b1269ad3d..42de260661 100644 --- a/board/toradex/colibri_vf/colibri_vf.c +++ b/board/toradex/colibri_vf/colibri_vf.c @@ -8,6 +8,7 @@ */ #include <common.h> +#include <dm.h> #include <asm/io.h> #include <asm/arch/imx-regs.h> #include <asm/arch/iomux-vf610.h> @@ -22,6 +23,7 @@ #include <netdev.h> #include <i2c.h> #include <g_dnl.h> +#include <asm/gpio.h> #include "../common/configblock.h" @@ -193,6 +195,26 @@ static void setup_tcon(void) } #endif +#ifdef CONFIG_VYBRID_GPIO +static void setup_iomux_gpio(void) +{ + static const iomux_v3_cfg_t gpio_pads[] = { + VF610_PAD_PTA17__GPIO_7, + VF610_PAD_PTA20__GPIO_10, + VF610_PAD_PTA21__GPIO_11, + VF610_PAD_PTA30__GPIO_20, + VF610_PAD_PTA31__GPIO_21, + VF610_PAD_PTB0__GPIO_22, + VF610_PAD_PTB1__GPIO_23, + VF610_PAD_PTB8__GPIO_30, + VF610_PAD_PTB9__GPIO_31, + VF610_PAD_PTC0__GPIO_45, + }; + + imx_iomux_v3_setup_multiple_pads(gpio_pads, ARRAY_SIZE(gpio_pads)); +} +#endif + #ifdef CONFIG_FSL_ESDHC struct fsl_esdhc_cfg esdhc_cfg[1] = { {ESDHC1_BASE_ADDR}, @@ -365,6 +387,10 @@ int board_early_init_f(void) setup_iomux_fsl_dcu(); #endif +#ifdef CONFIG_VYBRID_GPIO + setup_iomux_gpio(); +#endif + return 0; } @@ -375,6 +401,24 @@ static const struct boot_mode board_boot_modes[] = { }; #endif +#ifndef CONFIG_OF_CONTROL +static const struct vybrid_gpio_platdata vybrid_gpio[] = { + {0, GPIO0_BASE_ADDR}, + {1, GPIO1_BASE_ADDR}, + {2, GPIO2_BASE_ADDR}, + {3, GPIO3_BASE_ADDR}, + {4, GPIO4_BASE_ADDR}, +}; + +U_BOOT_DEVICES(vybrid_gpio) = { + { "gpio_vybrid", &vybrid_gpio[0] }, + { "gpio_vybrid", &vybrid_gpio[1] }, + { "gpio_vybrid", &vybrid_gpio[2] }, + { "gpio_vybrid", &vybrid_gpio[3] }, + { "gpio_vybrid", &vybrid_gpio[4] }, +}; +#endif + #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 85f71c5d4a..62c73042b7 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 a69bbd2002..27778b4fcc 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 0000000000..9fa0762b7c --- /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, +}; diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h index aef2014f52..5a01c7f2f9 100644 --- a/include/configs/colibri_vf.h +++ b/include/configs/colibri_vf.h @@ -80,6 +80,14 @@ #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE NFC_BASE_ADDR +/* Enable driver model */ +#define CONFIG_DM + +/* GPIO support */ +#define CONFIG_DM_GPIO +#define CONFIG_CMD_GPIO +#define CONFIG_VYBRID_GPIO + /* Dynamic MTD partition support */ #define CONFIG_CMD_MTDPARTS /* Enable 'mtdparts' command line support */ #define CONFIG_MTD_PARTITIONS |