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

	if (vreg->vlevel == vreg->last_set_vlevel)
		return 0;

	if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM)
	    && vreg->uV > vreg->last_set_uV) {
		/*                                                     */
		rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_PWM);
		if (rc)
			return rc;
	}

	rc = msm_spm_set_vdd(0, vreg->vlevel); /*                            */
	if (rc) {
		pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->rdesc.name, rc);
		return rc;
	}

	if (vreg->uV > vreg->last_set_uV) {
		/*                                        */
		udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV,
					vreg->step_rate));
	}

	if (!(vreg->init_mode & QPNP_FTS2_MODE_PWM)
	    && vreg->uV > vreg->last_set_uV) {
		/*                                       */
		udelay(QPNP_FTS2_MODE_CHANGE_DELAY - QPNP_SPMI_WRITE_MIN_DELAY);
		/*                                                           */
		rc = qpnp_fts2_set_mode(vreg, QPNP_FTS2_MODE_AUTO);
		if (rc)
			return rc;
	}

	vreg->last_set_uV = vreg->uV;
	vreg->last_set_vlevel = vreg->vlevel;

	return rc;
}
Example #2
0
static int _set_voltage(struct regulator_dev *rdev)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);
	int rc;

	rc = msm_spm_set_vdd(rdev_get_id(rdev), vreg->vlevel);
	if (!rc) {
		if (vreg->uV > vreg->last_set_uV) {
			
			udelay((vreg->uV - vreg->last_set_uV) /
						REGULATOR_SLEW_RATE);
		}
		vreg->last_set_uV = vreg->uV;
	} else {
		pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc);
		vreg->uV = vreg->last_set_uV;
	}

	return rc;
}
static int spm_regulator_write_voltage(struct spm_vreg *vreg, int uV)
{
	unsigned vlevel = spm_regulator_uv_to_vlevel(vreg, uV);
	bool spm_failed = false;
	int rc = 0;
	u8 reg;

	if (likely(!vreg->bypass_spm)) {
		/* Set voltage control register via SPM. */
		rc = msm_spm_set_vdd(vreg->cpu_num, vlevel);
		if (rc) {
			pr_debug("%s: msm_spm_set_vdd failed, rc=%d; falling back on SPMI write\n",
				vreg->rdesc.name, rc);
			spm_failed = true;
		}
	}

	if (unlikely(vreg->bypass_spm || spm_failed)) {
		/* Set voltage control register via SPMI. */
		reg = vlevel;
		rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
			vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
			&reg, 1);
		if (rc) {
			pr_err("%s: spmi_ext_register_writel failed, rc=%d\n",
				vreg->rdesc.name, rc);
			return rc;
		}
	}

	if (uV > vreg->last_set_uV) {
		/* Wait for voltage stepping to complete. */
		udelay(DIV_ROUND_UP(uV - vreg->last_set_uV, vreg->step_rate));
	}

	vreg->last_set_uV = uV;
	vreg->last_set_vlevel = vlevel;

	return rc;
}
static int qpnp_smps_init_voltage(struct spm_vreg *vreg)
{
	int rc;

	rc = qpnp_smps_read_voltage(vreg);
	if (rc) {
		pr_err("%s: voltage read failed, rc=%d\n", vreg->rdesc.name,
			rc);
		return rc;
	}

	vreg->vlevel = vreg->last_set_vlevel;
	vreg->uV = vreg->last_set_uV;

	/* Initialize SAW voltage control register */
	if (!vreg->bypass_spm) {
		rc = msm_spm_set_vdd(vreg->cpu_num, vreg->vlevel);
		if (rc)
			pr_err("%s: msm_spm_set_vdd failed, rc=%d\n",
			       vreg->rdesc.name, rc);
	}

	return 0;
}
Example #5
0
static int saw_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
			   unsigned *selector)
{
	struct saw_vreg *vreg = rdev_get_drvdata(rdev);
	int uV = min_uV;
	int rc;
	u8 vprog, band;

	if (uV < FTSMPS_BAND1_UV_MIN && max_uV >= FTSMPS_BAND1_UV_MIN)
		uV = FTSMPS_BAND1_UV_MIN;

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

	/* Round up for set points in the gaps between bands. */
	if (uV > FTSMPS_BAND1_UV_MAX && uV < FTSMPS_BAND2_UV_MIN)
		uV = FTSMPS_BAND2_UV_MIN;
	else if (uV > FTSMPS_BAND2_UV_MAX
			&& uV < FTSMPS_BAND3_UV_SET_POINT_MIN)
		uV = FTSMPS_BAND3_UV_SET_POINT_MIN;

	if (uV > FTSMPS_BAND2_UV_MAX) {
		vprog = (uV - FTSMPS_BAND3_UV_MIN + FTSMPS_BAND3_UV_STEP - 1)
			/ FTSMPS_BAND3_UV_STEP;
		band = FTSMPS_VCTRL_BAND_3;
		uV = FTSMPS_BAND3_UV_MIN + vprog * FTSMPS_BAND3_UV_STEP;
	} else if (uV > FTSMPS_BAND1_UV_MAX) {
		vprog = (uV - FTSMPS_BAND2_UV_MIN + FTSMPS_BAND2_UV_STEP - 1)
			/ FTSMPS_BAND2_UV_STEP;
		band = FTSMPS_VCTRL_BAND_2;
		uV = FTSMPS_BAND2_UV_MIN + vprog * FTSMPS_BAND2_UV_STEP;
	} else {
		vprog = (uV - FTSMPS_BAND1_UV_MIN
				+ FTSMPS_BAND1_UV_LOG_STEP - 1)
			/ FTSMPS_BAND1_UV_LOG_STEP;
		uV = FTSMPS_BAND1_UV_MIN + vprog * FTSMPS_BAND1_UV_LOG_STEP;
		vprog *= FTSMPS_BAND1_UV_LOG_STEP / FTSMPS_BAND1_UV_PHYS_STEP;
		band = FTSMPS_VCTRL_BAND_1;
	}

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

	rc = msm_spm_set_vdd(rdev_get_id(rdev), band | vprog);
	if (!rc) {
		if (uV > vreg->uV) {
			/* Wait for voltage to stabalize. */
			udelay((uV - vreg->uV) / REGULATOR_SLEW_RATE);
		}
		vreg->uV = uV;
	} else {
		pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc);
	}

	return rc;
}
static int _spm_regulator_set_voltage(struct regulator_dev *rdev)
{
	struct spm_vreg *vreg = rdev_get_drvdata(rdev);
	bool spm_failed = false;
	int rc = 0;
	u8 reg;

	if (vreg->vlevel == vreg->last_set_vlevel)
		return 0;

	if ((vreg->regulator_type == QPNP_TYPE_FTS2)
	    && !(vreg->init_mode & QPNP_SMPS_MODE_PWM)
	    && vreg->uV > vreg->last_set_uV) {
		/* Switch to PWM mode so that voltage ramping is fast. */
		rc = qpnp_smps_set_mode(vreg, QPNP_SMPS_MODE_PWM);
		if (rc)
			return rc;
	}

	if (likely(!vreg->bypass_spm)) {
		/* Set voltage control register via SPM. */
		rc = msm_spm_set_vdd(vreg->cpu_num, vreg->vlevel);
		if (rc) {
			pr_debug("%s: msm_spm_set_vdd failed, rc=%d; falling back on SPMI write\n",
				vreg->rdesc.name, rc);
			spm_failed = true;
		}
	}

	if (unlikely(vreg->bypass_spm || spm_failed)) {
		/* Set voltage control register via SPMI. */
		reg = vreg->vlevel;
		rc = spmi_ext_register_writel(vreg->spmi_dev->ctrl,
			vreg->spmi_dev->sid,
			vreg->spmi_base_addr + QPNP_SMPS_REG_VOLTAGE_SETPOINT,
			&reg, 1);
		if (rc) {
			pr_err("%s: spmi_ext_register_writel failed, rc=%d\n",
				vreg->rdesc.name, rc);
			return rc;
		}
	}

	if (vreg->uV > vreg->last_set_uV) {
		/* Wait for voltage stepping to complete. */
		udelay(DIV_ROUND_UP(vreg->uV - vreg->last_set_uV,
					vreg->step_rate));
	}

	if ((vreg->regulator_type == QPNP_TYPE_FTS2)
	    && !(vreg->init_mode & QPNP_SMPS_MODE_PWM)
	    && vreg->uV > vreg->last_set_uV) {
		/* Wait for mode transition to complete. */
		udelay(QPNP_FTS2_MODE_CHANGE_DELAY - QPNP_SPMI_WRITE_MIN_DELAY);
		/* Switch to AUTO mode so that power consumption is lowered. */
		rc = qpnp_smps_set_mode(vreg, QPNP_FTS2_MODE_AUTO);
		if (rc)
			return rc;
	}

	vreg->last_set_uV = vreg->uV;
	vreg->last_set_vlevel = vreg->vlevel;

	return rc;
}