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

Commit 0c4e61b0 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

leds: qpnp-wled: Improve auto calibration algorithm



If CABC is enabled and auto calibration is attempted, then OVP
fault can be seen even with a valid sink configuration and a
brightness level greater than or equal to 0.4 % dimming. This is
because of the modulation done through CABC pin which if low
enough can cause the brightness level to still go further down.

Fix this by disabling CABC on all sinks before running auto
calibration and re-enable it if the feature is enabled. Also,
modify the auto calibration brightness level to 200 so that the
load increase on WLED_VOUT can bring the voltage below OVP
threshold quick enough on a valid sink configuration.

Finally, disable WLED module before switching the sink
configuration and enable it after configuring sinks.

CRs-Fixed: 2125217
Change-Id: I570dc9eba540cd96328afd7c68f4643a112c4962
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 8b9dd591
Loading
Loading
Loading
Loading
+39 −24
Original line number Diff line number Diff line
@@ -1098,7 +1098,7 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr)
	return 0;
}

#define AUTO_CALIB_BRIGHTNESS		16
#define AUTO_CALIB_BRIGHTNESS		200
static int wled_auto_calibrate(struct qpnp_wled *wled)
{
	int rc = 0, i;
@@ -1128,6 +1128,17 @@ static int wled_auto_calibrate(struct qpnp_wled *wled)
		goto failed_calib;
	}

	if (wled->en_cabc) {
		for (i = 0; i < wled->max_strings; i++) {
			reg = 0;
			rc = qpnp_wled_masked_write_reg(wled,
				QPNP_WLED_CABC_REG(wled->sink_base, i),
				QPNP_WLED_CABC_MASK, reg);
			if (rc < 0)
				goto failed_calib;
		}
	}

	/* disable all sinks */
	rc = qpnp_wled_write_reg(wled,
		 QPNP_WLED_CURR_SINK_REG(wled->sink_base), 0);
@@ -1136,21 +1147,6 @@ static int wled_auto_calibrate(struct qpnp_wled *wled)
		goto failed_calib;
	}

	rc = qpnp_wled_masked_write_reg(wled,
		QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
		QPNP_WLED_MODULE_EN_MASK,
		QPNP_WLED_MODULE_EN_MASK);
	if (rc < 0) {
		pr_err("Failed to enable WLED module rc=%d\n", rc);
		goto failed_calib;
	}
	/*
	 * Delay for the WLED soft-start, check the OVP status
	 * only after soft-start is complete
	 */
	usleep_range(QPNP_WLED_SOFT_START_DLY_US,
			QPNP_WLED_SOFT_START_DLY_US + 1000);

	/* iterate through the strings one by one */
	for (i = 0; i < wled->max_strings; i++) {
		sink_test = 1 << (QPNP_WLED_CURR_SINK_SHIFT + i);
@@ -1174,6 +1170,15 @@ static int wled_auto_calibrate(struct qpnp_wled *wled)
			goto failed_calib;
		}

		/* Enable the module */
		rc = qpnp_wled_masked_write_reg(wled,
			QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
			QPNP_WLED_MODULE_EN_MASK, QPNP_WLED_MODULE_EN_MASK);
		if (rc < 0) {
			pr_err("Failed to enable WLED module rc=%d\n", rc);
			goto failed_calib;
		}

		/* delay for WLED soft-start */
		usleep_range(QPNP_WLED_SOFT_START_DLY_US,
				QPNP_WLED_SOFT_START_DLY_US + 1000);
@@ -1190,6 +1195,15 @@ static int wled_auto_calibrate(struct qpnp_wled *wled)
						i + 1);
		else
			sink_valid |= sink_test;

		/* Disable the module */
		rc = qpnp_wled_masked_write_reg(wled,
			QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
			QPNP_WLED_MODULE_EN_MASK, 0);
		if (rc < 0) {
			pr_err("Failed to disable WLED module rc=%d\n", rc);
			goto failed_calib;
		}
	}

	if (sink_valid == sink_config) {
@@ -1206,14 +1220,6 @@ static int wled_auto_calibrate(struct qpnp_wled *wled)
		goto failed_calib;
	}

	rc = qpnp_wled_masked_write_reg(wled,
			QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
			QPNP_WLED_MODULE_EN_MASK, 0);
	if (rc < 0) {
		pr_err("Failed to disable WLED module rc=%d\n", rc);
		goto failed_calib;
	}

	/* write the new sink configuration */
	rc = qpnp_wled_write_reg(wled,
			QPNP_WLED_CURR_SINK_REG(wled->sink_base), sink_config);
@@ -1224,6 +1230,15 @@ static int wled_auto_calibrate(struct qpnp_wled *wled)

	/* MODULATOR_EN setting for valid sinks */
	for (i = 0; i < wled->max_strings; i++) {
		if (wled->en_cabc) {
			reg = 1 << QPNP_WLED_CABC_SHIFT;
			rc = qpnp_wled_masked_write_reg(wled,
				QPNP_WLED_CABC_REG(wled->sink_base, i),
				QPNP_WLED_CABC_MASK, reg);
			if (rc < 0)
				goto failed_calib;
		}

		if (sink_config & (1 << (QPNP_WLED_CURR_SINK_SHIFT + i)))
			reg = (QPNP_WLED_MOD_EN << QPNP_WLED_MOD_EN_SHFT);
		else