
Manage flags for GPIO configuration: - open_drain, open_source, push_pull - pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
drivers/gpio/stm32_gpio.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index 302a434947..bc4c378260 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -19,6 +19,12 @@ #define MODE_BITS_MASK 3 #define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16))
+#define PUPD_BITS(gpio_pin) (gpio_pin * 2) +#define PUPD_MASK 3 + +#define OTYPE_BITS(gpio_pin) (gpio_pin) +#define OTYPE_MSK 1 + #ifndef CONFIG_SPL_BUILD /* * convert gpio offset to gpio index taking into account gpio holes @@ -139,12 +145,64 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) return GPIOF_FUNC; }
+static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, + int idx, + enum stm32_gpio_otype otype) +{ + int bits; + + bits = OTYPE_BITS(idx); + clrsetbits_le32(®s->otyper, OTYPE_MSK << bits, otype << bits); +} + +static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, + int idx, + enum stm32_gpio_pupd pupd) +{ + int bits; + + bits = PUPD_BITS(idx); + clrsetbits_le32(®s->pupdr, PUPD_MASK << bits, pupd << bits); +} + +static int stm32_gpio_set_config(struct udevice *dev, unsigned int offset, + enum gpio_config config) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int idx; + + idx = stm32_offset_to_index(dev, offset); + if (idx < 0) + return idx; + + switch (config) { + default: + return -ENOTSUPP; + case GPIO_CONF_DRIVE_OPEN_DRAIN: + stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD); + break; + case GPIO_CONF_DRIVE_PULL_PUSH: + stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP); + break; + case GPIO_CONF_BIAS_PULL_UP: + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); + break; + case GPIO_CONF_BIAS_PULL_DOWN: + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); + break; + } + + return 0; +} + static const struct dm_gpio_ops gpio_stm32_ops = { .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, .get_value = stm32_gpio_get_value, .set_value = stm32_gpio_set_value, .get_function = stm32_gpio_get_function, + .set_config = stm32_gpio_set_config, }; #endif