regulator: pbias: Convert to use regmap helper functions
PATCH 1/1 regulator: pbias: Convert to use regmap helper functions
This patch converts this driver to use the regmap helper functions provided by regulator core.
This fixes a few issues in current implementation:
1) In original code, the set voltage does not check max_uV, which means if request max_uV < 1800000, it will still set the voltage to 1800000.
2) The is_enable implementation is wrong in some cases:
e.g. for pbias_mmc_omap5: emable_mask is : BIT(27) | BIT(25) | BIT(26) However, pbias_regulator_enable() only sets BIT(26) | BIT(22) bits. So is_enable always return false in this case.
---
Hi Balaji,
I don't have this h/w, so please test if it works. Regards,
Axel
drivers/regulator/pbias-regulator.c | 86 ++++++++++--------------------------- 1 file changed, 23 insertions(+), 63 deletions(-)
drivers/regulator/pbias-regulator.c +23 -63
@@ -38,85 +38,41 @@ struct pbias_reg_info {struct pbias_regulator_data {struct regulator_desc desc;void __iomem *pbias_addr; -unsigned int pbias_reg;struct regulator_dev *dev;struct regmap *syscon;const struct pbias_reg_info *info;int voltage; }; -static int pbias_regulator_set_voltage (struct regulator_dev *dev, -int min_uV,int max_uV,unsigned *selector) +static int pbias_regulator_list_voltage (struct regulator_dev *rdev, +unsigned int selector) { -struct pbias_regulator_data *data =rdev_get_drvdata (dev); -const struct pbias_reg_info *info = data->info; -int ret, vmode; - -if (min_uV <=1800000 ) - vmode =0 ; -else if (min_uV >1800000 ) - vmode = info->vmode; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->vmode, vmode); - -return ret; -} - -static int pbias_regulator_get_voltage (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int value, voltage; - -regmap_read (data->syscon, data->pbias_reg, &value); - value &= info->vmode; - - voltage = value ?3000000 :1800000 ; - -return voltage; +switch (selector) { +case 0 : +return 1800000 ; +case 1 : +return 3000000 ; +default : +return -EINVAL ; + } }static int pbias_regulator_enable (struct regulator_dev *rdev) {struct pbias_regulator_data *data =rdev_get_drvdata (rdev);const struct pbias_reg_info *info = data->info; -int ret; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->enable_mask, info->enable); - -return ret; -} - -static int pbias_regulator_disable (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int ret; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->enable_mask,0 ); -return ret; -} - -static int pbias_regulator_is_enable (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int value; - -regmap_read (data->syscon, data->pbias_reg, &value); -return (value & info->enable_mask) == info->enable_mask; +return regmap_update_bits (data->syscon, rdev->desc->enable_reg, + info->enable_mask, info->enable); }static struct regulator_ops pbias_regulator_voltage_ops = { - .set_voltage = pbias_regulator_set_voltage, - .get_voltage = pbias_regulator_get_voltage, - .enable = pbias_regulator_enable, - .disable = pbias_regulator_disable, - .is_enabled = pbias_regulator_is_enable, + .list_voltage = pbias_regulator_list_voltage, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = pbias_regulator_enable, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, };static const struct pbias_reg_info pbias_mmc_omap2430 = {
@@ -192,6 +148,7 @@ static int pbias_regulator_probe(struct platform_device *pdev)if (IS_ERR (syscon))return PTR_ERR (syscon); + cfg.regmap = syscon; cfg.dev = &pdev->dev;for (idx =0 ; idx <PBIAS_NUM_REGS && data_idx < count; idx++) {
@@ -207,7 +164,6 @@ static int pbias_regulator_probe(struct platform_device *pdev)if (!res)return -EINVAL ; - drvdata[data_idx].pbias_reg = res->start; drvdata[data_idx].syscon = syscon; drvdata[data_idx].info = info; drvdata[data_idx].desc.name = info->name;
@@ -216,6 +172,10 @@ static int pbias_regulator_probe(struct platform_device *pdev) drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; drvdata[data_idx].desc.n_voltages =2 ; drvdata[data_idx].desc.enable_time = info->enable_time; + drvdata[data_idx].desc.vsel_reg = res->start; + drvdata[data_idx].desc.vsel_mask = info->vmode; + drvdata[data_idx].desc.enable_reg = res->start; + drvdata[data_idx].desc.enable_mask = info->enable_mask; cfg.init_data = pbias_matches[idx].init_data; cfg.driver_data = &drvdata[data_idx];
Signature · 1 line
1.8.1.2
Quoted 14 lines · Axel Lin
This patch converts this driver to use the regmap helper functions provided by regulator core.
This fixes a few issues in current implementation:
1) In original code, the set voltage does not check
max_uV, which means if requestmax_uV< 1800000, it will still set the voltage to 1800000.2) The
is_enableimplementation is wrong in some cases:
e.g. forpbias_mmc_omap5:emable_maskis : BIT(27) | BIT(25) | BIT(26) However,pbias_regulator_enable()only sets BIT(26) | BIT(22) bits. Sois_enablealways return false in this case.
Quoted 4 lines
Signed-off-by Axel Lin <[email protected]>---
Hi Balaji,
I don't have this h/w, so please test if it works.
Hi Axel,
There were few issues when I tried using regmap helper, will check on this.
Thanks and Regards,
Balaji T K
Quoted 141 lines
Regards,
Axeldrivers/regulator/pbias-regulator.c | 86 ++++++++++--------------------------- 1 file changed, 23 insertions(+), 63 deletions(-)drivers/regulator/pbias-regulator.c +23
-63@@ -38,85 +38,41 @@ struct pbias_reg_info {struct pbias_regulator_data {struct regulator_desc desc;void __iomem *pbias_addr; -unsigned int pbias_reg;struct regulator_dev *dev;struct regmap *syscon;const struct pbias_reg_info *info;int voltage; }; -static int pbias_regulator_set_voltage (struct regulator_dev *dev, -int min_uV,int max_uV,unsigned *selector) +static int pbias_regulator_list_voltage (struct regulator_dev *rdev, +unsigned int selector) { -struct pbias_regulator_data *data =rdev_get_drvdata (dev); -const struct pbias_reg_info *info = data->info; -int ret, vmode; - -if (min_uV <=1800000 ) - vmode =0 ; -else if (min_uV >1800000 ) - vmode = info->vmode; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->vmode, vmode); - -return ret; -} - -static int pbias_regulator_get_voltage (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int value, voltage; - -regmap_read (data->syscon, data->pbias_reg, &value); - value &= info->vmode; - - voltage = value ?3000000 :1800000 ; - -return voltage; +switch (selector) { +case 0 : +return 1800000 ; +case 1 : +return 3000000 ; +default : +return -EINVAL ; + } }static int pbias_regulator_enable (struct regulator_dev *rdev) {struct pbias_regulator_data *data =rdev_get_drvdata (rdev);const struct pbias_reg_info *info = data->info; -int ret; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->enable_mask, info->enable); - -return ret; -} - -static int pbias_regulator_disable (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int ret; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->enable_mask,0 ); -return ret; -} - -static int pbias_regulator_is_enable (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int value; - -regmap_read (data->syscon, data->pbias_reg, &value); -return (value & info->enable_mask) == info->enable_mask; +return regmap_update_bits (data->syscon, rdev->desc->enable_reg, + info->enable_mask, info->enable); }static struct regulator_ops pbias_regulator_voltage_ops = { - .set_voltage = pbias_regulator_set_voltage, - .get_voltage = pbias_regulator_get_voltage, - .enable = pbias_regulator_enable, - .disable = pbias_regulator_disable, - .is_enabled = pbias_regulator_is_enable, + .list_voltage = pbias_regulator_list_voltage, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = pbias_regulator_enable, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, };static const struct pbias_reg_info pbias_mmc_omap2430 = {@@ -192,6 +148,7 @@ static int pbias_regulator_probe(struct platform_device *pdev)if (IS_ERR (syscon))return PTR_ERR (syscon); + cfg.regmap = syscon; cfg.dev = &pdev->dev;for (idx =0 ; idx <PBIAS_NUM_REGS && data_idx < count; idx++) {@@ -207,7 +164,6 @@ static int pbias_regulator_probe(struct platform_device *pdev)if (!res)return -EINVAL ; - drvdata[data_idx].pbias_reg = res->start; drvdata[data_idx].syscon = syscon; drvdata[data_idx].info = info; drvdata[data_idx].desc.name = info->name;@@ -216,6 +172,10 @@ static int pbias_regulator_probe(struct platform_device *pdev) drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; drvdata[data_idx].desc.n_voltages =2 ; drvdata[data_idx].desc.enable_time = info->enable_time; + drvdata[data_idx].desc.vsel_reg = res->start; + drvdata[data_idx].desc.vsel_mask = info->vmode; + drvdata[data_idx].desc.enable_reg = res->start; + drvdata[data_idx].desc.enable_mask = info->enable_mask; cfg.init_data = pbias_matches[idx].init_data; cfg.driver_data = &drvdata[data_idx];
2014-03-06 23:20 GMT+08:00 Balaji T K <[email protected]>:
Quoted 23 lines · Axel Lin
Quoted 16 lines
This patch converts this driver to use the regmap helper functions provided by
regulator core.This fixes a few issues in current implementation:
1) In original code, the set voltage does not check
max_uV, which means if requestmax_uV< 1800000, it will still set the voltage to 1800000.2) The
is_enableimplementation is wrong in some cases:
e.g. forpbias_mmc_omap5:emable_maskis : BIT(27) | BIT(25) | BIT(26) However,pbias_regulator_enable()only sets BIT(26) | BIT(22) bits. Sois_enablealways return false in this case.Quoted 4 lines
Signed-off-by Axel Lin <[email protected]>---
Hi Balaji,
I don't have this h/w, so please test if it works.
Quoted 4 lines
Hi Axel,
There were few issues when I tried using regmap helper, will check on this.
Hi Balaji,
I decide to break this patch to 3 pathes as below:
[PATCH 1/3] regulator: pbias: Fix is_enabled callback implementation
This is pure bug fix for is_enabled logic
[PATCH 2/3] regulator: pbias: Convert to use regmap helper functions
This simply convert to use regmap.
[PATCH 3/3] regulator: pbias: Convert to use regulator_[enable|is_enabled]_regmap
This one depends on commit ca5d1b3524b4d
"regulator: helpers: Modify helpers enabling multi-bit control"
which is currently only available on regulator tree.
I sent it for review and test now, if it works, I'll resend it once
3.5-rc1 is release.
I'm sending the patches right away.
Regards,
Axel
Quoted 9 lines · Axel Lin
This patch converts this driver to use the regmap helper functions provided by regulator core.
This fixes a few issues in current implementation:
1) In original code, the set voltage does not check
max_uV, which means if requestmax_uV< 1800000, it will still set the voltage to 1800000.
Hi Axel,
May be I am not getting your logic here, why would max_uV be less than min_uV
The intention was to set vmode to 0 for any voltage request lesser than 1.8V. With regmap conversion, set voltage of 0V will become invalid. However since pbias is not set to 0V anywhere, I think it shouldn't be an issue. Will test and confirm.
Thanks and Regards
Balaji T K
Quoted 150 lines
2) The
is_enableimplementation is wrong in some cases:
e.g. forpbias_mmc_omap5:emable_maskis : BIT(27) | BIT(25) | BIT(26) However,pbias_regulator_enable()only sets BIT(26) | BIT(22) bits. Sois_enablealways return false in this case.Signed-off-by Axel Lin <[email protected]>---
Hi Balaji,
I don't have this h/w, so please test if it works. Regards,
Axeldrivers/regulator/pbias-regulator.c | 86 ++++++++++--------------------------- 1 file changed, 23 insertions(+), 63 deletions(-)drivers/regulator/pbias-regulator.c +23
-63@@ -38,85 +38,41 @@ struct pbias_reg_info {struct pbias_regulator_data {struct regulator_desc desc;void __iomem *pbias_addr; -unsigned int pbias_reg;struct regulator_dev *dev;struct regmap *syscon;const struct pbias_reg_info *info;int voltage; }; -static int pbias_regulator_set_voltage (struct regulator_dev *dev, -int min_uV,int max_uV,unsigned *selector) +static int pbias_regulator_list_voltage (struct regulator_dev *rdev, +unsigned int selector) { -struct pbias_regulator_data *data =rdev_get_drvdata (dev); -const struct pbias_reg_info *info = data->info; -int ret, vmode; - -if (min_uV <=1800000 ) - vmode =0 ; -else if (min_uV >1800000 ) - vmode = info->vmode; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->vmode, vmode); - -return ret; -} - -static int pbias_regulator_get_voltage (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int value, voltage; - -regmap_read (data->syscon, data->pbias_reg, &value); - value &= info->vmode; - - voltage = value ?3000000 :1800000 ; - -return voltage; +switch (selector) { +case 0 : +return 1800000 ; +case 1 : +return 3000000 ; +default : +return -EINVAL ; + } }static int pbias_regulator_enable (struct regulator_dev *rdev) {struct pbias_regulator_data *data =rdev_get_drvdata (rdev);const struct pbias_reg_info *info = data->info; -int ret; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->enable_mask, info->enable); - -return ret; -} - -static int pbias_regulator_disable (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int ret; - - ret =regmap_update_bits (data->syscon, data->pbias_reg, - info->enable_mask,0 ); -return ret; -} - -static int pbias_regulator_is_enable (struct regulator_dev *rdev) -{ -struct pbias_regulator_data *data =rdev_get_drvdata (rdev); -const struct pbias_reg_info *info = data->info; -int value; - -regmap_read (data->syscon, data->pbias_reg, &value); -return (value & info->enable_mask) == info->enable_mask; +return regmap_update_bits (data->syscon, rdev->desc->enable_reg, + info->enable_mask, info->enable); }static struct regulator_ops pbias_regulator_voltage_ops = { - .set_voltage = pbias_regulator_set_voltage, - .get_voltage = pbias_regulator_get_voltage, - .enable = pbias_regulator_enable, - .disable = pbias_regulator_disable, - .is_enabled = pbias_regulator_is_enable, + .list_voltage = pbias_regulator_list_voltage, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = pbias_regulator_enable, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, };static const struct pbias_reg_info pbias_mmc_omap2430 = {@@ -192,6 +148,7 @@ static int pbias_regulator_probe(struct platform_device *pdev)if (IS_ERR (syscon))return PTR_ERR (syscon); + cfg.regmap = syscon; cfg.dev = &pdev->dev;for (idx =0 ; idx <PBIAS_NUM_REGS && data_idx < count; idx++) {@@ -207,7 +164,6 @@ static int pbias_regulator_probe(struct platform_device *pdev)if (!res)return -EINVAL ; - drvdata[data_idx].pbias_reg = res->start; drvdata[data_idx].syscon = syscon; drvdata[data_idx].info = info; drvdata[data_idx].desc.name = info->name;@@ -216,6 +172,10 @@ static int pbias_regulator_probe(struct platform_device *pdev) drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; drvdata[data_idx].desc.n_voltages =2 ; drvdata[data_idx].desc.enable_time = info->enable_time; + drvdata[data_idx].desc.vsel_reg = res->start; + drvdata[data_idx].desc.vsel_mask = info->vmode; + drvdata[data_idx].desc.enable_reg = res->start; + drvdata[data_idx].desc.enable_mask = info->enable_mask; cfg.init_data = pbias_matches[idx].init_data; cfg.driver_data = &drvdata[data_idx];
2014-03-07 23:25 GMT+08:00 Balaji T K <[email protected]>:
Quoted 13 lines · Axel Lin
Quoted 11 lines
This patch converts this driver to use the regmap helper functions provided by
regulator core.This fixes a few issues in current implementation:
1) In original code, the set voltage does not check
max_uV, which means if requestmax_uV< 1800000, it will still set the voltage to 1800000.
Quoted 4 lines
Hi Axel,
May be I am not getting your logic here, why would
max_uVbe less thanmin_uV
I think this is an unlikely case here.
Quoted 3 lines
The intention was to set vmode to 0 for any voltage request lesser than 1.8V.
This statement sounds wrong to me.
For example, If the request voltage range is 1.0V ~ 1.5V. We should return error rather than set the voltage to 1.8V (which may damage the device).
Quoted 2 lines
With regmap conversion, set voltage of 0V will become invalid. However since pbias is not set to 0V anywhere, I think it shouldn't be an issue.
ok.
Quoted 1 line
Will test and confirm.
Thanks,
Axel
Mark Brown
maintainerQuoted 9 lines · Axel Lin
2014-03-07 23:25 GMT+08:00 Balaji T K <[email protected]>:
Quoted 2 lines
The intention was to set vmode to 0 for any voltage request lesser than 1.8V.
This statement sounds wrong to me.
For example, If the request voltage range is 1.0V ~ 1.5V. We should return error rather than set the voltage to 1.8V (which may damage the device).
Yes, that's the expected behaviour - the selected voltage still needs to be within spec.