Merge "regulator: qpnp-lcdb: Add a WA to toggle SC before module_enable"
This commit is contained in:
commit
46b41403c3
4 changed files with 98 additions and 33 deletions
|
@ -26,12 +26,10 @@ First Level Node - LCDB module
|
|||
Value type: <prop-encoded-array>
|
||||
Definition: Base address of the LCDB SPMI peripheral.
|
||||
|
||||
- qcom,force-module-reenable
|
||||
Usage: required if using SW mode for module enable
|
||||
Value type: <bool>
|
||||
Definition: This enables the workaround to force enable
|
||||
the vph_pwr_2p5_ok signal required for
|
||||
turning on the LCDB module.
|
||||
- qcom,pmic-revid
|
||||
Usage: required
|
||||
Value type: <phandle>
|
||||
Definition: Phandle to the PMIC's revid node
|
||||
|
||||
Touch-to-wake (TTW) properties:
|
||||
|
||||
|
|
|
@ -397,7 +397,7 @@
|
|||
interrupts = <0x3 0xec 0x1 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "sc-irq";
|
||||
|
||||
qcom,force-module-reenable;
|
||||
qcom,pmic-revid = <&pm660l_revid>;
|
||||
|
||||
lcdb_ldo_vreg: ldo {
|
||||
label = "ldo";
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/qpnp/qpnp-revid.h>
|
||||
|
||||
#define QPNP_LCDB_REGULATOR_DRIVER_NAME "qcom,qpnp-lcdb-regulator"
|
||||
|
||||
|
@ -192,6 +193,7 @@ struct qpnp_lcdb {
|
|||
struct device *dev;
|
||||
struct platform_device *pdev;
|
||||
struct regmap *regmap;
|
||||
struct pmic_revid_data *pmic_rev_id;
|
||||
u32 base;
|
||||
int sc_irq;
|
||||
|
||||
|
@ -199,9 +201,6 @@ struct qpnp_lcdb {
|
|||
bool ttw_enable;
|
||||
bool ttw_mode_sw;
|
||||
|
||||
/* top level DT params */
|
||||
bool force_module_reenable;
|
||||
|
||||
/* status parameters */
|
||||
bool lcdb_enabled;
|
||||
bool settings_saved;
|
||||
|
@ -579,6 +578,65 @@ static int qpnp_lcdb_ttw_exit(struct qpnp_lcdb *lcdb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qpnp_lcdb_enable_wa(struct qpnp_lcdb *lcdb)
|
||||
{
|
||||
int rc;
|
||||
u8 val = 0;
|
||||
|
||||
/* required only for PM660L */
|
||||
if (lcdb->pmic_rev_id->pmic_subtype != PM660L_SUBTYPE)
|
||||
return 0;
|
||||
|
||||
val = MODULE_EN_BIT;
|
||||
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
|
||||
&val, 1);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to enable lcdb rc= %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
|
||||
&val, 1);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to disable lcdb rc= %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* execute the below for rev1.1 */
|
||||
if (lcdb->pmic_rev_id->rev3 == PM660L_V1P1_REV3 &&
|
||||
lcdb->pmic_rev_id->rev4 == PM660L_V1P1_REV4) {
|
||||
/*
|
||||
* delay to make sure that the MID pin – ie the
|
||||
* output of the LCDB boost – returns to 0V
|
||||
* after the module is disabled
|
||||
*/
|
||||
usleep_range(10000, 10100);
|
||||
|
||||
rc = qpnp_lcdb_masked_write(lcdb,
|
||||
lcdb->base + LCDB_MISC_CTL_REG,
|
||||
DIS_SCP_BIT, DIS_SCP_BIT);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to disable SC rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
/* delay for SC-disable to take effect */
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
rc = qpnp_lcdb_masked_write(lcdb,
|
||||
lcdb->base + LCDB_MISC_CTL_REG,
|
||||
DIS_SCP_BIT, 0);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to enable SC rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
/* delay for SC-enable to take effect */
|
||||
usleep_range(1000, 1100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
|
||||
{
|
||||
int rc = 0, timeout, delay;
|
||||
|
@ -598,31 +656,20 @@ static int qpnp_lcdb_enable(struct qpnp_lcdb *lcdb)
|
|||
}
|
||||
}
|
||||
|
||||
rc = qpnp_lcdb_enable_wa(lcdb);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to execute enable_wa rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
val = MODULE_EN_BIT;
|
||||
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
|
||||
&val, 1);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to enable lcdb rc= %d\n", rc);
|
||||
pr_err("Failed to disable lcdb rc= %d\n", rc);
|
||||
goto fail_enable;
|
||||
}
|
||||
|
||||
if (lcdb->force_module_reenable) {
|
||||
val = 0;
|
||||
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
|
||||
&val, 1);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to enable lcdb rc= %d\n", rc);
|
||||
goto fail_enable;
|
||||
}
|
||||
val = MODULE_EN_BIT;
|
||||
rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
|
||||
&val, 1);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to disable lcdb rc= %d\n", rc);
|
||||
goto fail_enable;
|
||||
}
|
||||
}
|
||||
|
||||
/* poll for vreg_ok */
|
||||
timeout = 10;
|
||||
delay = lcdb->bst.soft_start_us + lcdb->ldo.soft_start_us +
|
||||
|
@ -1674,7 +1721,8 @@ static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb)
|
|||
return rc;
|
||||
}
|
||||
|
||||
if (lcdb->sc_irq >= 0) {
|
||||
if (lcdb->sc_irq >= 0 &&
|
||||
lcdb->pmic_rev_id->pmic_subtype != PM660L_SUBTYPE) {
|
||||
lcdb->sc_count = 0;
|
||||
rc = devm_request_threaded_irq(lcdb->dev, lcdb->sc_irq,
|
||||
NULL, qpnp_lcdb_sc_irq_handler, IRQF_ONESHOT,
|
||||
|
@ -1714,7 +1762,23 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
|
|||
{
|
||||
int rc = 0;
|
||||
const char *label;
|
||||
struct device_node *temp, *node = lcdb->dev->of_node;
|
||||
struct device_node *revid_dev_node, *temp, *node = lcdb->dev->of_node;
|
||||
|
||||
revid_dev_node = of_parse_phandle(node, "qcom,pmic-revid", 0);
|
||||
if (!revid_dev_node) {
|
||||
pr_err("Missing qcom,pmic-revid property - fail driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lcdb->pmic_rev_id = get_revid_data(revid_dev_node);
|
||||
if (IS_ERR(lcdb->pmic_rev_id)) {
|
||||
pr_debug("Unable to get revid data\n");
|
||||
/*
|
||||
* revid should to be defined, return -EPROBE_DEFER
|
||||
* until the revid module registers.
|
||||
*/
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(node, temp) {
|
||||
rc = of_property_read_string(temp, "label", &label);
|
||||
|
@ -1742,9 +1806,6 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
|
|||
}
|
||||
}
|
||||
|
||||
lcdb->force_module_reenable = of_property_read_bool(node,
|
||||
"qcom,force-module-reenable");
|
||||
|
||||
if (of_property_read_bool(node, "qcom,ttw-enable")) {
|
||||
rc = qpnp_lcdb_parse_ttw(lcdb);
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -208,6 +208,12 @@
|
|||
#define PM660_V1P1_REV3 0x01
|
||||
#define PM660_V1P1_REV4 0x01
|
||||
|
||||
/* PM660L REV_ID */
|
||||
#define PM660L_V1P1_REV1 0x00
|
||||
#define PM660L_V1P1_REV2 0x00
|
||||
#define PM660L_V1P1_REV3 0x01
|
||||
#define PM660L_V1P1_REV4 0x01
|
||||
|
||||
/* PMI8998 FAB_ID */
|
||||
#define PMI8998_FAB_ID_SMIC 0x11
|
||||
#define PMI8998_FAB_ID_GF 0x30
|
||||
|
|
Loading…
Add table
Reference in a new issue