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

Commit cf276499 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

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

parents a7ac8b43 75a77196
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -61,6 +61,12 @@ Subnode common properties for OLEDB and AB/IBB regulator devices.
		    controlled by SWIRE signal. When this is specified, output
		    voltage of the regulator is not controlled by SW.

- qcom,aod-pd-control:
	Usage:      optional
	Value type: <empty>
	Definition: A boolean property to specify that the pull down control
		    for AB/IBB needs to be configured during AOD mode.

Example:

pm8150a_amoled: oledb@e000 {
@@ -82,6 +88,7 @@ pm8150a_amoled: oledb@e000 {
		regulator-min-microvolt = <4600000>;
		regulator-max-microvolt = <6100000>;
		qcom,swire-control;
		qcom,aod-pd-control;
	};

	ibb_vreg: ibb@dc00 {
@@ -91,5 +98,6 @@ pm8150a_amoled: oledb@e000 {
		regulator-min-microvolt = <800000>;
		regulator-max-microvolt = <5400000>;
		qcom,swire-control;
		qcom,aod-pd-control;
	};
};
+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);