Ejemplo n.º 1
0
static int pm8901_nldo_set_voltage(struct pm8901_chip *chip,
		struct pm8901_vreg *vreg, int uV)
{
	int rc;
	u8 mask, val = 0;

	if (uV > NLDO_UV_MAX) {
		uV -= NLDO_FINE_STEP_UV;
		val = LDO_TEST_FINE_STEP_MASK;
	}

	/* update reference voltage and fine step selection if necessary */
	if ((vreg->test_reg[2] & LDO_TEST_FINE_STEP_MASK) != val) {
		val |= REGULATOR_BANK_SEL(2) | REGULATOR_BANK_WRITE;
		mask = LDO_TEST_FINE_STEP_MASK | val;

		rc = pm8901_vreg_write(chip, vreg->test_addr, val,
				mask, &vreg->test_reg[2]);
		if (rc) {
			pr_err("%s: pm8901_write failed\n", __func__);
			return rc;
		}
	}

	/* voltage programming */
	val = (uV - NLDO_UV_MIN) / NLDO_UV_STEP;
	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, val,
			LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
	if (rc)
		pr_err("%s: pm8901_write failed\n", __func__);

	return rc;
}
Ejemplo n.º 2
0
static int pm8901_smps_set_voltage(struct regulator_dev *dev,
		int min_uV, int max_uV)
{
	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
	struct pm8901_chip *chip = dev_get_drvdata(dev->dev.parent);
	int rc;
	u8 val, band;

	if (min_uV < SMPS_BAND_2_UV_MIN) {
		val = ((min_uV - SMPS_BAND_1_UV_MIN) / SMPS_BAND_1_UV_STEP);
		band = SMPS_VCTRL_BAND_1;
	} else if (min_uV < SMPS_BAND_3_UV_MIN) {
		val = ((min_uV - SMPS_BAND_2_UV_MIN) / SMPS_BAND_2_UV_STEP);
		band = SMPS_VCTRL_BAND_2;
	} else {
		val = ((min_uV - SMPS_BAND_3_UV_MIN) / SMPS_BAND_3_UV_STEP);
		band = SMPS_VCTRL_BAND_3;
	}

	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, band | val,
			SMPS_VCTRL_BAND_MASK | SMPS_VCTRL_VPROG_MASK,
			&vreg->ctrl_reg);
	if (rc)
		pr_err("%s: pm8901_write failed\n", __func__);

	return rc;
}
Ejemplo n.º 3
0
static int pm8901_vreg_set_mode(struct regulator_dev *dev, unsigned int mode)
{
	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
	struct pm8901_chip *chip = dev_get_drvdata(dev->dev.parent);
	int rc;
	u8 val;

	if (mode == REGULATOR_MODE_NORMAL) {
		/* high power mode */
		val = REGULATOR_PMR_STATE_HPM;
	} else if (mode == REGULATOR_MODE_STANDBY) {
		/* low power mode */
		val = REGULATOR_PMR_STATE_LPM;
	} else {
		return -EINVAL;
	}

	rc = pm8901_vreg_write(chip, vreg->pmr_addr,
			val, REGULATOR_PMR_STATE_MASK,
			&vreg->pmr_reg);
	if (rc)
		pr_err("%s: pm8901_vreg_write failed\n", __func__);

	return rc;
}
Ejemplo n.º 4
0
static int pm8901_vreg_enable(struct regulator_dev *dev)
{
	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
	struct pm8901_chip *chip = dev_get_drvdata(dev->dev.parent);
	int rc;

	rc = pm8901_vreg_write(chip, vreg->pmr_addr,
			REGULATOR_PMR_STATE_HPM,
			REGULATOR_PMR_STATE_MASK,
			&vreg->pmr_reg);
	if (rc)
		pr_err("%s: pm8901_write failed\n", __func__);
	return rc;
}
Ejemplo n.º 5
0
static int lcd_power_on()
{
    uint8_t buffer = 0x0, mask = 0x0, prev_val = 0x0;
    int ret = 0;

    /* Configure LDO L2 TEST Bank 2, to Range Select 0 */
    /* Not updating reference voltage */
    buffer = (0x80);            /* Write mode */
    buffer |= (PM8901_LDO_TEST_BANK(2));    /* Test Bank 2 */
    mask = buffer | LDO_TEST_RANGE_SELECT_MASK;

    if ((ret = pm8901_test_bank_read(&prev_val,
                                     PM8901_LDO_TEST_BANK(2),
                                     PM8901_LDO_L2_TEST_BANK))) {
        return ret;
    }
    if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK,
                                 prev_val))) {
        return ret;
    }

    /* Enable LDO L2 at Max Voltage (should be around 3.3v) */
    buffer = (0x0 << PM8901_LDO_CTL_ENABLE__S);
    /* Disable Pull Down */
    buffer |= (0x1 << PM8901_LDO_CTL_PULL_DOWN__S);
    /* Put LDO into normal mode instead of low power mode */
    buffer |= (0x0 << PM8901_LDO_CTL_MODE__S);

	/* Set voltage programming to 3.3V or 2.85V(8660 fluid) */
	if (board_machtype() == LINUX_MACHTYPE_8660_FLUID)
		buffer |= (0xB);
	else
		buffer |= (0xF);

    mask = buffer | LDO_CTL_ENABLE_MASK |
        LDO_CTL_PULL_DOWN_MASK |
        LDO_CTL_NORMAL_POWER_MODE_MASK | LDO_CTL_VOLTAGE_SET_MASK;

    /* Do a normal read here, as to not destroy the value in LDO control */
    if ((ret = pm8901_read(&prev_val, 1, PM8901_LDO_L2))) {
        return ret;
    }
    /* Configure the LDO2 for 3.3V or 2.85V(8660 fluid) */
    ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2, prev_val);

    /* Configure LDO L2 TEST Bank 4, for High Range Mode */
    buffer = (0x80);            /* Write mode */
    buffer |= (PM8901_LDO_TEST_BANK(4));    /* Test Bank 4 */
    buffer |= (0x01);           /* Put into High Range Mode */
    mask = buffer | LDO_TEST_OUTPUT_RANGE_MASK;

    if ((ret = pm8901_test_bank_read(&prev_val,
                                     PM8901_LDO_TEST_BANK(4),
                                     PM8901_LDO_L2_TEST_BANK))) {
        return ret;
    }
    if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK,
                                 prev_val))) {
        return ret;
    }

    /* Configure LDO L2 TEST Bank 2, to Range Select 0 */
    buffer = (0x80);            /* Write mode */
    buffer |= (PM8901_LDO_TEST_BANK(2));    /* Test Bank 2 */
    buffer |= (1<<1);           /* For fine step 50 mV */
    buffer |= (1<<3);           /* to update reference voltage */
    mask = buffer | LDO_TEST_RANGE_SELECT_MASK;
    mask |= (1<<2);             /* Setting mask to make ref voltage as 1.25 V */

    if ((ret = pm8901_test_bank_read(&prev_val,
                                     PM8901_LDO_TEST_BANK(2),
                                     PM8901_LDO_L2_TEST_BANK))) {
        return ret;
    }
    if ((ret = pm8901_vreg_write(&buffer, mask, PM8901_LDO_L2_TEST_BANK,
                                 prev_val))) {
        return ret;
    }

    /* Enable PMR for LDO L2 */
    buffer = 0x7F;
    mask = 0x7F;
    if ((ret = pm8901_read(&prev_val, 1, PM8901_PMR_7))) {
        return ret;
    }
    ret = pm8901_vreg_write(&buffer, mask, PM8901_PMR_7, prev_val);
    return ret;
}
Ejemplo n.º 6
0
static int pm8901_pldo_set_voltage(struct pm8901_chip *chip,
		struct pm8901_vreg *vreg, int uV)
{
	int min, max, step, fine_step, rc;
	u8 range_extn, vref, mask, val = 0;

	if (uV >= PLDO_LOW_UV_MIN &&
			uV <= PLDO_LOW_UV_MAX + PLDO_LOW_UV_STEP) {
		min = PLDO_LOW_UV_MIN;
		max = PLDO_LOW_UV_MAX;
		step = PLDO_LOW_UV_STEP;
		fine_step = PLDO_LOW_FINE_STEP_UV;
		range_extn = 0;
		vref = LDO_TEST_VREF_MASK;
	} else if (uV >= PLDO_NORM_UV_MIN &&
			uV <= PLDO_NORM_UV_MAX + PLDO_NORM_UV_STEP) {
		min = PLDO_NORM_UV_MIN;
		max = PLDO_NORM_UV_MAX;
		step = PLDO_NORM_UV_STEP;
		fine_step = PLDO_NORM_FINE_STEP_UV;
		range_extn = 0;
		vref = 0;
	} else {
		min = PLDO_HIGH_UV_MIN;
		max = PLDO_HIGH_UV_MAX;
		step = PLDO_HIGH_UV_STEP;
		fine_step = PLDO_HIGH_FINE_STEP_UV;
		range_extn = LDO_TEST_RANGE_EXTN_MASK;
		vref = 0;
	}

	if (uV > max) {
		uV -= fine_step;
		val = LDO_TEST_FINE_STEP_MASK;
	}

	/* update reference voltage and fine step selection if necessary */
	if ((vreg->test_reg[2] & LDO_TEST_FINE_STEP_MASK) != val ||
			(vreg->test_reg[2] & LDO_TEST_VREF_MASK) != vref) {
		val |= REGULATOR_BANK_SEL(2) | REGULATOR_BANK_WRITE |
			LDO_TEST_VREF_UPDATE_MASK | vref;
		mask = LDO_TEST_VREF_MASK | LDO_TEST_FINE_STEP_MASK | val;

		rc = pm8901_vreg_write(chip, vreg->test_addr, val,
				mask, &vreg->test_reg[2]);
		if (rc) {
			pr_err("%s: pm8901_write failed\n", __func__);
			return rc;
		}
	}

	/* update range extension if necessary */
	if ((vreg->test_reg[4] & LDO_TEST_RANGE_EXTN_MASK) != range_extn) {
		val = REGULATOR_BANK_SEL(4) | REGULATOR_BANK_WRITE |
			range_extn;
		mask = LDO_TEST_RANGE_EXTN_MASK | val;

		rc = pm8901_vreg_write(chip, vreg->test_addr, val,
				mask, &vreg->test_reg[4]);
		if (rc) {
			pr_err("%s: pm8901_write failed\n", __func__);
			return rc;
		}
	}

	/* voltage programming */
	val = (uV - min) / step;
	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, val,
			LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
	if (rc)
		pr_err("%s: pm8901_write failed\n", __func__);

	return rc;
}