aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sh-pfc
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2016-06-06 12:08:25 -0400
committerGeert Uytterhoeven <geert+renesas@glider.be>2016-06-10 03:00:19 -0400
commit8775306dcf48092ff9520463699f8fb373ceb57e (patch)
tree0eb508dcb23e771a0a3234539fb0332341c49d3f /drivers/pinctrl/sh-pfc
parent1a695a905c18548062509178b98bc91e67510864 (diff)
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')
-rw-r--r--drivers/pinctrl/sh-pfc/pfc-r8a7790.c58
-rw-r--r--drivers/pinctrl/sh-pfc/pinctrl.c41
-rw-r--r--drivers/pinctrl/sh-pfc/sh_pfc.h4
3 files changed, 40 insertions, 63 deletions
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
index eed8daa464cc..1537a0779399 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
@@ -4696,47 +4696,6 @@ static const char * const vin3_groups[] = {
4696 "vin3_clk", 4696 "vin3_clk",
4697}; 4697};
4698 4698
4699#define IOCTRL6 0x8c
4700
4701static int r8a7790_get_io_voltage(struct sh_pfc *pfc, unsigned int pin)
4702{
4703 u32 data, mask;
4704
4705 if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
4706 return -EINVAL;
4707
4708 data = ioread32(pfc->windows->virt + IOCTRL6),
4709 /* Bits in IOCTRL6 are numbered in opposite order to pins */
4710 mask = 0x80000000 >> (pin & 0x1f);
4711
4712 return (data & mask) ? 3300 : 1800;
4713}
4714
4715static int r8a7790_set_io_voltage(struct sh_pfc *pfc, unsigned int pin, u16 mV)
4716{
4717 u32 data, mask;
4718
4719 if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
4720 return -EINVAL;
4721
4722 if (mV != 1800 && mV != 3300)
4723 return -EINVAL;
4724
4725 data = ioread32(pfc->windows->virt + IOCTRL6);
4726 /* Bits in IOCTRL6 are numbered in opposite order to pins */
4727 mask = 0x80000000 >> (pin & 0x1f);
4728
4729 if (mV == 3300)
4730 data |= mask;
4731 else
4732 data &= ~mask;
4733
4734 iowrite32(~data, pfc->windows->virt); /* unlock reg */
4735 iowrite32(data, pfc->windows->virt + IOCTRL6);
4736
4737 return 0;
4738}
4739
4740static const struct sh_pfc_function pinmux_functions[] = { 4699static const struct sh_pfc_function pinmux_functions[] = {
4741 SH_PFC_FUNCTION(audio_clk), 4700 SH_PFC_FUNCTION(audio_clk),
4742 SH_PFC_FUNCTION(avb), 4701 SH_PFC_FUNCTION(avb),
@@ -5736,14 +5695,23 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
5736 { }, 5695 { },
5737}; 5696};
5738 5697
5739static const struct sh_pfc_soc_operations pinmux_ops = { 5698static int r8a7790_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl)
5740 .get_io_voltage = r8a7790_get_io_voltage, 5699{
5741 .set_io_voltage = r8a7790_set_io_voltage, 5700 if (pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31))
5701 return -EINVAL;
5702
5703 *pocctrl = 0xe606008c;
5704
5705 return 31 - (pin & 0x1f);
5706}
5707
5708static const struct sh_pfc_soc_operations r8a7790_pinmux_ops = {
5709 .pin_to_pocctrl = r8a7790_pin_to_pocctrl,
5742}; 5710};
5743 5711
5744const struct sh_pfc_soc_info r8a7790_pinmux_info = { 5712const struct sh_pfc_soc_info r8a7790_pinmux_info = {
5745 .name = "r8a77900_pfc", 5713 .name = "r8a77900_pfc",
5746 .ops = &pinmux_ops, 5714 .ops = &r8a7790_pinmux_ops,
5747 .unlock_reg = 0xe6060000, /* PMMR */ 5715 .unlock_reg = 0xe6060000, /* PMMR */
5748 5716
5749 .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, 5717 .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
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,
632 } 632 }
633 633
634 case PIN_CONFIG_POWER_SOURCE: { 634 case PIN_CONFIG_POWER_SOURCE: {
635 int ret; 635 u32 pocctrl, val;
636 int bit;
636 637
637 if (!pfc->info->ops || !pfc->info->ops->get_io_voltage) 638 if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
638 return -ENOTSUPP; 639 return -ENOTSUPP;
639 640
641 bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl);
642 if (WARN(bit < 0, "invalid pin %#x", _pin))
643 return bit;
644
640 spin_lock_irqsave(&pfc->lock, flags); 645 spin_lock_irqsave(&pfc->lock, flags);
641 ret = pfc->info->ops->get_io_voltage(pfc, _pin); 646 val = sh_pfc_read_reg(pfc, pocctrl, 32);
642 spin_unlock_irqrestore(&pfc->lock, flags); 647 spin_unlock_irqrestore(&pfc->lock, flags);
643 648
644 if (ret < 0) 649 *config = (val & BIT(bit)) ? 3300 : 1800;
645 return ret;
646
647 *config = ret;
648 break; 650 break;
649 } 651 }
650 652
@@ -696,20 +698,29 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
696 } 698 }
697 699
698 case PIN_CONFIG_POWER_SOURCE: { 700 case PIN_CONFIG_POWER_SOURCE: {
699 unsigned int arg = 701 unsigned int mV = pinconf_to_config_argument(configs[i]);
700 pinconf_to_config_argument(configs[i]); 702 u32 pocctrl, val;
701 int ret; 703 int bit;
702 704
703 if (!pfc->info->ops || !pfc->info->ops->set_io_voltage) 705 if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl)
704 return -ENOTSUPP; 706 return -ENOTSUPP;
705 707
708 bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl);
709 if (WARN(bit < 0, "invalid pin %#x", _pin))
710 return bit;
711
712 if (mV != 1800 && mV != 3300)
713 return -EINVAL;
714
706 spin_lock_irqsave(&pfc->lock, flags); 715 spin_lock_irqsave(&pfc->lock, flags);
707 ret = pfc->info->ops->set_io_voltage(pfc, _pin, arg); 716 val = sh_pfc_read_reg(pfc, pocctrl, 32);
717 if (mV == 3300)
718 val |= BIT(bit);
719 else
720 val &= ~BIT(bit);
721 sh_pfc_write_reg(pfc, pocctrl, 32, val);
708 spin_unlock_irqrestore(&pfc->lock, flags); 722 spin_unlock_irqrestore(&pfc->lock, flags);
709 723
710 if (ret)
711 return ret;
712
713 break; 724 break;
714 } 725 }
715 726
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
index 656ea32f776c..ea3a52751455 100644
--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
+++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
@@ -189,9 +189,7 @@ struct sh_pfc_soc_operations {
189 unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin); 189 unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin);
190 void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, 190 void (*set_bias)(struct sh_pfc *pfc, unsigned int pin,
191 unsigned int bias); 191 unsigned int bias);
192 int (*get_io_voltage)(struct sh_pfc *pfc, unsigned int pin); 192 int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl);
193 int (*set_io_voltage)(struct sh_pfc *pfc, unsigned int pin,
194 u16 voltage_mV);
195}; 193};
196 194
197struct sh_pfc_soc_info { 195struct sh_pfc_soc_info {