diff options
| author | Anson Huang <b20788@freescale.com> | 2013-01-23 15:11:34 +0800 | 
|---|---|---|
| committer | Jason Liu <r64343@freescale.com> | 2013-02-26 11:00:25 +0800 | 
| commit | 8a75c917639c5fd756158821730307fb90cca307 (patch) | |
| tree | 941faeafb46c84a3c0c5373f5bc0553cdda0d559 | |
| parent | 35a938a97a3ecaa035a834345e258699b01c226d (diff) | |
ENGR00241003-2 pfuze: using _sel interface to add delay supportrel_imx_3.0.35_1.0.2
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.c | 85 | 
1 files changed, 82 insertions, 3 deletions
| diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 34ca0fb45961..4458d3def6a2 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,9 @@ 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) | 
