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

Commit f9cba4d6 authored by Abhijeet Dharmapurikar's avatar Abhijeet Dharmapurikar
Browse files

power: qpnp-smbcharger: cleanup deglich api



The deglitch time is set at many places. Create a single api to
set this.

Also, use the hvdcp status api in the deglitch workaround checker
function instead of reading the register again. This fixes a bug
where the code could end up potentially reading an incorrect register/bit
for hvdcp status.

CRs-Fixed: 948903
Change-Id: I26f72960288e2b7af73a3d807cce966ccd3d68f4
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent 8f66dead
Loading
Loading
Loading
Loading
+56 −73
Original line number Diff line number Diff line
@@ -1679,6 +1679,34 @@ static int smbchg_get_min_parallel_current_ma(struct smbchg_chip *chip)
	return chip->parallel.min_current_thr_ma;
}

static bool is_hvdcp_present(struct smbchg_chip *chip)
{
	int rc;
	u8 reg, hvdcp_sel;

	rc = smbchg_read(chip, &reg,
			chip->usb_chgpth_base + USBIN_HVDCP_STS, 1);
	if (rc < 0) {
		pr_err("Couldn't read hvdcp status rc = %d\n", rc);
		return false;
	}

	pr_smb(PR_STATUS, "HVDCP_STS = 0x%02x\n", reg);
	/*
	 * If a valid HVDCP is detected, notify it to the usb_psy only
	 * if USB is still present.
	 */
	if (chip->schg_version == QPNP_SCHG_LITE)
		hvdcp_sel = SCHG_LITE_USBIN_HVDCP_SEL_BIT;
	else
		hvdcp_sel = USBIN_HVDCP_SEL_BIT;

	if ((reg & hvdcp_sel) && is_usb_present(chip))
		return true;

	return false;
}

#define FCC_CFG			0xF2
#define FCC_500MA_VAL		0x4
#define FCC_MASK		SMB_MASK(4, 0)
@@ -3122,29 +3150,26 @@ static int smbchg_hw_aicl_rerun_en(struct smbchg_chip *chip, bool en)
	return rc;
}

static int smbchg_aicl_config(struct smbchg_chip *chip)
static int smbchg_aicl_deglitch_config(struct smbchg_chip *chip, bool longer)
{
	int rc = 0;

	rc = smbchg_sec_masked_write(chip,
		chip->usb_chgpth_base + USB_AICL_CFG,
		USB_AICL_DEGLITCH_MASK, USB_AICL_DEGLITCH_LONG);
	if (rc) {
		USB_AICL_DEGLITCH_MASK,
		longer ? USB_AICL_DEGLITCH_LONG : USB_AICL_DEGLITCH_SHORT);
	if (rc < 0) {
		pr_err("Couldn't write to USB_AICL_CFG rc=%d\n", rc);
		return rc;
	}
	rc = smbchg_sec_masked_write(chip,
		chip->dc_chgpth_base + DC_AICL_CFG,
		DC_AICL_DEGLITCH_MASK, DC_AICL_DEGLITCH_LONG);
	if (rc) {
		DC_AICL_DEGLITCH_MASK,
		longer ? DC_AICL_DEGLITCH_LONG : DC_AICL_DEGLITCH_SHORT);
	if (rc < 0) {
		pr_err("Couldn't write to DC_AICL_CFG rc=%d\n", rc);
		return rc;
	}
	if (!chip->very_weak_charger) {
		rc = smbchg_hw_aicl_rerun_en(chip, true);
		if (rc)
			pr_err("Couldn't enable AICL rerun rc= %d\n", rc);
	}
	return rc;
}

@@ -3155,18 +3180,10 @@ static void smbchg_aicl_deglitch_wa_en(struct smbchg_chip *chip, bool en)
	if (chip->force_aicl_rerun)
		return;
	if (en && !chip->aicl_deglitch_short) {
		rc = smbchg_sec_masked_write(chip,
			chip->usb_chgpth_base + USB_AICL_CFG,
			USB_AICL_DEGLITCH_MASK, USB_AICL_DEGLITCH_SHORT);
		if (rc) {
			pr_err("Couldn't write to USB_AICL_CFG rc=%d\n", rc);
			return;
		}
		rc = smbchg_sec_masked_write(chip,
			chip->dc_chgpth_base + DC_AICL_CFG,
			DC_AICL_DEGLITCH_MASK, DC_AICL_DEGLITCH_SHORT);
		if (rc) {
			pr_err("Couldn't write to DC_AICL_CFG rc=%d\n", rc);
		/* set to short deglitch */
		rc = smbchg_aicl_deglitch_config(chip, false);
		if (rc < 0) {
			pr_err("Couldn't config short deglitch rc=%d\n", rc);
			return;
		}
		if (!chip->very_weak_charger) {
@@ -3179,22 +3196,14 @@ static void smbchg_aicl_deglitch_wa_en(struct smbchg_chip *chip, bool en)
		}
		pr_smb(PR_STATUS, "AICL deglitch set to short\n");
	} else if (!en && chip->aicl_deglitch_short) {
		rc = smbchg_sec_masked_write(chip,
			chip->usb_chgpth_base + USB_AICL_CFG,
			USB_AICL_DEGLITCH_MASK, USB_AICL_DEGLITCH_LONG);
		if (rc) {
			pr_err("Couldn't write to USB_AICL_CFG rc=%d\n", rc);
			return;
		}
		rc = smbchg_sec_masked_write(chip,
			chip->dc_chgpth_base + DC_AICL_CFG,
			DC_AICL_DEGLITCH_MASK, DC_AICL_DEGLITCH_LONG);
		if (rc) {
			pr_err("Couldn't write to DC_AICL_CFG rc=%d\n", rc);
		/* set to long deglitch */
		rc = smbchg_aicl_deglitch_config(chip, true);
		if (rc < 0) {
			pr_err("Couldn't config long deglitch rc=%d\n", rc);
			return;
		}
		rc = smbchg_hw_aicl_rerun_en(chip, false);
		if (rc) {
		if (rc < 0) {
			pr_err("Couldn't disable AICL rerun rc= %d\n", rc);
			return;
		}
@@ -3207,7 +3216,6 @@ static void smbchg_aicl_deglitch_wa_check(struct smbchg_chip *chip)
{
	union power_supply_propval prop = {0,};
	int rc;
	u8 reg;
	bool low_volt_chgr = true;

	if (!(chip->wa_flags & SMBCHG_AICL_DEGLITCH_WA))
@@ -3223,13 +3231,7 @@ static void smbchg_aicl_deglitch_wa_check(struct smbchg_chip *chip)
		return;

	if (is_usb_present(chip)) {
		rc = smbchg_read(chip, &reg,
				chip->usb_chgpth_base + USBIN_HVDCP_STS, 1);
		if (rc < 0) {
			pr_err("Couldn't read hvdcp status rc = %d\n", rc);
			return;
		}
		if (reg & USBIN_HVDCP_SEL_BIT)
		if (is_hvdcp_present(chip))
			low_volt_chgr = false;
	} else if (is_dc_present(chip)) {
		if (chip->dc_psy_type == POWER_SUPPLY_TYPE_WIPOWER)
@@ -4220,34 +4222,6 @@ out:
	return rc;
}

static bool is_hvdcp_present(struct  smbchg_chip *chip)
{
	int rc;
	u8 reg, hvdcp_sel;

	rc = smbchg_read(chip, &reg,
			chip->usb_chgpth_base + USBIN_HVDCP_STS, 1);
	if (rc < 0) {
		pr_err("Couldn't read hvdcp status rc = %d\n", rc);
		return false;
	}

	pr_smb(PR_STATUS, "HVDCP_STS = 0x%02x\n", reg);
	/*
	 * If a valid HVDCP is detected, notify it to the usb_psy only
	 * if USB is still present.
	 */
	if (chip->schg_version == QPNP_SCHG_LITE)
		hvdcp_sel = SCHG_LITE_USBIN_HVDCP_SEL_BIT;
	else
		hvdcp_sel = USBIN_HVDCP_SEL_BIT;

	if ((reg & hvdcp_sel) && is_usb_present(chip))
		return true;

	return false;
}

#define HVDCP_ADAPTER_SEL_MASK	SMB_MASK(5, 4)
#define HVDCP_5V		0x00
#define HVDCP_9V		0x10
@@ -6724,8 +6698,17 @@ static int smbchg_hw_init(struct smbchg_chip *chip)
		return rc;
	}

	if (chip->force_aicl_rerun)
		rc = smbchg_aicl_config(chip);
	/* set to long aicl deglitch */
	rc = smbchg_aicl_deglitch_config(chip, true);

	if (chip->force_aicl_rerun) {
		rc = smbchg_hw_aicl_rerun_en(chip, true);
		if (rc < 0) {
			dev_err(chip->dev, "Couldn't set hw aicl rerun rc = %d\n",
					rc);
			return rc;
		}
	}

	if (chip->schg_version == QPNP_SCHG_LITE) {
		/* enable OTG hiccup mode */