diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index b27296382816..923bcc49af99 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -107,8 +107,10 @@ #define IEN(off) (0x1800 + (off) * 8) #define ISEL(off) (0x2C00 + (off) * 8) #define SD_CH(off, ch) ((off) + (ch) * 4) +#define ETH_POC(off, ch) ((off) + (ch) * 4) #define QSPI (0x3008) +#define PVDD_2500 2 /* I/O domain voltage 2.5V */ #define PVDD_1800 1 /* I/O domain voltage <= 1.8V */ #define PVDD_3300 0 /* I/O domain voltage >= 3.3V */ @@ -116,7 +118,6 @@ #define PWPR_PFCWE BIT(6) /* PFC Register Write Enable */ #define PM_MASK 0x03 -#define PVDD_MASK 0x01 #define PFC_MASK 0x07 #define IEN_MASK 0x01 #define IOLH_MASK 0x03 @@ -135,10 +136,12 @@ * struct rzg2l_register_offsets - specific register offsets * @pwpr: PWPR register offset * @sd_ch: SD_CH register offset + * @eth_poc: ETH_POC register offset */ struct rzg2l_register_offsets { u16 pwpr; u16 sd_ch; + u16 eth_poc; }; /** @@ -604,6 +607,10 @@ static int rzg2l_caps_to_pwr_reg(const struct rzg2l_register_offsets *regs, u32 return SD_CH(regs->sd_ch, 0); if (caps & PIN_CFG_IO_VMC_SD1) return SD_CH(regs->sd_ch, 1); + if (caps & PIN_CFG_IO_VMC_ETH0) + return ETH_POC(regs->eth_poc, 0); + if (caps & PIN_CFG_IO_VMC_ETH1) + return ETH_POC(regs->eth_poc, 1); if (caps & PIN_CFG_IO_VMC_QSPI) return QSPI; @@ -615,6 +622,7 @@ static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; const struct rzg2l_register_offsets *regs = &hwcfg->regs; int pwr_reg; + u8 val; if (caps & PIN_CFG_SOFT_PS) return pctrl->settings[pin].power_source; @@ -623,7 +631,18 @@ static int rzg2l_get_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps if (pwr_reg < 0) return pwr_reg; - return (readl(pctrl->base + pwr_reg) & PVDD_MASK) ? 1800 : 3300; + val = readb(pctrl->base + pwr_reg); + switch (val) { + case PVDD_1800: + return 1800; + case PVDD_2500: + return 2500; + case PVDD_3300: + return 3300; + default: + /* Should not happen. */ + return -EINVAL; + } } static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps, u32 ps) @@ -631,17 +650,32 @@ static int rzg2l_set_power_source(struct rzg2l_pinctrl *pctrl, u32 pin, u32 caps const struct rzg2l_hwcfg *hwcfg = pctrl->data->hwcfg; const struct rzg2l_register_offsets *regs = &hwcfg->regs; int pwr_reg; + u8 val; if (caps & PIN_CFG_SOFT_PS) { pctrl->settings[pin].power_source = ps; return 0; } + switch (ps) { + case 1800: + val = PVDD_1800; + break; + case 2500: + val = PVDD_2500; + break; + case 3300: + val = PVDD_3300; + break; + default: + return -EINVAL; + } + pwr_reg = rzg2l_caps_to_pwr_reg(regs, caps); if (pwr_reg < 0) return pwr_reg; - writel((ps == 1800) ? PVDD_1800 : PVDD_3300, pctrl->base + pwr_reg); + writeb(val, pctrl->base + pwr_reg); pctrl->settings[pin].power_source = ps; return 0; @@ -1885,6 +1919,7 @@ static const struct rzg2l_hwcfg rzg2l_hwcfg = { .regs = { .pwpr = 0x3014, .sd_ch = 0x3000, + .eth_poc = 0x300c, }, .iolh_groupa_ua = { /* 3v3 power source */ @@ -1897,6 +1932,7 @@ static const struct rzg2l_hwcfg rzg3s_hwcfg = { .regs = { .pwpr = 0x3000, .sd_ch = 0x3004, + .eth_poc = 0x3010, }, .iolh_groupa_ua = { /* 1v8 power source */