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

Commit b1c7f424 authored by Ashay Jaiswal's avatar Ashay Jaiswal Committed by Jishnu Prakash
Browse files

power: smb5: Disable charger-hw ADC channels before reading USBIN_V



There could be a possible hardware coupling between USBIN_V channel and
other voltage based ADC channel which could lead to false USBIN_OV
interrupts. Fix this by disabling voltage based charger-hw ADC channels
before reading USBIN_V.

Change-Id: I230698c0eeb3a8c646c843a4533f38671484925e
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
Signed-off-by: default avatarGuru Das Srinagesh <gurus@codeaurora.org>
Signed-off-by: default avatarHarry Yang <harryy@codeaurora.org>
parent ba3a7712
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -350,7 +350,7 @@ static int smb5_chg_config_init(struct smb5 *chip)
	case PMI632_SUBTYPE:
		chip->chg.smb_version = PMI632_SUBTYPE;
		chg->wa_flags |= WEAK_ADAPTER_WA | USBIN_OV_WA
				| CHG_TERMINATION_WA;
				| CHG_TERMINATION_WA | USBIN_ADC_WA;
		chg->param = smb5_pmi632_params;
		chg->use_extcon = true;
		chg->name = "pmi632_charger";
@@ -3310,6 +3310,7 @@ static int smb5_probe(struct platform_device *pdev)
	chg->connector_health = -EINVAL;
	chg->otg_present = false;
	chg->main_fcc_max = -EINVAL;
	mutex_init(&chg->adc_lock);

	chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
	if (!chg->regmap) {
+45 −4
Original line number Diff line number Diff line
@@ -3273,12 +3273,36 @@ int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
				    union power_supply_propval *val)
{
	union power_supply_propval pval = {0, };
	int rc;
	int rc, ret = 0;
	u8 reg;

	mutex_lock(&chg->adc_lock);

	if (chg->wa_flags & USBIN_ADC_WA) {
		/* Store ADC channel config in order to restore later */
		rc = smblib_read(chg, BATIF_ADC_CHANNEL_EN_REG, &reg);
		if (rc < 0) {
			smblib_err(chg, "Couldn't read ADC config rc=%d\n", rc);
			ret = rc;
			goto unlock;
		}

		/* Disable all ADC channels except IBAT channel */
		rc = smblib_write(chg, BATIF_ADC_CHANNEL_EN_REG,
						IBATT_CHANNEL_EN_BIT);
		if (rc < 0) {
			smblib_err(chg, "Couldn't disable ADC channels rc=%d\n",
						rc);
			ret = rc;
			goto unlock;
		}
	}

	rc = smblib_get_prop_usb_present(chg, &pval);
	if (rc < 0) {
		smblib_err(chg, "Couldn't get usb presence status rc=%d\n", rc);
		return -ENODATA;
		ret = -ENODATA;
		goto restore_adc_config;
	}

	/*
@@ -3287,9 +3311,26 @@ int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
	 * voltages.
	 */
	if (chg->smb_version == PM8150B_SUBTYPE && pval.intval)
		return smblib_read_mid_voltage_chan(chg, val);
		rc = smblib_read_mid_voltage_chan(chg, val);
	else
		return smblib_read_usbin_voltage_chan(chg, val);
		rc = smblib_read_usbin_voltage_chan(chg, val);
	if (rc < 0) {
		smblib_err(chg, "Failed to read USBIN over vadc, rc=%d\n", rc);
		ret = rc;
	}

restore_adc_config:
	 /* Restore ADC channel config */
	if (chg->wa_flags & USBIN_ADC_WA)
		rc = smblib_write(chg, BATIF_ADC_CHANNEL_EN_REG, reg);
		if (rc < 0)
			smblib_err(chg, "Couldn't write ADC config rc=%d\n",
						rc);

unlock:
	mutex_unlock(&chg->adc_lock);

	return ret;
}

int smblib_get_prop_vph_voltage_now(struct smb_charger *chg,
+2 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ enum {
	WEAK_ADAPTER_WA			= BIT(2),
	USBIN_OV_WA			= BIT(3),
	CHG_TERMINATION_WA		= BIT(4),
	USBIN_ADC_WA			= BIT(5),
};

enum jeita_cfg_stat {
@@ -386,6 +387,7 @@ struct smb_charger {
	struct mutex		irq_status_lock;
	struct mutex		dcin_aicl_lock;
	spinlock_t		typec_pr_lock;
	struct mutex		adc_lock;

	/* power supplies */
	struct power_supply		*batt_psy;
+1 −0
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ enum {
#define SHIP_MODE_EN_BIT			BIT(0)

#define BATIF_ADC_CHANNEL_EN_REG		(BATIF_BASE + 0x82)
#define IBATT_CHANNEL_EN_BIT			BIT(6)
#define CONN_THM_CHANNEL_EN_BIT			BIT(4)
#define DIE_TEMP_CHANNEL_EN_BIT			BIT(2)
#define MISC_THM_CHANNEL_EN_BIT			BIT(1)