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

Commit 42cee208 authored by Ashay Jaiswal's avatar Ashay Jaiswal Committed by Subbaraman Narayanamurthy
Browse files

power: smb5-lib: skip DPDM regulator request during pr_swap



During pr_swap from source to sink charger hardware will receive
a plug-in event and request for DPDM regulator, this will reset
USB's state machine. Fix this by skipping DPDM request during
pr_swap and add a delayed work to detect actual cable removal
during PR_SWAP.

Change-Id: I44d558d73e94709e9ac09f3e8817037d5c4a8670
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent fc77ef6b
Loading
Loading
Loading
Loading
+40 −0
Original line number Original line Diff line number Diff line
@@ -951,6 +951,9 @@ static int smblib_request_dpdm(struct smb_charger *chg, bool enable)
{
{
	int rc = 0;
	int rc = 0;


	if (chg->pr_swap_in_progress)
		return 0;

	/* fetch the DPDM regulator */
	/* fetch the DPDM regulator */
	if (!chg->dpdm_reg && of_get_property(chg->dev->of_node,
	if (!chg->dpdm_reg && of_get_property(chg->dev->of_node,
				"dpdm-supply", NULL)) {
				"dpdm-supply", NULL)) {
@@ -4910,6 +4913,8 @@ void smblib_usb_plugin_locked(struct smb_charger *chg)
						chg->chg_freq.freq_removal);
						chg->chg_freq.freq_removal);


	if (vbus_rising) {
	if (vbus_rising) {
		cancel_delayed_work_sync(&chg->pr_swap_detach_work);
		vote(chg->awake_votable, DETACH_DETECT_VOTER, false, 0);
		rc = smblib_request_dpdm(chg, true);
		rc = smblib_request_dpdm(chg, true);
		if (rc < 0)
		if (rc < 0)
			smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc);
			smblib_err(chg, "Couldn't to enable DPDM rc=%d\n", rc);
@@ -6021,14 +6026,24 @@ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg,
	return 0;
	return 0;
}
}


#define DETACH_DETECT_DELAY_MS 20
int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
				const union power_supply_propval *val)
				const union power_supply_propval *val)
{
{
	int rc;
	int rc;
	u8 stat = 0, orientation;
	u8 stat = 0, orientation;


	smblib_dbg(chg, PR_MISC, "Requested PR_SWAP %d\n", val->intval);
	chg->pr_swap_in_progress = val->intval;
	chg->pr_swap_in_progress = val->intval;


	/* check for cable removal during pr_swap */
	if (!chg->pr_swap_in_progress) {
		cancel_delayed_work_sync(&chg->pr_swap_detach_work);
		vote(chg->awake_votable, DETACH_DETECT_VOTER, true, 0);
		schedule_delayed_work(&chg->pr_swap_detach_work,
				msecs_to_jiffies(DETACH_DETECT_DELAY_MS));
	}

	rc = smblib_masked_write(chg, TYPE_C_DEBOUNCE_OPTION_REG,
	rc = smblib_masked_write(chg, TYPE_C_DEBOUNCE_OPTION_REG,
			REDUCE_TCCDEBOUNCE_TO_2MS_BIT,
			REDUCE_TCCDEBOUNCE_TO_2MS_BIT,
			val->intval ? REDUCE_TCCDEBOUNCE_TO_2MS_BIT : 0);
			val->intval ? REDUCE_TCCDEBOUNCE_TO_2MS_BIT : 0);
@@ -6080,6 +6095,28 @@ int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg,
/***************
/***************
 * Work Queues *
 * Work Queues *
 ***************/
 ***************/
static void smblib_pr_swap_detach_work(struct work_struct *work)
{
	struct smb_charger *chg = container_of(work, struct smb_charger,
						pr_swap_detach_work.work);
	int rc;
	u8 stat;

	rc = smblib_read(chg, TYPE_C_STATE_MACHINE_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read STATE_MACHINE_STS rc=%d\n", rc);
		goto out;
	}
	smblib_dbg(chg, PR_REGISTER, "STATE_MACHINE_STS %x\n", stat);
	if (!(stat & TYPEC_ATTACH_DETACH_STATE_BIT)) {
		rc = smblib_request_dpdm(chg, false);
		if (rc < 0)
			smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc);
	}
out:
	vote(chg->awake_votable, DETACH_DETECT_VOTER, false, 0);
}

static void smblib_uusb_otg_work(struct work_struct *work)
static void smblib_uusb_otg_work(struct work_struct *work)
{
{
	struct smb_charger *chg = container_of(work, struct smb_charger,
	struct smb_charger *chg = container_of(work, struct smb_charger,
@@ -6808,6 +6845,8 @@ int smblib_init(struct smb_charger *chg)
	INIT_DELAYED_WORK(&chg->thermal_regulation_work,
	INIT_DELAYED_WORK(&chg->thermal_regulation_work,
					smblib_thermal_regulation_work);
					smblib_thermal_regulation_work);
	INIT_DELAYED_WORK(&chg->usbov_dbc_work, smblib_usbov_dbc_work);
	INIT_DELAYED_WORK(&chg->usbov_dbc_work, smblib_usbov_dbc_work);
	INIT_DELAYED_WORK(&chg->pr_swap_detach_work,
					smblib_pr_swap_detach_work);


	if (chg->wa_flags & CHG_TERMINATION_WA) {
	if (chg->wa_flags & CHG_TERMINATION_WA) {
		INIT_WORK(&chg->chg_termination_work,
		INIT_WORK(&chg->chg_termination_work,
@@ -6947,6 +6986,7 @@ int smblib_deinit(struct smb_charger *chg)
		cancel_delayed_work_sync(&chg->lpd_detach_work);
		cancel_delayed_work_sync(&chg->lpd_detach_work);
		cancel_delayed_work_sync(&chg->thermal_regulation_work);
		cancel_delayed_work_sync(&chg->thermal_regulation_work);
		cancel_delayed_work_sync(&chg->usbov_dbc_work);
		cancel_delayed_work_sync(&chg->usbov_dbc_work);
		cancel_delayed_work_sync(&chg->pr_swap_detach_work);
		power_supply_unreg_notifier(&chg->nb);
		power_supply_unreg_notifier(&chg->nb);
		smblib_destroy_votables(chg);
		smblib_destroy_votables(chg);
		qcom_step_chg_deinit();
		qcom_step_chg_deinit();
+2 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,7 @@ enum print_reason {
#define USB_SUSPEND_VOTER		"USB_SUSPEND_VOTER"
#define USB_SUSPEND_VOTER		"USB_SUSPEND_VOTER"
#define CHARGER_TYPE_VOTER		"CHARGER_TYPE_VOTER"
#define CHARGER_TYPE_VOTER		"CHARGER_TYPE_VOTER"
#define HDC_IRQ_VOTER			"HDC_IRQ_VOTER"
#define HDC_IRQ_VOTER			"HDC_IRQ_VOTER"
#define DETACH_DETECT_VOTER		"DETACH_DETECT_VOTER"


#define BOOST_BACK_STORM_COUNT	3
#define BOOST_BACK_STORM_COUNT	3
#define WEAK_CHG_STORM_COUNT	8
#define WEAK_CHG_STORM_COUNT	8
@@ -417,6 +418,7 @@ struct smb_charger {
	struct delayed_work	lpd_detach_work;
	struct delayed_work	lpd_detach_work;
	struct delayed_work	thermal_regulation_work;
	struct delayed_work	thermal_regulation_work;
	struct delayed_work	usbov_dbc_work;
	struct delayed_work	usbov_dbc_work;
	struct delayed_work	pr_swap_detach_work;


	struct alarm		lpd_recheck_timer;
	struct alarm		lpd_recheck_timer;
	struct alarm		moisture_protection_alarm;
	struct alarm		moisture_protection_alarm;