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

Commit 3b113a5b authored by Harry Yang's avatar Harry Yang
Browse files

qcom-charger: typec legacy cable detection



Currently the legacy cable bit is always asserted during off mode
PON via USBIN. This causes PD to be disallowed even when a
non-legacy cable is attached in off mode.

Fix this by always allowing PD upon USBIN attach PON, but keep the
normal legacy detection flow for all subsequent insertions.

CRs-Fixed: 1107607
Change-Id: I20acd75643955b6d2144389159a0dad41f01a532
Signed-off-by: default avatarHarry Yang <harryy@codeaurora.org>
parent 0b44da4a
Loading
Loading
Loading
Loading
+1 −8
Original line number Diff line number Diff line
/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017 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
@@ -1144,13 +1144,6 @@ static int smb2_configure_typec(struct smb_charger *chg)
		return rc;
	}

	rc = smblib_validate_initial_typec_legacy_status(chg);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't validate typec legacy status rc=%d\n",
			rc);
		return rc;
	}

	return rc;
}

+23 −40
Original line number Diff line number Diff line
/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017 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
@@ -627,6 +627,21 @@ static void smblib_uusb_removal(struct smb_charger *chg)
		smblib_err(chg, "Couldn't un-vote for USB ICL rc=%d\n", rc);
}

static bool smblib_sysok_reason_usbin(struct smb_charger *chg)
{
	int rc;
	u8 stat;

	rc = smblib_read(chg, SYSOK_REASON_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't get SYSOK_REASON_STATUS rc=%d\n", rc);
		/* assuming 'not usbin' in case of read failure */
		return false;
	}

	return stat & SYSOK_REASON_USBIN_BIT;
}

/*********************
 * VOTABLE CALLBACKS *
 *********************/
@@ -2852,6 +2867,8 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
	typec_source_removal(chg);
	typec_sink_removal(chg);

	chg->usb_ever_removed = true;

	smblib_update_usb_type(chg);
}

@@ -2860,6 +2877,7 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
{
	int rp;
	bool vbus_cc_short = false;
	bool valid_legacy_cable;

	vote(chg->pd_disallowed_votable_indirect, CC_DETACHED_VOTER, false, 0);

@@ -2871,10 +2889,12 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
		typec_sink_removal(chg);
	}

	valid_legacy_cable = legacy_cable &&
		(chg->usb_ever_removed || !smblib_sysok_reason_usbin(chg));
	vote(chg->pd_disallowed_votable_indirect, LEGACY_CABLE_VOTER,
			legacy_cable, 0);
			valid_legacy_cable, 0);

	if (legacy_cable) {
	if (valid_legacy_cable) {
		rp = smblib_get_prop_ufp_mode(chg);
		if (rp == POWER_SUPPLY_TYPEC_SOURCE_HIGH
				|| rp == POWER_SUPPLY_TYPEC_NON_COMPLIANT) {
@@ -3476,40 +3496,3 @@ int smblib_deinit(struct smb_charger *chg)

	return 0;
}

int smblib_validate_initial_typec_legacy_status(struct smb_charger *chg)
{
	int rc;
	u8 stat;


	if (qpnp_pon_is_warm_reset())
		return 0;

	rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read TYPE_C_STATUS_5 rc=%d\n", rc);
		return rc;
	}

	if ((stat & TYPEC_LEGACY_CABLE_STATUS_BIT) == 0)
		return 0;

	rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
				 TYPEC_DISABLE_CMD_BIT, TYPEC_DISABLE_CMD_BIT);
	if (rc < 0) {
		smblib_err(chg, "Couldn't disable typec rc=%d\n", rc);
		return rc;
	}

	usleep_range(150000, 151000);

	rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
				 TYPEC_DISABLE_CMD_BIT, 0);
	if (rc < 0) {
		smblib_err(chg, "Couldn't enable typec rc=%d\n", rc);
		return rc;
	}

	return 0;
}
+2 −3
Original line number Diff line number Diff line
/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017 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
@@ -233,6 +233,7 @@ struct smb_charger {

	/* extcon for VBUS / ID notification to USB for uUSB */
	struct extcon_dev	*extcon;
	bool			usb_ever_removed;
};

int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
@@ -377,8 +378,6 @@ int smblib_get_prop_slave_current_now(struct smb_charger *chg,
int smblib_set_prop_ship_mode(struct smb_charger *chg,
				const union power_supply_propval *val);

int smblib_validate_initial_typec_legacy_status(struct smb_charger *chg);

int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);
#endif /* __SMB2_CHARGER_H */
+5 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017 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
@@ -860,6 +860,10 @@ enum {
#define WDOG_STATUS_1_BIT			BIT(1)
#define BARK_BITE_STATUS_BIT			BIT(0)

#define SYSOK_REASON_STATUS_REG			(MISC_BASE + 0x0D)
#define SYSOK_REASON_DCIN_BIT			BIT(1)
#define SYSOK_REASON_USBIN_BIT			BIT(0)

/* MISC Interrupt Bits */
#define SWITCHER_POWER_OK_RT_STS_BIT		BIT(7)
#define TEMPERATURE_CHANGE_RT_STS_BIT		BIT(6)