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

Commit b2c7c840 authored by Xiaozhe Shi's avatar Xiaozhe Shi Committed by Ashay Jaiswal
Browse files

power: qpnp-smbcharger: disable pulse skip during OTG



The charger pulse skip mode can cause drastic dips on VBUS when OTG is
enabled. This dip can cause a glitch in the fuel gauge and lock up the
entire peripheral.
Disable the pulse skip mode before enabling OTG and only reenable it
after OTG is disabled.

CRs-Fixed: 862602
Change-Id: Ifb0df393db4a03020a5753aa5d92dfa796e3bd86
Signed-off-by: default avatarXiaozhe Shi <xiaozhes@codeaurora.org>
parent 0dab3364
Loading
Loading
Loading
Loading
+28 −20
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ struct smbchg_chip {
	bool				safety_timer_en;
	bool				aicl_complete;
	bool				usb_ov_det;
	bool				otg_pulse_skip_en;
	bool				otg_pulse_skip_dis;
	const char			*battery_type;
	bool				very_weak_charger;
	bool				parallel_charger_detected;
@@ -2693,37 +2693,40 @@ static int smbchg_safety_timer_enable(struct smbchg_chip *chip, bool enable)
	return 0;
}

enum skip_reason {
	REASON_OTG_ENABLED	= BIT(0),
	REASON_FLASH_ENABLED	= BIT(1)
};

#define OTG_TRIM6		0xF6
#define TR_ENB_SKIP_BIT		BIT(2)
#define OTG_EN_BIT		BIT(0)
static int smbchg_otg_pulse_skip_enable(struct smbchg_chip *chip, bool enable)
static int smbchg_otg_pulse_skip_disable(struct smbchg_chip *chip,
				enum skip_reason reason, bool disable)
{
	int rc;
	u8 reg;

	if (enable == chip->otg_pulse_skip_en)
		return 0;
	bool disabled;

	rc = smbchg_read(chip, &reg, chip->bat_if_base + CMD_CHG_REG, 1);
	if (rc < 0) {
		dev_err(chip->dev,
				"Couldn't read OTG enable bit rc=%d\n", rc);
		return rc;
	}

	/* If OTG is not enabled, don't set OTG pulse skip enable */
	if (!(reg & OTG_EN_BIT))
	disabled = !!chip->otg_pulse_skip_dis;
	pr_smb(PR_STATUS, "%s pulse skip, reason %d\n",
			disable ? "disabling" : "enabling", reason);
	if (disable)
		chip->otg_pulse_skip_dis |= reason;
	else
		chip->otg_pulse_skip_dis &= ~reason;
	if (disabled == !!chip->otg_pulse_skip_dis)
		return 0;
	disabled = !!chip->otg_pulse_skip_dis;

	rc = smbchg_sec_masked_write(chip, chip->otg_base + OTG_TRIM6,
			TR_ENB_SKIP_BIT, enable ? TR_ENB_SKIP_BIT : 0);
			TR_ENB_SKIP_BIT, disabled ? TR_ENB_SKIP_BIT : 0);
	if (rc < 0) {
		dev_err(chip->dev,
			"Couldn't %s otg pulse skip rc = %d\n",
			enable ? "enable" : "disable", rc);
			disabled ? "disable" : "enable", rc);
		return rc;
	}
	chip->otg_pulse_skip_en = enable;
	pr_smb(PR_STATUS, "%s pulse skip\n", disabled ? "disabled" : "enabled");
	return 0;
}

@@ -3183,6 +3186,9 @@ static int smbchg_otg_regulator_enable(struct regulator_dev *rdev)
	struct smbchg_chip *chip = rdev_get_drvdata(rdev);

	chip->otg_retries = 0;
	smbchg_otg_pulse_skip_disable(chip, REASON_OTG_ENABLED, true);
	/* sleep to make sure the pulse skip is actually disabled */
	msleep(20);
	rc = smbchg_masked_write(chip, chip->bat_if_base + CMD_CHG_REG,
			OTG_EN_BIT, OTG_EN_BIT);
	if (rc < 0)
@@ -3202,6 +3208,7 @@ static int smbchg_otg_regulator_disable(struct regulator_dev *rdev)
			OTG_EN_BIT, 0);
	if (rc < 0)
		dev_err(chip->dev, "Couldn't disable OTG mode rc=%d\n", rc);
	smbchg_otg_pulse_skip_disable(chip, REASON_OTG_ENABLED, false);
	pr_smb(PR_STATUS, "Disabling OTG Boost\n");
	return rc;
}
@@ -4742,7 +4749,8 @@ static int smbchg_battery_set_property(struct power_supply *psy,
		rc = smbchg_safety_timer_enable(chip, val->intval);
		break;
	case POWER_SUPPLY_PROP_FLASH_ACTIVE:
		rc = smbchg_otg_pulse_skip_enable(chip, val->intval);
		rc = smbchg_otg_pulse_skip_disable(chip,
				REASON_FLASH_ENABLED, val->intval);
		break;
	case POWER_SUPPLY_PROP_FORCE_TLIM:
		rc = smbchg_force_tlim_en(chip, val->intval);
@@ -4851,7 +4859,7 @@ static int smbchg_battery_get_property(struct power_supply *psy,
		val->intval = chip->safety_timer_en;
		break;
	case POWER_SUPPLY_PROP_FLASH_ACTIVE:
		val->intval = chip->otg_pulse_skip_en;
		val->intval = chip->otg_pulse_skip_dis;
		break;
	case POWER_SUPPLY_PROP_DP_DM:
		val->intval = chip->pulse_cnt;