From: Benjamin Tietz <benja...@micronet24.de> will bind as a gpio-driver, if DM_GPIO was selected. Defaults to the old behaviour. --- drivers/gpio/stm32_gpio.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+)
From: Benjamin Tietz <benja...@micronet24.de>
will bind as a gpio-driver, if DM_GPIO was selected. Defaults to the old behaviour. --- drivers/gpio/stm32_gpio.c | 133 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index be662c3..844b3e1 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -220,6 +220,138 @@ out: return rv; } +#ifdef CONFIG_DM_GPIO +#include <asm-generic/gpio.h> +#include <dm/device.h> +#include <clk.h> +#include <dt-bindings/gpio/gpio.h> + +struct stm32_gpio_priv { + int portnum; + u32 requested; +}; + +static int stm32_gpio_request(struct udevice *dev, unsigned offset, const char *label) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + if(priv->requested & (1<<offset)) + return -EBUSY; + if(!priv->requested) { + struct udevice *clk = NULL; + int clk_id; + if((clk_id = clk_get_by_index(dev, 0, &clk)) >= 0) + clk_enable(clk, clk_id); + } + priv->requested |= 1<<offset; + return 0; +} + +static int stm32_gpio_free(struct udevice *dev, unsigned offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + priv->requested &= ~(1<<offset); + if(!priv->requested) { + struct udevice *clk = NULL; + int clk_id; + if((clk_id = clk_get_by_index(dev, 0, &clk)) >= 0) + clk_disable(clk, clk_id); + } + return 0; +} + +static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_dsc dsc = { + .port = priv->portnum, + .pin = offset, + }; + return stm32_gpio_config(&dsc, &ctl_in); +} + +static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, int value) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_dsc dsc = { + .port = priv->portnum, + .pin = offset, + }; + int ret = stm32_gpio_config(&dsc, &ctl_out); + if(ret >= 0) + ret = stm32_gpout_set(&dsc, value); + return ret; +} + +static int stm32_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_dsc dsc = { + .port = priv->portnum, + .pin = offset, + }; + return !!stm32_gpin_get(&dsc); +} + +static int stm32_gpio_set_value(struct udevice *dev, unsigned offset, int value) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_dsc dsc = { + .port = priv->portnum, + .pin = offset, + }; + return stm32_gpout_set(&dsc, value); +} + +static struct dm_gpio_ops stm32_gpio_ops = { + .request = stm32_gpio_request, + .free = stm32_gpio_free, + .direction_input = stm32_gpio_direction_input, + .direction_output = stm32_gpio_direction_output, + .get_value = stm32_gpio_get_value, + .set_value = stm32_gpio_set_value, +}; + +static int stm32_gpio_probe(struct udevice *dev) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + fdt_addr_t addr; + fdt_size_t size; + int i; + priv->requested = 0; + + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + if(size < sizeof(struct stm32_gpio_ctl)) + return -EINVAL; + + for(i=0; i < sizeof(io_base)/sizeof(io_base[0]); i++) { + if(io_base[i] != addr) + continue; + priv->portnum = i; + uc_priv->bank_name = dev->name; + uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "gpio-count", 16); + return 0; + } + return -ENXIO; +} + +static const struct udevice_id stm32_gpio_ids[] = { + { .compatible = "st,stm32-gpio" }, + { } +}; + +U_BOOT_DRIVER(stm32_gpio) = { + .name = "stm32_gpio", + .id = UCLASS_GPIO, + .ops = &stm32_gpio_ops, + .probe = stm32_gpio_probe, + .priv_auto_alloc_size = sizeof(struct stm32_gpio_priv), + .of_match = stm32_gpio_ids, +}; +#else /* Common GPIO API */ int gpio_request(unsigned gpio, const char *label) @@ -277,3 +409,4 @@ int gpio_set_value(unsigned gpio, int value) return stm32_gpout_set(&dsc, value); } +#endif
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot