Message ID | 20210303132619.3938128-6-geert+renesas@glider.be |
---|---|
State | Accepted |
Commit | 1d3928a3e69cd6ec0ea837d3eeccb2ff604b5072 |
Headers | show |
Series | pinctrl: renesas: Bias improvements and r8a7791 support | expand |
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@glider.be> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> > --- > 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
Hi Niklas, On Mon, Mar 22, 2021 at 4:07 PM Niklas Söderlund <niklas.soderlund@ragnatech.se> wrote: > 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/ ? I think there can be multiple, in the generic case. > > 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@glider.be> > > Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
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]; };
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 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@glider.be> --- drivers/pinctrl/renesas/pinctrl.c | 49 ++++++++++++++++++++----------- drivers/pinctrl/renesas/sh_pfc.h | 4 +-- 2 files changed, 34 insertions(+), 19 deletions(-)