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: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 38c806b..d8a72c5 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3679,6 +3679,17 @@
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);
}
@@ -3709,15 +3720,15 @@
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_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_dbg(chg, PR_MISC, "TypeC removal\n");
smblib_handle_typec_removal(chg);
}
}
@@ -3851,6 +3862,30 @@
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 *
***************/