summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorKiran Gunda <kgunda@codeaurora.org>2017-08-08 16:58:47 +0530
committerKiran Gunda <kgunda@codeaurora.org>2017-08-12 20:15:05 +0530
commit9d2a24f8e567683caada125f3bdbd268bd019694 (patch)
treea3e8d362de91205e502b334c6b3cd96b4fededec /drivers/regulator
parent0d2bf7e89532535858e8f6e0eb628c953d9192ad (diff)
regulator: qpnp-lcdb: Add headroom voltage for boost
Increase the boost headroom to 200mV. Also add a device tree property to make the headroom configurable. Change-Id: Ibc932f191e64824ba948153a7ae80f109ffcdff9 Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/qpnp-lcdb-regulator.c84
1 files changed, 53 insertions, 31 deletions
diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c
index 724e8a4c00da..27f2d9851c2a 100644
--- a/drivers/regulator/qpnp-lcdb-regulator.c
+++ b/drivers/regulator/qpnp-lcdb-regulator.c
@@ -147,6 +147,8 @@
#define MIN_SOFT_START_US 0
#define MAX_SOFT_START_US 2000
+#define BST_HEADROOM_DEFAULT_MV 200
+
struct ldo_regulator {
struct regulator_desc rdesc;
struct regulator_dev *rdev;
@@ -187,6 +189,7 @@ struct bst_params {
int soft_start_us;
int vreg_ok_dbc_us;
int voltage_mv;
+ u16 headroom_mv;
};
struct qpnp_lcdb {
@@ -853,28 +856,40 @@ irq_handled:
#define VOLTAGE_STEP_50_MV 50
#define VOLTAGE_STEP_50MV_OFFSET 0xA
static int qpnp_lcdb_set_bst_voltage(struct qpnp_lcdb *lcdb,
- int voltage_mv)
+ int voltage_mv, u8 type)
{
int rc = 0;
u8 val = 0;
+ int bst_voltage_mv;
+ struct ldo_regulator *ldo = &lcdb->ldo;
+ struct ncp_regulator *ncp = &lcdb->ncp;
+ struct bst_params *bst = &lcdb->bst;
+
+ /* Vout_Boost = headroom_mv + max( Vout_LDO, abs (Vout_NCP)) */
+ bst_voltage_mv = max(voltage_mv, max(ldo->voltage_mv, ncp->voltage_mv));
+ bst_voltage_mv += bst->headroom_mv;
+
+ if (bst_voltage_mv < MIN_BST_VOLTAGE_MV)
+ bst_voltage_mv = MIN_BST_VOLTAGE_MV;
+ else if (bst_voltage_mv > MAX_BST_VOLTAGE_MV)
+ bst_voltage_mv = MAX_BST_VOLTAGE_MV;
+
+ if (bst_voltage_mv != bst->voltage_mv) {
+ val = DIV_ROUND_UP(bst_voltage_mv - MIN_BST_VOLTAGE_MV,
+ VOLTAGE_STEP_50_MV);
- if (voltage_mv < MIN_BST_VOLTAGE_MV)
- voltage_mv = MIN_BST_VOLTAGE_MV;
- else if (voltage_mv > MAX_BST_VOLTAGE_MV)
- voltage_mv = MAX_BST_VOLTAGE_MV;
-
- val = DIV_ROUND_UP(voltage_mv - MIN_BST_VOLTAGE_MV,
- VOLTAGE_STEP_50_MV);
-
- rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
- LCDB_BST_OUTPUT_VOLTAGE_REG,
- SET_OUTPUT_VOLTAGE_MASK, val);
- if (rc < 0)
- pr_err("Failed to set boost voltage %d mv rc=%d\n",
- voltage_mv, rc);
- else
- pr_debug("Boost voltage set = %d mv (0x%02x = 0x%02x)\n",
- voltage_mv, LCDB_BST_OUTPUT_VOLTAGE_REG, val);
+ rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
+ LCDB_BST_OUTPUT_VOLTAGE_REG,
+ SET_OUTPUT_VOLTAGE_MASK, val);
+ if (rc < 0) {
+ pr_err("Failed to set boost voltage %d mv rc=%d\n",
+ bst_voltage_mv, rc);
+ } else {
+ pr_debug("Boost voltage set = %d mv (0x%02x = 0x%02x)\n",
+ bst_voltage_mv, LCDB_BST_OUTPUT_VOLTAGE_REG, val);
+ bst->voltage_mv = bst_voltage_mv;
+ }
+ }
return rc;
}
@@ -905,25 +920,16 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
u16 offset = LCDB_LDO_OUTPUT_VOLTAGE_REG;
u8 val = 0;
- if (type == BST)
- return qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv);
-
- if (type == NCP)
- offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
-
if (!is_between(voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV)) {
pr_err("Invalid voltage %dmv (min=%d max=%d)\n",
voltage_mv, MIN_VOLTAGE_MV, MAX_VOLTAGE_MV);
return -EINVAL;
}
- /* Change the BST voltage to LDO + 100mV */
- if (type == LDO) {
- rc = qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv + 100);
- if (rc < 0) {
- pr_err("Failed to set boost voltage rc=%d\n", rc);
- return rc;
- }
+ rc = qpnp_lcdb_set_bst_voltage(lcdb, voltage_mv, type);
+ if (rc < 0) {
+ pr_err("Failed to set boost voltage rc=%d\n", rc);
+ return rc;
}
/* Below logic is only valid for LDO and NCP type */
@@ -936,6 +942,9 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
val += VOLTAGE_STEP_50MV_OFFSET;
}
+ if (type == NCP)
+ offset = LCDB_NCP_OUTPUT_VOLTAGE_REG;
+
rc = qpnp_lcdb_masked_write(lcdb, lcdb->base + offset,
SET_OUTPUT_VOLTAGE_MASK, val);
if (rc < 0)
@@ -1058,6 +1067,8 @@ static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO);
if (rc < 0)
pr_err("Failed to set LDO voltage rc=%c\n", rc);
+ else
+ lcdb->ldo.voltage_mv = min_uV / 1000;
return rc;
}
@@ -1129,6 +1140,8 @@ static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP);
if (rc < 0)
pr_err("Failed to set LDO voltage rc=%c\n", rc);
+ else
+ lcdb->ncp.voltage_mv = min_uV / 1000;
return rc;
}
@@ -1389,6 +1402,12 @@ static int qpnp_lcdb_bst_dt_init(struct qpnp_lcdb *lcdb)
return -EINVAL;
}
+ /* Boost head room configuration */
+ of_property_read_u16(node, "qcom,bst-headroom-mv",
+ &lcdb->bst.headroom_mv);
+ if (lcdb->bst.headroom_mv < BST_HEADROOM_DEFAULT_MV)
+ lcdb->bst.headroom_mv = BST_HEADROOM_DEFAULT_MV;
+
return 0;
}
@@ -1695,6 +1714,9 @@ static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb)
}
lcdb->bst.soft_start_us = (val & SOFT_START_MASK) * 200 + 200;
+ if (!lcdb->bst.headroom_mv)
+ lcdb->bst.headroom_mv = BST_HEADROOM_DEFAULT_MV;
+
return 0;
}