diff options
author | Kiran Gunda <kgunda@codeaurora.org> | 2017-08-08 16:58:47 +0530 |
---|---|---|
committer | Kiran Gunda <kgunda@codeaurora.org> | 2017-08-12 20:15:05 +0530 |
commit | 9d2a24f8e567683caada125f3bdbd268bd019694 (patch) | |
tree | a3e8d362de91205e502b334c6b3cd96b4fededec /drivers | |
parent | 0d2bf7e89532535858e8f6e0eb628c953d9192ad (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')
-rw-r--r-- | drivers/regulator/qpnp-lcdb-regulator.c | 84 |
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; } |