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

Commit 86e11556 authored by Abhijeet Dharmapurikar's avatar Abhijeet Dharmapurikar
Browse files

smb-lib: ignore disconnects during power role swap



During a power_role swap, the CC lines get disconnected for a bit.
This causes the charger driver to prematurely declare a disconnection
and it resets back to disconnected state.

Update the code to distinguish a disconnect caused during PR_SWAP vs
a real disconnect.
Avoid
- resetting the CC line to HW control
- switching DRP mode
- enabling the crude sensor workaround
- enabling APSD
during a discconnet caused by PR_SWAP

Note that PR_SWAP setting/unsetting needs to done regardless of the
connected state of the CC line. When PR_SWAP is notified to be
completed and the CC lines are still seen disconnected call the real
disconnect code.

While at it Vconn can be disabled too in the real disconnect code path.

Change-Id: I97ab7ee343c5b2bcf25797e6acbb1de37f5ba00a
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent e91e2202
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -432,6 +432,7 @@ static enum power_supply_property smb2_usb_props[] = {
	POWER_SUPPLY_PROP_CTM_CURRENT_MAX,
	POWER_SUPPLY_PROP_HW_CURRENT_MAX,
	POWER_SUPPLY_PROP_REAL_TYPE,
	POWER_SUPPLY_PROP_PR_SWAP,
};

static int smb2_usb_get_prop(struct power_supply *psy,
@@ -536,6 +537,9 @@ static int smb2_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_HW_CURRENT_MAX:
		rc = smblib_get_charge_current(chg, &val->intval);
		break;
	case POWER_SUPPLY_PROP_PR_SWAP:
		rc = smblib_get_prop_pr_swap_in_progress(chg, val);
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -594,6 +598,9 @@ static int smb2_usb_set_prop(struct power_supply *psy,
		rc = vote(chg->usb_icl_votable, CTM_VOTER,
						val->intval >= 0, val->intval);
		break;
	case POWER_SUPPLY_PROP_PR_SWAP:
		rc = smblib_set_prop_pr_swap_in_progress(chg, val);
		break;
	default:
		pr_err("set prop %d is not supported\n", psp);
		rc = -EINVAL;
+39 −4
Original line number Diff line number Diff line
@@ -3669,6 +3669,17 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
	if (rc < 0)
		smblib_err(chg, "Couldn't restore crude sensor rc=%d\n", rc);

	mutex_lock(&chg->vconn_oc_lock);
	if (!chg->vconn_en)
		goto unlock;

	smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
				 VCONN_EN_VALUE_BIT, 0);
	chg->vconn_en = false;

unlock:
	mutex_unlock(&chg->vconn_oc_lock);

	typec_sink_removal(chg);
	smblib_update_usb_type(chg);
}
@@ -3699,13 +3710,13 @@ static void smblib_handle_typec_debounce_done(struct smb_charger *chg,
	union power_supply_propval pval = {0, };

	if (rising) {
		if (!chg->typec_present) {
		if (!chg->typec_present && !chg->pr_swap_in_progress) {
			chg->typec_present = true;
			smblib_dbg(chg, PR_MISC, "TypeC insertion\n");
			smblib_handle_typec_insertion(chg, sink_attached);
		}
	} else {
		if (chg->typec_present) {
		if (chg->typec_present && !chg->pr_swap_in_progress) {
			chg->typec_present = false;
			smblib_dbg(chg, PR_MISC, "TypeC removal\n");
			smblib_handle_typec_removal(chg);
@@ -3841,6 +3852,30 @@ irqreturn_t smblib_handle_wdog_bark(int irq, void *data)
	return IRQ_HANDLED;
}

/**************
 * Additional USB PSY getters/setters
 * that call interrupt functions
***************/

int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg,
				union power_supply_propval *val)
{
	val->intval = chg->pr_swap_in_progress;
	return 0;
}

int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
				const union power_supply_propval *val)
{
	chg->pr_swap_in_progress = val->intval;
	/*
	 * call the cc changed irq to handle real removals while
	 * PR_SWAP was in progress
	 */
	smblib_usb_typec_change(chg);
	return 0;
}

/***************
 * Work Queues *
 ***************/
+5 −0
Original line number Diff line number Diff line
@@ -321,6 +321,7 @@ struct smb_charger {
	u8			typec_status[5];
	bool			typec_legacy_valid;
	int			fake_input_current_limited;
	bool			pr_swap_in_progress;

	/* workaround flag */
	u32			wa_flags;
@@ -506,6 +507,10 @@ int smblib_rerun_aicl(struct smb_charger *chg);
int smblib_set_icl_current(struct smb_charger *chg, int icl_ua);
int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua);
int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua);
int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
				const union power_supply_propval *val);

int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);