Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eba41a5e authored by Axel Lin's avatar Axel Lin Committed by Mark Brown
Browse files

regulator: Support set_voltage_time_sel for drivers implement set_voltage



In currently implementation of _regulator_do_set_voltage, set_voltage_time_sel will
only be called if set_voltage_sel is implemented.

set_voltage_time_sel actually only needs get_voltage_sel to get old_selector.

This patch makes regulator core support set_voltage_time_sel for drivers
implement either set_voltage or set_voltage_sel.

Signed-off-by: default avatarAxel Lin <axel.lin@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 576ca436
Loading
Loading
Loading
Loading
+31 −28
Original line number Diff line number Diff line
@@ -1856,23 +1856,35 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
	int ret;
	int delay = 0;
	unsigned int selector;
	int old_selector = -1;
	int best_val = INT_MAX;

	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);

	min_uV += rdev->constraints->uV_offset;
	max_uV += rdev->constraints->uV_offset;

	/*
	 * If we can't obtain the old selector there is not enough
	 * info to call set_voltage_time_sel().
	 */
	if (rdev->desc->ops->set_voltage_time_sel &&
	    rdev->desc->ops->get_voltage_sel) {
		old_selector = rdev->desc->ops->get_voltage_sel(rdev);
		if (old_selector < 0)
			return old_selector;
	}

	if (rdev->desc->ops->set_voltage) {
		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
						   &selector);

		if (rdev->desc->ops->list_voltage)
			selector = rdev->desc->ops->list_voltage(rdev,
			best_val = rdev->desc->ops->list_voltage(rdev,
								 selector);
		else
			selector = -1;
			best_val = -1;
	} else if (rdev->desc->ops->set_voltage_sel) {
		int best_val = INT_MAX;
		int i;

		selector = 0;
@@ -1891,36 +1903,27 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
			}
		}

		/*
		 * If we can't obtain the old selector there is not enough
		 * info to call set_voltage_time_sel().
		 */
		if (rdev->desc->ops->set_voltage_time_sel &&
		    rdev->desc->ops->get_voltage_sel) {
			unsigned int old_selector = 0;

			ret = rdev->desc->ops->get_voltage_sel(rdev);
			if (ret < 0)
				return ret;
			old_selector = ret;
			ret = rdev->desc->ops->set_voltage_time_sel(rdev,
						old_selector, selector);
			if (ret < 0)
				rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n", ret);
			else
				delay = ret;
		}

		if (best_val != INT_MAX) {
		if (best_val != INT_MAX)
			ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
			selector = best_val;
		} else {
		else
			ret = -EINVAL;
		}
	} else {
		ret = -EINVAL;
	}

	/* Call set_voltage_time_sel if successfully obtained old_selector */
	if (ret == 0 && old_selector >= 0 &&
	    rdev->desc->ops->set_voltage_time_sel) {

		delay = rdev->desc->ops->set_voltage_time_sel(rdev,
						old_selector, selector);
		if (delay < 0) {
			rdev_warn(rdev, "set_voltage_time_sel() failed: %d\n",
				  delay);
			delay = 0;
		}
	}

	/* Insert any necessary delays */
	if (delay >= 1000) {
		mdelay(delay / 1000);
@@ -1933,7 +1936,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
		_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
				     NULL);

	trace_regulator_set_voltage_complete(rdev_get_name(rdev), selector);
	trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);

	return ret;
}