/**
* enum qpnp_labibb_mode - working mode of LAB/IBB regulators
- * %QPNP_LABIBB_STANDALONE_MODE: configure LAB/IBB regulator as a
- * standalone regulator
* %QPNP_LABIBB_LCD_MODE: configure LAB and IBB regulators
* together to provide power supply for LCD
* %QPNP_LABIBB_AMOLED_MODE: configure LAB and IBB regulators
* supported by qpnp_labibb_regulator
*/
enum qpnp_labibb_mode {
- QPNP_LABIBB_STANDALONE_MODE = 1,
QPNP_LABIBB_LCD_MODE,
QPNP_LABIBB_AMOLED_MODE,
QPNP_LABIBB_MAX_MODE,
u16 ibb_base;
struct lab_regulator lab_vreg;
struct ibb_regulator ibb_vreg;
- int mode;
+ enum qpnp_labibb_mode mode;
+ bool standalone;
bool ttw_en;
bool in_ttw_mode;
bool ibb_settings_saved;
u8 i, val;
u32 tmp;
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE) {
- if (labibb->mode == QPNP_LABIBB_LCD_MODE)
- val = REG_LAB_IBB_LCD_MODE;
- else
- val = REG_LAB_IBB_AMOLED_MODE;
-
- rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
- REG_LAB_LCD_AMOLED_SEL, &val, 1);
-
- if (rc) {
- pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
- REG_LAB_LCD_AMOLED_SEL, rc);
- return rc;
- }
+ if (labibb->mode == QPNP_LABIBB_LCD_MODE)
+ val = REG_LAB_IBB_LCD_MODE;
+ else
+ val = REG_LAB_IBB_AMOLED_MODE;
- val = LAB_IBB_EN_RDY_EN;
- rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
- REG_LAB_IBB_EN_RDY, &val, 1);
+ rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
+ REG_LAB_LCD_AMOLED_SEL, &val, 1);
- if (rc) {
- pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
- REG_LAB_IBB_EN_RDY, rc);
- return rc;
- }
+ if (rc) {
+ pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
+ REG_LAB_LCD_AMOLED_SEL, rc);
+ return rc;
}
val = 0;
if (!labibb->lab_vreg.vreg_enabled && !labibb->swire_control) {
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
+ if (!labibb->standalone)
return qpnp_labibb_regulator_enable(labibb);
val = LAB_ENABLE_CTL_EN;
if (labibb->lab_vreg.vreg_enabled && !labibb->swire_control) {
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
+ if (!labibb->standalone)
return qpnp_labibb_regulator_disable(labibb);
val = 0;
}
}
+ val = (labibb->standalone) ? 0 : LAB_IBB_EN_RDY_EN;
+ rc = qpnp_labibb_sec_write(labibb, labibb->lab_base,
+ REG_LAB_IBB_EN_RDY, &val, 1);
+
+ if (rc) {
+ pr_err("qpnp_lab_sec_write register %x failed rc = %d\n",
+ REG_LAB_IBB_EN_RDY, rc);
+ return rc;
+ }
+
rc = qpnp_labibb_read(labibb, &val,
labibb->ibb_base + REG_IBB_ENABLE_CTL, 1);
if (rc) {
return rc;
}
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE &&
- !(val & LAB_MODULE_RDY_EN)) {
+ if (!(val & LAB_MODULE_RDY_EN)) {
val = LAB_MODULE_RDY_EN;
rc = qpnp_labibb_write(labibb, labibb->lab_base +
cfg.driver_data = labibb;
cfg.of_node = of_node;
+ if (of_get_property(labibb->dev->of_node, "parent-supply",
+ NULL))
+ init_data->supply_regulator = "parent";
+
init_data->constraints.valid_ops_mask
|= REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS;
u32 i, tmp;
u8 val;
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE) {
- if (labibb->mode == QPNP_LABIBB_LCD_MODE)
- val = REG_LAB_IBB_LCD_MODE;
- else
- val = REG_LAB_IBB_AMOLED_MODE;
+ if (labibb->mode == QPNP_LABIBB_LCD_MODE)
+ val = REG_LAB_IBB_LCD_MODE;
+ else
+ val = REG_LAB_IBB_AMOLED_MODE;
- rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
- REG_LAB_LCD_AMOLED_SEL, &val, 1);
+ rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
+ REG_LAB_LCD_AMOLED_SEL, &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
- REG_IBB_LCD_AMOLED_SEL, rc);
- return rc;
- }
+ if (rc) {
+ pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
+ REG_IBB_LCD_AMOLED_SEL, rc);
+ return rc;
}
rc = of_property_read_u32(of_node, "qcom,qpnp-ibb-lab-pwrdn-delay",
if (of_property_read_bool(of_node, "qcom,qpnp-ibb-en-discharge"))
val |= PWRUP_PWRDN_CTL_1_DISCHARGE_EN;
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
- val |= (IBB_PWRUP_PWRDN_CTL_1_EN_DLY1 |
- IBB_PWRUP_PWRDN_CTL_1_LAB_VREG_OK);
+ val |= (IBB_PWRUP_PWRDN_CTL_1_EN_DLY1 |
+ IBB_PWRUP_PWRDN_CTL_1_LAB_VREG_OK);
rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
REG_IBB_PWRUP_PWRDN_CTL_1,
static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev)
{
- int rc;
+ int rc, delay, retries = 10;
u8 val;
-
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
if (!labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) {
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
+ if (!labibb->standalone)
return qpnp_labibb_regulator_enable(labibb);
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_EN);
return rc;
}
- udelay(labibb->ibb_vreg.soft_start);
+ delay = labibb->ibb_vreg.soft_start;
+ while (retries--) {
+ /* Wait for a small period before reading IBB_STATUS1 */
+ usleep_range(delay, delay + 100);
- rc = qpnp_labibb_read(labibb, &val,
- labibb->ibb_base + REG_IBB_STATUS1, 1);
- if (rc) {
- pr_err("qpnp_ibb_regulator_enable read register %x failed rc = %d\n",
- REG_IBB_STATUS1, rc);
- return rc;
+ rc = qpnp_labibb_read(labibb, &val,
+ labibb->ibb_base + REG_IBB_STATUS1, 1);
+ if (rc) {
+ pr_err("qpnp_ibb_regulator_enable read register %x failed rc = %d\n",
+ REG_IBB_STATUS1, rc);
+ return rc;
+ }
+
+ if (val & IBB_STATUS1_VREG_OK)
+ break;
}
- if ((val & IBB_STATUS1_VREG_OK_MASK) != IBB_STATUS1_VREG_OK) {
+ if (!(val & IBB_STATUS1_VREG_OK)) {
pr_err("qpnp_ibb_regulator_enable failed\n");
return -EINVAL;
}
if (labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) {
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
+ if (!labibb->standalone)
return qpnp_labibb_regulator_disable(labibb);
rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
}
}
+ if (labibb->standalone) {
+ val = 0;
+ rc = qpnp_labibb_sec_write(labibb, labibb->ibb_base,
+ REG_IBB_PWRUP_PWRDN_CTL_1, &val, 1);
+ if (rc) {
+ pr_err("qpnp_labibb_sec_write register %x failed rc = %d\n",
+ REG_IBB_PWRUP_PWRDN_CTL_1, rc);
+ return rc;
+ }
+ labibb->ibb_vreg.pwrup_dly = 0;
+ labibb->ibb_vreg.pwrdn_dly = 0;
+ }
+
rc = qpnp_labibb_read(labibb, &val,
labibb->ibb_base + REG_IBB_MODULE_RDY, 1);
if (rc) {
return rc;
}
- if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE &&
- !(val & IBB_MODULE_RDY_EN)) {
+ if (!(val & IBB_MODULE_RDY_EN)) {
val = IBB_MODULE_RDY_EN;
rc = qpnp_labibb_write(labibb, labibb->ibb_base +
cfg.driver_data = labibb;
cfg.of_node = of_node;
+ if (of_get_property(labibb->dev->of_node, "parent-supply",
+ NULL))
+ init_data->supply_regulator = "parent";
+
init_data->constraints.valid_ops_mask
|= REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS;
labibb->mode = QPNP_LABIBB_LCD_MODE;
} else if (strcmp("amoled", mode_name) == 0) {
labibb->mode = QPNP_LABIBB_AMOLED_MODE;
- } else if (strcmp("stand-alone", mode_name) == 0) {
- labibb->mode = QPNP_LABIBB_STANDALONE_MODE;
} else {
pr_err("Invalid device property in qpnp,qpnp-labibb-mode: %s\n",
mode_name);
return rc;
}
+ labibb->standalone = of_property_read_bool(labibb->dev->of_node,
+ "qcom,labibb-standalone");
+
labibb->ttw_en = of_property_read_bool(labibb->dev->of_node,
"qcom,labibb-touch-to-wake-en");
if (labibb->ttw_en && labibb->mode != QPNP_LABIBB_LCD_MODE) {