[PATCH v2 00/11] stm32mp1: activate gpio hog support and add new pinctrl ops

Hi,
This V2 serie of [1] updates the two pincontrol drivers for stm32mp1 and activates the gpio hog support. It also adds pin information in pinmux command output for stm32 and stmfx.
It is a rebased version, as dependency [2] is accepted merged. I also split some patch for review.
[1] http://patchwork.ozlabs.org/project/uboot/list/?series=138122&state=*
[2] V3 "dm: add support of new binding in gpio and pincontrol" http://patchwork.ozlabs.org/project/uboot/list/?series=152777&state=*
Regards.
Patrick
Changes in v2: - NEW: split previous patch [5/5] gpio: stmfx: add set_config ops - NEW: split previous patch [5/5] gpio: stmfx: add set_config ops - NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
Patrick Delaunay (11): configs: stm32mp1: activate CONFIG_GPIO_HOG board: stm32mp1: update the gpio hog support gpio: stm32: add ops set_dir_flags gpio: stm32: add ops get_dir_flags gpio: stmfx: move function to prepare new ops introduction gpio: stmfx: rename function used to change pin configuration gpio: stmfx: add function stmfx_read_reg and stmfx_write_reg gpio: stmfx: add ops set_dir_flag gpio: stmfx: add ops get_dir_flags pinctrl: stmfx: add information on pin configuration pinctrl: stm32: add information on pin configuration
board/st/stm32mp1/stm32mp1.c | 10 +- configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + drivers/gpio/stm32_gpio.c | 149 ++++++++++++++++-- drivers/pinctrl/pinctrl-stmfx.c | 225 ++++++++++++++++++++-------- drivers/pinctrl/pinctrl_stm32.c | 27 +++- 6 files changed, 325 insertions(+), 88 deletions(-)

This patch activates the new configuration CONFIG_GPIO_HOG.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 2 files changed, 2 insertions(+)
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index c7dd2926c9..f180b460d6 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -72,6 +72,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index ca4a10813b..97a27986a9 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -59,6 +59,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y

HI Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
This patch activates the new configuration CONFIG_GPIO_HOG.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 2 files changed, 2 insertions(+)
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index c7dd2926c9..f180b460d6 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -72,6 +72,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index ca4a10813b..97a27986a9 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -59,6 +59,7 @@ CONFIG_FASTBOOT_BUF_SIZE=0x02000000 CONFIG_FASTBOOT_USB_DEV=1 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=1 +CONFIG_GPIO_HOG=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_STM32=y CONFIG_DM_I2C=y
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

This patch updates the current gpio hog implementation and uses the new API gpio_hog_probe_all(), activated with CONFIG_GPIO_HOG.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
board/st/stm32mp1/stm32mp1.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 4553329b25..f4a032f781 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -664,17 +664,11 @@ static void board_ev1_init(void) /* board dependent setup after realloc */ int board_init(void) { - struct udevice *dev; - /* address of boot parameters */ gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
- /* probe all PINCTRL for hog */ - for (uclass_first_device(UCLASS_PINCTRL, &dev); - dev; - uclass_next_device(&dev)) { - pr_debug("probe pincontrol = %s\n", dev->name); - } + if (CONFIG_IS_ENABLED(DM_GPIO_HOG)) + gpio_hog_probe_all();
board_key_check();

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
This patch updates the current gpio hog implementation and uses the new API gpio_hog_probe_all(), activated with CONFIG_GPIO_HOG.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
board/st/stm32mp1/stm32mp1.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 4553329b25..f4a032f781 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -664,17 +664,11 @@ static void board_ev1_init(void) /* board dependent setup after realloc */ int board_init(void) {
struct udevice *dev;
/* address of boot parameters */ gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
/* probe all PINCTRL for hog */
for (uclass_first_device(UCLASS_PINCTRL, &dev);
dev;
uclass_next_device(&dev)) {
pr_debug("probe pincontrol = %s\n", dev->name);
}
if (CONFIG_IS_ENABLED(DM_GPIO_HOG))
gpio_hog_probe_all();
board_key_check();
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Manage flags for GPIO configuration: - open_drain, open_source, push_pull - pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/gpio/stm32_gpio.c | 90 +++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 14 deletions(-)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index 4f710b6b6a..f120ee9808 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -18,9 +18,48 @@ #include <linux/errno.h> #include <linux/io.h>
-#define MODE_BITS(gpio_pin) (gpio_pin * 2) +#define MODE_BITS(gpio_pin) ((gpio_pin) * 2) #define MODE_BITS_MASK 3 -#define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16)) +#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 + +static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs, + int idx, + int mode) +{ + int bits_index; + int mask; + + bits_index = MODE_BITS(idx); + mask = MODE_BITS_MASK << bits_index; + + clrsetbits_le32(®s->moder, mask, mode << bits_index); +} + +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); +}
/* * convert gpio offset to gpio index taking into account gpio holes @@ -47,18 +86,13 @@ static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) { struct stm32_gpio_priv *priv = dev_get_priv(dev); struct stm32_gpio_regs *regs = priv->regs; - int bits_index; - int mask; int idx;
idx = stm32_offset_to_index(dev, offset); if (idx < 0) return idx;
- bits_index = MODE_BITS(idx); - mask = MODE_BITS_MASK << bits_index; - - clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index); + stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
return 0; } @@ -68,18 +102,13 @@ static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, { struct stm32_gpio_priv *priv = dev_get_priv(dev); struct stm32_gpio_regs *regs = priv->regs; - int bits_index; - int mask; int idx;
idx = stm32_offset_to_index(dev, offset); if (idx < 0) return idx;
- bits_index = MODE_BITS(idx); - mask = MODE_BITS_MASK << bits_index; - - clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index); + stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
writel(BSRR_BIT(idx, value), ®s->bsrr);
@@ -141,12 +170,45 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) return GPIOF_FUNC; }
+static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, + ulong flags) +{ + 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; + + if (flags & GPIOD_IS_OUT) { + int value = GPIOD_FLAGS_OUTPUT(flags); + + if (flags & GPIOD_OPEN_DRAIN) + stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD); + else + stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP); + stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT); + writel(BSRR_BIT(idx, value), ®s->bsrr); + + } else if (flags & GPIOD_IS_IN) { + stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN); + if (flags & GPIOD_PULL_UP) + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP); + else if (flags & GPIOD_PULL_DOWN) + stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN); + } + + 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_dir_flags = stm32_gpio_set_dir_flags, };
static int gpio_stm32_probe(struct udevice *dev)

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Manage flags for GPIO configuration:
- open_drain, open_source, push_pull
- pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
drivers/gpio/stm32_gpio.c | 90 +++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 14 deletions(-)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index 4f710b6b6a..f120ee9808 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -18,9 +18,48 @@ #include <linux/errno.h> #include <linux/io.h>
-#define MODE_BITS(gpio_pin) (gpio_pin * 2) +#define MODE_BITS(gpio_pin) ((gpio_pin) * 2) #define MODE_BITS_MASK 3 -#define BSRR_BIT(gpio_pin, value) BIT(gpio_pin + (value ? 0 : 16)) +#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
+static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs,
int idx,
int mode)
+{
- int bits_index;
- int mask;
- bits_index = MODE_BITS(idx);
- mask = MODE_BITS_MASK << bits_index;
- clrsetbits_le32(®s->moder, mask, mode << bits_index);
+}
+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);
+}
/*
- convert gpio offset to gpio index taking into account gpio holes
@@ -47,18 +86,13 @@ static int stm32_gpio_direction_input(struct udevice *dev, unsigned offset) { struct stm32_gpio_priv *priv = dev_get_priv(dev); struct stm32_gpio_regs *regs = priv->regs;
int bits_index;
int mask; int idx;
idx = stm32_offset_to_index(dev, offset); if (idx < 0) return idx;
bits_index = MODE_BITS(idx);
mask = MODE_BITS_MASK << bits_index;
clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_IN << bits_index);
stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
return 0;
} @@ -68,18 +102,13 @@ static int stm32_gpio_direction_output(struct udevice *dev, unsigned offset, { struct stm32_gpio_priv *priv = dev_get_priv(dev); struct stm32_gpio_regs *regs = priv->regs;
int bits_index;
int mask; int idx;
idx = stm32_offset_to_index(dev, offset); if (idx < 0) return idx;
bits_index = MODE_BITS(idx);
mask = MODE_BITS_MASK << bits_index;
clrsetbits_le32(®s->moder, mask, STM32_GPIO_MODE_OUT << bits_index);
stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
writel(BSRR_BIT(idx, value), ®s->bsrr);
@@ -141,12 +170,45 @@ static int stm32_gpio_get_function(struct udevice *dev, unsigned int offset) return GPIOF_FUNC; }
+static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
ulong flags)
+{
- 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;
- if (flags & GPIOD_IS_OUT) {
int value = GPIOD_FLAGS_OUTPUT(flags);
if (flags & GPIOD_OPEN_DRAIN)
stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_OD);
else
stm32_gpio_set_otype(regs, idx, STM32_GPIO_OTYPE_PP);
stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_OUT);
writel(BSRR_BIT(idx, value), ®s->bsrr);
- } else if (flags & GPIOD_IS_IN) {
stm32_gpio_set_moder(regs, idx, STM32_GPIO_MODE_IN);
if (flags & GPIOD_PULL_UP)
stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_UP);
else if (flags & GPIOD_PULL_DOWN)
stm32_gpio_set_pupd(regs, idx, STM32_GPIO_PUPD_DOWN);
- }
- 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_dir_flags = stm32_gpio_set_dir_flags,
};
static int gpio_stm32_probe(struct udevice *dev)
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Add ops get_dir_flags() to read dir flags from GPIO registers.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/gpio/stm32_gpio.c | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index f120ee9808..5bff27f75b 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -41,6 +41,11 @@ static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs, clrsetbits_le32(®s->moder, mask, mode << bits_index); }
+static int stm32_gpio_get_moder(struct stm32_gpio_regs *regs, int idx) +{ + return (readl(®s->moder) >> MODE_BITS(idx)) & MODE_BITS_MASK; +} + static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, int idx, enum stm32_gpio_otype otype) @@ -51,6 +56,12 @@ static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, clrsetbits_le32(®s->otyper, OTYPE_MSK << bits, otype << bits); }
+static enum stm32_gpio_otype stm32_gpio_get_otype(struct stm32_gpio_regs *regs, + int idx) +{ + return (readl(®s->otyper) >> OTYPE_BITS(idx)) & OTYPE_MSK; +} + static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, int idx, enum stm32_gpio_pupd pupd) @@ -61,6 +72,12 @@ static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, clrsetbits_le32(®s->pupdr, PUPD_MASK << bits, pupd << bits); }
+static enum stm32_gpio_pupd stm32_gpio_get_pupd(struct stm32_gpio_regs *regs, + int idx) +{ + return (readl(®s->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK; +} + /* * convert gpio offset to gpio index taking into account gpio holes * into gpio bank @@ -202,6 +219,47 @@ static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, return 0; }
+static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, + ulong *flags) +{ + struct stm32_gpio_priv *priv = dev_get_priv(dev); + struct stm32_gpio_regs *regs = priv->regs; + int idx; + ulong dir_flags = 0; + + idx = stm32_offset_to_index(dev, offset); + if (idx < 0) + return idx; + + switch (stm32_gpio_get_moder(regs, idx)) { + case STM32_GPIO_MODE_OUT: + dir_flags |= GPIOD_IS_OUT; + if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD) + dir_flags |= GPIOD_OPEN_DRAIN; + if (readl(®s->idr) & BIT(idx)) + dir_flags |= GPIOD_IS_OUT_ACTIVE; + break; + case STM32_GPIO_MODE_IN: + dir_flags |= GPIOD_IS_IN; + switch (stm32_gpio_get_pupd(regs, idx)) { + case STM32_GPIO_PUPD_UP: + dir_flags |= GPIOD_PULL_UP; + break; + case STM32_GPIO_PUPD_DOWN: + dir_flags |= GPIOD_PULL_DOWN; + break; + default: + break; + } + break; + default: + break; + } + *flags = dir_flags; + + return 0; +} + static const struct dm_gpio_ops gpio_stm32_ops = { .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, @@ -209,6 +267,7 @@ static const struct dm_gpio_ops gpio_stm32_ops = { .set_value = stm32_gpio_set_value, .get_function = stm32_gpio_get_function, .set_dir_flags = stm32_gpio_set_dir_flags, + .get_dir_flags = stm32_gpio_get_dir_flags, };
static int gpio_stm32_probe(struct udevice *dev)

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Add ops get_dir_flags() to read dir flags from GPIO registers.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
drivers/gpio/stm32_gpio.c | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
diff --git a/drivers/gpio/stm32_gpio.c b/drivers/gpio/stm32_gpio.c index f120ee9808..5bff27f75b 100644 --- a/drivers/gpio/stm32_gpio.c +++ b/drivers/gpio/stm32_gpio.c @@ -41,6 +41,11 @@ static void stm32_gpio_set_moder(struct stm32_gpio_regs *regs, clrsetbits_le32(®s->moder, mask, mode << bits_index); }
+static int stm32_gpio_get_moder(struct stm32_gpio_regs *regs, int idx) +{
- return (readl(®s->moder) >> MODE_BITS(idx)) & MODE_BITS_MASK;
+}
static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, int idx, enum stm32_gpio_otype otype) @@ -51,6 +56,12 @@ static void stm32_gpio_set_otype(struct stm32_gpio_regs *regs, clrsetbits_le32(®s->otyper, OTYPE_MSK << bits, otype << bits); }
+static enum stm32_gpio_otype stm32_gpio_get_otype(struct stm32_gpio_regs *regs,
int idx)
+{
- return (readl(®s->otyper) >> OTYPE_BITS(idx)) & OTYPE_MSK;
+}
static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, int idx, enum stm32_gpio_pupd pupd) @@ -61,6 +72,12 @@ static void stm32_gpio_set_pupd(struct stm32_gpio_regs *regs, clrsetbits_le32(®s->pupdr, PUPD_MASK << bits, pupd << bits); }
+static enum stm32_gpio_pupd stm32_gpio_get_pupd(struct stm32_gpio_regs *regs,
int idx)
+{
- return (readl(®s->pupdr) >> PUPD_BITS(idx)) & PUPD_MASK;
+}
/*
- convert gpio offset to gpio index taking into account gpio holes
- into gpio bank
@@ -202,6 +219,47 @@ static int stm32_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, return 0; }
+static int stm32_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
ulong *flags)
+{
- struct stm32_gpio_priv *priv = dev_get_priv(dev);
- struct stm32_gpio_regs *regs = priv->regs;
- int idx;
- ulong dir_flags = 0;
- idx = stm32_offset_to_index(dev, offset);
- if (idx < 0)
return idx;
- switch (stm32_gpio_get_moder(regs, idx)) {
- case STM32_GPIO_MODE_OUT:
dir_flags |= GPIOD_IS_OUT;
if (stm32_gpio_get_otype(regs, idx) == STM32_GPIO_OTYPE_OD)
dir_flags |= GPIOD_OPEN_DRAIN;
if (readl(®s->idr) & BIT(idx))
dir_flags |= GPIOD_IS_OUT_ACTIVE;
break;
- case STM32_GPIO_MODE_IN:
dir_flags |= GPIOD_IS_IN;
switch (stm32_gpio_get_pupd(regs, idx)) {
case STM32_GPIO_PUPD_UP:
dir_flags |= GPIOD_PULL_UP;
break;
case STM32_GPIO_PUPD_DOWN:
dir_flags |= GPIOD_PULL_DOWN;
break;
default:
break;
}
break;
- default:
break;
- }
- *flags = dir_flags;
- return 0;
+}
static const struct dm_gpio_ops gpio_stm32_ops = { .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, @@ -209,6 +267,7 @@ static const struct dm_gpio_ops gpio_stm32_ops = { .set_value = stm32_gpio_set_value, .get_function = stm32_gpio_get_function, .set_dir_flags = stm32_gpio_set_dir_flags,
- .get_dir_flags = stm32_gpio_get_dir_flags,
};
static int gpio_stm32_probe(struct udevice *dev)
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Move the functions stmfx_pinctrl_set_pupd and stmfx_pinctrl_set_type; they can be used by the new ops get_dir_flags and set_dir_flags introduced by next patch.
No functional change.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: - NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
drivers/pinctrl/pinctrl-stmfx.c | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index a3240ccd5a..d74121725c 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -74,6 +74,36 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
+static int stmfx_pinctrl_set_pupd(struct udevice *dev, + unsigned int pin, u32 pupd) +{ + u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); + u32 mask = get_mask(pin); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + ret = (ret & ~mask) | (pupd ? mask : 0); + + return stmfx_write(dev, reg, ret); +} + +static int stmfx_pinctrl_set_type(struct udevice *dev, + unsigned int pin, u32 type) +{ + u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); + u32 mask = get_mask(pin); + int ret; + + ret = stmfx_read(dev, reg); + if (ret < 0) + return ret; + ret = (ret & ~mask) | (type ? mask : 0); + + return stmfx_write(dev, reg, ret); +} + static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) { u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); @@ -190,36 +220,6 @@ static const struct pinconf_param stmfx_pinctrl_conf_params[] = { { "output-low", PIN_CONFIG_OUTPUT, 0 }, };
-static int stmfx_pinctrl_set_pupd(struct udevice *dev, - unsigned int pin, u32 pupd) -{ - u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); - u32 mask = get_mask(pin); - int ret; - - ret = stmfx_read(dev, reg); - if (ret < 0) - return ret; - ret = (ret & ~mask) | (pupd ? mask : 0); - - return stmfx_write(dev, reg, ret); -} - -static int stmfx_pinctrl_set_type(struct udevice *dev, - unsigned int pin, u32 type) -{ - u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); - u32 mask = get_mask(pin); - int ret; - - ret = stmfx_read(dev, reg); - if (ret < 0) - return ret; - ret = (ret & ~mask) | (type ? mask : 0); - - return stmfx_write(dev, reg, ret); -} - static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, unsigned int param, unsigned int arg) {

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Move the functions stmfx_pinctrl_set_pupd and stmfx_pinctrl_set_type; they can be used by the new ops get_dir_flags and set_dir_flags introduced by next patch.
No functional change.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2:
- NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
drivers/pinctrl/pinctrl-stmfx.c | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index a3240ccd5a..d74121725c 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -74,6 +74,36 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
+static int stmfx_pinctrl_set_pupd(struct udevice *dev,
unsigned int pin, u32 pupd)
+{
- u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin);
- u32 mask = get_mask(pin);
- int ret;
- ret = stmfx_read(dev, reg);
- if (ret < 0)
return ret;
- ret = (ret & ~mask) | (pupd ? mask : 0);
- return stmfx_write(dev, reg, ret);
+}
+static int stmfx_pinctrl_set_type(struct udevice *dev,
unsigned int pin, u32 type)
+{
- u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin);
- u32 mask = get_mask(pin);
- int ret;
- ret = stmfx_read(dev, reg);
- if (ret < 0)
return ret;
- ret = (ret & ~mask) | (type ? mask : 0);
- return stmfx_write(dev, reg, ret);
+}
static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) { u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); @@ -190,36 +220,6 @@ static const struct pinconf_param stmfx_pinctrl_conf_params[] = { { "output-low", PIN_CONFIG_OUTPUT, 0 }, };
-static int stmfx_pinctrl_set_pupd(struct udevice *dev,
unsigned int pin, u32 pupd)
-{
- u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin);
- u32 mask = get_mask(pin);
- int ret;
- ret = stmfx_read(dev, reg);
- if (ret < 0)
return ret;
- ret = (ret & ~mask) | (pupd ? mask : 0);
- return stmfx_write(dev, reg, ret);
-}
-static int stmfx_pinctrl_set_type(struct udevice *dev,
unsigned int pin, u32 type)
-{
- u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin);
- u32 mask = get_mask(pin);
- int ret;
- ret = stmfx_read(dev, reg);
- if (ret < 0)
return ret;
- ret = (ret & ~mask) | (type ? mask : 0);
- return stmfx_write(dev, reg, ret);
-}
static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, unsigned int param, unsigned int arg) {
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Rename the two function used to change the pin configuration from stmfx_pinctrl_.. stmfx_conf_... to clarify the function usage.
No functional change.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: - NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
drivers/pinctrl/pinctrl-stmfx.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index d74121725c..657ca2e240 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -74,8 +74,7 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
-static int stmfx_pinctrl_set_pupd(struct udevice *dev, - unsigned int pin, u32 pupd) +static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int pin, u32 pupd) { u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); u32 mask = get_mask(pin); @@ -89,8 +88,7 @@ static int stmfx_pinctrl_set_pupd(struct udevice *dev, return stmfx_write(dev, reg, ret); }
-static int stmfx_pinctrl_set_type(struct udevice *dev, - unsigned int pin, u32 type) +static int stmfx_conf_set_type(struct udevice *dev, unsigned int pin, u32 type) { u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); u32 mask = get_mask(pin); @@ -235,22 +233,22 @@ static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_DRIVE_PUSH_PULL: - ret = stmfx_pinctrl_set_type(dev, pin, 0); + ret = stmfx_conf_set_type(dev, pin, 0); break; case PIN_CONFIG_BIAS_PULL_DOWN: - ret = stmfx_pinctrl_set_type(dev, pin, 1); + ret = stmfx_conf_set_type(dev, pin, 1); if (ret) return ret; - ret = stmfx_pinctrl_set_pupd(dev, pin, 0); + ret = stmfx_conf_set_pupd(dev, pin, 0); break; case PIN_CONFIG_BIAS_PULL_UP: - ret = stmfx_pinctrl_set_type(dev, pin, 1); + ret = stmfx_conf_set_type(dev, pin, 1); if (ret) return ret; - ret = stmfx_pinctrl_set_pupd(dev, pin, 1); + ret = stmfx_conf_set_pupd(dev, pin, 1); break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: - ret = stmfx_pinctrl_set_type(dev, pin, 1); + ret = stmfx_conf_set_type(dev, pin, 1); break; case PIN_CONFIG_OUTPUT: ret = stmfx_gpio_direction_output(plat->gpio, pin, arg);

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Rename the two function used to change the pin configuration from stmfx_pinctrl_.. stmfx_conf_... to clarify the function usage.
No functional change.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2:
- NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
drivers/pinctrl/pinctrl-stmfx.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index d74121725c..657ca2e240 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -74,8 +74,7 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
-static int stmfx_pinctrl_set_pupd(struct udevice *dev,
unsigned int pin, u32 pupd)
+static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int pin, u32 pupd) { u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); u32 mask = get_mask(pin); @@ -89,8 +88,7 @@ static int stmfx_pinctrl_set_pupd(struct udevice *dev, return stmfx_write(dev, reg, ret); }
-static int stmfx_pinctrl_set_type(struct udevice *dev,
unsigned int pin, u32 type)
+static int stmfx_conf_set_type(struct udevice *dev, unsigned int pin, u32 type) { u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); u32 mask = get_mask(pin); @@ -235,22 +233,22 @@ static int stmfx_pinctrl_conf_set(struct udevice *dev, unsigned int pin, case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_DRIVE_PUSH_PULL:
ret = stmfx_pinctrl_set_type(dev, pin, 0);
break; case PIN_CONFIG_BIAS_PULL_DOWN:ret = stmfx_conf_set_type(dev, pin, 0);
ret = stmfx_pinctrl_set_type(dev, pin, 1);
if (ret) return ret;ret = stmfx_conf_set_type(dev, pin, 1);
ret = stmfx_pinctrl_set_pupd(dev, pin, 0);
break; case PIN_CONFIG_BIAS_PULL_UP:ret = stmfx_conf_set_pupd(dev, pin, 0);
ret = stmfx_pinctrl_set_type(dev, pin, 1);
if (ret) return ret;ret = stmfx_conf_set_type(dev, pin, 1);
ret = stmfx_pinctrl_set_pupd(dev, pin, 1);
break; case PIN_CONFIG_DRIVE_OPEN_DRAIN:ret = stmfx_conf_set_pupd(dev, pin, 1);
ret = stmfx_pinctrl_set_type(dev, pin, 1);
break; case PIN_CONFIG_OUTPUT: ret = stmfx_gpio_direction_output(plat->gpio, pin, arg);ret = stmfx_conf_set_type(dev, pin, 1);
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Add the helper functions stmfx_read_reg() and stmfx_write_reg() to avoid duplicated code for access to stmfx's register with mask.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: - NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
drivers/pinctrl/pinctrl-stmfx.c | 68 +++++++++++++-------------------- 1 file changed, 26 insertions(+), 42 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 657ca2e240..5d15424b84 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -74,43 +74,49 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
-static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int pin, u32 pupd) +static int stmfx_read_reg(struct udevice *dev, u8 reg_base, uint offset) { - u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin); - u32 mask = get_mask(pin); + u8 reg = reg_base + get_reg(offset); + u32 mask = get_mask(offset); int ret;
ret = stmfx_read(dev, reg); if (ret < 0) return ret; - ret = (ret & ~mask) | (pupd ? mask : 0);
- return stmfx_write(dev, reg, ret); + return ret < 0 ? ret : !!(ret & mask); }
-static int stmfx_conf_set_type(struct udevice *dev, unsigned int pin, u32 type) +static int stmfx_write_reg(struct udevice *dev, u8 reg_base, uint offset, + uint val) { - u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin); - u32 mask = get_mask(pin); + u8 reg = reg_base + get_reg(offset); + u32 mask = get_mask(offset); int ret;
ret = stmfx_read(dev, reg); if (ret < 0) return ret; - ret = (ret & ~mask) | (type ? mask : 0); + ret = (ret & ~mask) | (val ? mask : 0);
return stmfx_write(dev, reg, ret); }
-static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) +static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int offset, + uint pupd) { - u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset); - u32 mask = get_mask(offset); - int ret; + return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd); +}
- ret = stmfx_read(dev, reg); +static int stmfx_conf_set_type(struct udevice *dev, unsigned int offset, + uint type) +{ + return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type); +}
- return ret < 0 ? ret : !!(ret & mask); +static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) +{ + return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset); }
static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value) @@ -123,50 +129,28 @@ static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset) { - u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); - u32 mask = get_mask(offset); - int ret; - - ret = stmfx_read(dev, reg); + int ret = stmfx_read_reg(dev, STMFX_REG_GPIO_DIR, offset);
if (ret < 0) return ret; /* On stmfx, gpio pins direction is (0)input, (1)output. */
- return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT; + return ret ? GPIOF_OUTPUT : GPIOF_INPUT; }
static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset) { - u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); - u32 mask = get_mask(offset); - int ret; - - ret = stmfx_read(dev, reg); - if (ret < 0) - return ret; - - ret &= ~mask; - - return stmfx_write(dev, reg, ret & ~mask); + return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 0); }
static int stmfx_gpio_direction_output(struct udevice *dev, unsigned int offset, int value) { - u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset); - u32 mask = get_mask(offset); - int ret; - - ret = stmfx_gpio_set(dev, offset, value); - if (ret < 0) - return ret; - - ret = stmfx_read(dev, reg); + int ret = stmfx_gpio_set(dev, offset, value); if (ret < 0) return ret;
- return stmfx_write(dev, reg, ret | mask); + return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1); }
static int stmfx_gpio_probe(struct udevice *dev)

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Add the helper functions stmfx_read_reg() and stmfx_write_reg() to avoid duplicated code for access to stmfx's register with mask.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2:
- NEW: split previous patch [5/5] gpio: stmfx: add set_config ops
drivers/pinctrl/pinctrl-stmfx.c | 68 +++++++++++++-------------------- 1 file changed, 26 insertions(+), 42 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 657ca2e240..5d15424b84 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -74,43 +74,49 @@ static int stmfx_write(struct udevice *dev, uint offset, unsigned int val) return dm_i2c_reg_write(dev_get_parent(dev), offset, val); }
-static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int pin, u32 pupd) +static int stmfx_read_reg(struct udevice *dev, u8 reg_base, uint offset) {
- u8 reg = STMFX_REG_GPIO_PUPD + get_reg(pin);
- u32 mask = get_mask(pin);
u8 reg = reg_base + get_reg(offset);
u32 mask = get_mask(offset); int ret;
ret = stmfx_read(dev, reg); if (ret < 0) return ret;
ret = (ret & ~mask) | (pupd ? mask : 0);
return stmfx_write(dev, reg, ret);
- return ret < 0 ? ret : !!(ret & mask);
}
-static int stmfx_conf_set_type(struct udevice *dev, unsigned int pin, u32 type) +static int stmfx_write_reg(struct udevice *dev, u8 reg_base, uint offset,
uint val)
{
- u8 reg = STMFX_REG_GPIO_TYPE + get_reg(pin);
- u32 mask = get_mask(pin);
u8 reg = reg_base + get_reg(offset);
u32 mask = get_mask(offset); int ret;
ret = stmfx_read(dev, reg); if (ret < 0) return ret;
- ret = (ret & ~mask) | (type ? mask : 0);
ret = (ret & ~mask) | (val ? mask : 0);
return stmfx_write(dev, reg, ret);
}
-static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) +static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int offset,
uint pupd)
{
- u32 reg = STMFX_REG_GPIO_STATE + get_reg(offset);
- u32 mask = get_mask(offset);
- int ret;
- return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd);
+}
- ret = stmfx_read(dev, reg);
+static int stmfx_conf_set_type(struct udevice *dev, unsigned int offset,
uint type)
+{
- return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type);
+}
- return ret < 0 ? ret : !!(ret & mask);
+static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) +{
- return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset);
}
static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value) @@ -123,50 +129,28 @@ static int stmfx_gpio_set(struct udevice *dev, unsigned int offset, int value)
static int stmfx_gpio_get_function(struct udevice *dev, unsigned int offset) {
- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
- u32 mask = get_mask(offset);
- int ret;
- ret = stmfx_read(dev, reg);
int ret = stmfx_read_reg(dev, STMFX_REG_GPIO_DIR, offset);
if (ret < 0) return ret; /* On stmfx, gpio pins direction is (0)input, (1)output. */
- return ret & mask ? GPIOF_OUTPUT : GPIOF_INPUT;
- return ret ? GPIOF_OUTPUT : GPIOF_INPUT;
}
static int stmfx_gpio_direction_input(struct udevice *dev, unsigned int offset) {
- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
- u32 mask = get_mask(offset);
- int ret;
- ret = stmfx_read(dev, reg);
- if (ret < 0)
return ret;
- ret &= ~mask;
- return stmfx_write(dev, reg, ret & ~mask);
- return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 0);
}
static int stmfx_gpio_direction_output(struct udevice *dev, unsigned int offset, int value) {
- u32 reg = STMFX_REG_GPIO_DIR + get_reg(offset);
- u32 mask = get_mask(offset);
- int ret;
- ret = stmfx_gpio_set(dev, offset, value);
- if (ret < 0)
return ret;
- ret = stmfx_read(dev, reg);
- int ret = stmfx_gpio_set(dev, offset, value); if (ret < 0) return ret;
- return stmfx_write(dev, reg, ret | mask);
- return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1);
}
static int stmfx_gpio_probe(struct udevice *dev)
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Manage the flags for GPIO configuration: - open_drain, push_pull - pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/pinctrl/pinctrl-stmfx.c | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 5d15424b84..88df9e61a7 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -153,6 +153,42 @@ static int stmfx_gpio_direction_output(struct udevice *dev, return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1); }
+static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, + ulong flags) +{ + int ret = -ENOTSUPP; + + if (flags & GPIOD_IS_OUT) { + if (flags & GPIOD_OPEN_SOURCE) + return -ENOTSUPP; + if (flags & GPIOD_OPEN_DRAIN) + ret = stmfx_conf_set_type(dev, offset, 0); + else /* PUSH-PULL */ + ret = stmfx_conf_set_type(dev, offset, 1); + if (ret) + return ret; + ret = stmfx_gpio_direction_output(dev, offset, + GPIOD_FLAGS_OUTPUT(flags)); + } else if (flags & GPIOD_IS_IN) { + ret = stmfx_gpio_direction_input(dev, offset); + if (ret) + return ret; + if (flags & GPIOD_PULL_UP) { + ret = stmfx_conf_set_type(dev, offset, 1); + if (ret) + return ret; + ret = stmfx_conf_set_pupd(dev, offset, 1); + } else if (flags & GPIOD_PULL_DOWN) { + ret = stmfx_conf_set_type(dev, offset, 1); + if (ret) + return ret; + ret = stmfx_conf_set_pupd(dev, offset, 0); + } + } + + return ret; +} + static int stmfx_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); @@ -181,6 +217,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = { .get_function = stmfx_gpio_get_function, .direction_input = stmfx_gpio_direction_input, .direction_output = stmfx_gpio_direction_output, + .set_dir_flags = stmfx_gpio_set_dir_flags, };
U_BOOT_DRIVER(stmfx_gpio) = {

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Manage the flags for GPIO configuration:
- open_drain, push_pull
- pull_up, pull_down
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
drivers/pinctrl/pinctrl-stmfx.c | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 5d15424b84..88df9e61a7 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -153,6 +153,42 @@ static int stmfx_gpio_direction_output(struct udevice *dev, return stmfx_write_reg(dev, STMFX_REG_GPIO_DIR, offset, 1); }
+static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset,
ulong flags)
+{
- int ret = -ENOTSUPP;
- if (flags & GPIOD_IS_OUT) {
if (flags & GPIOD_OPEN_SOURCE)
return -ENOTSUPP;
if (flags & GPIOD_OPEN_DRAIN)
ret = stmfx_conf_set_type(dev, offset, 0);
else /* PUSH-PULL */
ret = stmfx_conf_set_type(dev, offset, 1);
if (ret)
return ret;
ret = stmfx_gpio_direction_output(dev, offset,
GPIOD_FLAGS_OUTPUT(flags));
- } else if (flags & GPIOD_IS_IN) {
ret = stmfx_gpio_direction_input(dev, offset);
if (ret)
return ret;
if (flags & GPIOD_PULL_UP) {
ret = stmfx_conf_set_type(dev, offset, 1);
if (ret)
return ret;
ret = stmfx_conf_set_pupd(dev, offset, 1);
} else if (flags & GPIOD_PULL_DOWN) {
ret = stmfx_conf_set_type(dev, offset, 1);
if (ret)
return ret;
ret = stmfx_conf_set_pupd(dev, offset, 0);
}
- }
- return ret;
+}
static int stmfx_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); @@ -181,6 +217,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = { .get_function = stmfx_gpio_get_function, .direction_input = stmfx_gpio_direction_input, .direction_output = stmfx_gpio_direction_output,
- .set_dir_flags = stmfx_gpio_set_dir_flags,
};
U_BOOT_DRIVER(stmfx_gpio) = {
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Add support of ops get_dir_flags() to read dir flags from STMFX registers.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/pinctrl/pinctrl-stmfx.c | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 88df9e61a7..1d326ecf17 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -108,12 +108,22 @@ static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int offset, return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd); }
+static int stmfx_conf_get_pupd(struct udevice *dev, unsigned int offset) +{ + return stmfx_read_reg(dev, STMFX_REG_GPIO_PUPD, offset); +} + static int stmfx_conf_set_type(struct udevice *dev, unsigned int offset, uint type) { return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type); }
+static int stmfx_conf_get_type(struct udevice *dev, unsigned int offset) +{ + return stmfx_read_reg(dev, STMFX_REG_GPIO_TYPE, offset); +} + static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) { return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset); @@ -189,6 +199,45 @@ static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, return ret; }
+static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset, + ulong *flags) +{ + ulong dir_flags = 0; + int ret; + + if (stmfx_gpio_get_function(dev, offset) == GPIOF_OUTPUT) { + dir_flags |= GPIOD_IS_OUT; + ret = stmfx_conf_get_type(dev, offset); + if (ret < 0) + return ret; + if (ret == 0) + dir_flags |= GPIOD_OPEN_DRAIN; + /* 1 = push-pull (default), open source not supported */ + ret = stmfx_gpio_get(dev, offset); + if (ret < 0) + return ret; + if (ret) + dir_flags |= GPIOD_IS_OUT_ACTIVE; + } else { + dir_flags |= GPIOD_IS_IN; + ret = stmfx_conf_get_type(dev, offset); + if (ret < 0) + return ret; + if (ret == 1) { + ret = stmfx_conf_get_pupd(dev, offset); + if (ret < 0) + return ret; + if (ret == 1) + dir_flags |= GPIOD_PULL_UP; + else + dir_flags |= GPIOD_PULL_DOWN; + } + } + *flags = dir_flags; + + return 0; +} + static int stmfx_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); @@ -218,6 +267,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = { .direction_input = stmfx_gpio_direction_input, .direction_output = stmfx_gpio_direction_output, .set_dir_flags = stmfx_gpio_set_dir_flags, + .get_dir_flags = stmfx_gpio_get_dir_flags, };
U_BOOT_DRIVER(stmfx_gpio) = {

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Add support of ops get_dir_flags() to read dir flags from STMFX registers.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
drivers/pinctrl/pinctrl-stmfx.c | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 88df9e61a7..1d326ecf17 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -108,12 +108,22 @@ static int stmfx_conf_set_pupd(struct udevice *dev, unsigned int offset, return stmfx_write_reg(dev, STMFX_REG_GPIO_PUPD, offset, pupd); }
+static int stmfx_conf_get_pupd(struct udevice *dev, unsigned int offset) +{
- return stmfx_read_reg(dev, STMFX_REG_GPIO_PUPD, offset);
+}
static int stmfx_conf_set_type(struct udevice *dev, unsigned int offset, uint type) { return stmfx_write_reg(dev, STMFX_REG_GPIO_TYPE, offset, type); }
+static int stmfx_conf_get_type(struct udevice *dev, unsigned int offset) +{
- return stmfx_read_reg(dev, STMFX_REG_GPIO_TYPE, offset);
+}
static int stmfx_gpio_get(struct udevice *dev, unsigned int offset) { return stmfx_read_reg(dev, STMFX_REG_GPIO_STATE, offset); @@ -189,6 +199,45 @@ static int stmfx_gpio_set_dir_flags(struct udevice *dev, unsigned int offset, return ret; }
+static int stmfx_gpio_get_dir_flags(struct udevice *dev, unsigned int offset,
ulong *flags)
+{
- ulong dir_flags = 0;
- int ret;
- if (stmfx_gpio_get_function(dev, offset) == GPIOF_OUTPUT) {
dir_flags |= GPIOD_IS_OUT;
ret = stmfx_conf_get_type(dev, offset);
if (ret < 0)
return ret;
if (ret == 0)
dir_flags |= GPIOD_OPEN_DRAIN;
/* 1 = push-pull (default), open source not supported */
ret = stmfx_gpio_get(dev, offset);
if (ret < 0)
return ret;
if (ret)
dir_flags |= GPIOD_IS_OUT_ACTIVE;
- } else {
dir_flags |= GPIOD_IS_IN;
ret = stmfx_conf_get_type(dev, offset);
if (ret < 0)
return ret;
if (ret == 1) {
ret = stmfx_conf_get_pupd(dev, offset);
if (ret < 0)
return ret;
if (ret == 1)
dir_flags |= GPIOD_PULL_UP;
else
dir_flags |= GPIOD_PULL_DOWN;
}
- }
- *flags = dir_flags;
- return 0;
+}
static int stmfx_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); @@ -218,6 +267,7 @@ static const struct dm_gpio_ops stmfx_gpio_ops = { .direction_input = stmfx_gpio_direction_input, .direction_output = stmfx_gpio_direction_output, .set_dir_flags = stmfx_gpio_set_dir_flags,
- .get_dir_flags = stmfx_gpio_get_dir_flags,
};
U_BOOT_DRIVER(stmfx_gpio) = {
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Add information on pin configuration used for pinmux command.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/pinctrl/pinctrl-stmfx.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 1d326ecf17..c2ea82770e 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -358,6 +358,34 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, return pin_name; }
+static const char *stmfx_pinctrl_get_pin_conf(struct udevice *dev, + unsigned int pin, int func) +{ + int pupd, type; + + type = stmfx_conf_get_type(dev, pin); + if (type < 0) + return ""; + + if (func == GPIOF_OUTPUT) { + if (type) + return "drive-open-drain"; + else + return ""; /* default: push-pull*/ + } + if (!type) + return ""; /* default: bias-disable*/ + + pupd = stmfx_conf_get_pupd(dev, pin); + if (pupd < 0) + return ""; + + if (pupd) + return "bias-pull-up"; + else + return "bias-pull-down"; +} + static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector, char *buf, int size) @@ -369,7 +397,9 @@ static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, if (func < 0) return func;
- snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output"); + snprintf(buf, size, "%s ", func == GPIOF_INPUT ? "input" : "output"); + + strncat(buf, stmfx_pinctrl_get_pin_conf(dev, selector, func), size);
return 0; }

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Add information on pin configuration used for pinmux command.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
drivers/pinctrl/pinctrl-stmfx.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-stmfx.c b/drivers/pinctrl/pinctrl-stmfx.c index 1d326ecf17..c2ea82770e 100644 --- a/drivers/pinctrl/pinctrl-stmfx.c +++ b/drivers/pinctrl/pinctrl-stmfx.c @@ -358,6 +358,34 @@ static const char *stmfx_pinctrl_get_pin_name(struct udevice *dev, return pin_name; }
+static const char *stmfx_pinctrl_get_pin_conf(struct udevice *dev,
unsigned int pin, int func)
+{
- int pupd, type;
- type = stmfx_conf_get_type(dev, pin);
- if (type < 0)
return "";
- if (func == GPIOF_OUTPUT) {
if (type)
return "drive-open-drain";
else
return ""; /* default: push-pull*/
- }
- if (!type)
return ""; /* default: bias-disable*/
- pupd = stmfx_conf_get_pupd(dev, pin);
- if (pupd < 0)
return "";
- if (pupd)
return "bias-pull-up";
- else
return "bias-pull-down";
+}
static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector, char *buf, int size) @@ -369,7 +397,9 @@ static int stmfx_pinctrl_get_pin_muxing(struct udevice *dev, if (func < 0) return func;
- snprintf(buf, size, "%s", func == GPIOF_INPUT ? "input" : "output");
snprintf(buf, size, "%s ", func == GPIOF_INPUT ? "input" : "output");
strncat(buf, stmfx_pinctrl_get_pin_conf(dev, selector, func), size);
return 0;
}
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks

Add information on pin configuration used for pinmux command: - bias configuration for output (disable, pull up, pull down) - otype for input (open drain or push pull)
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
Changes in v2: None
drivers/pinctrl/pinctrl_stm32.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index fc241fdcde..71fa29a389 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -45,6 +45,17 @@ static const char * const pinmux_mode[PINMUX_MODE_COUNT] = { "alt function", };
+static const char * const pinmux_output[] = { + [STM32_GPIO_PUPD_NO] = "bias-disable", + [STM32_GPIO_PUPD_UP] = "bias-pull-up", + [STM32_GPIO_PUPD_DOWN] = "bias-pull-down", +}; + +static const char * const pinmux_input[] = { + [STM32_GPIO_OTYPE_PP] = "drive-push-pull", + [STM32_GPIO_OTYPE_OD] = "drive-open-drain", +}; + static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) { struct stm32_gpio_priv *priv = dev_get_priv(dev); @@ -182,10 +193,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, int size) { struct udevice *gpio_dev; + struct stm32_gpio_priv *priv; const char *label; int mode; int af_num; unsigned int gpio_idx; + u32 pupd, otype;
/* look up for the bank which owns the requested pin */ gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx); @@ -194,9 +207,9 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, return -ENODEV;
mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label); - dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", selector, gpio_idx, mode); + priv = dev_get_priv(gpio_dev);
switch (mode) { @@ -211,9 +224,17 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); break; case GPIOF_OUTPUT: + pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) & + PUPD_MASK; + snprintf(buf, size, "%s %s %s", + pinmux_mode[mode], pinmux_output[pupd], + label ? label : ""); + break; case GPIOF_INPUT: - snprintf(buf, size, "%s %s", - pinmux_mode[mode], label ? label : ""); + otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK; + snprintf(buf, size, "%s %s %s", + pinmux_mode[mode], pinmux_input[otype], + label ? label : ""); break; }

Hi Patrick
On 6/4/20 2:30 PM, Patrick Delaunay wrote:
Add information on pin configuration used for pinmux command:
- bias configuration for output (disable, pull up, pull down)
- otype for input (open drain or push pull)
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Changes in v2: None
drivers/pinctrl/pinctrl_stm32.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index fc241fdcde..71fa29a389 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -45,6 +45,17 @@ static const char * const pinmux_mode[PINMUX_MODE_COUNT] = { "alt function", };
+static const char * const pinmux_output[] = {
- [STM32_GPIO_PUPD_NO] = "bias-disable",
- [STM32_GPIO_PUPD_UP] = "bias-pull-up",
- [STM32_GPIO_PUPD_DOWN] = "bias-pull-down",
+};
+static const char * const pinmux_input[] = {
- [STM32_GPIO_OTYPE_PP] = "drive-push-pull",
- [STM32_GPIO_OTYPE_OD] = "drive-open-drain",
+};
static int stm32_pinctrl_get_af(struct udevice *dev, unsigned int offset) { struct stm32_gpio_priv *priv = dev_get_priv(dev); @@ -182,10 +193,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, int size) { struct udevice *gpio_dev;
struct stm32_gpio_priv *priv; const char *label; int mode; int af_num; unsigned int gpio_idx;
u32 pupd, otype;
/* look up for the bank which owns the requested pin */ gpio_dev = stm32_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
@@ -194,9 +207,9 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, return -ENODEV;
mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label);
- dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", selector, gpio_idx, mode);
priv = dev_get_priv(gpio_dev);
switch (mode) {
@@ -211,9 +224,17 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, snprintf(buf, size, "%s %d", pinmux_mode[mode], af_num); break; case GPIOF_OUTPUT:
pupd = (readl(&priv->regs->pupdr) >> (gpio_idx * 2)) &
PUPD_MASK;
snprintf(buf, size, "%s %s %s",
pinmux_mode[mode], pinmux_output[pupd],
label ? label : "");
case GPIOF_INPUT:break;
snprintf(buf, size, "%s %s",
pinmux_mode[mode], label ? label : "");
otype = (readl(&priv->regs->otyper) >> gpio_idx) & OTYPE_MSK;
snprintf(buf, size, "%s %s %s",
pinmux_mode[mode], pinmux_input[otype],
break; }label ? label : "");
Reviewed-by: Patrice Chotard patrice.chotard@st.com
Thanks
participants (2)
-
Patrice CHOTARD
-
Patrick Delaunay