goto done; rc = pm8xxx_misc_masked_write(chip, ctrl_addr, PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK | PM8058_SMPS_LEGACY_VREF_SEL | PM8058_SMPS_LEGACY_VPROG_MASK, PM8058_REGULATOR_ENABLE | PM8058_REGULATOR_PULL_DOWN_EN | vref_sel | vprog); if (rc) goto done; } rc = pm8xxx_misc_masked_write(chip, master_enable_addr, master_enable_bit, master_enable_bit); if (rc) goto done; rc = pm8xxx_misc_masked_write(chip, ctrl_addr, PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK, PM8058_REGULATOR_DISABLE | PM8058_REGULATOR_PULL_DOWN_EN); done: return rc; } static int __pm8058_disable_ldo_locally_set_pull_down(struct pm8xxx_misc_chip *chip, u16 ctrl_addr, u16 master_enable_addr, u8 master_enable_bit)
static int __pm8058_disable_smps_locally_set_pull_down(struct pm8xxx_misc_chip *chip, u16 ctrl_addr, u16 test2_addr, u16 master_enable_addr, u8 master_enable_bit) { int rc = 0; u8 vref_sel, vlow_sel, band, vprog, bank, reg; bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: pm8xxx_writeb(0x%03X) failed: rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_readb(chip->dev->parent, test2_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } if ((reg & PM8058_SMPS_ADVANCED_MODE_MASK) == PM8058_SMPS_ADVANCED_MODE) { rc = pm8xxx_readb(chip->dev->parent, ctrl_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, ctrl_addr, rc); goto done; } band = (reg & PM8058_SMPS_ADVANCED_BAND_MASK) >> PM8058_SMPS_ADVANCED_BAND_SHIFT; switch (band) { case 3: vref_sel = 0; vlow_sel = 0; break; case 2: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = 0; break; case 1: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = PM8058_SMPS_LEGACY_VLOW_SEL; break; default: pr_err("%s: regulator already disabled\n", __func__); return -EPERM; } vprog = (reg & PM8058_SMPS_ADVANCED_VPROG_MASK); vprog = (vprog + 1) >> 1; if (vprog > PM8058_SMPS_LEGACY_VPROG_MASK) vprog = PM8058_SMPS_LEGACY_VPROG_MASK; bank = PM8058_REGULATOR_BANK_SEL(1); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_LEGACY_VLOW_SEL, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(1) | vlow_sel); if (rc) goto done; bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_ADVANCED_MODE_MASK, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(7) | PM8058_SMPS_LEGACY_MODE); if (rc) goto done; rc = pm8xxx_misc_masked_write(chip, ctrl_addr, PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK | PM8058_SMPS_LEGACY_VREF_SEL | PM8058_SMPS_LEGACY_VPROG_MASK, PM8058_REGULATOR_ENABLE | PM8058_REGULATOR_PULL_DOWN_EN | vref_sel | vprog); if (rc) goto done; }
/* * Set an SMPS regulator to be disabled in its CTRL register, but enabled * in the master enable register. Also set it's pull down enable bit. * Take care to make sure that the output voltage doesn't change if switching * from advanced mode to legacy mode. */ static int __pm8058_disable_smps_locally_set_pull_down(struct pm8xxx_misc_chip *chip, u16 ctrl_addr, u16 test2_addr, u16 master_enable_addr, u8 master_enable_bit) { int rc = 0; u8 vref_sel, vlow_sel, band, vprog, bank, reg; bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: pm8xxx_writeb(0x%03X) failed: rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_readb(chip->dev->parent, test2_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } /* Check if in advanced mode. */ if ((reg & PM8058_SMPS_ADVANCED_MODE_MASK) == PM8058_SMPS_ADVANCED_MODE) { /* Determine current output voltage. */ rc = pm8xxx_readb(chip->dev->parent, ctrl_addr, ®); if (rc) { pr_err("%s: FAIL pm8xxx_readb(0x%03X): rc=%d\n", __func__, ctrl_addr, rc); goto done; } band = (reg & PM8058_SMPS_ADVANCED_BAND_MASK) >> PM8058_SMPS_ADVANCED_BAND_SHIFT; switch (band) { case 3: vref_sel = 0; vlow_sel = 0; break; case 2: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = 0; break; case 1: vref_sel = PM8058_SMPS_LEGACY_VREF_SEL; vlow_sel = PM8058_SMPS_LEGACY_VLOW_SEL; break; default: pr_err("%s: regulator already disabled\n", __func__); return -EPERM; } vprog = (reg & PM8058_SMPS_ADVANCED_VPROG_MASK); /* Round up if fine step is in use. */ vprog = (vprog + 1) >> 1; if (vprog > PM8058_SMPS_LEGACY_VPROG_MASK) vprog = PM8058_SMPS_LEGACY_VPROG_MASK; /* Set VLOW_SEL bit. */ bank = PM8058_REGULATOR_BANK_SEL(1); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_LEGACY_VLOW_SEL, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(1) | vlow_sel); if (rc) goto done; /* Switch to legacy mode */ bank = PM8058_REGULATOR_BANK_SEL(7); rc = pm8xxx_writeb(chip->dev->parent, test2_addr, bank); if (rc) { pr_err("%s: FAIL pm8xxx_writeb(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8xxx_misc_masked_write(chip, test2_addr, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_MASK | PM8058_SMPS_ADVANCED_MODE_MASK, PM8058_REGULATOR_BANK_WRITE | PM8058_REGULATOR_BANK_SEL(7) | PM8058_SMPS_LEGACY_MODE); if (rc) goto done; /* Enable locally, enable pull down, keep voltage the same. */ rc = pm8xxx_misc_masked_write(chip, ctrl_addr, PM8058_REGULATOR_ENABLE_MASK | PM8058_REGULATOR_PULL_DOWN_MASK | PM8058_SMPS_LEGACY_VREF_SEL | PM8058_SMPS_LEGACY_VPROG_MASK, PM8058_REGULATOR_ENABLE | PM8058_REGULATOR_PULL_DOWN_EN | vref_sel | vprog); if (rc) goto done; }