mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
regulator: qpnp-lcdb: Add support for voltage step programming
LCDB peripheral on certain PMICs requires the voltage programming in 500 mV steps. Add the support for the same. Change-Id: I42f95edad0e1c6b0b87fbdceeab1c1ff9eeecb4a Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
This commit is contained in:
parent
8d29642673
commit
6e523d9f8b
@ -31,6 +31,14 @@ First Level Node - LCDB module
|
||||
Value type: <phandle>
|
||||
Definition: Phandle to the PMIC's revid node
|
||||
|
||||
- qcom,voltage-step-ramp
|
||||
Usage: optional
|
||||
Value type: <bool>
|
||||
Definition: Required only if the voltage needs to be set in the
|
||||
steps of 500 mV starting from the 4500 mV. This needs
|
||||
to be enabled only on platforms where voltage needs to
|
||||
be ramped up with multiple steps.
|
||||
|
||||
Touch-to-wake (TTW) properties:
|
||||
|
||||
TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable
|
||||
|
@ -181,6 +181,7 @@ struct ldo_regulator {
|
||||
int soft_start_us;
|
||||
int vreg_ok_dbc_us;
|
||||
int voltage_mv;
|
||||
int prev_voltage_mv;
|
||||
};
|
||||
|
||||
struct ncp_regulator {
|
||||
@ -195,6 +196,7 @@ struct ncp_regulator {
|
||||
int soft_start_us;
|
||||
int vreg_ok_dbc_us;
|
||||
int voltage_mv;
|
||||
int prev_voltage_mv;
|
||||
};
|
||||
|
||||
struct bst_params {
|
||||
@ -228,6 +230,7 @@ struct qpnp_lcdb {
|
||||
bool lcdb_enabled;
|
||||
bool settings_saved;
|
||||
bool lcdb_sc_disable;
|
||||
bool voltage_step_ramp;
|
||||
int sc_count;
|
||||
ktime_t sc_module_enable_time;
|
||||
|
||||
@ -249,6 +252,7 @@ enum lcdb_module {
|
||||
LDO,
|
||||
NCP,
|
||||
BST,
|
||||
LDO_NCP,
|
||||
};
|
||||
|
||||
enum pfm_hysteresis {
|
||||
@ -316,6 +320,12 @@ static u32 ncp_ilim_ma[] = {
|
||||
.valid = _valid \
|
||||
} \
|
||||
|
||||
static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb,
|
||||
int voltage_start_mv, u8 type);
|
||||
|
||||
static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
|
||||
int voltage_mv, u8 type);
|
||||
|
||||
static bool is_between(int value, int min, int max)
|
||||
{
|
||||
if (value < min || value > max)
|
||||
@ -781,9 +791,13 @@ static int qpnp_lcdb_enable_wa(struct qpnp_lcdb *lcdb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define VOLTAGE_START_MV 4500
|
||||
#define VOLTAGE_STEP_MV 500
|
||||
|
||||
static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
|
||||
{
|
||||
int rc = 0, timeout, delay;
|
||||
int voltage_mv = VOLTAGE_START_MV;
|
||||
u8 val = 0;
|
||||
|
||||
if (lcdb->lcdb_enabled || lcdb->lcdb_sc_disable) {
|
||||
@ -806,6 +820,22 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (lcdb->voltage_step_ramp) {
|
||||
if (lcdb->ldo.voltage_mv < VOLTAGE_START_MV)
|
||||
voltage_mv = lcdb->ldo.voltage_mv;
|
||||
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, LDO);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (lcdb->ncp.voltage_mv < VOLTAGE_START_MV)
|
||||
voltage_mv = lcdb->ncp.voltage_mv;
|
||||
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, voltage_mv, NCP);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
val = MODULE_EN_BIT;
|
||||
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
|
||||
&val, 1);
|
||||
@ -842,6 +872,17 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
|
||||
}
|
||||
|
||||
lcdb->lcdb_enabled = true;
|
||||
if (lcdb->voltage_step_ramp) {
|
||||
usleep_range(10000, 11000);
|
||||
rc = qpnp_lcdb_set_voltage_step(lcdb,
|
||||
voltage_mv + VOLTAGE_STEP_MV,
|
||||
LDO_NCP);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to set LCDB voltage rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
pr_debug("lcdb enabled successfully!\n");
|
||||
|
||||
return 0;
|
||||
@ -1128,6 +1169,56 @@ static int qpnp_lcdb_set_voltage(struct qpnp_lcdb *lcdb,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qpnp_lcdb_set_voltage_step(struct qpnp_lcdb *lcdb,
|
||||
int voltage_start_mv, u8 type)
|
||||
{
|
||||
int i, ldo_voltage, ncp_voltage, voltage, rc = 0;
|
||||
|
||||
for (i = voltage_start_mv; i <= (MAX_VOLTAGE_MV + VOLTAGE_STEP_MV);
|
||||
i += VOLTAGE_STEP_MV) {
|
||||
|
||||
ldo_voltage = (lcdb->ldo.voltage_mv < i) ?
|
||||
lcdb->ldo.voltage_mv : i;
|
||||
|
||||
ncp_voltage = (lcdb->ncp.voltage_mv < i) ?
|
||||
lcdb->ncp.voltage_mv : i;
|
||||
if (type == LDO_NCP) {
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, ldo_voltage, LDO);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, ncp_voltage, NCP);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
pr_debug(" LDO voltage step %d NCP voltage step %d\n",
|
||||
ldo_voltage, ncp_voltage);
|
||||
|
||||
if ((i >= lcdb->ncp.voltage_mv) &&
|
||||
(i >= lcdb->ldo.voltage_mv))
|
||||
break;
|
||||
} else {
|
||||
voltage = (type == LDO) ? ldo_voltage : ncp_voltage;
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, voltage, type);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
pr_debug("%s voltage step %d\n",
|
||||
(type == LDO) ? "LDO" : "NCP", voltage);
|
||||
if ((type == LDO) && (i >= lcdb->ldo.voltage_mv))
|
||||
break;
|
||||
|
||||
if ((type == NCP) && (i >= lcdb->ncp.voltage_mv))
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qpnp_lcdb_get_voltage(struct qpnp_lcdb *lcdb,
|
||||
u32 *voltage_mv, u8 type)
|
||||
{
|
||||
@ -1236,11 +1327,17 @@ static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int rc = 0;
|
||||
struct qpnp_lcdb *lcdb = rdev_get_drvdata(rdev);
|
||||
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, LDO);
|
||||
lcdb->ldo.voltage_mv = min_uV / 1000;
|
||||
if (lcdb->voltage_step_ramp)
|
||||
rc = qpnp_lcdb_set_voltage_step(lcdb,
|
||||
lcdb->ldo.prev_voltage_mv + VOLTAGE_STEP_MV, LDO);
|
||||
else
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ldo.voltage_mv, LDO);
|
||||
|
||||
if (rc < 0)
|
||||
pr_err("Failed to set LDO voltage rc=%c\n", rc);
|
||||
else
|
||||
lcdb->ldo.voltage_mv = min_uV / 1000;
|
||||
lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -1309,11 +1406,17 @@ static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int rc = 0;
|
||||
struct qpnp_lcdb *lcdb = rdev_get_drvdata(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);
|
||||
lcdb->ncp.voltage_mv = min_uV / 1000;
|
||||
if (lcdb->voltage_step_ramp)
|
||||
rc = qpnp_lcdb_set_voltage_step(lcdb,
|
||||
lcdb->ncp.prev_voltage_mv + VOLTAGE_STEP_MV, NCP);
|
||||
else
|
||||
lcdb->ncp.voltage_mv = min_uV / 1000;
|
||||
rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ncp.voltage_mv, NCP);
|
||||
|
||||
if (rc < 0)
|
||||
pr_err("Failed to set NCP voltage rc=%c\n", rc);
|
||||
else
|
||||
lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -1675,6 +1778,8 @@ static int qpnp_lcdb_init_ldo(struct qpnp_lcdb *lcdb)
|
||||
return rc;
|
||||
}
|
||||
|
||||
lcdb->ldo.prev_voltage_mv = lcdb->ldo.voltage_mv;
|
||||
|
||||
rc = qpnp_lcdb_read(lcdb, lcdb->base +
|
||||
LCDB_LDO_VREG_OK_CTL_REG, &val, 1);
|
||||
if (rc < 0) {
|
||||
@ -1780,6 +1885,8 @@ static int qpnp_lcdb_init_ncp(struct qpnp_lcdb *lcdb)
|
||||
return rc;
|
||||
}
|
||||
|
||||
lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv;
|
||||
|
||||
rc = qpnp_lcdb_read(lcdb, lcdb->base +
|
||||
LCDB_NCP_VREG_OK_CTL_REG, &val, 1);
|
||||
if (rc < 0) {
|
||||
@ -2038,6 +2145,9 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
|
||||
if (lcdb->sc_irq < 0)
|
||||
pr_debug("sc irq is not defined\n");
|
||||
|
||||
lcdb->voltage_step_ramp =
|
||||
of_property_read_bool(node, "qcom,voltage-step-ramp");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user