static int spm_regulator_enable(struct regulator_dev *rdev)
{
	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
	int rc;

	rc = _spm_regulator_set_voltage(rdev);

	if (!rc)
		vreg->online = true;

	return rc;
}
示例#2
0
static int spm_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
					int max_uV, unsigned *selector)
{
	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
	const struct voltage_range *range = vreg->range;
	int uV = min_uV;
	unsigned vlevel;

	if (uV < range->set_point_min_uV && max_uV >= range->set_point_min_uV)
		uV = range->set_point_min_uV;

	if (uV < range->set_point_min_uV || uV > range->max_uV) {
		pr_err("%s: request v=[%d, %d] is outside possible v=[%d, %d]\n",
			vreg->rdesc.name, min_uV, max_uV,
			range->set_point_min_uV, range->max_uV);
		return -EINVAL;
	}

	vlevel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
	uV = vlevel * range->step_uV + range->min_uV;

	if (uV > max_uV) {
		pr_err("%s: request v=[%d, %d] cannot be met by any set point\n",
			vreg->rdesc.name, min_uV, max_uV);
		return -EINVAL;
	}

	*selector = vlevel -
		(vreg->range->set_point_min_uV - vreg->range->min_uV)
			/ vreg->range->step_uV;

	/* Fix VSET for ULT HF Buck */
	if ((vreg->regulator_type == QPNP_TYPE_ULT_HF) &&
					(range == &ult_hf_range1)) {

		vlevel &= 0x1F;
		vlevel |= ULT_SMPS_RANGE_SPLIT;
	}

	vreg->vlevel = vlevel;
	vreg->uV = uV;

	if (!vreg->online)
		return 0;

	return _spm_regulator_set_voltage(rdev);
}
static int spm_regulator_set_voltage(struct regulator_dev *rdev, int min_uV,
					int max_uV, unsigned *selector)
{
	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
	const struct voltage_range *range = vreg->range;
	int uV = min_uV;
	unsigned vlevel;

	if (uV < range->set_point_min_uV && max_uV >= range->set_point_min_uV)
		uV = range->set_point_min_uV;

	if (uV < range->set_point_min_uV || uV > range->max_uV) {
		pr_err("%s: request v=[%d, %d] is outside possible v=[%d, %d]\n",
			vreg->rdesc.name, min_uV, max_uV,
			range->set_point_min_uV, range->max_uV);
		return -EINVAL;
	}

	vlevel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
	uV = vlevel * range->step_uV + range->min_uV;

	if (uV > max_uV) {
		pr_err("%s: request v=[%d, %d] cannot be met by any set point\n",
			vreg->rdesc.name, min_uV, max_uV);
		return -EINVAL;
	}

	vreg->vlevel = vlevel;
	vreg->uV = uV;
	*selector = vlevel -
		(vreg->range->set_point_min_uV - vreg->range->min_uV)
			/ vreg->range->step_uV;

	if (!vreg->online)
		return 0;

	return _spm_regulator_set_voltage(rdev);
}