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

Commit f6279805 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

regulator: qpnp-amoled: Add support to configure AB/IBB PD control in AOD



As per the hardware recommendation, add support to configure
AB/IBB PD control dynamically during AOD entry/exit.

Change-Id: Ib8f3ef4222dd06f41c0609391717e66e30bc6d5b
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 4e654050
Loading
Loading
Loading
Loading
+75 −14
Original line number Diff line number Diff line
@@ -35,15 +35,23 @@
/* AB */
#define AB_STATUS1(chip)		(chip->ab_base + 0x08)
#define AB_LDO_SW_DBG_CTL(chip)		(chip->ab_base + 0x72)
#define AB_LDO_PD_CTL(chip)		(chip->ab_base + 0x78)

/* AB_STATUS1 */
#define VREG_OK_BIT			BIT(6)
#define VREG_OK_SHIFT			6

/* AB_LDO_PD_CTL */
#define PULLDN_EN_BIT			BIT(7)

/* IBB */
#define IBB_PD_CTL(chip)		(chip->ibb_base + 0x47)
#define IBB_PS_CTL(chip)		(chip->ibb_base + 0x50)
#define IBB_NLIMIT_DAC(chip)		(chip->ibb_base + 0x61)
#define IBB_SMART_PS_CTL(chip)		(chip->ibb_base + 0x65)

/* AB_STATUS1 */
#define VREG_OK_BIT			BIT(6)
#define VREG_OK_SHIFT			6
/* IBB_PD_CTL */
#define ENABLE_PD_BIT			BIT(7)

struct amoled_regulator {
	struct regulator_desc	rdesc;
@@ -65,6 +73,7 @@ struct ab_regulator {

	/* DT params */
	bool			swire_control;
	bool			pd_control;
};

struct ibb_regulator {
@@ -72,6 +81,7 @@ struct ibb_regulator {

	/* DT params */
	bool			swire_control;
	bool			pd_control;
};

struct qpnp_amoled {
@@ -120,7 +130,7 @@ static int qpnp_amoled_write(struct qpnp_amoled *chip,
	return rc;
}

int qpnp_amoled_masked_write(struct qpnp_amoled *chip,
static int qpnp_amoled_masked_write(struct qpnp_amoled *chip,
				u16 addr, u8 mask, u8 value)
{
	int rc = 0;
@@ -208,6 +218,13 @@ static int qpnp_ab_ibb_regulator_get_voltage(struct regulator_dev *rdev)
	return 0;
}

static int qpnp_ab_pd_control(struct qpnp_amoled *chip, bool en)
{
	u8 val = en ? PULLDN_EN_BIT : 0;

	return qpnp_amoled_write(chip, AB_LDO_PD_CTL(chip), &val, 1);
}

#define AB_VREG_OK_POLL_TRIES		50
#define AB_VREG_OK_POLL_TIME_US		2000
#define AB_VREG_OK_POLL_HIGH_TRIES	8
@@ -301,6 +318,14 @@ static int qpnp_ab_poll_vreg_ok(struct qpnp_amoled *chip, bool status)
	return -ETIMEDOUT;
}

static int qpnp_ibb_pd_control(struct qpnp_amoled *chip, bool en)
{
	u8 val = en ? ENABLE_PD_BIT : 0;

	return qpnp_amoled_masked_write(chip, IBB_PD_CTL(chip), ENABLE_PD_BIT,
					val);
}

static int qpnp_ibb_aod_config(struct qpnp_amoled *chip, bool aod)
{
	int rc;
@@ -363,18 +388,54 @@ static void qpnp_amoled_aod_work(struct work_struct *work)
		rc = qpnp_ibb_aod_config(chip, false);
		if (rc < 0)
			goto error;

		if (chip->ibb.pd_control) {
			rc = qpnp_ibb_pd_control(chip, true);
			if (rc < 0)
				goto error;
		}

		if (chip->ab.pd_control) {
			rc = qpnp_ab_pd_control(chip, true);
			if (rc < 0)
				goto error;
		}
	} else if (mode == REGULATOR_MODE_IDLE) {
		/* poll for VREG_OK low */
		rc = qpnp_ab_poll_vreg_ok(chip, false);
		if (rc < 0)
			goto error;

		if (chip->ibb.pd_control) {
			rc = qpnp_ibb_pd_control(chip, false);
			if (rc < 0)
				goto error;
		}

		if (chip->ab.pd_control) {
			rc = qpnp_ab_pd_control(chip, false);
			if (rc < 0)
				goto error;
		}

		val = 0xF1;
	} else if (mode == REGULATOR_MODE_STANDBY) {
		/* Restore the normal configuration without any delay */
		rc = qpnp_ibb_aod_config(chip, false);
		if (rc < 0)
			goto error;

		if (chip->ibb.pd_control) {
			rc = qpnp_ibb_pd_control(chip, true);
			if (rc < 0)
				goto error;
		}

		if (chip->ab.pd_control) {
			rc = qpnp_ab_pd_control(chip, true);
			if (rc < 0)
				goto error;
		}
	}

	rc = qpnp_amoled_write(chip, AB_LDO_SW_DBG_CTL(chip), &val, 1);
@@ -620,7 +681,6 @@ static int qpnp_amoled_parse_dt(struct qpnp_amoled *chip)
{
	struct device_node *temp, *node = chip->dev->of_node;
	const __be32 *prop_addr;
	bool swire_control;
	int rc = 0;
	u32 base, val;

@@ -642,23 +702,24 @@ static int qpnp_amoled_parse_dt(struct qpnp_amoled *chip)
		case OLEDB_PERIPH_TYPE:
			chip->oledb_base = base;
			chip->oledb.vreg.node = temp;
			swire_control = of_property_read_bool(temp,
			chip->oledb.swire_control = of_property_read_bool(temp,
							"qcom,swire-control");
			chip->oledb.swire_control = swire_control;
			break;
		case AB_PERIPH_TYPE:
			chip->ab_base = base;
			chip->ab.vreg.node = temp;
			swire_control = of_property_read_bool(temp,
			chip->ab.swire_control = of_property_read_bool(temp,
							"qcom,swire-control");
			chip->ab.swire_control = swire_control;
			chip->ab.pd_control = of_property_read_bool(temp,
							"qcom,aod-pd-control");
			break;
		case IBB_PERIPH_TYPE:
			chip->ibb_base = base;
			chip->ibb.vreg.node = temp;
			swire_control = of_property_read_bool(temp,
			chip->ibb.swire_control = of_property_read_bool(temp,
							"qcom,swire-control");
			chip->ibb.swire_control = swire_control;
			chip->ibb.pd_control = of_property_read_bool(temp,
							"qcom,aod-pd-control");
			break;
		default:
			pr_err("Unknown peripheral type 0x%x\n", val);