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

Commit 94bd0759 authored by Chandana Kishori Chiluveru's avatar Chandana Kishori Chiluveru Committed by Gerrit - the friendly Code Review server
Browse files

QUSB2PHY: Fix leakage current issue during wall charger disconnect



It is required to disable QUSB2PHY level shifter by writing to
TCSR_QUSB2PHY_CX2PX_LVL_SHIFT_KEEPER register during disconnect
to avoid leakage current. Hence add support for the same.

Change-Id: I666617d513314903533f2356b5db4b9ca3eac6e4
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: default avatarChandana Kishori Chiluveru <cchiluve@codeaurora.org>
parent d5954b91
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -160,6 +160,9 @@ Optional properties:
   "efuse_addr": EFUSE address to read and update analog tune parameter.
   "emu_phy_base" : phy base address used for programming emulation target phy.
   "ref_clk_addr" : ref_clk bcr address used for on/off ref_clk before reset.
   "tcsr_clamp_dig_n" : To enable/disable digital clamp to the phy. When
   de-asserted, it will prevent random leakage from qusb2 phy resulting from
   out of sequence turn on/off of 1p8, 3p3 and DVDD regulators.
   "refgen_north_bg_reg" : address used to read REFGEN status for overriding QUSB PHY register.
 - clocks: a list of phandles to the PHY clocks. Use as per
   Documentation/devicetree/bindings/clock/clock-bindings.txt
+25 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ struct qusb_phy {
	void __iomem		*base;
	void __iomem		*tune2_efuse_reg;
	void __iomem		*ref_clk_base;
	void __iomem		*tcsr_clamp_dig_n;

	struct clk		*ref_clk_src;
	struct clk		*ref_clk;
@@ -652,6 +653,9 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
			wmb();

			qusb_phy_enable_clocks(qphy, false);
			if (qphy->tcsr_clamp_dig_n)
				writel_relaxed(0x0,
					qphy->tcsr_clamp_dig_n);
			qusb_phy_enable_power(qphy, false);

			/*
@@ -674,6 +678,9 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend)
				qphy->base + QUSB2PHY_PORT_INTR_CTRL);
		} else {
			qusb_phy_enable_power(qphy, true);
			if (qphy->tcsr_clamp_dig_n)
				writel_relaxed(0x1,
					qphy->tcsr_clamp_dig_n);
			qusb_phy_enable_clocks(qphy, true);
		}
		qphy->suspended = false;
@@ -723,6 +730,10 @@ static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev)
		}
		qphy->dpdm_enable = true;
		if (qphy->put_into_high_z_state) {
			if (qphy->tcsr_clamp_dig_n)
				writel_relaxed(0x1,
				qphy->tcsr_clamp_dig_n);

			qusb_phy_gdsc(qphy, true);
			qusb_phy_enable_clocks(qphy, true);

@@ -776,6 +787,9 @@ static int qusb_phy_dpdm_regulator_disable(struct regulator_dev *rdev)

	if (qphy->dpdm_enable) {
		if (!qphy->cable_connected) {
			if (qphy->tcsr_clamp_dig_n)
				writel_relaxed(0x0,
					qphy->tcsr_clamp_dig_n);
			dev_dbg(qphy->phy.dev, "turn off for HVDCP case\n");
			ret = qusb_phy_enable_power(qphy, false);
			if (ret < 0) {
@@ -916,6 +930,17 @@ static int qusb_phy_probe(struct platform_device *pdev)
		}
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
						"tcsr_clamp_dig_n_1p8");
	if (res) {
		qphy->tcsr_clamp_dig_n = devm_ioremap_nocache(dev,
				res->start, resource_size(res));
		if (IS_ERR(qphy->tcsr_clamp_dig_n)) {
			dev_err(dev, "err reading tcsr_clamp_dig_n\n");
			qphy->tcsr_clamp_dig_n = NULL;
		}
	}

	qphy->ref_clk_src = devm_clk_get(dev, "ref_clk_src");
	if (IS_ERR(qphy->ref_clk_src))
		dev_dbg(dev, "clk get failed for ref_clk_src\n");