Hi Geert, Thanks for your work. On 2021-03-03 14:26:18 +0100, Geert Uytterhoeven wrote: > Currently, the common R-Car bias handling supports pin controllers with > either: > 1. Separate pin Pull-Enable (PUEN) and pin Pull-Up/Down control (PUD) > registers, for controlling both pin pull-up and pin pull-down, > 2. A single pin Pull-Up control register (PUPR), for controlling pin > pull-up. > > Add support for a variant of #2, where some bits in the single pin s/bits/bit/ ? > Pull-Up control register (PUPR) control pin pull-down instead of pin > pull-up. This is the case for the "ASEBRK#/ACK" pin on R-Car M2-W, > M2-N, and E2, and the "ACK" pin on RZ/G1M, RZ/G1N, RZ/G1E, and RZ/G1C. > To describe such a register, SoC-specific drivers need to provide two > instances of pinmux_bias_reg: a first one with the puen field filled in, > listing pins with pull-up functionality, and a second one with the pud > field filled in, listing pins with pull-down functionality. > > Signed-off-by: Geert Uytterhoeven <geert+renesas@xxxxxxxxx> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@xxxxxxxxxxxx> > --- > drivers/pinctrl/renesas/pinctrl.c | 49 ++++++++++++++++++++----------- > drivers/pinctrl/renesas/sh_pfc.h | 4 +-- > 2 files changed, 34 insertions(+), 19 deletions(-) > > diff --git a/drivers/pinctrl/renesas/pinctrl.c b/drivers/pinctrl/renesas/pinctrl.c > index b7ebbc877b544305..bb488af298623407 100644 > --- a/drivers/pinctrl/renesas/pinctrl.c > +++ b/drivers/pinctrl/renesas/pinctrl.c > @@ -847,7 +847,7 @@ rcar_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin, > { > unsigned int i, j; > > - for (i = 0; pfc->info->bias_regs[i].puen; i++) { > + for (i = 0; pfc->info->bias_regs[i].puen || pfc->info->bias_regs[i].pud; i++) { > for (j = 0; j < ARRAY_SIZE(pfc->info->bias_regs[i].pins); j++) { > if (pfc->info->bias_regs[i].pins[j] == pin) { > *bit = j; > @@ -870,12 +870,19 @@ unsigned int rcar_pinmux_get_bias(struct sh_pfc *pfc, unsigned int pin) > if (!reg) > return PIN_CONFIG_BIAS_DISABLE; > > - if (!(sh_pfc_read(pfc, reg->puen) & BIT(bit))) > - return PIN_CONFIG_BIAS_DISABLE; > - else if (!reg->pud || (sh_pfc_read(pfc, reg->pud) & BIT(bit))) > - return PIN_CONFIG_BIAS_PULL_UP; > - else > - return PIN_CONFIG_BIAS_PULL_DOWN; > + if (reg->puen) { > + if (!(sh_pfc_read(pfc, reg->puen) & BIT(bit))) > + return PIN_CONFIG_BIAS_DISABLE; > + else if (!reg->pud || (sh_pfc_read(pfc, reg->pud) & BIT(bit))) > + return PIN_CONFIG_BIAS_PULL_UP; > + else > + return PIN_CONFIG_BIAS_PULL_DOWN; > + } else { > + if (sh_pfc_read(pfc, reg->pud) & BIT(bit)) > + return PIN_CONFIG_BIAS_PULL_DOWN; > + else > + return PIN_CONFIG_BIAS_DISABLE; > + } > } > > void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > @@ -889,19 +896,27 @@ void rcar_pinmux_set_bias(struct sh_pfc *pfc, unsigned int pin, > if (!reg) > return; > > - enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit); > - if (bias != PIN_CONFIG_BIAS_DISABLE) > - enable |= BIT(bit); > + if (reg->puen) { > + enable = sh_pfc_read(pfc, reg->puen) & ~BIT(bit); > + if (bias != PIN_CONFIG_BIAS_DISABLE) > + enable |= BIT(bit); > > - if (reg->pud) { > - updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); > - if (bias == PIN_CONFIG_BIAS_PULL_UP) > - updown |= BIT(bit); > + if (reg->pud) { > + updown = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); > + if (bias == PIN_CONFIG_BIAS_PULL_UP) > + updown |= BIT(bit); > > - sh_pfc_write(pfc, reg->pud, updown); > - } > + sh_pfc_write(pfc, reg->pud, updown); > + } > > - sh_pfc_write(pfc, reg->puen, enable); > + sh_pfc_write(pfc, reg->puen, enable); > + } else { > + enable = sh_pfc_read(pfc, reg->pud) & ~BIT(bit); > + if (bias == PIN_CONFIG_BIAS_PULL_DOWN) > + enable |= BIT(bit); > + > + sh_pfc_write(pfc, reg->pud, enable); > + } > } > > #define PORTnCR_PULMD_OFF (0 << 6) > diff --git a/drivers/pinctrl/renesas/sh_pfc.h b/drivers/pinctrl/renesas/sh_pfc.h > index fc8391712af8cf4b..320898861c4b4c56 100644 > --- a/drivers/pinctrl/renesas/sh_pfc.h > +++ b/drivers/pinctrl/renesas/sh_pfc.h > @@ -188,9 +188,9 @@ struct pinmux_drive_reg { > .reg = r, \ > .fields = > > -struct pinmux_bias_reg { > +struct pinmux_bias_reg { /* At least one of puen/pud must exist */ > u32 puen; /* Pull-enable or pull-up control register */ > - u32 pud; /* Pull-up/down control register (optional) */ > + u32 pud; /* Pull-up/down or pull-down control register */ > const u16 pins[32]; > }; > > -- > 2.25.1 > -- Regards, Niklas Söderlund