diff options
Diffstat (limited to 'drivers/regulator/core.c')
| -rw-r--r-- | drivers/regulator/core.c | 42 | 
1 files changed, 40 insertions, 2 deletions
| diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8be080e..cd1b201c91e2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -199,8 +199,11 @@ static int regulator_check_consumers(struct regulator_dev *rdev,  			*min_uV = regulator->min_uV;  	} -	if (*min_uV > *max_uV) +	if (*min_uV > *max_uV) { +		dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n", +			regulator->min_uV, regulator->max_uV);  		return -EINVAL; +	}  	return 0;  } @@ -880,7 +883,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,  		/* final: [min_uV..max_uV] valid iff constraints valid */  		if (max_uV < min_uV) { -			rdev_err(rdev, "unsupportable voltage constraints\n"); +			rdev_err(rdev, +				 "unsupportable voltage constraints %u-%uuV\n", +				 min_uV, max_uV);  			return -EINVAL;  		} @@ -1867,6 +1872,28 @@ int regulator_is_enabled(struct regulator *regulator)  EXPORT_SYMBOL_GPL(regulator_is_enabled);  /** + * regulator_can_change_voltage - check if regulator can change voltage + * @regulator: regulator source + * + * Returns positive if the regulator driver backing the source/client + * can change its voltage, false otherwise. Usefull for detecting fixed + * or dummy regulators and disabling voltage change logic in the client + * driver. + */ +int regulator_can_change_voltage(struct regulator *regulator) +{ +	struct regulator_dev	*rdev = regulator->rdev; + +	if (rdev->constraints && +	    rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE && +	    rdev->desc->n_voltages > 1) +		return 1; + +	return 0; +} +EXPORT_SYMBOL_GPL(regulator_can_change_voltage); + +/**   * regulator_count_voltages - count regulator_list_voltage() selectors   * @regulator: regulator source   * @@ -1897,6 +1924,10 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev,  {  	if (selector >= rdev->desc->n_voltages)  		return -EINVAL; +	if (selector < rdev->desc->linear_min_sel) +		return 0; + +	selector -= rdev->desc->linear_min_sel;  	return rdev->desc->min_uV + (rdev->desc->uV_step * selector);  } @@ -1985,6 +2016,11 @@ int regulator_is_supported_voltage(struct regulator *regulator,  			return ret;  	} +	/* Any voltage within constrains range is fine? */ +	if (rdev->desc->continuous_voltage_range) +		return min_uV >= rdev->constraints->min_uV && +				max_uV <= rdev->constraints->max_uV; +  	ret = regulator_count_voltages(regulator);  	if (ret < 0)  		return ret; @@ -2120,6 +2156,8 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev,  	if (ret < 0)  		return ret; +	ret += rdev->desc->linear_min_sel; +  	/* Map back into a voltage to verify we're still in bounds */  	voltage = rdev->desc->ops->list_voltage(rdev, ret);  	if (voltage < min_uV || voltage > max_uV) | 
