summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2013-01-23 15:11:34 +0800
committerAnson Huang <b20788@freescale.com>2013-01-28 10:19:10 +0800
commit64eb436e9876a2d95abea34464addf37a0888f61 (patch)
treecfc68caa765533940e5c9560bc5c20317ac9a197
parentc03a6de3bd70b3f99afa3ec532fbb7178819bfad (diff)
ENGR00241003-2 pfuze: using _sel interface to add delay supportrel_imx_3.0.35_1.1.2rel_imx_3.0.35_1.1.13.0-imx6-ts3
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>
-rw-r--r--drivers/regulator/pfuze100-regulator.c86
1 files changed, 83 insertions, 3 deletions
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 17a8da1e2099..8ab80b70d276 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
@@ -550,6 +550,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);
@@ -569,6 +587,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 int pfuze100_regulator_ldo_standby_enable(struct regulator_dev *rdev)
{
struct pfuze_regulator_priv *priv = rdev_get_drvdata(rdev);
@@ -681,11 +759,13 @@ static int pfuze100_regulator_sw_standby_disable(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_suspend_enable = pfuze100_regulator_sw_standby_enable,
.set_suspend_disable = pfuze100_regulator_sw_standby_disable,
.set_suspend_voltage = pfuze100_regulator_sw_standby_voltage,
+ .set_voltage_time_sel = pfuze100_regulator_set_voltage_time_sel,
+
};
static int __devinit pfuze100_regulator_probe(struct platform_device *pdev)