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

Commit 879af4d5 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "regulator: qpnp-labibb: do not disable IBB when entering TTW mode"

parents 5660cc2f ff4f254e
Loading
Loading
Loading
Loading
+72 −54
Original line number Diff line number Diff line
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -160,6 +160,7 @@
#define IBB_MODULE_RDY_EN		BIT(7)

/* REG_IBB_ENABLE_CTL */
#define IBB_ENABLE_CTL_MASK		(BIT(7) | BIT(6))
#define IBB_ENABLE_CTL_SWIRE_RDY	BIT(6)
#define IBB_ENABLE_CTL_MODULE_EN	BIT(7)

@@ -243,6 +244,17 @@ enum qpnp_labibb_mode {
	QPNP_LABIBB_MAX_MODE,
};

/**
 * IBB_SW_CONTROL_EN: Specifies IBB is enabled through software.
 * IBB_SW_CONTROL_DIS: Specifies IBB is disabled through software.
 * IBB_HW_CONTROL: Specifies IBB is controlled through SWIRE (hardware).
 */
enum ibb_mode {
	IBB_SW_CONTROL_EN,
	IBB_SW_CONTROL_DIS,
	IBB_HW_CONTROL,
};

static const int ibb_discharge_resistor_plan[] = {
	300,
	64,
@@ -606,6 +618,29 @@ static int qpnp_labibb_get_matching_idx(const char *val)
	return -EINVAL;
}

static int qpnp_ibb_set_mode(struct qpnp_labibb *labibb, enum ibb_mode mode)
{
	int rc;
	u8 val;

	if (mode == IBB_SW_CONTROL_EN)
		val = IBB_ENABLE_CTL_MODULE_EN;
	else if (mode == IBB_HW_CONTROL)
		val = IBB_ENABLE_CTL_SWIRE_RDY;
	else if (mode == IBB_SW_CONTROL_DIS)
		val = 0;
	else
		return -EINVAL;

	rc = qpnp_labibb_masked_write(labibb,
		labibb->ibb_base + REG_IBB_ENABLE_CTL,
		IBB_ENABLE_CTL_MASK, val);
	if (rc)
		pr_err("Unable to configure IBB_ENABLE_CTL rc=%d\n", rc);

	return rc;
}

static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
				struct device_node *of_node)
{
@@ -847,9 +882,7 @@ static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
	}

	if (labibb->swire_control) {
		val = IBB_ENABLE_CTL_SWIRE_RDY;
		rc = qpnp_labibb_write(labibb,
			labibb->ibb_base + REG_IBB_ENABLE_CTL, &val, 1);
		rc = qpnp_ibb_set_mode(labibb, IBB_HW_CONTROL);
		if (rc)
			pr_err("Unable to set SWIRE_RDY rc=%d\n", rc);
	}
@@ -1026,12 +1059,9 @@ static int qpnp_labibb_regulator_ttw_mode_enter(struct qpnp_labibb *labibb)
		return rc;
	}

	val = IBB_ENABLE_CTL_SWIRE_RDY;
	rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_ENABLE_CTL,
		&val, 1);
	rc = qpnp_ibb_set_mode(labibb, IBB_HW_CONTROL);
	if (rc) {
		pr_err("qpnp_labibb_write register %x failed rc = %d\n",
				REG_IBB_ENABLE_CTL, rc);
		pr_err("Unable to set SWIRE_RDY rc = %d\n", rc);
		return rc;
	}
	labibb->in_ttw_mode = true;
@@ -1082,16 +1112,6 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
		return rc;
	}

	val = 0;
	rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_ENABLE_CTL,
		&val, 1);

	if (rc) {
		pr_err("qpnp_labibb_write register %x failed rc = %d\n",
				REG_IBB_ENABLE_CTL, rc);
		return rc;
	}

	labibb->in_ttw_mode = false;
	return rc;
}
@@ -1099,7 +1119,7 @@ static int qpnp_labibb_regulator_ttw_mode_exit(struct qpnp_labibb *labibb)
static int qpnp_labibb_regulator_enable(struct qpnp_labibb *labibb)
{
	int rc;
	u8 val = IBB_ENABLE_CTL_MODULE_EN;
	u8 val;
	int dly;
	int retries;
	bool enabled = false;
@@ -1113,12 +1133,9 @@ static int qpnp_labibb_regulator_enable(struct qpnp_labibb *labibb)
		}
	}

	rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_ENABLE_CTL,
		&val, 1);

	rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_EN);
	if (rc) {
		pr_err("write register %x failed rc = %d\n",
			REG_IBB_ENABLE_CTL, rc);
		pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
		return rc;
	}

@@ -1174,12 +1191,11 @@ static int qpnp_labibb_regulator_enable(struct qpnp_labibb *labibb)

	return 0;
err_out:
	val = 0;
	rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_ENABLE_CTL,
		&val, 1);
	if (rc)
		pr_err("write register %x failed rc = %d\n",
				REG_IBB_ENABLE_CTL, rc);
	rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
	if (rc) {
		pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
		return rc;
	}
	return -EINVAL;
}

@@ -1191,12 +1207,28 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb)
	int retries;
	bool disabled = false;

	val = 0;
	rc = qpnp_labibb_write(labibb,
			labibb->ibb_base + REG_IBB_ENABLE_CTL, &val, 1);
	/*
	 * When TTW mode is enabled and LABIBB regulators are disabled, it is
	 * recommended not to disable IBB through IBB_ENABLE_CTL when switching
	 * to SWIRE control on entering TTW mode. Hence, just enter TTW mode
	 * and mark the regulators disabled. When we exit TTW mode, normal
	 * mode settings will be restored anyways and regulators will be
	 * enabled as before.
	 */
	if (labibb->ttw_en && !labibb->in_ttw_mode) {
		rc = qpnp_labibb_regulator_ttw_mode_enter(labibb);
		if (rc) {
		pr_err("write register %x failed rc = %d\n",
			REG_IBB_ENABLE_CTL, rc);
			pr_err("Error in entering TTW mode rc = %d\n", rc);
			return rc;
		}
		labibb->lab_vreg.vreg_enabled = 0;
		labibb->ibb_vreg.vreg_enabled = 0;
		return 0;
	}

	rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
	if (rc) {
		pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
		return rc;
	}

@@ -1227,13 +1259,6 @@ static int qpnp_labibb_regulator_disable(struct qpnp_labibb *labibb)
	labibb->lab_vreg.vreg_enabled = 0;
	labibb->ibb_vreg.vreg_enabled = 0;

	if (labibb->ttw_en && !labibb->in_ttw_mode) {
		rc = qpnp_labibb_regulator_ttw_mode_enter(labibb);
		if (rc) {
			pr_err("Error in entering TTW mode rc = %d\n", rc);
			return rc;
		}
	}
	return 0;
}

@@ -1938,12 +1963,9 @@ static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev)
		if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
			return qpnp_labibb_regulator_enable(labibb);

		val = IBB_ENABLE_CTL_MODULE_EN;
		rc = qpnp_labibb_write(labibb,
			labibb->ibb_base + REG_IBB_ENABLE_CTL, &val, 1);
		rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_EN);
		if (rc) {
			pr_err("qpnp_ibb_regulator_enable write register %x failed rc = %d\n",
				REG_IBB_ENABLE_CTL, rc);
			pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
			return rc;
		}

@@ -1970,7 +1992,6 @@ static int qpnp_ibb_regulator_enable(struct regulator_dev *rdev)
static int qpnp_ibb_regulator_disable(struct regulator_dev *rdev)
{
	int rc;
	u8 val;
	struct qpnp_labibb *labibb  = rdev_get_drvdata(rdev);

	if (labibb->ibb_vreg.vreg_enabled && !labibb->swire_control) {
@@ -1978,12 +1999,9 @@ static int qpnp_ibb_regulator_disable(struct regulator_dev *rdev)
		if (labibb->mode != QPNP_LABIBB_STANDALONE_MODE)
			return qpnp_labibb_regulator_disable(labibb);

		val = 0;
		rc = qpnp_labibb_write(labibb, labibb->ibb_base +
			REG_IBB_ENABLE_CTL, &val, 1);
		rc = qpnp_ibb_set_mode(labibb, IBB_SW_CONTROL_DIS);
		if (rc) {
			pr_err("qpnp_ibb_regulator_enable write register %x failed rc = %d\n",
				REG_IBB_ENABLE_CTL, rc);
			pr_err("Unable to set IBB_MODULE_EN rc = %d\n", rc);
			return rc;
		}