diff options
author | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2016-06-06 18:08:25 +0200 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2016-06-10 09:00:19 +0200 |
commit | 8775306dcf48092ff9520463699f8fb373ceb57e (patch) | |
tree | 0eb508dcb23e771a0a3234539fb0332341c49d3f /drivers/pinctrl/sh-pfc/pinctrl.c | |
parent | Linux 4.7-rc1 (diff) | |
download | linux-8775306dcf48092ff9520463699f8fb373ceb57e.tar.xz linux-8775306dcf48092ff9520463699f8fb373ceb57e.zip |
pinctrl: sh-pfc: refactor voltage setting
All known hardware being able to switch voltages has the same POCCTRL
register. So, factor out the common code to the core and keep only
the pin-to-bit mapping SoC specific. Convert the only user, r8a7790.
In case POCCTRL should ever get more complex (more voltages to select?),
we should probably switch over to a describing array like drive strength
does currently.
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Diffstat (limited to 'drivers/pinctrl/sh-pfc/pinctrl.c')
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index fdb445d68b9a..d4e65bc7dacd 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -632,19 +632,21 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, } case PIN_CONFIG_POWER_SOURCE: { - int ret; + u32 pocctrl, val; + int bit; - if (!pfc->info->ops || !pfc->info->ops->get_io_voltage) + if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl) return -ENOTSUPP; + bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl); + if (WARN(bit < 0, "invalid pin %#x", _pin)) + return bit; + spin_lock_irqsave(&pfc->lock, flags); - ret = pfc->info->ops->get_io_voltage(pfc, _pin); + val = sh_pfc_read_reg(pfc, pocctrl, 32); spin_unlock_irqrestore(&pfc->lock, flags); - if (ret < 0) - return ret; - - *config = ret; + *config = (val & BIT(bit)) ? 3300 : 1800; break; } @@ -696,20 +698,29 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, } case PIN_CONFIG_POWER_SOURCE: { - unsigned int arg = - pinconf_to_config_argument(configs[i]); - int ret; + unsigned int mV = pinconf_to_config_argument(configs[i]); + u32 pocctrl, val; + int bit; - if (!pfc->info->ops || !pfc->info->ops->set_io_voltage) + if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl) return -ENOTSUPP; + bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl); + if (WARN(bit < 0, "invalid pin %#x", _pin)) + return bit; + + if (mV != 1800 && mV != 3300) + return -EINVAL; + spin_lock_irqsave(&pfc->lock, flags); - ret = pfc->info->ops->set_io_voltage(pfc, _pin, arg); + val = sh_pfc_read_reg(pfc, pocctrl, 32); + if (mV == 3300) + val |= BIT(bit); + else + val &= ~BIT(bit); + sh_pfc_write_reg(pfc, pocctrl, 32, val); spin_unlock_irqrestore(&pfc->lock, flags); - if (ret) - return ret; - break; } |