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

Commit 71a9ef40 authored by Harry Yang's avatar Harry Yang Committed by Ashay Jaiswal
Browse files

power: smb5: Fix TypeC settings for PR_SWAP



During TypeC PR_SWAP, SW is selected as source to control CC_COUT.
CC orientation needs to be fixed in the middle of swap, so when
there is a momentary disconnect, PD PHY can know which CC to
communicate on. Add force CC_OUT support by SW override.

Also, PMIC5, the new generation of PMICs, requires VSafe0V check
bypass in order to get from AttachWait.SRC to Attached.SRC state
to become source during PR_SWAP.

Change-Id: I54ac5c21fc4b08cec47b9094e74c6ec0a5fc5179
Signed-off-by: default avatarHarry Yang <harryy@codeaurora.org>
parent 202aa1fb
Loading
Loading
Loading
Loading
+42 −6
Original line number Diff line number Diff line
@@ -3426,19 +3426,55 @@ int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
				const union power_supply_propval *val)
{
	int rc;
	u8 stat = 0, orientation;

	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);
	rc = smblib_masked_write(chg, TYPE_C_DEBOUNCE_OPTION_REG,
			REDUCE_TCCDEBOUNCE_TO_2MS_BIT,
			val->intval ? REDUCE_TCCDEBOUNCE_TO_2MS_BIT : 0);
	if (rc < 0)
		smblib_err(chg, "Couldn't set tCC debounce rc=%d\n", rc);

	rc = smblib_masked_write(chg, TYPE_C_EXIT_STATE_CFG_REG,
			BYPASS_VSAFE0V_DURING_ROLE_SWAP_BIT,
			val->intval ? BYPASS_VSAFE0V_DURING_ROLE_SWAP_BIT : 0);
	if (rc < 0)
		smblib_err(chg, "Couldn't set exit state cfg rc=%d\n", rc);

	if (chg->pr_swap_in_progress) {
		rc = smblib_read(chg, TYPE_C_MISC_STATUS_REG, &stat);
		if (rc < 0) {
			smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n",
				rc);
		}

		orientation =
			stat & CC_ORIENTATION_BIT ? TYPEC_CCOUT_VALUE_BIT : 0;
		rc = smblib_masked_write(chg, TYPE_C_CCOUT_CONTROL_REG,
			TYPEC_CCOUT_SRC_BIT | TYPEC_CCOUT_BUFFER_EN_BIT
					| TYPEC_CCOUT_VALUE_BIT,
			TYPEC_CCOUT_SRC_BIT | TYPEC_CCOUT_BUFFER_EN_BIT
					| orientation);
		if (rc < 0) {
			smblib_err(chg, "Couldn't read TYPE_C_CCOUT_CONTROL_REG rc=%d\n",
				rc);
		}
	} else {
		rc = smblib_masked_write(chg, TYPE_C_CCOUT_CONTROL_REG,
			TYPEC_CCOUT_SRC_BIT, 0);
		if (rc < 0) {
			smblib_err(chg, "Couldn't read TYPE_C_CCOUT_CONTROL_REG rc=%d\n",
				rc);
		}

		/* enable DRP */
		rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG,
				 TYPEC_POWER_ROLE_CMD_MASK, 0);
		if (rc < 0)
			smblib_err(chg, "Couldn't enable DRP rc=%d\n", rc);
	}

	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -287,10 +287,12 @@ enum {
#define VCONN_EN_SRC_BIT			BIT(0)

#define TYPE_C_CCOUT_CONTROL_REG		(TYPEC_BASE + 0x48)
#define TYPEC_CCOUT_BUFFER_EN_BIT		BIT(2)
#define TYPEC_CCOUT_VALUE_BIT			BIT(1)
#define TYPEC_CCOUT_SRC_BIT			BIT(0)

#define TYPE_C_EXIT_STATE_CFG_REG		(TYPEC_BASE + 0x50)
#define BYPASS_VSAFE0V_DURING_ROLE_SWAP_BIT	BIT(3)
#define EXIT_SNK_BASED_ON_CC_BIT		BIT(0)

#define TYPE_C_INTERRUPT_EN_CFG_1_REG			(TYPEC_BASE + 0x5E)