diff options
author | Anson Huang <b20788@freescale.com> | 2013-01-23 15:11:34 +0800 |
---|---|---|
committer | Richard Liu <r66033@freescale.com> | 2013-04-09 15:08:12 +0800 |
commit | 04b8319d18f12d8959d3639659d62f6cfd322868 (patch) | |
tree | 7eb01c06d4f976ae224a269eb3ceffc9abc442a3 | |
parent | 2b921385a5784918ea19052d3bf0c4c416251d1a (diff) |
ENGR00241003-2 pfuze: using _sel interface to add delay support
use regulator _sel interface set to support auto delay,
as when regulator's voltage go up, it will take some time
to ramp up to the required voltage, so the delay is necessary.
_sel interface set support such function, now we switch to this
interface set.
Signed-off-by: Anson Huang <b20788@freescale.com>
Acked-by: Lily Zhang
Conflicts:
drivers/regulator/pfuze100-regulator.c
-rw-r--r-- | drivers/regulator/pfuze100-regulator.c | 86 |
1 files changed, 83 insertions, 3 deletions
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 34ca0fb45961..477111aa0b94 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -526,6 +526,24 @@ pfuze100_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, } +static int pfuze100_regulator_set_voltage_sel(struct regulator_dev *rdev, + unsigned selector) +{ + struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + int ret; + + dev_dbg(rdev_get_dev(rdev), "%s id: %d vol: %d\n", + __func__, id, pfuze100_regulators[id].voltages[selector]); + + pfuze_lock(priv->pfuze); + ret = pfuze_reg_rmw(priv->pfuze, pfuze100_regulators[id].reg, + pfuze100_regulators[id].vsel_mask, + selector << pfuze100_regulators[id].vsel_shift); + pfuze_unlock(priv->pfuze); + return ret; +} + static int pfuze100_regulator_get_voltage(struct regulator_dev *rdev) { struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev); @@ -545,6 +563,66 @@ static int pfuze100_regulator_get_voltage(struct regulator_dev *rdev) return pfuze100_regulators[id].voltages[val]; } +static int pfuze100_regulator_get_voltage_sel(struct regulator_dev *rdev) +{ + struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + int ret; + unsigned char val; + + pfuze_lock(priv->pfuze); + ret = pfuze_reg_read(priv->pfuze, pfuze100_regulators[id].reg, &val); + pfuze_unlock(priv->pfuze); + if (ret) + return ret; + + val &= pfuze100_regulators[id].vsel_mask; + val >>= pfuze100_regulators[id].vsel_shift; + dev_dbg(rdev_get_dev(rdev), "%s id: %d, vol=%d\n", __func__, id, + pfuze100_regulators[id].voltages[val]); + return (int) val; +} + +static int pfuze100_regulator_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_sel, + unsigned int new_sel) +{ + struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + int ret; + unsigned char step_delay; + + pfuze_lock(priv->pfuze); + /*read SWxDVSSPEED from SWxCONF,got ramp step value*/ + ret = pfuze_reg_read(priv->pfuze, pfuze100_regulators[id].reg + 0x4, + &step_delay); + pfuze_unlock(priv->pfuze); + + if (ret) + return ret; + /* + * one step + * 00: 2us, + * 01: 4us, + * 02: 8us, + * 03: 16us, + */ + step_delay >>= 5; + step_delay &= 0x3; + step_delay <<= 1; + + if (pfuze100_regulators[id].voltages[old_sel] < + pfuze100_regulators[id].voltages[new_sel]) + ret = DIV_ROUND_UP(pfuze100_regulators[id].voltages[new_sel] - + pfuze100_regulators[id].voltages[old_sel], 25000) + * step_delay; + else + ret = 0; /* no delay if voltage drop */ + dev_dbg(rdev_get_dev(rdev), "%s id: %d, new_sel = %d, old_sel = %d, \ + delay = %d\n", __func__, id, new_sel, old_sel, ret); + return ret; +} + static struct regulator_ops pfuze100_ldo_regulator_ops = { .enable = pfuze100_regulator_enable, .disable = pfuze100_regulator_disable, @@ -594,8 +672,10 @@ static int pfuze100_sw_regulator_is_enabled(struct regulator_dev *rdev) static struct regulator_ops pfuze100_sw_regulator_ops = { .is_enabled = pfuze100_sw_regulator_is_enabled, .list_voltage = pfuze100_regulator_list_voltage, - .set_voltage = pfuze100_regulator_set_voltage, - .get_voltage = pfuze100_regulator_get_voltage, + .set_voltage_sel = pfuze100_regulator_set_voltage_sel, + .get_voltage_sel = pfuze100_regulator_get_voltage_sel, + .set_voltage_time_sel = pfuze100_regulator_set_voltage_time_sel, + }; static int __devinit pfuze100_regulator_probe(struct platform_device *pdev) |