[PATCH] pinctrl: sunxi: A523: fix voltage withstand encoding

Chen-Yu Tsai wens at kernel.org
Wed Jul 22 10:26:38 PDT 2026


On Wed, Jul 22, 2026 at 6:43 AM Andre Przywara <andre.przywara at arm.com> 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 at arm.com>


Reviewed-by: Chen-Yu Tsai <wens at kernel.org>
Tested-by: Chen-Yu Tsai <wens at kernel.org> # 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
>



More information about the linux-arm-kernel mailing list