summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/sirf
diff options
context:
space:
mode:
authorWei Chen <Wei.Chen@csr.com>2015-08-04 23:22:14 -0400
committerLinus Walleij <linus.walleij@linaro.org>2015-08-13 08:37:21 -0400
commit627b1516a390e19fb26b1c0c9bd2546722524965 (patch)
treefe510df1500b4a0edd7fff542c1ec37f58378128 /drivers/pinctrl/sirf
parent39ce8150a079e3ae6ed9abf26d7918a558ef7c19 (diff)
pinctrl: atlas7: clear ugly branch statements for pull and drivestrength
To set/get atlas7 pull & drive strength, we use lots of if/else to check pad type. But except mask value or immediate value, all actions in these conditional branches are the same. So we use predefined pull info table and drive strength table to reduce these redundancy code. Signed-off-by: Wei Chen <Wei.Chen@csr.com> Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/sirf')
-rw-r--r--drivers/pinctrl/sirf/pinctrl-atlas7.c193
1 files changed, 94 insertions, 99 deletions
diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c
index d16e62996e05..9df0c5f25824 100644
--- a/drivers/pinctrl/sirf/pinctrl-atlas7.c
+++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c
@@ -3510,11 +3510,19 @@ struct atlas7_pinctrl_data atlas7_ioc_data = {
3510 .confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs), 3510 .confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs),
3511}; 3511};
3512 3512
3513/* Simple map data structure */
3513struct map_data { 3514struct map_data {
3514 u8 idx; 3515 u8 idx;
3515 u8 data; 3516 u8 data;
3516}; 3517};
3517 3518
3519/**
3520 * struct atlas7_pull_info - Atlas7 Pad pull info
3521 * @type:The type of this Pad.
3522 * @mask:The mas value of this pin's pull bits.
3523 * @v2s: The map of pull register value to pull status.
3524 * @s2v: The map of pull status to pull register value.
3525 */
3518struct atlas7_pull_info { 3526struct atlas7_pull_info {
3519 u8 pad_type; 3527 u8 pad_type;
3520 u8 mask; 3528 u8 mask;
@@ -3597,6 +3605,65 @@ static const struct atlas7_pull_info atlas7_pull_map[] = {
3597 { PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v }, 3605 { PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v },
3598}; 3606};
3599 3607
3608/**
3609 * struct atlas7_ds_ma_info - Atlas7 Pad DriveStrength & currents info
3610 * @ma: The Drive Strength in current value .
3611 * @ds_16st: The correspond raw value of 16st pad.
3612 * @ds_4we: The correspond raw value of 4we pad.
3613 * @ds_0204m31: The correspond raw value of 0204m31 pad.
3614 * @ds_0610m31: The correspond raw value of 0610m31 pad.
3615 */
3616struct atlas7_ds_ma_info {
3617 u32 ma;
3618 u32 ds_16st;
3619 u32 ds_4we;
3620 u32 ds_0204m31;
3621 u32 ds_0610m31;
3622};
3623
3624static const struct atlas7_ds_ma_info atlas7_ma2ds_map[] = {
3625 { 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL },
3626 { 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL },
3627 { 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0 },
3628 { 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL },
3629 { 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1 },
3630 { 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL },
3631 { 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL },
3632 { 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL },
3633 { 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL },
3634 { 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL },
3635 { 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL },
3636 { 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL },
3637 { 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL },
3638 { 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL },
3639 { 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL },
3640 { 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL },
3641};
3642
3643/**
3644 * struct atlas7_ds_info - Atlas7 Pad DriveStrength info
3645 * @type: The type of this Pad.
3646 * @mask: The mask value of this pin's pull bits.
3647 * @imval: The immediate value of drives trength register.
3648 */
3649struct atlas7_ds_info {
3650 u8 type;
3651 u8 mask;
3652 u8 imval;
3653 u8 reserved;
3654};
3655
3656static const struct atlas7_ds_info atlas7_ds_map[] = {
3657 { PAD_T_4WE_PD, DS_2BIT_MASK, DS_2BIT_IM_VAL },
3658 { PAD_T_4WE_PU, DS_2BIT_MASK, DS_2BIT_IM_VAL },
3659 { PAD_T_16ST, DS_4BIT_MASK, DS_4BIT_IM_VAL },
3660 { PAD_T_M31_0204_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3661 { PAD_T_M31_0204_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3662 { PAD_T_M31_0610_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3663 { PAD_T_M31_0610_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL },
3664 { PAD_T_AD, DS_NULL, DS_NULL },
3665};
3666
3600static inline u32 atlas7_pin_to_bank(u32 pin) 3667static inline u32 atlas7_pin_to_bank(u32 pin)
3601{ 3668{
3602 return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0; 3669 return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0;
@@ -3799,70 +3866,27 @@ static int atlas7_pmx_set_mux(struct pinctrl_dev *pctldev,
3799 return 0; 3866 return 0;
3800} 3867}
3801 3868
3802struct atlas7_ds_info {
3803 u32 ma;
3804 u32 ds_16st;
3805 u32 ds_4we;
3806 u32 ds_0204m31;
3807 u32 ds_0610m31;
3808};
3809
3810const struct atlas7_ds_info atlas7_ds_map[] = {
3811 { 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL},
3812 { 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL},
3813 { 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0},
3814 { 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL},
3815 { 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1},
3816 { 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL},
3817 { 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL},
3818 { 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL},
3819 { 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL},
3820 { 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL},
3821 { 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL},
3822 { 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL},
3823 { 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL},
3824 { 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL},
3825 { 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL},
3826 { 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL},
3827};
3828
3829static u32 convert_current_to_drive_strength(u32 type, u32 ma) 3869static u32 convert_current_to_drive_strength(u32 type, u32 ma)
3830{ 3870{
3831 int idx; 3871 int idx;
3832 3872
3833 for (idx = 0; idx < ARRAY_SIZE(atlas7_ds_map); idx++) { 3873 for (idx = 0; idx < ARRAY_SIZE(atlas7_ma2ds_map); idx++) {
3834 if (atlas7_ds_map[idx].ma != ma) 3874 if (atlas7_ma2ds_map[idx].ma != ma)
3835 continue; 3875 continue;
3836 3876
3837 if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) 3877 if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU)
3838 return atlas7_ds_map[idx].ds_4we; 3878 return atlas7_ma2ds_map[idx].ds_4we;
3839 else if (type == PAD_T_16ST) 3879 else if (type == PAD_T_16ST)
3840 return atlas7_ds_map[idx].ds_16st; 3880 return atlas7_ma2ds_map[idx].ds_16st;
3841 else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU) 3881 else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU)
3842 return atlas7_ds_map[idx].ds_0204m31; 3882 return atlas7_ma2ds_map[idx].ds_0204m31;
3843 else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) 3883 else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU)
3844 return atlas7_ds_map[idx].ds_0610m31; 3884 return atlas7_ma2ds_map[idx].ds_0610m31;
3845 } 3885 }
3846 3886
3847 return DS_NULL; 3887 return DS_NULL;
3848} 3888}
3849 3889
3850static u32 altas7_pinctrl_get_pull_sel(struct atlas7_pmx *pmx, u32 pin)
3851{
3852 struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin];
3853 const struct atlas7_pull_info *pull_info;
3854 int bank;
3855 unsigned long regv;
3856
3857 bank = atlas7_pin_to_bank(pin);
3858 pull_info = &atlas7_pull_map[conf->type];
3859
3860 regv = readl(pmx->regs[bank] + conf->pupd_reg);
3861 regv = (regv >> conf->pupd_bit) & pull_info->mask;
3862
3863 return pull_info->v2s[regv].data;
3864}
3865
3866static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev, 3890static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev,
3867 u32 pin, u32 sel) 3891 u32 pin, u32 sel)
3868{ 3892{
@@ -3871,19 +3895,17 @@ static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev,
3871 const struct atlas7_pull_info *pull_info; 3895 const struct atlas7_pull_info *pull_info;
3872 u32 bank; 3896 u32 bank;
3873 unsigned long regv; 3897 unsigned long regv;
3874 void __iomem *pull_sel_reg, *pull_clr_reg; 3898 void __iomem *pull_sel_reg;
3875 3899
3876 bank = atlas7_pin_to_bank(pin); 3900 bank = atlas7_pin_to_bank(pin);
3877 pull_info = &atlas7_pull_map[conf->type]; 3901 pull_info = &atlas7_pull_map[conf->type];
3878
3879 pull_sel_reg = pmx->regs[bank] + conf->pupd_reg; 3902 pull_sel_reg = pmx->regs[bank] + conf->pupd_reg;
3880 pull_clr_reg = CLR_REG(pull_sel_reg);
3881 3903
3882 /* Retrieve correspond register value from table by sel */ 3904 /* Retrieve correspond register value from table by sel */
3883 regv = pull_info->s2v[sel].data & pull_info->mask; 3905 regv = pull_info->s2v[sel].data & pull_info->mask;
3884 3906
3885 /* Clear & Set new value to pull register */ 3907 /* Clear & Set new value to pull register */
3886 writel(pull_info->mask << conf->pupd_bit, pull_clr_reg); 3908 writel(pull_info->mask << conf->pupd_bit, CLR_REG(pull_sel_reg));
3887 writel(regv << conf->pupd_bit, pull_sel_reg); 3909 writel(regv << conf->pupd_bit, pull_sel_reg);
3888 3910
3889 pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n", 3911 pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n",
@@ -3896,43 +3918,25 @@ static int __altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev,
3896{ 3918{
3897 struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 3919 struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
3898 struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin]; 3920 struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin];
3899 u32 type = conf->type; 3921 const struct atlas7_ds_info *ds_info;
3900 u32 shift = conf->drvstr_bit; 3922 u32 bank;
3901 u32 bank = atlas7_pin_to_bank(pin); 3923 void __iomem *ds_sel_reg;
3902 void __iomem *ds_sel_reg, *ds_clr_reg;
3903
3904 ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg;
3905 ds_clr_reg = CLR_REG(ds_sel_reg);
3906 if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) {
3907 if (sel & (~DS_2BIT_MASK))
3908 goto unsupport;
3909
3910 writel(DS_2BIT_IM_VAL << shift, ds_clr_reg);
3911 writel(sel << shift, ds_sel_reg);
3912
3913 return 0;
3914 } else if (type == PAD_T_16ST) {
3915 if (sel & (~DS_4BIT_MASK))
3916 goto unsupport;
3917 3924
3918 writel(DS_4BIT_IM_VAL << shift, ds_clr_reg); 3925 ds_info = &atlas7_ds_map[conf->type];
3919 writel(sel << shift, ds_sel_reg); 3926 if (sel & (~(ds_info->mask)))
3927 goto unsupport;
3920 3928
3921 return 0; 3929 bank = atlas7_pin_to_bank(pin);
3922 } else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU || 3930 ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg;
3923 type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) {
3924 if (sel & (~DS_1BIT_MASK))
3925 goto unsupport;
3926 3931
3927 writel(DS_1BIT_IM_VAL << shift, ds_clr_reg); 3932 writel(ds_info->imval << conf->drvstr_bit, CLR_REG(ds_sel_reg));
3928 writel(sel << shift, ds_sel_reg); 3933 writel(sel << conf->drvstr_bit, ds_sel_reg);
3929 3934
3930 return 0; 3935 return 0;
3931 }
3932 3936
3933unsupport: 3937unsupport:
3934 pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n", 3938 pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n",
3935 pin, type, sel); 3939 pin, conf->type, sel);
3936 return -ENOTSUPP; 3940 return -ENOTSUPP;
3937} 3941}
3938 3942
@@ -4185,6 +4189,8 @@ static int atlas7_pinmux_suspend_noirq(struct device *dev)
4185 struct atlas7_pmx *pmx = dev_get_drvdata(dev); 4189 struct atlas7_pmx *pmx = dev_get_drvdata(dev);
4186 struct atlas7_pad_status *status; 4190 struct atlas7_pad_status *status;
4187 struct atlas7_pad_config *conf; 4191 struct atlas7_pad_config *conf;
4192 const struct atlas7_ds_info *ds_info;
4193 const struct atlas7_pull_info *pull_info;
4188 int idx; 4194 int idx;
4189 u32 bank; 4195 u32 bank;
4190 unsigned long regv; 4196 unsigned long regv;
@@ -4212,27 +4218,16 @@ save_ds_sel:
4212 goto save_pull_sel; 4218 goto save_pull_sel;
4213 4219
4214 /* Save Drive Strength selector */ 4220 /* Save Drive Strength selector */
4221 ds_info = &atlas7_ds_map[conf->type];
4215 regv = readl(pmx->regs[bank] + conf->drvstr_reg); 4222 regv = readl(pmx->regs[bank] + conf->drvstr_reg);
4216 if (PAD_T_4WE_PD == conf->type || PAD_T_4WE_PU == conf->type) 4223 status->dstr = (regv >> conf->drvstr_bit) & ds_info->mask;
4217 status->dstr = (regv >> conf->drvstr_bit) &
4218 DS_2BIT_MASK;
4219 else if (PAD_T_16ST == conf->type)
4220 status->dstr = (regv >> conf->drvstr_bit) &
4221 DS_4BIT_MASK;
4222 else if (PAD_T_M31_0204_PD == conf->type ||
4223 PAD_T_M31_0204_PU == conf->type ||
4224 PAD_T_M31_0610_PD == conf->type ||
4225 PAD_T_M31_0610_PU == conf->type)
4226 status->dstr = (regv >> conf->drvstr_bit) &
4227 DS_1BIT_MASK;
4228 4224
4229save_pull_sel: 4225save_pull_sel:
4230 /* Save Pull selector */ 4226 /* Save Pull selector */
4227 pull_info = &atlas7_pull_map[conf->type];
4231 regv = readl(pmx->regs[bank] + conf->pupd_reg); 4228 regv = readl(pmx->regs[bank] + conf->pupd_reg);
4232 status->pull = altas7_pinctrl_get_pull_sel(pmx, idx); 4229 regv = (regv >> conf->pupd_bit) & pull_info->mask;
4233 pr_debug("idx %d %p %x: %x %x %x\n", idx, 4230 status->pull = pull_info->v2s[regv].data;
4234 pmx->regs[bank], conf->mux_reg,
4235 status->func, status->pull, status->dstr);
4236 } 4231 }
4237 4232
4238 /* 4233 /*