diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/da8xx_gpio.c | 193 | ||||
-rw-r--r-- | drivers/gpio/omap_gpio.c | 10 |
2 files changed, 177 insertions, 26 deletions
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c index e410f5f9df..1a1d37ae2a 100644 --- a/drivers/gpio/da8xx_gpio.c +++ b/drivers/gpio/da8xx_gpio.c @@ -7,11 +7,14 @@ */ #include <common.h> +#include <dm.h> +#include <fdtdec.h> #include <asm/io.h> #include <asm/gpio.h> #include <asm/arch/hardware.h> #include <asm/arch/davinci_misc.h> +#ifndef CONFIG_DM_GPIO static struct gpio_registry { int is_registered; char name[GPIO_NAME_SIZE]; @@ -303,7 +306,7 @@ static const struct pinmux_config gpio_pinmux[] = { #define davinci_configure_pin_mux(a, b) #endif /* CONFIG_SOC_DA8XX */ -int gpio_request(unsigned gpio, const char *label) +int gpio_request(unsigned int gpio, const char *label) { if (gpio >= MAX_NUM_GPIOS) return -1; @@ -320,7 +323,7 @@ int gpio_request(unsigned gpio, const char *label) return 0; } -int gpio_free(unsigned gpio) +int gpio_free(unsigned int gpio) { if (gpio >= MAX_NUM_GPIOS) return -1; @@ -333,42 +336,30 @@ int gpio_free(unsigned gpio) /* Do not configure as input or change pin mux here */ return 0; } +#endif -int gpio_direction_input(unsigned gpio) +static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value) { - struct davinci_gpio *bank; - - bank = GPIO_BANK(gpio); - setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); + clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); + gpio_set_value(gpio, value); return 0; } -int gpio_direction_output(unsigned gpio, int value) +static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio) { - struct davinci_gpio *bank; - - bank = GPIO_BANK(gpio); - clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); - gpio_set_value(gpio, value); + setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); return 0; } -int gpio_get_value(unsigned gpio) +static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio) { - struct davinci_gpio *bank; unsigned int ip; - - bank = GPIO_BANK(gpio); ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio)); return ip ? 1 : 0; } -int gpio_set_value(unsigned gpio, int value) +static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value) { - struct davinci_gpio *bank; - - bank = GPIO_BANK(gpio); - if (value) bank->set_data = 1U << GPIO_BIT(gpio); else @@ -377,14 +368,21 @@ int gpio_set_value(unsigned gpio, int value) return 0; } +static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio) +{ + return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); +} + +#ifndef CONFIG_DM_GPIO + void gpio_info(void) { - unsigned gpio, dir, val; + unsigned int gpio, dir, val; struct davinci_gpio *bank; for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) { bank = GPIO_BANK(gpio); - dir = in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); + dir = _gpio_get_dir(bank, gpio); val = gpio_get_value(gpio); printf("% 4d: %s: %d [%c] %s\n", @@ -393,3 +391,150 @@ void gpio_info(void) gpio_registry[gpio].name); } } + +int gpio_direction_input(unsigned int gpio) +{ + struct davinci_gpio *bank; + + bank = GPIO_BANK(gpio); + return _gpio_direction_input(bank, gpio); +} + +int gpio_direction_output(unsigned int gpio, int value) +{ + struct davinci_gpio *bank; + + bank = GPIO_BANK(gpio); + return _gpio_direction_output(bank, gpio, value); +} + +int gpio_get_value(unsigned int gpio) +{ + struct davinci_gpio *bank; + + bank = GPIO_BANK(gpio); + return _gpio_get_value(bank, gpio); +} + +int gpio_set_value(unsigned int gpio, int value) +{ + struct davinci_gpio *bank; + + bank = GPIO_BANK(gpio); + return _gpio_set_value(bank, gpio, value); +} + +#else /* CONFIG_DM_GPIO */ + +static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset) +{ + struct davinci_gpio_bank *bank = dev_get_priv(dev); + + /* The device tree is not broken into banks but the infrastructure is + * expecting it this way, so we'll first include the 0x10 offset, then + * calculate the bank manually based on the offset. + */ + + return ((struct davinci_gpio *)bank->base) + 0x10 + (offset >> 5); +} + +static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset) +{ + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); + + _gpio_direction_input(base, offset); + return 0; +} + +static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset, + int value) +{ + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); + + _gpio_direction_output(base, offset, value); + return 0; +} + +static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset) +{ + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); + + return _gpio_get_value(base, offset); +} + +static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset, + int value) +{ + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); + + _gpio_set_value(base, offset, value); + + return 0; +} + +static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset) +{ + unsigned int dir; + struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset); + + dir = _gpio_get_dir(base, offset); + + if (dir) + return GPIOF_INPUT; + + return GPIOF_OUTPUT; +} + +static const struct dm_gpio_ops gpio_davinci_ops = { + .direction_input = davinci_gpio_direction_input, + .direction_output = davinci_gpio_direction_output, + .get_value = davinci_gpio_get_value, + .set_value = davinci_gpio_set_value, + .get_function = davinci_gpio_get_function, +}; + +static int davinci_gpio_probe(struct udevice *dev) +{ + struct davinci_gpio_bank *bank = dev_get_priv(dev); + struct davinci_gpio_platdata *plat = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + const void *fdt = gd->fdt_blob; + int node = dev_of_offset(dev); + + uc_priv->bank_name = plat->port_name; + uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1); + bank->base = (struct davinci_gpio *)plat->base; + return 0; +} + +static const struct udevice_id davinci_gpio_ids[] = { + { .compatible = "ti,dm6441-gpio" }, + { } +}; + +static int davinci_gpio_ofdata_to_platdata(struct udevice *dev) +{ + struct davinci_gpio_platdata *plat = dev_get_platdata(dev); + fdt_addr_t addr; + + addr = devfdt_get_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->base = addr; + return 0; +} + +U_BOOT_DRIVER(gpio_davinci) = { + .name = "gpio_davinci", + .id = UCLASS_GPIO, + .ops = &gpio_davinci_ops, + .ofdata_to_platdata = of_match_ptr(davinci_gpio_ofdata_to_platdata), + .of_match = davinci_gpio_ids, + .bind = dm_scan_fdt_dev, + .platdata_auto_alloc_size = sizeof(struct davinci_gpio_platdata), + .probe = davinci_gpio_probe, + .priv_auto_alloc_size = sizeof(struct davinci_gpio_bank), +}; + +#endif diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index d128f942a0..79a975ce71 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -288,11 +288,17 @@ static int omap_gpio_probe(struct udevice *dev) struct gpio_bank *bank = dev_get_priv(dev); struct omap_gpio_platdata *plat = dev_get_platdata(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + int banknum; + char name[18], *str; - uc_priv->bank_name = plat->port_name; + banknum = plat->bank_index; + sprintf(name, "GPIO%d_", banknum + 1); + str = strdup(name); + if (!str) + return -ENOMEM; + uc_priv->bank_name = str; uc_priv->gpio_count = GPIO_PER_BANK; bank->base = (void *)plat->base; - return 0; } |