Skip to content

Commit

Permalink
regulator: qpnp-lcdb: Add support for voltage step programming
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
I-n-o-k committed Oct 8, 2018
1 parent 9fc9808 commit 08368b3
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
122 changes: 116 additions & 6 deletions drivers/regulator/qpnp-lcdb-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -230,8 +232,8 @@ struct qpnp_lcdb {
bool lcdb_enabled;
bool settings_saved;
bool lcdb_sc_disable;
/* Tracks the secure UI mode entry/exit */
bool secure_mode;
bool voltage_step_ramp;
int sc_count;
ktime_t sc_module_enable_time;

Expand All @@ -253,6 +255,7 @@ enum lcdb_module {
LDO,
NCP,
BST,
LDO_NCP,
};

enum pfm_hysteresis {
Expand Down Expand Up @@ -324,6 +327,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)
Expand Down Expand Up @@ -787,9 +796,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) {
Expand All @@ -812,6 +825,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);
Expand Down Expand Up @@ -848,6 +877,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;
Expand Down Expand Up @@ -1134,6 +1174,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)
{
Expand Down Expand Up @@ -1251,11 +1341,17 @@ static int qpnp_lcdb_ldo_regulator_set_voltage(struct regulator_dev *rdev,
if (lcdb->secure_mode)
return 0;

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;
}
Expand Down Expand Up @@ -1333,11 +1429,17 @@ static int qpnp_lcdb_ncp_regulator_set_voltage(struct regulator_dev *rdev,
if (lcdb->secure_mode)
return 0;

rc = qpnp_lcdb_set_voltage(lcdb, min_uV / 1000, NCP);
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
rc = qpnp_lcdb_set_voltage(lcdb, lcdb->ncp.voltage_mv, NCP);

if (rc < 0)
pr_err("Failed to set LDO voltage rc=%c\n", rc);
pr_err("Failed to set NCP voltage rc=%c\n", rc);
else
lcdb->ncp.voltage_mv = min_uV / 1000;
lcdb->ncp.prev_voltage_mv = lcdb->ncp.voltage_mv;

return rc;
}
Expand Down Expand Up @@ -1699,6 +1801,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) {
Expand Down Expand Up @@ -1804,6 +1908,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) {
Expand Down Expand Up @@ -2040,6 +2146,7 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
}

of_node_put(revid_dev_node);

for_each_available_child_of_node(node, temp) {
rc = of_property_read_string(temp, "label", &label);
if (rc < 0) {
Expand Down Expand Up @@ -2079,6 +2186,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;
}

Expand Down

0 comments on commit 08368b3

Please sign in to comment.