summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorHarry Yang <harryy@codeaurora.org>2016-12-08 12:37:40 -0800
committerHarry Yang <harryy@codeaurora.org>2017-01-04 22:57:17 -0800
commitd9a8a3b2e153758557e462c843a897c305bd12a8 (patch)
tree9f48c3cd504e37023c15d30a95f34689e1c2b84c /drivers/power
parent8bb66a7e413624884e697d295b7e136f96209cd9 (diff)
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: Harry Yang <harryy@codeaurora.org>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c9
-rw-r--r--drivers/power/qcom-charger/smb-lib.c63
-rw-r--r--drivers/power/qcom-charger/smb-lib.h5
-rw-r--r--drivers/power/qcom-charger/smb-reg.h6
4 files changed, 31 insertions, 52 deletions
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index 463cbb7cb8ba..cd137790ba42 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -1,4 +1,4 @@
-/* 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;
}
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index 86140386f0e3..317216cdc698 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -1,4 +1,4 @@
-/* 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;
-}
diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h
index f6335aae2637..b65c0211405a 100644
--- a/drivers/power/qcom-charger/smb-lib.h
+++ b/drivers/power/qcom-charger/smb-lib.h
@@ -1,4 +1,4 @@
-/* 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 */
diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/qcom-charger/smb-reg.h
index a30efbe3651e..a9606ab1944b 100644
--- a/drivers/power/qcom-charger/smb-reg.h
+++ b/drivers/power/qcom-charger/smb-reg.h
@@ -1,4 +1,4 @@
-/* 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)