diff options
author | Stefano Babic <sbabic@denx.de> | 2017-05-09 18:03:44 +0200 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2017-05-09 18:03:44 +0200 |
commit | 4f66e09bb9fbc47b73f67c3cc08ee2663e8fcdb1 (patch) | |
tree | 89bc85aa5a8ca9b60027cdd2f1a40fc83f6278c4 /drivers/pinctrl/pinctrl_stm32.c | |
parent | 809b133722eee0e7bdfa6595daabc0bb2f5aa698 (diff) | |
parent | 85ea850976daea57c8045f3569566fad5ce9fe0f (diff) |
Merge branch 'master' of git://git.denx.de/u-boot
Signed-off-by: Stefano Babic <sbabic@denx.de>
Diffstat (limited to 'drivers/pinctrl/pinctrl_stm32.c')
-rw-r--r-- | drivers/pinctrl/pinctrl_stm32.c | 50 |
1 files changed, 46 insertions, 4 deletions
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index aa2c440b14..d7b5ea3e1c 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -1,10 +1,46 @@ #include <common.h> -#include <asm/arch/gpio.h> #include <dm.h> #include <dm/pinctrl.h> +#include <asm/arch/gpio.h> +#include <asm/gpio.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; +#define MAX_PINS_ONE_IP 70 +#define MODE_BITS_MASK 3 +#define OSPEED_MASK 3 +#define PUPD_MASK 3 +#define OTYPE_MSK 1 +#define AFR_MASK 0xF + +static int stm32_gpio_config(struct gpio_desc *desc, + const struct stm32_gpio_ctl *ctl) +{ + struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); + struct stm32_gpio_regs *regs = priv->regs; + u32 index; + + if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 || + ctl->pupd > 2 || ctl->speed > 3) + return -EINVAL; + + index = (desc->offset & 0x07) * 4; + clrsetbits_le32(®s->afr[desc->offset >> 3], AFR_MASK << index, + ctl->af << index); + + index = desc->offset * 2; + clrsetbits_le32(®s->moder, MODE_BITS_MASK << index, + ctl->mode << index); + clrsetbits_le32(®s->ospeedr, OSPEED_MASK << index, + ctl->speed << index); + clrsetbits_le32(®s->pupdr, PUPD_MASK << index, ctl->pupd << index); + + index = desc->offset; + clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); + + return 0; +} static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin) { gpio_dsc->port = (port_pin & 0xF000) >> 12; @@ -18,6 +54,7 @@ static int prep_gpio_dsc(struct stm32_gpio_dsc *gpio_dsc, u32 port_pin) static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node) { gpio_fn &= 0x00FF; + gpio_ctl->af = 0; switch (gpio_fn) { case 0: @@ -59,7 +96,7 @@ static int prep_gpio_ctl(struct stm32_gpio_ctl *gpio_ctl, u32 gpio_fn, int node) static int stm32_pinctrl_set_state_simple(struct udevice *dev, struct udevice *periph) { - u32 pin_mux[50]; + u32 pin_mux[MAX_PINS_ONE_IP]; struct fdtdec_phandle_args args; int rv, len; @@ -85,11 +122,16 @@ static int stm32_pinctrl_set_state_simple(struct udevice *dev, if (len < 0) return -EINVAL; for (i = 0; i < len; i++) { + struct gpio_desc desc; debug("%s: pinmux = %x\n", __func__, *(pin_mux + i)); prep_gpio_dsc(&gpio_dsc, *(pin_mux + i)); prep_gpio_ctl(&gpio_ctl, *(pin_mux + i), args.node); - - rv = stm32_gpio_config(&gpio_dsc, &gpio_ctl); + rv = uclass_get_device_by_seq(UCLASS_GPIO, + gpio_dsc.port, &desc.dev); + if (rv) + return rv; + desc.offset = gpio_dsc.pin; + rv = stm32_gpio_config(&desc, &gpio_ctl); debug("%s: rv = %d\n\n", __func__, rv); if (rv) return rv; |