Commit 39d652e0 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'regulator/topic/pwm',...

Merge remote-tracking branches 'regulator/topic/pwm', 'regulator/topic/qcom-spmi', 'regulator/topic/rk808' and 'regulator/topic/s2mps11' into regulator-next
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -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:

+14 −7
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+47 −31
Original line number Diff line number Diff line
@@ -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;
Loading