Re: [PATCH] pinctrl: sunxi: A523: fix voltage withstand encoding
From: Chen-Yu Tsai
Date: Wed Jul 22 2026 - 13:33:48 EST
On Wed, Jul 22, 2026 at 6:43 AM Andre Przywara <andre.przywara@xxxxxxx> wrote:
>
> The Allwinner A523 uses the same GPIO voltage "withstand" programming
> (setting the input level voltage thresholds) as the previous SoCs, but
> for some odd reason inverts the encoding of 1.8V vs. 3.3V.
>
> Add a new bias voltage type to note this difference, and select it for
> the A523. At the same time also use the newer "CTL" version, which in
> addition allows to turn off the withstand programming for I/O voltages
> other than exact 1.8V or 3.3V (for instance for 2.5V sometimes used for
> Ethernet PHYs). The A523 has that enable register, but didn't use it
> so far.
>
> This fixes eMMC and reportedly Ethernet operation on some A523 boards.
>
> Fixes: 648be4cd9517 ("pinctrl: sunxi: Add support for the Allwinner A523")
> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
Reviewed-by: Chen-Yu Tsai <wens@xxxxxxxxxx>
Tested-by: Chen-Yu Tsai <wens@xxxxxxxxxx> # Fixes eMMC on Orange Pi 4A
> ---
> drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c | 2 +-
> drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c | 2 +-
> drivers/pinctrl/sunxi/pinctrl-sunxi.c | 6 ++++++
> drivers/pinctrl/sunxi/pinctrl-sunxi.h | 2 ++
> 4 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c b/drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c
> index dfdcfa740ecc9..cffc1e53eef14 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun55i-a523-r.c
> @@ -26,7 +26,7 @@ static const u8 a523_r_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =
> static struct sunxi_pinctrl_desc a523_r_pinctrl_data = {
> .irq_banks = ARRAY_SIZE(a523_r_irq_bank_map),
> .irq_bank_map = a523_r_irq_bank_map,
> - .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
> + .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV,
> .pin_base = PL_BASE,
> };
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c b/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c
> index 801f62abc93df..001bd42afa3ef 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c
> @@ -26,7 +26,7 @@ static const u8 a523_irq_bank_muxes[SUNXI_PINCTRL_MAX_BANKS] =
> static struct sunxi_pinctrl_desc a523_pinctrl_data = {
> .irq_banks = ARRAY_SIZE(a523_irq_bank_map),
> .irq_bank_map = a523_irq_bank_map,
> - .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
> + .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV,
> };
>
> static int a523_pinctrl_probe(struct platform_device *pdev)
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> index cabcb8b6f38e5..634d9f1f23947 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
> @@ -718,6 +718,7 @@ static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl,
> {
> unsigned short bank;
> unsigned long flags;
> + bool inverted = false;
> u32 val, reg;
> int uV;
>
> @@ -757,6 +758,9 @@ static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl,
> writel(reg | val, pctl->membase +
> sunxi_grp_config_reg(pctl, pin));
> return 0;
> + case BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV:
> + inverted = true;
> + fallthrough;
> case BIAS_VOLTAGE_PIO_POW_MODE_CTL:
> val = uV > 1800000 && uV <= 2500000 ? BIT(bank) : 0;
>
> @@ -771,6 +775,8 @@ static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl,
> fallthrough;
> case BIAS_VOLTAGE_PIO_POW_MODE_SEL:
> val = uV <= 1800000 ? 1 : 0;
> + if (inverted)
> + val = !val;
>
> raw_spin_lock_irqsave(&pctl->lock, flags);
> reg = readl(pctl->membase + pctl->pow_mod_sel_offset);
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> index d0936a32123ba..2c8648c3301b6 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
> @@ -128,8 +128,10 @@ enum sunxi_desc_bias_voltage {
> * Bias voltage is set through PIO_POW_MOD_SEL_REG
> * and PIO_POW_MOD_CTL_REG register, as seen on
> * A100 and D1 SoC, for example.
> + * Some SoCs invert the encoding for 1.8V vs. 3.3V.
> */
> BIAS_VOLTAGE_PIO_POW_MODE_CTL,
> + BIAS_VOLTAGE_PIO_POW_MODE_CTL_INV,
> };
>
> struct sunxi_desc_function {
> --
> 2.46.4
>