Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37265b61 authored by Kiran Gunda's avatar Kiran Gunda
Browse files

regulator: qpnp-lcdb: Add a DT property for LDO power-down delay



Add "qcom,pwrdn-delay-ms" device tree property to meet the power
down delay spec for few display panels. Also, enable force-pull
down on module disable to do a quick discharge of the LDO.

Change-Id: I07d55cdbfe3b253579ca3722fc02604a4a7483e0
Signed-off-by: default avatarKiran Gunda <kgunda@codeaurora.org>
parent 154aa474
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,12 @@ First Level Node - LCDB module
		     to be enabled only on platforms where voltage needs to
		     to be enabled only on platforms where voltage needs to
		     be ramped up with multiple steps.
		     be ramped up with multiple steps.


- qcom,pwrdn-delay-ms
	Usage:      optional
	Value type: <u32>
	Definition:  Required to control the LDO power down delay.
		     Possible values are 0, 1, 4, 8.

Touch-to-wake (TTW) properties:
Touch-to-wake (TTW) properties:


TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable
TTW supports 2 modes of operation - HW and SW. In the HW mode the enable/disable
+94 −2
Original line number Original line Diff line number Diff line
@@ -114,6 +114,10 @@
#define PFM_CURRENT_SHIFT		2
#define PFM_CURRENT_SHIFT		2


#define LCDB_PWRUP_PWRDN_CTL_REG	0x66
#define LCDB_PWRUP_PWRDN_CTL_REG	0x66
#define PWRUP_DELAY_MASK		GENAMSK(3, 2)
#define PWRDN_DELAY_MASK		GENMASK(1, 0)
#define PWRDN_DELAY_MIN_MS		0
#define PWRDN_DELAY_MAX_MS		8


/* LDO */
/* LDO */
#define LCDB_LDO_OUTPUT_VOLTAGE_REG	0x71
#define LCDB_LDO_OUTPUT_VOLTAGE_REG	0x71
@@ -126,6 +130,10 @@
#define LDO_DIS_PULLDOWN_BIT		BIT(1)
#define LDO_DIS_PULLDOWN_BIT		BIT(1)
#define LDO_PD_STRENGTH_BIT		BIT(0)
#define LDO_PD_STRENGTH_BIT		BIT(0)


#define LCDB_LDO_FORCE_PD_CTL_REG	0x79
#define LDO_FORCE_PD_EN_BIT		BIT(0)
#define LDO_FORCE_PD_MODE		BIT(7)

#define LCDB_LDO_ILIM_CTL1_REG		0x7B
#define LCDB_LDO_ILIM_CTL1_REG		0x7B
#define EN_LDO_ILIM_BIT			BIT(7)
#define EN_LDO_ILIM_BIT			BIT(7)
#define SET_LDO_ILIM_MASK		GENMASK(2, 0)
#define SET_LDO_ILIM_MASK		GENMASK(2, 0)
@@ -220,7 +228,9 @@ struct qpnp_lcdb {
	struct regmap			*regmap;
	struct regmap			*regmap;
	struct pmic_revid_data		*pmic_rev_id;
	struct pmic_revid_data		*pmic_rev_id;
	u32				base;
	u32				base;
	u32				wa_flags;
	int				sc_irq;
	int				sc_irq;
	int				pwrdn_delay_ms;


	/* TTW params */
	/* TTW params */
	bool				ttw_enable;
	bool				ttw_enable;
@@ -292,6 +302,11 @@ enum lcdb_settings_index {
	LCDB_SETTING_MAX,
	LCDB_SETTING_MAX,
};
};


enum lcdb_wa_flags {
	NCP_SCP_DISABLE_WA = BIT(0),
	FORCE_PD_ENABLE_WA = BIT(1),
};

static u32 soft_start_us[] = {
static u32 soft_start_us[] = {
	0,
	0,
	500,
	500,
@@ -313,6 +328,13 @@ static u32 ncp_ilim_ma[] = {
	810,
	810,
};
};


static const u32 pwrup_pwrdn_ms[] = {
	0,
	1,
	4,
	8,
};

#define SETTING(_id, _sec_access, _valid)	\
#define SETTING(_id, _sec_access, _valid)	\
	[_id] = {				\
	[_id] = {				\
		.address = _id##_REG,		\
		.address = _id##_REG,		\
@@ -915,6 +937,18 @@ static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb)
		return 0;
		return 0;
	}
	}


	if (lcdb->wa_flags & FORCE_PD_ENABLE_WA) {
		/*
		 * force pull-down to enable quick discharge after
		 * turning off
		 */
		val = LDO_FORCE_PD_EN_BIT | LDO_FORCE_PD_MODE;
		rc = qpnp_lcdb_write(lcdb, lcdb->base +
				     LCDB_LDO_FORCE_PD_CTL_REG, &val, 1);
		if (rc < 0)
			return rc;
	}

	val = 0;
	val = 0;
	rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
	rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_ENABLE_CTL1_REG,
							&val, 1);
							&val, 1);
@@ -923,6 +957,17 @@ static int qpnp_lcdb_disable(struct qpnp_lcdb *lcdb)
	else
	else
		lcdb->lcdb_enabled = false;
		lcdb->lcdb_enabled = false;


	if (lcdb->wa_flags & FORCE_PD_ENABLE_WA) {
		/* wait for 10 msec after module disable for LDO to discharge */
		usleep_range(10000, 11000);

		val = 0;
		rc = qpnp_lcdb_write(lcdb, lcdb->base +
				     LCDB_LDO_FORCE_PD_CTL_REG, &val, 1);
		if (rc < 0)
			return rc;
	}

	return rc;
	return rc;
}
}


@@ -2020,11 +2065,40 @@ static int qpnp_lcdb_init_bst(struct qpnp_lcdb *lcdb)
	return 0;
	return 0;
}
}


static void qpnp_lcdb_pmic_config(struct qpnp_lcdb *lcdb)
{
	switch (lcdb->pmic_rev_id->pmic_subtype) {
	case PM660L_SUBTYPE:
		if (lcdb->pmic_rev_id->rev4 < PM660L_V2P0_REV4)
			lcdb->wa_flags |= NCP_SCP_DISABLE_WA;
		break;
	case PMI632_SUBTYPE:
	case PM6150L_SUBTYPE:
		lcdb->wa_flags |= FORCE_PD_ENABLE_WA;
		break;
	default:
		break;
	}

	pr_debug("LCDB wa_flags = 0x%2x\n", lcdb->wa_flags);
}

static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb)
static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb)
{
{
	int rc = 0;
	int rc = 0;
	u8 val = 0;
	u8 val = 0;


	qpnp_lcdb_pmic_config(lcdb);

	if (lcdb->pwrdn_delay_ms != -EINVAL) {
		rc = qpnp_lcdb_masked_write(lcdb, lcdb->base +
					    LCDB_PWRUP_PWRDN_CTL_REG,
					    PWRDN_DELAY_MASK,
					    lcdb->pwrdn_delay_ms);
		if (rc < 0)
			return rc;
	}

	rc = qpnp_lcdb_init_bst(lcdb);
	rc = qpnp_lcdb_init_bst(lcdb);
	if (rc < 0) {
	if (rc < 0) {
		pr_err("Failed to initialize BOOST rc=%d\n", rc);
		pr_err("Failed to initialize BOOST rc=%d\n", rc);
@@ -2082,7 +2156,8 @@ static int qpnp_lcdb_hw_init(struct qpnp_lcdb *lcdb)


static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
{
{
	int rc = 0;
	int rc = 0, i = 0;
	u32 tmp;
	const char *label;
	const char *label;
	struct device_node *revid_dev_node, *temp, *node = lcdb->dev->of_node;
	struct device_node *revid_dev_node, *temp, *node = lcdb->dev->of_node;


@@ -2146,7 +2221,24 @@ static int qpnp_lcdb_parse_dt(struct qpnp_lcdb *lcdb)
	lcdb->voltage_step_ramp =
	lcdb->voltage_step_ramp =
			of_property_read_bool(node, "qcom,voltage-step-ramp");
			of_property_read_bool(node, "qcom,voltage-step-ramp");


	return rc;
	lcdb->pwrdn_delay_ms = -EINVAL;
	rc = of_property_read_u32(node, "qcom,pwrdn-delay-ms", &tmp);
	if (!rc) {
		if (!is_between(tmp, PWRDN_DELAY_MIN_MS, PWRDN_DELAY_MAX_MS)) {
			pr_err("Invalid PWRDN_DLY val %d (min=%d max=%d)\n",
				tmp, PWRDN_DELAY_MIN_MS, PWRDN_DELAY_MAX_MS);
			return -EINVAL;
		}

		for (i = 0; i < ARRAY_SIZE(pwrup_pwrdn_ms); i++) {
			if (tmp == pwrup_pwrdn_ms[i]) {
				lcdb->pwrdn_delay_ms = i;
				break;
			}
		}
	}

	return 0;
}
}


static int qpnp_lcdb_regulator_probe(struct platform_device *pdev)
static int qpnp_lcdb_regulator_probe(struct platform_device *pdev)