diff options
| -rw-r--r-- | Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt | 37 | ||||
| -rw-r--r-- | drivers/pwm/core.c | 21 | ||||
| -rw-r--r-- | drivers/pwm/pwm-clps711x.c | 2 | ||||
| -rw-r--r-- | drivers/pwm/pwm-pxa.c | 2 | ||||
| -rw-r--r-- | drivers/regulator/pwm-regulator.c | 78 | ||||
| -rw-r--r-- | drivers/regulator/qcom_spmi-regulator.c | 275 | ||||
| -rw-r--r-- | drivers/regulator/rk808-regulator.c | 310 | ||||
| -rw-r--r-- | drivers/regulator/s2mps11.c | 13 | ||||
| -rw-r--r-- | include/linux/mfd/samsung/core.h | 3 | ||||
| -rw-r--r-- | include/linux/pwm.h | 33 | 
10 files changed, 444 insertions, 330 deletions
diff --git a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt index d00bfd8624a5..46c6f3ed1a1c 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt @@ -7,6 +7,7 @@ Qualcomm SPMI Regulators  			"qcom,pm8841-regulators"  			"qcom,pm8916-regulators"  			"qcom,pm8941-regulators" +			"qcom,pm8994-regulators"  - interrupts:  	Usage: optional @@ -68,6 +69,37 @@ Qualcomm SPMI Regulators  	Definition: Reference to regulator supplying the input pin, as  		    described in the data sheet. +- vdd_s1-supply: +- vdd_s2-supply: +- vdd_s3-supply: +- vdd_s4-supply: +- vdd_s5-supply: +- vdd_s6-supply: +- vdd_s7-supply: +- vdd_s8-supply: +- vdd_s9-supply: +- vdd_s10-supply: +- vdd_s11-supply: +- vdd_s12-supply: +- vdd_l1-supply: +- vdd_l2_l26_l28-supply: +- vdd_l3_l11-supply: +- vdd_l4_l27_l31-supply: +- vdd_l5_l7-supply: +- vdd_l6_l12_l32-supply: +- vdd_l8_l16_l30-supply: +- vdd_l9_l10_l18_l22-supply: +- vdd_l13_l19_l23_l24-supply: +- vdd_l14_l15-supply: +- vdd_l17_l29-supply: +- vdd_l20_l21-supply: +- vdd_l25-supply: +- vdd_lvs_1_2-supply: +	Usage: optional (pm8994 only) +	Value type: <phandle> +	Definition: Reference to regulator supplying the input pin, as +		    described in the data sheet. +  The regulator node houses sub-nodes for each regulator within the device. Each  sub-node is identified using the node's name, with valid values listed for each @@ -85,6 +117,11 @@ pm8941:  	l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,  	mvs1, mvs2 +pm8994: +	s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, +	l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, +	l21, l22, l23, l24, l25, l26, l27, l28, l29, l30, l31, l32, lvs1, lvs2 +  The content of each sub-node is defined by the standard binding for regulators -  see regulator.txt - with additional custom properties described below: diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 7831bc6b51dd..680fbc795a0a 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -128,6 +128,13 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)  	set_bit(PWMF_REQUESTED, &pwm->flags);  	pwm->label = label; +	/* +	 * FIXME: This should be removed once all PWM users properly make use +	 * of struct pwm_args to initialize the PWM device. As long as this is +	 * here, the PWM state and hardware state can get out of sync. +	 */ +	pwm_apply_args(pwm); +  	return 0;  } @@ -146,12 +153,12 @@ of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args)  	if (IS_ERR(pwm))  		return pwm; -	pwm_set_period(pwm, args->args[1]); +	pwm->args.period = args->args[1];  	if (args->args[2] & PWM_POLARITY_INVERTED) -		pwm_set_polarity(pwm, PWM_POLARITY_INVERSED); +		pwm->args.polarity = PWM_POLARITY_INVERSED;  	else -		pwm_set_polarity(pwm, PWM_POLARITY_NORMAL); +		pwm->args.polarity = PWM_POLARITY_NORMAL;  	return pwm;  } @@ -172,7 +179,7 @@ of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)  	if (IS_ERR(pwm))  		return pwm; -	pwm_set_period(pwm, args->args[1]); +	pwm->args.period = args->args[1];  	return pwm;  } @@ -747,13 +754,13 @@ struct pwm_device *pwm_get(struct device *dev, const char *con_id)  	if (!chip)  		goto out; +	pwm->args.period = chosen->period; +	pwm->args.polarity = chosen->polarity; +  	pwm = pwm_request_from_chip(chip, chosen->index, con_id ?: dev_id);  	if (IS_ERR(pwm))  		goto out; -	pwm_set_period(pwm, chosen->period); -	pwm_set_polarity(pwm, chosen->polarity); -  out:  	mutex_unlock(&pwm_lookup_lock);  	return pwm; diff --git a/drivers/pwm/pwm-clps711x.c b/drivers/pwm/pwm-clps711x.c index a80c10803636..7d335422cfda 100644 --- a/drivers/pwm/pwm-clps711x.c +++ b/drivers/pwm/pwm-clps711x.c @@ -60,7 +60,7 @@ static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)  		return -EINVAL;  	/* Store constant period value */ -	pwm_set_period(pwm, DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq)); +	pwm->args.period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq);  	return 0;  } diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c index cb2f7024cf68..58b709f29130 100644 --- a/drivers/pwm/pwm-pxa.c +++ b/drivers/pwm/pwm-pxa.c @@ -160,7 +160,7 @@ pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)  	if (IS_ERR(pwm))  		return pwm; -	pwm_set_period(pwm, args->args[0]); +	pwm->args.period = args->args[0];  	return pwm;  } diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 4689d62f4841..fafa3488e960 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -59,18 +59,18 @@ static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,  					 unsigned selector)  {  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); -	unsigned int pwm_reg_period; +	struct pwm_args pargs;  	int dutycycle;  	int ret; -	pwm_reg_period = pwm_get_period(drvdata->pwm); +	pwm_get_args(drvdata->pwm, &pargs); -	dutycycle = (pwm_reg_period * +	dutycycle = (pargs.period *  		    drvdata->duty_cycle_table[selector].dutycycle) / 100; -	ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period); +	ret = pwm_config(drvdata->pwm, dutycycle, pargs.period);  	if (ret) { -		dev_err(&rdev->dev, "Failed to configure PWM\n"); +		dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);  		return ret;  	} @@ -113,18 +113,6 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev)  	return pwm_is_enabled(drvdata->pwm);  } -/** - * Continuous voltage call-backs - */ -static int pwm_voltage_to_duty_cycle_percentage(struct regulator_dev *rdev, int req_uV) -{ -	int min_uV = rdev->constraints->min_uV; -	int max_uV = rdev->constraints->max_uV; -	int diff = max_uV - min_uV; - -	return ((req_uV * 100) - (min_uV * 100)) / diff; -} -  static int pwm_regulator_get_voltage(struct regulator_dev *rdev)  {  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); @@ -138,21 +126,42 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev,  {  	struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);  	unsigned int ramp_delay = rdev->constraints->ramp_delay; -	unsigned int period = pwm_get_period(drvdata->pwm); -	int duty_cycle; +	struct pwm_args pargs; +	unsigned int req_diff = min_uV - rdev->constraints->min_uV; +	unsigned int diff; +	unsigned int duty_pulse; +	u64 req_period; +	u32 rem;  	int ret; -	duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV); +	pwm_get_args(drvdata->pwm, &pargs); +	diff = rdev->constraints->max_uV - rdev->constraints->min_uV; + +	/* First try to find out if we get the iduty cycle time which is +	 * factor of PWM period time. If (request_diff_to_min * pwm_period) +	 * is perfect divided by voltage_range_diff then it is possible to +	 * get duty cycle time which is factor of PWM period. This will help +	 * to get output voltage nearer to requested value as there is no +	 * calculation loss. +	 */ +	req_period = req_diff * pargs.period; +	div_u64_rem(req_period, diff, &rem); +	if (!rem) { +		do_div(req_period, diff); +		duty_pulse = (unsigned int)req_period; +	} else { +		duty_pulse = (pargs.period / 100) * ((req_diff * 100) / diff); +	} -	ret = pwm_config(drvdata->pwm, (period / 100) * duty_cycle, period); +	ret = pwm_config(drvdata->pwm, duty_pulse, pargs.period);  	if (ret) { -		dev_err(&rdev->dev, "Failed to configure PWM\n"); +		dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);  		return ret;  	}  	ret = pwm_enable(drvdata->pwm);  	if (ret) { -		dev_err(&rdev->dev, "Failed to enable PWM\n"); +		dev_err(&rdev->dev, "Failed to enable PWM: %d\n", ret);  		return ret;  	}  	drvdata->volt_uV = min_uV; @@ -200,8 +209,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev,  	if ((length < sizeof(*duty_cycle_table)) ||  	    (length % sizeof(*duty_cycle_table))) { -		dev_err(&pdev->dev, -			"voltage-table length(%d) is invalid\n", +		dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",  			length);  		return -EINVAL;  	} @@ -214,7 +222,7 @@ static int pwm_regulator_init_table(struct platform_device *pdev,  					 (u32 *)duty_cycle_table,  					 length / sizeof(u32));  	if (ret) { -		dev_err(&pdev->dev, "Failed to read voltage-table\n"); +		dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret);  		return ret;  	} @@ -277,16 +285,24 @@ static int pwm_regulator_probe(struct platform_device *pdev)  	drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);  	if (IS_ERR(drvdata->pwm)) { -		dev_err(&pdev->dev, "Failed to get PWM\n"); -		return PTR_ERR(drvdata->pwm); +		ret = PTR_ERR(drvdata->pwm); +		dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret); +		return ret;  	} +	/* +	 * FIXME: pwm_apply_args() should be removed when switching to the +	 * atomic PWM API. +	 */ +	pwm_apply_args(drvdata->pwm); +  	regulator = devm_regulator_register(&pdev->dev,  					    &drvdata->desc, &config);  	if (IS_ERR(regulator)) { -		dev_err(&pdev->dev, "Failed to register regulator %s\n", -			drvdata->desc.name); -		return PTR_ERR(regulator); +		ret = PTR_ERR(regulator); +		dev_err(&pdev->dev, "Failed to register regulator %s: %d\n", +			drvdata->desc.name, ret); +		return ret;  	}  	return 0; diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 88a5dc88badc..84cce21e98cd 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -246,6 +246,7 @@ enum spmi_common_control_register_index {  /* Minimum voltage stepper delay for each step. */  #define SPMI_FTSMPS_STEP_DELAY		8 +#define SPMI_DEFAULT_STEP_DELAY		20  /*   * The ratio SPMI_FTSMPS_STEP_MARGIN_NUM/SPMI_FTSMPS_STEP_MARGIN_DEN is used to @@ -254,13 +255,6 @@ enum spmi_common_control_register_index {  #define SPMI_FTSMPS_STEP_MARGIN_NUM	4  #define SPMI_FTSMPS_STEP_MARGIN_DEN	5 -/* - * This voltage in uV is returned by get_voltage functions when there is no way - * to determine the current voltage level.  It is needed because the regulator - * framework treats a 0 uV voltage as an error. - */ -#define VOLTAGE_UNKNOWN 1 -  /* VSET value to decide the range of ULT SMPS */  #define ULT_SMPS_RANGE_SPLIT 0x60 @@ -539,12 +533,12 @@ static int spmi_regulator_common_disable(struct regulator_dev *rdev)  }  static int spmi_regulator_select_voltage(struct spmi_regulator *vreg, -		int min_uV, int max_uV, u8 *range_sel, u8 *voltage_sel, -		unsigned *selector) +					 int min_uV, int max_uV)  {  	const struct spmi_voltage_range *range;  	int uV = min_uV;  	int lim_min_uV, lim_max_uV, i, range_id, range_max_uV; +	int selector, voltage_sel;  	/* Check if request voltage is outside of physically settable range. */  	lim_min_uV = vreg->set_points->range[0].set_point_min_uV; @@ -570,14 +564,13 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,  	range_id = i;  	range = &vreg->set_points->range[range_id]; -	*range_sel = range->range_sel;  	/*  	 * Force uV to be an allowed set point by applying a ceiling function to  	 * the uV value.  	 */ -	*voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV); -	uV = *voltage_sel * range->step_uV + range->min_uV; +	voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV); +	uV = voltage_sel * range->step_uV + range->min_uV;  	if (uV > max_uV) {  		dev_err(vreg->dev, @@ -587,12 +580,48 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,  		return -EINVAL;  	} -	*selector = 0; +	selector = 0;  	for (i = 0; i < range_id; i++) -		*selector += vreg->set_points->range[i].n_voltages; -	*selector += (uV - range->set_point_min_uV) / range->step_uV; +		selector += vreg->set_points->range[i].n_voltages; +	selector += (uV - range->set_point_min_uV) / range->step_uV; -	return 0; +	return selector; +} + +static int spmi_sw_selector_to_hw(struct spmi_regulator *vreg, +				  unsigned selector, u8 *range_sel, +				  u8 *voltage_sel) +{ +	const struct spmi_voltage_range *range, *end; + +	range = vreg->set_points->range; +	end = range + vreg->set_points->count; + +	for (; range < end; range++) { +		if (selector < range->n_voltages) { +			*voltage_sel = selector; +			*range_sel = range->range_sel; +			return 0; +		} + +		selector -= range->n_voltages; +	} + +	return -EINVAL; +} + +static int spmi_hw_selector_to_sw(struct spmi_regulator *vreg, u8 hw_sel, +				  const struct spmi_voltage_range *range) +{ +	int sw_sel = hw_sel; +	const struct spmi_voltage_range *r = vreg->set_points->range; + +	while (r != range) { +		sw_sel += r->n_voltages; +		r++; +	} + +	return sw_sel;  }  static const struct spmi_voltage_range * @@ -614,12 +643,11 @@ spmi_regulator_find_range(struct spmi_regulator *vreg)  }  static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg, -		int min_uV, int max_uV, u8 *range_sel, u8 *voltage_sel, -		unsigned *selector) +		int min_uV, int max_uV)  {  	const struct spmi_voltage_range *range;  	int uV = min_uV; -	int i; +	int i, selector;  	range = spmi_regulator_find_range(vreg);  	if (!range) @@ -637,8 +665,8 @@ static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,  	 * Force uV to be an allowed set point by applying a ceiling function to  	 * the uV value.  	 */ -	*voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV); -	uV = *voltage_sel * range->step_uV + range->min_uV; +	uV = DIV_ROUND_UP(uV - range->min_uV, range->step_uV); +	uV = uV * range->step_uV + range->min_uV;  	if (uV > max_uV) {  		/* @@ -648,43 +676,49 @@ static int spmi_regulator_select_voltage_same_range(struct spmi_regulator *vreg,  		goto different_range;  	} -	*selector = 0; +	selector = 0;  	for (i = 0; i < vreg->set_points->count; i++) {  		if (uV >= vreg->set_points->range[i].set_point_min_uV  		    && uV <= vreg->set_points->range[i].set_point_max_uV) { -			*selector += +			selector +=  			    (uV - vreg->set_points->range[i].set_point_min_uV)  				/ vreg->set_points->range[i].step_uV;  			break;  		} -		*selector += vreg->set_points->range[i].n_voltages; +		selector += vreg->set_points->range[i].n_voltages;  	} -	if (*selector >= vreg->set_points->n_voltages) +	if (selector >= vreg->set_points->n_voltages)  		goto different_range; -	return 0; +	return selector;  different_range: -	return spmi_regulator_select_voltage(vreg, min_uV, max_uV, -			range_sel, voltage_sel, selector); +	return spmi_regulator_select_voltage(vreg, min_uV, max_uV);  } -static int spmi_regulator_common_set_voltage(struct regulator_dev *rdev, -		int min_uV, int max_uV, unsigned *selector) +static int spmi_regulator_common_map_voltage(struct regulator_dev *rdev, +					     int min_uV, int max_uV)  {  	struct spmi_regulator *vreg = rdev_get_drvdata(rdev); -	int ret; -	u8 buf[2]; -	u8 range_sel, voltage_sel;  	/*  	 * Favor staying in the current voltage range if possible.  This avoids  	 * voltage spikes that occur when changing the voltage range.  	 */ -	ret = spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV, -		&range_sel, &voltage_sel, selector); +	return spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV); +} + +static int +spmi_regulator_common_set_voltage(struct regulator_dev *rdev, unsigned selector) +{ +	struct spmi_regulator *vreg = rdev_get_drvdata(rdev); +	int ret; +	u8 buf[2]; +	u8 range_sel, voltage_sel; + +	ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);  	if (ret)  		return ret; @@ -719,24 +753,24 @@ static int spmi_regulator_common_get_voltage(struct regulator_dev *rdev)  	range = spmi_regulator_find_range(vreg);  	if (!range) -		return VOLTAGE_UNKNOWN; +		return -EINVAL; -	return range->step_uV * voltage_sel + range->min_uV; +	return spmi_hw_selector_to_sw(vreg, voltage_sel, range);  } -static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev, -		int min_uV, int max_uV, unsigned *selector) +static int spmi_regulator_single_map_voltage(struct regulator_dev *rdev, +		int min_uV, int max_uV)  {  	struct spmi_regulator *vreg = rdev_get_drvdata(rdev); -	int ret; -	u8 range_sel, sel; -	ret = spmi_regulator_select_voltage(vreg, min_uV, max_uV, &range_sel, -		&sel, selector); -	if (ret) { -		dev_err(vreg->dev, "could not set voltage, ret=%d\n", ret); -		return ret; -	} +	return spmi_regulator_select_voltage(vreg, min_uV, max_uV); +} + +static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev, +						   unsigned selector) +{ +	struct spmi_regulator *vreg = rdev_get_drvdata(rdev); +	u8 sel = selector;  	/*  	 * Certain types of regulators do not have a range select register so @@ -748,27 +782,24 @@ static int spmi_regulator_single_range_set_voltage(struct regulator_dev *rdev,  static int spmi_regulator_single_range_get_voltage(struct regulator_dev *rdev)  {  	struct spmi_regulator *vreg = rdev_get_drvdata(rdev); -	const struct spmi_voltage_range *range = vreg->set_points->range; -	u8 voltage_sel; +	u8 selector; +	int ret; -	spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_SET, &voltage_sel, 1); +	ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_VOLTAGE_SET, &selector, 1); +	if (ret) +		return ret; -	return range->step_uV * voltage_sel + range->min_uV; +	return selector;  }  static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev, -		int min_uV, int max_uV, unsigned *selector) +						  unsigned selector)  {  	struct spmi_regulator *vreg = rdev_get_drvdata(rdev);  	int ret;  	u8 range_sel, voltage_sel; -	/* -	 * Favor staying in the current voltage range if possible. This avoids -	 * voltage spikes that occur when changing the voltage range. -	 */ -	ret = spmi_regulator_select_voltage_same_range(vreg, min_uV, max_uV, -		&range_sel, &voltage_sel, selector); +	ret = spmi_sw_selector_to_hw(vreg, selector, &range_sel, &voltage_sel);  	if (ret)  		return ret; @@ -783,7 +814,7 @@ static int spmi_regulator_ult_lo_smps_set_voltage(struct regulator_dev *rdev,  		voltage_sel |= ULT_SMPS_RANGE_SPLIT;  	return spmi_vreg_update_bits(vreg, SPMI_COMMON_REG_VOLTAGE_SET, -	       voltage_sel, 0xff); +				     voltage_sel, 0xff);  }  static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev) @@ -796,12 +827,12 @@ static int spmi_regulator_ult_lo_smps_get_voltage(struct regulator_dev *rdev)  	range = spmi_regulator_find_range(vreg);  	if (!range) -		return VOLTAGE_UNKNOWN; +		return -EINVAL;  	if (range->range_sel == 1)  		voltage_sel &= ~ULT_SMPS_RANGE_SPLIT; -	return range->step_uV * voltage_sel + range->min_uV; +	return spmi_hw_selector_to_sw(vreg, voltage_sel, range);  }  static int spmi_regulator_common_list_voltage(struct regulator_dev *rdev, @@ -1007,8 +1038,10 @@ static struct regulator_ops spmi_smps_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_common_set_voltage, -	.get_voltage		= spmi_regulator_common_get_voltage, +	.set_voltage_sel	= spmi_regulator_common_set_voltage, +	.set_voltage_time_sel	= spmi_regulator_set_voltage_time_sel, +	.get_voltage_sel	= spmi_regulator_common_get_voltage, +	.map_voltage		= spmi_regulator_common_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_mode		= spmi_regulator_common_set_mode,  	.get_mode		= spmi_regulator_common_get_mode, @@ -1020,8 +1053,9 @@ static struct regulator_ops spmi_ldo_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_common_set_voltage, -	.get_voltage		= spmi_regulator_common_get_voltage, +	.set_voltage_sel	= spmi_regulator_common_set_voltage, +	.get_voltage_sel	= spmi_regulator_common_get_voltage, +	.map_voltage		= spmi_regulator_common_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_mode		= spmi_regulator_common_set_mode,  	.get_mode		= spmi_regulator_common_get_mode, @@ -1036,8 +1070,9 @@ static struct regulator_ops spmi_ln_ldo_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_common_set_voltage, -	.get_voltage		= spmi_regulator_common_get_voltage, +	.set_voltage_sel	= spmi_regulator_common_set_voltage, +	.get_voltage_sel	= spmi_regulator_common_get_voltage, +	.map_voltage		= spmi_regulator_common_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_bypass		= spmi_regulator_common_set_bypass,  	.get_bypass		= spmi_regulator_common_get_bypass, @@ -1056,8 +1091,9 @@ static struct regulator_ops spmi_boost_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_single_range_set_voltage, -	.get_voltage		= spmi_regulator_single_range_get_voltage, +	.set_voltage_sel	= spmi_regulator_single_range_set_voltage, +	.get_voltage_sel	= spmi_regulator_single_range_get_voltage, +	.map_voltage		= spmi_regulator_single_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_input_current_limit = spmi_regulator_set_ilim,  }; @@ -1066,9 +1102,10 @@ static struct regulator_ops spmi_ftsmps_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_common_set_voltage, +	.set_voltage_sel	= spmi_regulator_common_set_voltage,  	.set_voltage_time_sel	= spmi_regulator_set_voltage_time_sel, -	.get_voltage		= spmi_regulator_common_get_voltage, +	.get_voltage_sel	= spmi_regulator_common_get_voltage, +	.map_voltage		= spmi_regulator_common_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_mode		= spmi_regulator_common_set_mode,  	.get_mode		= spmi_regulator_common_get_mode, @@ -1080,8 +1117,9 @@ static struct regulator_ops spmi_ult_lo_smps_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_ult_lo_smps_set_voltage, -	.get_voltage		= spmi_regulator_ult_lo_smps_get_voltage, +	.set_voltage_sel	= spmi_regulator_ult_lo_smps_set_voltage, +	.set_voltage_time_sel	= spmi_regulator_set_voltage_time_sel, +	.get_voltage_sel	= spmi_regulator_ult_lo_smps_get_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_mode		= spmi_regulator_common_set_mode,  	.get_mode		= spmi_regulator_common_get_mode, @@ -1093,8 +1131,10 @@ static struct regulator_ops spmi_ult_ho_smps_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_single_range_set_voltage, -	.get_voltage		= spmi_regulator_single_range_get_voltage, +	.set_voltage_sel	= spmi_regulator_single_range_set_voltage, +	.set_voltage_time_sel	= spmi_regulator_set_voltage_time_sel, +	.get_voltage_sel	= spmi_regulator_single_range_get_voltage, +	.map_voltage		= spmi_regulator_single_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_mode		= spmi_regulator_common_set_mode,  	.get_mode		= spmi_regulator_common_get_mode, @@ -1106,8 +1146,9 @@ static struct regulator_ops spmi_ult_ldo_ops = {  	.enable			= spmi_regulator_common_enable,  	.disable		= spmi_regulator_common_disable,  	.is_enabled		= spmi_regulator_common_is_enabled, -	.set_voltage		= spmi_regulator_single_range_set_voltage, -	.get_voltage		= spmi_regulator_single_range_get_voltage, +	.set_voltage_sel	= spmi_regulator_single_range_set_voltage, +	.get_voltage_sel	= spmi_regulator_single_range_get_voltage, +	.map_voltage		= spmi_regulator_single_map_voltage,  	.list_voltage		= spmi_regulator_common_list_voltage,  	.set_mode		= spmi_regulator_common_set_mode,  	.get_mode		= spmi_regulator_common_get_mode, @@ -1201,7 +1242,7 @@ static int spmi_regulator_match(struct spmi_regulator *vreg, u16 force_type)  	ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_DIG_MAJOR_REV, version,  		ARRAY_SIZE(version));  	if (ret) { -		dev_err(vreg->dev, "could not read version registers\n"); +		dev_dbg(vreg->dev, "could not read version registers\n");  		return ret;  	}  	dig_major_rev	= version[SPMI_COMMON_REG_DIG_MAJOR_REV @@ -1245,11 +1286,11 @@ found:  	return 0;  } -static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg) +static int spmi_regulator_init_slew_rate(struct spmi_regulator *vreg)  {  	int ret;  	u8 reg = 0; -	int step, delay, slew_rate; +	int step, delay, slew_rate, step_delay;  	const struct spmi_voltage_range *range;  	ret = spmi_vreg_read(vreg, SPMI_COMMON_REG_STEP_CTRL, ®, 1); @@ -1262,6 +1303,15 @@ static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)  	if (!range)  		return -EINVAL; +	switch (vreg->logical_type) { +	case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS: +		step_delay = SPMI_FTSMPS_STEP_DELAY; +		break; +	default: +		step_delay = SPMI_DEFAULT_STEP_DELAY; +		break; +	} +  	step = reg & SPMI_FTSMPS_STEP_CTRL_STEP_MASK;  	step >>= SPMI_FTSMPS_STEP_CTRL_STEP_SHIFT; @@ -1270,7 +1320,7 @@ static int spmi_regulator_ftsmps_init_slew_rate(struct spmi_regulator *vreg)  	/* slew_rate has units of uV/us */  	slew_rate = SPMI_FTSMPS_CLOCK_RATE * range->step_uV * (1 << step); -	slew_rate /= 1000 * (SPMI_FTSMPS_STEP_DELAY << delay); +	slew_rate /= 1000 * (step_delay << delay);  	slew_rate *= SPMI_FTSMPS_STEP_MARGIN_NUM;  	slew_rate /= SPMI_FTSMPS_STEP_MARGIN_DEN; @@ -1411,10 +1461,16 @@ static int spmi_regulator_of_parse(struct device_node *node,  		return ret;  	} -	if (vreg->logical_type == SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS) { -		ret = spmi_regulator_ftsmps_init_slew_rate(vreg); +	switch (vreg->logical_type) { +	case SPMI_REGULATOR_LOGICAL_TYPE_FTSMPS: +	case SPMI_REGULATOR_LOGICAL_TYPE_ULT_LO_SMPS: +	case SPMI_REGULATOR_LOGICAL_TYPE_ULT_HO_SMPS: +	case SPMI_REGULATOR_LOGICAL_TYPE_SMPS: +		ret = spmi_regulator_init_slew_rate(vreg);  		if (ret)  			return ret; +	default: +		break;  	}  	if (vreg->logical_type != SPMI_REGULATOR_LOGICAL_TYPE_VS) @@ -1510,10 +1566,61 @@ static const struct spmi_regulator_data pm8916_regulators[] = {  	{ }  }; +static const struct spmi_regulator_data pm8994_regulators[] = { +	{ "s1", 0x1400, "vdd_s1", }, +	{ "s2", 0x1700, "vdd_s2", }, +	{ "s3", 0x1a00, "vdd_s3", }, +	{ "s4", 0x1d00, "vdd_s4", }, +	{ "s5", 0x2000, "vdd_s5", }, +	{ "s6", 0x2300, "vdd_s6", }, +	{ "s7", 0x2600, "vdd_s7", }, +	{ "s8", 0x2900, "vdd_s8", }, +	{ "s9", 0x2c00, "vdd_s9", }, +	{ "s10", 0x2f00, "vdd_s10", }, +	{ "s11", 0x3200, "vdd_s11", }, +	{ "s12", 0x3500, "vdd_s12", }, +	{ "l1", 0x4000, "vdd_l1", }, +	{ "l2", 0x4100, "vdd_l2_l26_l28", }, +	{ "l3", 0x4200, "vdd_l3_l11", }, +	{ "l4", 0x4300, "vdd_l4_l27_l31", }, +	{ "l5", 0x4400, "vdd_l5_l7", }, +	{ "l6", 0x4500, "vdd_l6_l12_l32", }, +	{ "l7", 0x4600, "vdd_l5_l7", }, +	{ "l8", 0x4700, "vdd_l8_l16_l30", }, +	{ "l9", 0x4800, "vdd_l9_l10_l18_l22", }, +	{ "l10", 0x4900, "vdd_l9_l10_l18_l22", }, +	{ "l11", 0x4a00, "vdd_l3_l11", }, +	{ "l12", 0x4b00, "vdd_l6_l12_l32", }, +	{ "l13", 0x4c00, "vdd_l13_l19_l23_l24", }, +	{ "l14", 0x4d00, "vdd_l14_l15", }, +	{ "l15", 0x4e00, "vdd_l14_l15", }, +	{ "l16", 0x4f00, "vdd_l8_l16_l30", }, +	{ "l17", 0x5000, "vdd_l17_l29", }, +	{ "l18", 0x5100, "vdd_l9_l10_l18_l22", }, +	{ "l19", 0x5200, "vdd_l13_l19_l23_l24", }, +	{ "l20", 0x5300, "vdd_l20_l21", }, +	{ "l21", 0x5400, "vdd_l20_l21", }, +	{ "l22", 0x5500, "vdd_l9_l10_l18_l22", }, +	{ "l23", 0x5600, "vdd_l13_l19_l23_l24", }, +	{ "l24", 0x5700, "vdd_l13_l19_l23_l24", }, +	{ "l25", 0x5800, "vdd_l25", }, +	{ "l26", 0x5900, "vdd_l2_l26_l28", }, +	{ "l27", 0x5a00, "vdd_l4_l27_l31", }, +	{ "l28", 0x5b00, "vdd_l2_l26_l28", }, +	{ "l29", 0x5c00, "vdd_l17_l29", }, +	{ "l30", 0x5d00, "vdd_l8_l16_l30", }, +	{ "l31", 0x5e00, "vdd_l4_l27_l31", }, +	{ "l32", 0x5f00, "vdd_l6_l12_l32", }, +	{ "lvs1", 0x8000, "vdd_lvs_1_2", }, +	{ "lvs2", 0x8100, "vdd_lvs_1_2", }, +	{ } +}; +  static const struct of_device_id qcom_spmi_regulator_match[] = {  	{ .compatible = "qcom,pm8841-regulators", .data = &pm8841_regulators },  	{ .compatible = "qcom,pm8916-regulators", .data = &pm8916_regulators },  	{ .compatible = "qcom,pm8941-regulators", .data = &pm8941_regulators }, +	{ .compatible = "qcom,pm8994-regulators", .data = &pm8994_regulators },  	{ }  };  MODULE_DEVICE_TABLE(of, qcom_spmi_regulator_match); @@ -1573,7 +1680,7 @@ static int qcom_spmi_regulator_probe(struct platform_device *pdev)  		ret = spmi_regulator_match(vreg, reg->force_type);  		if (ret) -			goto err; +			continue;  		config.dev = dev;  		config.driver_data = vreg; diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index d86a3dcd61e2..40d07ba036e7 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -55,6 +55,42 @@  /* max steps for increase voltage of Buck1/2, equal 100mv*/  #define MAX_STEPS_ONE_TIME 8 +#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg,	\ +	_vmask, _ereg, _emask, _etime)					\ +	[_id] = {							\ +		.name		= (_match),				\ +		.supply_name	= (_supply),				\ +		.of_match	= of_match_ptr(_match),			\ +		.regulators_node = of_match_ptr("regulators"),		\ +		.type		= REGULATOR_VOLTAGE,			\ +		.id		= (_id),				\ +		.n_voltages	= (((_max) - (_min)) / (_step) + 1),	\ +		.owner		= THIS_MODULE,				\ +		.min_uV		= (_min) * 1000,			\ +		.uV_step	= (_step) * 1000,			\ +		.vsel_reg	= (_vreg),				\ +		.vsel_mask	= (_vmask),				\ +		.enable_reg	= (_ereg),				\ +		.enable_mask	= (_emask),				\ +		.enable_time	= (_etime),				\ +		.ops		= &rk808_reg_ops,			\ +	} + +#define RK8XX_DESC_SWITCH(_id, _match, _supply, _ereg, _emask)		\ +	[_id] = {							\ +		.name		= (_match),				\ +		.supply_name	= (_supply),				\ +		.of_match	= of_match_ptr(_match),			\ +		.regulators_node = of_match_ptr("regulators"),		\ +		.type		= REGULATOR_VOLTAGE,			\ +		.id		= (_id),				\ +		.enable_reg	= (_ereg),				\ +		.enable_mask	= (_emask),				\ +		.owner		= THIS_MODULE,				\ +		.ops		= &rk808_switch_ops			\ +	} + +  struct rk808_regulator_data {  	struct gpio_desc *dvs_gpio[2];  }; @@ -66,27 +102,11 @@ static const int rk808_buck_config_regs[] = {  	RK808_BUCK4_CONFIG_REG,  }; -static const struct regulator_linear_range rk808_buck_voltage_ranges[] = { -	REGULATOR_LINEAR_RANGE(712500, 0, 63, 12500), -}; - -static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = { -	REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000), -}; - -static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = { -	REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000), -}; -  static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {  	REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),  	REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),  }; -static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = { -	REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000), -}; -  static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)  {  	struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev); @@ -242,6 +262,21 @@ static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)  static int rk808_set_suspend_voltage(struct regulator_dev *rdev, int uv)  {  	unsigned int reg; +	int sel = regulator_map_voltage_linear(rdev, uv, uv); + +	if (sel < 0) +		return -EINVAL; + +	reg = rdev->desc->vsel_reg + RK808_SLP_REG_OFFSET; + +	return regmap_update_bits(rdev->regmap, reg, +				  rdev->desc->vsel_mask, +				  sel); +} + +static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv) +{ +	unsigned int reg;  	int sel = regulator_map_voltage_linear_range(rdev, uv, uv);  	if (sel < 0) @@ -277,8 +312,8 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)  }  static struct regulator_ops rk808_buck1_2_ops = { -	.list_voltage		= regulator_list_voltage_linear_range, -	.map_voltage		= regulator_map_voltage_linear_range, +	.list_voltage		= regulator_list_voltage_linear, +	.map_voltage		= regulator_map_voltage_linear,  	.get_voltage_sel	= rk808_buck1_2_get_voltage_sel_regmap,  	.set_voltage_sel	= rk808_buck1_2_set_voltage_sel,  	.set_voltage_time_sel	= rk808_buck1_2_set_voltage_time_sel, @@ -292,6 +327,19 @@ static struct regulator_ops rk808_buck1_2_ops = {  };  static struct regulator_ops rk808_reg_ops = { +	.list_voltage		= regulator_list_voltage_linear, +	.map_voltage		= regulator_map_voltage_linear, +	.get_voltage_sel	= regulator_get_voltage_sel_regmap, +	.set_voltage_sel	= regulator_set_voltage_sel_regmap, +	.enable			= regulator_enable_regmap, +	.disable		= regulator_disable_regmap, +	.is_enabled		= regulator_is_enabled_regmap, +	.set_suspend_voltage	= rk808_set_suspend_voltage, +	.set_suspend_enable	= rk808_set_suspend_enable, +	.set_suspend_disable	= rk808_set_suspend_disable, +}; + +static struct regulator_ops rk808_reg_ops_ranges = {  	.list_voltage		= regulator_list_voltage_linear_range,  	.map_voltage		= regulator_map_voltage_linear_range,  	.get_voltage_sel	= regulator_get_voltage_sel_regmap, @@ -299,7 +347,7 @@ static struct regulator_ops rk808_reg_ops = {  	.enable			= regulator_enable_regmap,  	.disable		= regulator_disable_regmap,  	.is_enabled		= regulator_is_enabled_regmap, -	.set_suspend_voltage	= rk808_set_suspend_voltage, +	.set_suspend_voltage	= rk808_set_suspend_voltage_range,  	.set_suspend_enable	= rk808_set_suspend_enable,  	.set_suspend_disable	= rk808_set_suspend_disable,  }; @@ -316,12 +364,14 @@ static const struct regulator_desc rk808_reg[] = {  	{  		.name = "DCDC_REG1",  		.supply_name = "vcc1", +		.of_match = of_match_ptr("DCDC_REG1"), +		.regulators_node = of_match_ptr("regulators"),  		.id = RK808_ID_DCDC1,  		.ops = &rk808_buck1_2_ops,  		.type = REGULATOR_VOLTAGE, +		.min_uV = 712500, +		.uV_step = 12500,  		.n_voltages = 64, -		.linear_ranges = rk808_buck_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),  		.vsel_reg = RK808_BUCK1_ON_VSEL_REG,  		.vsel_mask = RK808_BUCK_VSEL_MASK,  		.enable_reg = RK808_DCDC_EN_REG, @@ -330,12 +380,14 @@ static const struct regulator_desc rk808_reg[] = {  	}, {  		.name = "DCDC_REG2",  		.supply_name = "vcc2", +		.of_match = of_match_ptr("DCDC_REG2"), +		.regulators_node = of_match_ptr("regulators"),  		.id = RK808_ID_DCDC2,  		.ops = &rk808_buck1_2_ops,  		.type = REGULATOR_VOLTAGE, +		.min_uV = 712500, +		.uV_step = 12500,  		.n_voltages = 64, -		.linear_ranges = rk808_buck_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),  		.vsel_reg = RK808_BUCK2_ON_VSEL_REG,  		.vsel_mask = RK808_BUCK_VSEL_MASK,  		.enable_reg = RK808_DCDC_EN_REG, @@ -344,6 +396,8 @@ static const struct regulator_desc rk808_reg[] = {  	}, {  		.name = "DCDC_REG3",  		.supply_name = "vcc3", +		.of_match = of_match_ptr("DCDC_REG3"), +		.regulators_node = of_match_ptr("regulators"),  		.id = RK808_ID_DCDC3,  		.ops = &rk808_switch_ops,  		.type = REGULATOR_VOLTAGE, @@ -351,55 +405,23 @@ static const struct regulator_desc rk808_reg[] = {  		.enable_reg = RK808_DCDC_EN_REG,  		.enable_mask = BIT(2),  		.owner = THIS_MODULE, -	}, { -		.name = "DCDC_REG4", -		.supply_name = "vcc4", -		.id = RK808_ID_DCDC4, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 16, -		.linear_ranges = rk808_buck4_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges), -		.vsel_reg = RK808_BUCK4_ON_VSEL_REG, -		.vsel_mask = RK808_BUCK4_VSEL_MASK, -		.enable_reg = RK808_DCDC_EN_REG, -		.enable_mask = BIT(3), -		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG1", -		.supply_name = "vcc6", -		.id = RK808_ID_LDO1, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 17, -		.linear_ranges = rk808_ldo_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), -		.vsel_reg = RK808_LDO1_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(0), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG2", -		.supply_name = "vcc6", -		.id = RK808_ID_LDO2, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 17, -		.linear_ranges = rk808_ldo_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), -		.vsel_reg = RK808_LDO2_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(1), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { +	}, +	RK8XX_DESC(RK808_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3300, 100, +		RK808_BUCK4_ON_VSEL_REG, RK808_BUCK4_VSEL_MASK, +		RK808_DCDC_EN_REG, BIT(3), 0), +	RK8XX_DESC(RK808_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100, +		RK808_LDO1_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(0), 400), +	RK8XX_DESC(RK808_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100, +		RK808_LDO2_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(1), 400), +	{  		.name = "LDO_REG3",  		.supply_name = "vcc7", +		.of_match = of_match_ptr("LDO_REG3"), +		.regulators_node = of_match_ptr("regulators"),  		.id = RK808_ID_LDO3, -		.ops = &rk808_reg_ops, +		.ops = &rk808_reg_ops_ranges,  		.type = REGULATOR_VOLTAGE,  		.n_voltages = 16,  		.linear_ranges = rk808_ldo3_voltage_ranges, @@ -410,117 +432,26 @@ static const struct regulator_desc rk808_reg[] = {  		.enable_mask = BIT(2),  		.enable_time = 400,  		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG4", -		.supply_name = "vcc9", -		.id = RK808_ID_LDO4, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 17, -		.linear_ranges = rk808_ldo_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), -		.vsel_reg = RK808_LDO4_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(3), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG5", -		.supply_name = "vcc9", -		.id = RK808_ID_LDO5, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 17, -		.linear_ranges = rk808_ldo_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), -		.vsel_reg = RK808_LDO5_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(4), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG6", -		.supply_name = "vcc10", -		.id = RK808_ID_LDO6, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 18, -		.linear_ranges = rk808_ldo6_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), -		.vsel_reg = RK808_LDO6_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(5), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG7", -		.supply_name = "vcc7", -		.id = RK808_ID_LDO7, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 18, -		.linear_ranges = rk808_ldo6_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), -		.vsel_reg = RK808_LDO7_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(6), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { -		.name = "LDO_REG8", -		.supply_name = "vcc11", -		.id = RK808_ID_LDO8, -		.ops = &rk808_reg_ops, -		.type = REGULATOR_VOLTAGE, -		.n_voltages = 17, -		.linear_ranges = rk808_ldo_voltage_ranges, -		.n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), -		.vsel_reg = RK808_LDO8_ON_VSEL_REG, -		.vsel_mask = RK808_LDO_VSEL_MASK, -		.enable_reg = RK808_LDO_EN_REG, -		.enable_mask = BIT(7), -		.enable_time = 400, -		.owner = THIS_MODULE, -	}, { -		.name = "SWITCH_REG1", -		.supply_name = "vcc8", -		.id = RK808_ID_SWITCH1, -		.ops = &rk808_switch_ops, -		.type = REGULATOR_VOLTAGE, -		.enable_reg = RK808_DCDC_EN_REG, -		.enable_mask = BIT(5), -		.owner = THIS_MODULE, -	}, { -		.name = "SWITCH_REG2", -		.supply_name = "vcc12", -		.id = RK808_ID_SWITCH2, -		.ops = &rk808_switch_ops, -		.type = REGULATOR_VOLTAGE, -		.enable_reg = RK808_DCDC_EN_REG, -		.enable_mask = BIT(6), -		.owner = THIS_MODULE,  	}, -}; - -static struct of_regulator_match rk808_reg_matches[] = { -	[RK808_ID_DCDC1]	= { .name = "DCDC_REG1" }, -	[RK808_ID_DCDC2]	= { .name = "DCDC_REG2" }, -	[RK808_ID_DCDC3]	= { .name = "DCDC_REG3" }, -	[RK808_ID_DCDC4]	= { .name = "DCDC_REG4" }, -	[RK808_ID_LDO1]		= { .name = "LDO_REG1" }, -	[RK808_ID_LDO2]		= { .name = "LDO_REG2" }, -	[RK808_ID_LDO3]		= { .name = "LDO_REG3" }, -	[RK808_ID_LDO4]		= { .name = "LDO_REG4" }, -	[RK808_ID_LDO5]		= { .name = "LDO_REG5" }, -	[RK808_ID_LDO6]		= { .name = "LDO_REG6" }, -	[RK808_ID_LDO7]		= { .name = "LDO_REG7" }, -	[RK808_ID_LDO8]		= { .name = "LDO_REG8" }, -	[RK808_ID_SWITCH1]	= { .name = "SWITCH_REG1" }, -	[RK808_ID_SWITCH2]	= { .name = "SWITCH_REG2" }, +	RK8XX_DESC(RK808_ID_LDO4, "LDO_REG4", "vcc9", 1800, 3400, 100, +		RK808_LDO4_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(3), 400), +	RK8XX_DESC(RK808_ID_LDO5, "LDO_REG5", "vcc9", 1800, 3400, 100, +		RK808_LDO5_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(4), 400), +	RK8XX_DESC(RK808_ID_LDO6, "LDO_REG6", "vcc10", 800, 2500, 100, +		RK808_LDO6_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(5), 400), +	RK8XX_DESC(RK808_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100, +		RK808_LDO7_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(6), 400), +	RK8XX_DESC(RK808_ID_LDO8, "LDO_REG8", "vcc11", 1800, 3400, 100, +		RK808_LDO8_ON_VSEL_REG, RK808_LDO_VSEL_MASK, RK808_LDO_EN_REG, +		BIT(7), 400), +	RK8XX_DESC_SWITCH(RK808_ID_SWITCH1, "SWITCH_REG1", "vcc8", +		RK808_DCDC_EN_REG, BIT(5)), +	RK8XX_DESC_SWITCH(RK808_ID_SWITCH2, "SWITCH_REG2", "vcc12", +		RK808_DCDC_EN_REG, BIT(6)),  };  static int rk808_regulator_dt_parse_pdata(struct device *dev, @@ -529,17 +460,12 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,  				   struct rk808_regulator_data *pdata)  {  	struct device_node *np; -	int tmp, ret, i; +	int tmp, ret = 0, i;  	np = of_get_child_by_name(client_dev->of_node, "regulators");  	if (!np)  		return -ENXIO; -	ret = of_regulator_match(dev, np, rk808_reg_matches, -				 RK808_NUM_REGULATORS); -	if (ret < 0) -		goto dt_parse_end; -  	for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) {  		pdata->dvs_gpio[i] =  			devm_gpiod_get_index_optional(client_dev, "dvs", i, @@ -586,18 +512,12 @@ static int rk808_regulator_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, pdata); +	config.dev = &client->dev; +	config.driver_data = pdata; +	config.regmap = rk808->regmap; +  	/* Instantiate the regulators */  	for (i = 0; i < RK808_NUM_REGULATORS; i++) { -		if (!rk808_reg_matches[i].init_data || -		    !rk808_reg_matches[i].of_node) -			continue; - -		config.dev = &client->dev; -		config.driver_data = pdata; -		config.regmap = rk808->regmap; -		config.of_node = rk808_reg_matches[i].of_node; -		config.init_data = rk808_reg_matches[i].init_data; -  		rk808_rdev = devm_regulator_register(&pdev->dev,  						     &rk808_reg[i], &config);  		if (IS_ERR(rk808_rdev)) { diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 6dfa3502e1f1..02fb6b4ea820 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -267,6 +267,7 @@ static struct regulator_ops s2mps11_buck_ops = {  	.ops		= &s2mps11_ldo_ops,		\  	.type		= REGULATOR_VOLTAGE,		\  	.owner		= THIS_MODULE,			\ +	.ramp_delay	= RAMP_DELAY_12_MVUS,		\  	.min_uV		= MIN_800_MV,			\  	.uV_step	= step,				\  	.n_voltages	= S2MPS11_LDO_N_VOLTAGES,	\ @@ -1237,17 +1238,7 @@ static struct platform_driver s2mps11_pmic_driver = {  	.id_table = s2mps11_pmic_id,  }; -static int __init s2mps11_pmic_init(void) -{ -	return platform_driver_register(&s2mps11_pmic_driver); -} -subsys_initcall(s2mps11_pmic_init); - -static void __exit s2mps11_pmic_exit(void) -{ -	platform_driver_unregister(&s2mps11_pmic_driver); -} -module_exit(s2mps11_pmic_exit); +module_platform_driver(s2mps11_pmic_driver);  /* Module information */  MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 6bc4bcd488ac..5a23dd4df432 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -30,6 +30,9 @@  #define MIN_600_MV		600000  #define MIN_500_MV		500000 +/* Ramp delay in uV/us */ +#define RAMP_DELAY_12_MVUS	12000 +  /* Macros to represent steps for LDO/BUCK */  #define STEP_50_MV		50000  #define STEP_25_MV		25000 diff --git a/include/linux/pwm.h b/include/linux/pwm.h index cfc3ed46cad2..b78d27c42629 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -74,6 +74,24 @@ enum pwm_polarity {  	PWM_POLARITY_INVERSED,  }; +/** + * struct pwm_args - board-dependent PWM arguments + * @period: reference period + * @polarity: reference polarity + * + * This structure describes board-dependent arguments attached to a PWM + * device. These arguments are usually retrieved from the PWM lookup table or + * device tree. + * + * Do not confuse this with the PWM state: PWM arguments represent the initial + * configuration that users want to use on this PWM device rather than the + * current PWM hardware state. + */ +struct pwm_args { +	unsigned int period; +	enum pwm_polarity polarity; +}; +  enum {  	PWMF_REQUESTED = 1 << 0,  	PWMF_ENABLED = 1 << 1, @@ -92,6 +110,7 @@ enum {   * @period: period of the PWM signal (in nanoseconds)   * @duty_cycle: duty cycle of the PWM signal (in nanoseconds)   * @polarity: polarity of the PWM signal + * @args: PWM arguments   */  struct pwm_device {  	const char *label; @@ -105,6 +124,8 @@ struct pwm_device {  	unsigned int period;  	unsigned int duty_cycle;  	enum pwm_polarity polarity; + +	struct pwm_args args;  };  static inline bool pwm_is_enabled(const struct pwm_device *pwm) @@ -144,6 +165,18 @@ static inline enum pwm_polarity pwm_get_polarity(const struct pwm_device *pwm)  	return pwm ? pwm->polarity : PWM_POLARITY_NORMAL;  } +static inline void pwm_get_args(const struct pwm_device *pwm, +				struct pwm_args *args) +{ +	*args = pwm->args; +} + +static inline void pwm_apply_args(struct pwm_device *pwm) +{ +	pwm_set_period(pwm, pwm->args.period); +	pwm_set_polarity(pwm, pwm->args.polarity); +} +  /**   * struct pwm_ops - PWM controller operations   * @request: optional hook for requesting a PWM  | 
