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; }
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; }
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; }
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; }
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; }
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; }