diff options
Diffstat (limited to 'qemu/roms/u-boot/drivers/gpio/mxc_gpio.c')
-rw-r--r-- | qemu/roms/u-boot/drivers/gpio/mxc_gpio.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/drivers/gpio/mxc_gpio.c b/qemu/roms/u-boot/drivers/gpio/mxc_gpio.c new file mode 100644 index 000000000..6a572d545 --- /dev/null +++ b/qemu/roms/u-boot/drivers/gpio/mxc_gpio.c @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2009 + * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> + * + * Copyright (C) 2011 + * Stefano Babic, DENX Software Engineering, <sbabic@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/gpio.h> +#include <asm/io.h> +#include <errno.h> + +enum mxc_gpio_direction { + MXC_GPIO_DIRECTION_IN, + MXC_GPIO_DIRECTION_OUT, +}; + +#define GPIO_TO_PORT(n) (n / 32) + +/* GPIO port description */ +static unsigned long gpio_ports[] = { + [0] = GPIO1_BASE_ADDR, + [1] = GPIO2_BASE_ADDR, + [2] = GPIO3_BASE_ADDR, +#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \ + defined(CONFIG_MX53) || defined(CONFIG_MX6) + [3] = GPIO4_BASE_ADDR, +#endif +#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6) + [4] = GPIO5_BASE_ADDR, + [5] = GPIO6_BASE_ADDR, +#endif +#if defined(CONFIG_MX53) || defined(CONFIG_MX6) + [6] = GPIO7_BASE_ADDR, +#endif +}; + +static int mxc_gpio_direction(unsigned int gpio, + enum mxc_gpio_direction direction) +{ + unsigned int port = GPIO_TO_PORT(gpio); + struct gpio_regs *regs; + u32 l; + + if (port >= ARRAY_SIZE(gpio_ports)) + return -1; + + gpio &= 0x1f; + + regs = (struct gpio_regs *)gpio_ports[port]; + + l = readl(®s->gpio_dir); + + switch (direction) { + case MXC_GPIO_DIRECTION_OUT: + l |= 1 << gpio; + break; + case MXC_GPIO_DIRECTION_IN: + l &= ~(1 << gpio); + } + writel(l, ®s->gpio_dir); + + return 0; +} + +int gpio_set_value(unsigned gpio, int value) +{ + unsigned int port = GPIO_TO_PORT(gpio); + struct gpio_regs *regs; + u32 l; + + if (port >= ARRAY_SIZE(gpio_ports)) + return -1; + + gpio &= 0x1f; + + regs = (struct gpio_regs *)gpio_ports[port]; + + l = readl(®s->gpio_dr); + if (value) + l |= 1 << gpio; + else + l &= ~(1 << gpio); + writel(l, ®s->gpio_dr); + + return 0; +} + +int gpio_get_value(unsigned gpio) +{ + unsigned int port = GPIO_TO_PORT(gpio); + struct gpio_regs *regs; + u32 val; + + if (port >= ARRAY_SIZE(gpio_ports)) + return -1; + + gpio &= 0x1f; + + regs = (struct gpio_regs *)gpio_ports[port]; + + val = (readl(®s->gpio_psr) >> gpio) & 0x01; + + return val; +} + +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) +{ + return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + int ret = gpio_set_value(gpio, value); + + if (ret < 0) + return ret; + + return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT); +} |