diff options
Diffstat (limited to 'drivers/regulator/da903x.c')
| -rw-r--r-- | drivers/regulator/da903x.c | 225 | 
1 files changed, 74 insertions, 151 deletions
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index f8c4661a7a8..b431ae357fc 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -12,6 +12,7 @@  #include <linux/kernel.h>  #include <linux/init.h>  #include <linux/err.h> +#include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/regulator/driver.h>  #include <linux/regulator/machine.h> @@ -75,9 +76,7 @@  struct da903x_regulator_info {  	struct regulator_desc desc; -	int	min_uV;  	int	max_uV; -	int	step_uV;  	int	vol_reg;  	int	vol_shift;  	int	vol_nbits; @@ -87,10 +86,6 @@ struct da903x_regulator_info {  	int	enable_bit;  }; -static int da9034_ldo12_data[] = { 1700, 1750, 1800, 1850, 1900, 1950, -				   2000, 2050, 2700, 2750, 2800, 2850, -				   2900, 2950, 3000, 3050 }; -  static inline struct device *to_da903x_dev(struct regulator_dev *rdev)  {  	return rdev_get_dev(rdev)->parent->parent; @@ -99,39 +94,38 @@ static inline struct device *to_da903x_dev(struct regulator_dev *rdev)  static inline int check_range(struct da903x_regulator_info *info,  				int min_uV, int max_uV)  { -	if (min_uV < info->min_uV || min_uV > info->max_uV) +	if (min_uV < info->desc.min_uV || min_uV > info->max_uV)  		return -EINVAL;  	return 0;  }  /* DA9030/DA9034 common operations */ -static int da903x_set_ldo_voltage(struct regulator_dev *rdev, -				  int min_uV, int max_uV) +static int da903x_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)  {  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);  	struct device *da9034_dev = to_da903x_dev(rdev);  	uint8_t val, mask; -	if (check_range(info, min_uV, max_uV)) { -		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); +	if (rdev->desc->n_voltages == 1)  		return -EINVAL; -	} -	val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; -	val <<= info->vol_shift; +	val = selector << info->vol_shift;  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;  	return da903x_update(da9034_dev, info->vol_reg, val, mask);  } -static int da903x_get_voltage(struct regulator_dev *rdev) +static int da903x_get_voltage_sel(struct regulator_dev *rdev)  {  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);  	struct device *da9034_dev = to_da903x_dev(rdev);  	uint8_t val, mask;  	int ret; +	if (rdev->desc->n_voltages == 1) +		return 0; +  	ret = da903x_read(da9034_dev, info->vol_reg, &val);  	if (ret)  		return ret; @@ -139,7 +133,7 @@ static int da903x_get_voltage(struct regulator_dev *rdev)  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;  	val = (val & mask) >> info->vol_shift; -	return info->min_uV + info->step_uV * val; +	return val;  }  static int da903x_enable(struct regulator_dev *rdev) @@ -174,33 +168,16 @@ static int da903x_is_enabled(struct regulator_dev *rdev)  	return !!(reg_val & (1 << info->enable_bit));  } -static int da903x_list_voltage(struct regulator_dev *rdev, unsigned selector) -{ -	struct da903x_regulator_info *info = rdev_get_drvdata(rdev); -	int ret; - -	ret = info->min_uV + info->step_uV * selector; -	if (ret > info->max_uV) -		return -EINVAL; -	return ret; -} -  /* DA9030 specific operations */ -static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, -				       int min_uV, int max_uV) +static int da9030_set_ldo1_15_voltage_sel(struct regulator_dev *rdev, +					  unsigned selector)  {  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);  	struct device *da903x_dev = to_da903x_dev(rdev);  	uint8_t val, mask;  	int ret; -	if (check_range(info, min_uV, max_uV)) { -		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); -		return -EINVAL; -	} - -	val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; -	val <<= info->vol_shift; +	val = selector << info->vol_shift;  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;  	val |= DA9030_LDO_UNLOCK; /* have to set UNLOCK bits */  	mask |= DA9030_LDO_UNLOCK_MASK; @@ -213,70 +190,57 @@ static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev,  	return da903x_update(da903x_dev, info->vol_reg, val, mask);  } -static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, -				  int min_uV, int max_uV) +static int da9030_map_ldo14_voltage(struct regulator_dev *rdev, +				    int min_uV, int max_uV)  {  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev); -	struct device *da903x_dev = to_da903x_dev(rdev); -	uint8_t val, mask; -	int thresh; +	int thresh, sel;  	if (check_range(info, min_uV, max_uV)) {  		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);  		return -EINVAL;  	} -	thresh = (info->max_uV + info->min_uV) / 2; +	thresh = (info->max_uV + info->desc.min_uV) / 2;  	if (min_uV < thresh) { -		val = (thresh - min_uV + info->step_uV - 1) / info->step_uV; -		val |= 0x4; +		sel = DIV_ROUND_UP(thresh - min_uV, info->desc.uV_step); +		sel |= 0x4;  	} else { -		val = (min_uV - thresh + info->step_uV - 1) / info->step_uV; +		sel = DIV_ROUND_UP(min_uV - thresh, info->desc.uV_step);  	} -	val <<= info->vol_shift; -	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift; - -	return da903x_update(da903x_dev, info->vol_reg, val, mask); +	return sel;  } -static int da9030_get_ldo14_voltage(struct regulator_dev *rdev) +static int da9030_list_ldo14_voltage(struct regulator_dev *rdev, +				     unsigned selector)  {  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev); -	struct device *da903x_dev = to_da903x_dev(rdev); -	uint8_t val, mask; -	int ret; +	int volt; -	ret = da903x_read(da903x_dev, info->vol_reg, &val); -	if (ret) -		return ret; +	if (selector & 0x4) +		volt = rdev->desc->min_uV + +		       rdev->desc->uV_step * (3 - (selector & ~0x4)); +	else +		volt = (info->max_uV + rdev->desc->min_uV) / 2 + +		       rdev->desc->uV_step * (selector & ~0x4); -	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift; -	val = (val & mask) >> info->vol_shift; +	if (volt > info->max_uV) +		return -EINVAL; -	if (val & 0x4) -		return info->min_uV + info->step_uV * (3 - (val & ~0x4)); -	else -		return (info->max_uV + info->min_uV) / 2 + -			info->step_uV * (val & ~0x4); +	return volt;  }  /* DA9034 specific operations */ -static int da9034_set_dvc_voltage(struct regulator_dev *rdev, -				  int min_uV, int max_uV) +static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev, +				      unsigned selector)  {  	struct da903x_regulator_info *info = rdev_get_drvdata(rdev);  	struct device *da9034_dev = to_da903x_dev(rdev);  	uint8_t val, mask;  	int ret; -	if (check_range(info, min_uV, max_uV)) { -		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); -		return -EINVAL; -	} - -	val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; -	val <<= info->vol_shift; +	val = selector << info->vol_shift;  	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift;  	ret = da903x_update(da9034_dev, info->vol_reg, val, mask); @@ -288,58 +252,16 @@ static int da9034_set_dvc_voltage(struct regulator_dev *rdev,  	return ret;  } -static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, -				    int min_uV, int max_uV) -{ -	struct da903x_regulator_info *info = rdev_get_drvdata(rdev); -	struct device *da9034_dev = to_da903x_dev(rdev); -	uint8_t val, mask; - -	if (check_range(info, min_uV, max_uV)) { -		pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV); -		return -EINVAL; -	} - -	val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; -	val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); -	val <<= info->vol_shift; -	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift; - -	return da903x_update(da9034_dev, info->vol_reg, val, mask); -} - -static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) -{ -	struct da903x_regulator_info *info = rdev_get_drvdata(rdev); -	struct device *da9034_dev = to_da903x_dev(rdev); -	uint8_t val, mask; -	int ret; - -	ret = da903x_read(da9034_dev, info->vol_reg, &val); -	if (ret) -		return ret; - -	mask = ((1 << info->vol_nbits) - 1)  << info->vol_shift; -	val = (val & mask) >> info->vol_shift; - -	if (val >= 8) -		return 2700000 + info->step_uV * (val - 8); - -	return info->min_uV + info->step_uV * val; -} - -static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, -				     unsigned selector) -{ -	if (selector >= ARRAY_SIZE(da9034_ldo12_data)) -		return -EINVAL; -	return da9034_ldo12_data[selector] * 1000; -} +static const struct regulator_linear_range da9034_ldo12_ranges[] = { +	REGULATOR_LINEAR_RANGE(1700000, 0, 7, 50000), +	REGULATOR_LINEAR_RANGE(2700000, 8, 15, 50000), +};  static struct regulator_ops da903x_regulator_ldo_ops = { -	.set_voltage	= da903x_set_ldo_voltage, -	.get_voltage	= da903x_get_voltage, -	.list_voltage	= da903x_list_voltage, +	.set_voltage_sel = da903x_set_voltage_sel, +	.get_voltage_sel = da903x_get_voltage_sel, +	.list_voltage	= regulator_list_voltage_linear, +	.map_voltage	= regulator_map_voltage_linear,  	.enable		= da903x_enable,  	.disable	= da903x_disable,  	.is_enabled	= da903x_is_enabled, @@ -347,9 +269,10 @@ static struct regulator_ops da903x_regulator_ldo_ops = {  /* NOTE: this is dedicated for the insane DA9030 LDO14 */  static struct regulator_ops da9030_regulator_ldo14_ops = { -	.set_voltage	= da9030_set_ldo14_voltage, -	.get_voltage	= da9030_get_ldo14_voltage, -	.list_voltage	= da903x_list_voltage, +	.set_voltage_sel = da903x_set_voltage_sel, +	.get_voltage_sel = da903x_get_voltage_sel, +	.list_voltage	= da9030_list_ldo14_voltage, +	.map_voltage	= da9030_map_ldo14_voltage,  	.enable		= da903x_enable,  	.disable	= da903x_disable,  	.is_enabled	= da903x_is_enabled, @@ -357,18 +280,20 @@ static struct regulator_ops da9030_regulator_ldo14_ops = {  /* NOTE: this is dedicated for the DA9030 LDO1 and LDO15 that have locks  */  static struct regulator_ops da9030_regulator_ldo1_15_ops = { -	.set_voltage	= da9030_set_ldo1_15_voltage, -	.get_voltage	= da903x_get_voltage, -	.list_voltage	= da903x_list_voltage, +	.set_voltage_sel = da9030_set_ldo1_15_voltage_sel, +	.get_voltage_sel = da903x_get_voltage_sel, +	.list_voltage	= regulator_list_voltage_linear, +	.map_voltage	= regulator_map_voltage_linear,  	.enable		= da903x_enable,  	.disable	= da903x_disable,  	.is_enabled	= da903x_is_enabled,  };  static struct regulator_ops da9034_regulator_dvc_ops = { -	.set_voltage	= da9034_set_dvc_voltage, -	.get_voltage	= da903x_get_voltage, -	.list_voltage	= da903x_list_voltage, +	.set_voltage_sel = da9034_set_dvc_voltage_sel, +	.get_voltage_sel = da903x_get_voltage_sel, +	.list_voltage	= regulator_list_voltage_linear, +	.map_voltage	= regulator_map_voltage_linear,  	.enable		= da903x_enable,  	.disable	= da903x_disable,  	.is_enabled	= da903x_is_enabled, @@ -376,9 +301,10 @@ static struct regulator_ops da9034_regulator_dvc_ops = {  /* NOTE: this is dedicated for the insane LDO12 */  static struct regulator_ops da9034_regulator_ldo12_ops = { -	.set_voltage	= da9034_set_ldo12_voltage, -	.get_voltage	= da9034_get_ldo12_voltage, -	.list_voltage	= da9034_list_ldo12_voltage, +	.set_voltage_sel = da903x_set_voltage_sel, +	.get_voltage_sel = da903x_get_voltage_sel, +	.list_voltage	= regulator_list_voltage_linear_range, +	.map_voltage	= regulator_map_voltage_linear_range,  	.enable		= da903x_enable,  	.disable	= da903x_disable,  	.is_enabled	= da903x_is_enabled, @@ -393,10 +319,10 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {  		.id	= _pmic##_ID_LDO##_id,				\  		.n_voltages = (step) ? ((max - min) / step + 1) : 1,	\  		.owner	= THIS_MODULE,					\ +		.min_uV	 = (min) * 1000,				\ +		.uV_step = (step) * 1000,				\  	},								\ -	.min_uV		= (min) * 1000,					\  	.max_uV		= (max) * 1000,					\ -	.step_uV	= (step) * 1000,				\  	.vol_reg	= _pmic##_##vreg,				\  	.vol_shift	= (shift),					\  	.vol_nbits	= (nbits),					\ @@ -413,10 +339,10 @@ static struct regulator_ops da9034_regulator_ldo12_ops = {  		.id	= _pmic##_ID_##_id,				\  		.n_voltages = (step) ? ((max - min) / step + 1) : 1,	\  		.owner	= THIS_MODULE,					\ +		.min_uV = (min) * 1000,					\ +		.uV_step = (step) * 1000,				\  	},								\ -	.min_uV		= (min) * 1000,					\  	.max_uV		= (max) * 1000,					\ -	.step_uV	= (step) * 1000,				\  	.vol_reg	= _pmic##_##vreg,				\  	.vol_shift	= (0),						\  	.vol_nbits	= (nbits),					\ @@ -505,10 +431,11 @@ static inline struct da903x_regulator_info *find_regulator_info(int id)  	return NULL;  } -static int __devinit da903x_regulator_probe(struct platform_device *pdev) +static int da903x_regulator_probe(struct platform_device *pdev)  {  	struct da903x_regulator_info *ri = NULL;  	struct regulator_dev *rdev; +	struct regulator_config config = { };  	ri = find_regulator_info(pdev->id);  	if (ri == NULL) { @@ -519,7 +446,9 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)  	/* Workaround for the weird LDO12 voltage setting */  	if (ri->desc.id == DA9034_ID_LDO12) {  		ri->desc.ops = &da9034_regulator_ldo12_ops; -		ri->desc.n_voltages = ARRAY_SIZE(da9034_ldo12_data); +		ri->desc.n_voltages = 16; +		ri->desc.linear_ranges = da9034_ldo12_ranges; +		ri->desc.n_linear_ranges = ARRAY_SIZE(da9034_ldo12_ranges);  	}  	if (ri->desc.id == DA9030_ID_LDO14) @@ -528,8 +457,11 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)  	if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)  		ri->desc.ops = &da9030_regulator_ldo1_15_ops; -	rdev = regulator_register(&ri->desc, &pdev->dev, -				  pdev->dev.platform_data, ri); +	config.dev = &pdev->dev; +	config.init_data = dev_get_platdata(&pdev->dev); +	config.driver_data = ri; + +	rdev = devm_regulator_register(&pdev->dev, &ri->desc, &config);  	if (IS_ERR(rdev)) {  		dev_err(&pdev->dev, "failed to register regulator %s\n",  				ri->desc.name); @@ -540,21 +472,12 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)  	return 0;  } -static int __devexit da903x_regulator_remove(struct platform_device *pdev) -{ -	struct regulator_dev *rdev = platform_get_drvdata(pdev); - -	regulator_unregister(rdev); -	return 0; -} -  static struct platform_driver da903x_regulator_driver = {  	.driver	= {  		.name	= "da903x-regulator",  		.owner	= THIS_MODULE,  	},  	.probe		= da903x_regulator_probe, -	.remove		= __devexit_p(da903x_regulator_remove),  };  static int __init da903x_regulator_init(void)  | 
