diff options
author | Yilun Lin <yllin@chromium.org> | 2019-11-26 14:34:38 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-03 06:11:59 +0000 |
commit | 901d132e7f057199517848c7b77dd86eb2922bdb (patch) | |
tree | 286b337fb9d4bcd00ca9e338dc194515eddc4cf0 | |
parent | fe387a175ad92df2a165854b683ffa76c41750a6 (diff) | |
download | chrome-ec-901d132e7f057199517848c7b77dd86eb2922bdb.tar.gz |
charger/rt946x: do BC1.2 recognition when required
BC1.2 and USB enumeration may have a race condition on
operating D+/D- pins. This CL make BC1.2 detection runs
only when required. That is, only if the CC pins exists RP (sink),
and the port is not PD capable, then the source could be a
BC1.2 device.
Also, drops notifying AC_CHANGE, since it's not accurate while
we only enable BC1.2 detection on the state.
TEST=ensure BC1.2 detection only runs on a BC1.2 charger plug.
BUG=b:141005922
BRANCH=kukui
Change-Id: I0aac4221858b316165302494933bf0f54809dcf1
Signed-off-by: Yilun Lin <yllin@chromium.org>
Signed-off-by: Eric Yilun Lin <yllin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1936076
Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r-- | driver/charger/rt946x.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/driver/charger/rt946x.c b/driver/charger/rt946x.c index 342aa704f7..f5d6204b55 100644 --- a/driver/charger/rt946x.c +++ b/driver/charger/rt946x.c @@ -19,8 +19,10 @@ #include "driver/wpc/p9221.h" #include "rt946x.h" #include "task.h" +#include "tcpm.h" #include "timer.h" #include "usb_charge.h" +#include "usb_pd.h" #include "util.h" /* Console output macros */ @@ -545,12 +547,8 @@ static int rt946x_init_setting(void) if (rv) return rv; #endif - /* Enable/Disable BC 1.2 detection */ -#ifdef HAS_TASK_USB_CHG - rv = rt946x_enable_bc12_detection(1); -#else + /* Disable BC 1.2 detection by default. It will be enabled on demand */ rv = rt946x_enable_bc12_detection(0); -#endif if (rv) return rv; /* Disable WDT */ @@ -1190,13 +1188,47 @@ int rt946x_toggle_bc12_detection(void) return rt946x_enable_bc12_detection(1); } -#ifdef CONFIG_CHARGER_MT6370_BC12_GPIO -static void usb_pd_connect(void) +static void check_pd_capable(void) { - rt946x_toggle_bc12_detection(); + const int port = TASK_ID_TO_USB_CHG_PORT(TASK_ID_USB_CHG); + + if (!pd_capable(port)) { + enum tcpc_cc_voltage_status cc1, cc2; + + tcpm_get_cc(port, &cc1, &cc2); + /* if CC is not changed. */ + if (cc_is_rp(cc1) || cc_is_rp(cc2)) + rt946x_toggle_bc12_detection(); + } } -DECLARE_HOOK(HOOK_USB_PD_CONNECT, usb_pd_connect, HOOK_PRIO_DEFAULT); -#endif +DECLARE_DEFERRED(check_pd_capable); + +static void rt946x_usb_connect(void) +{ + const int port = TASK_ID_TO_USB_CHG_PORT(TASK_ID_USB_CHG); + enum tcpc_cc_voltage_status cc1, cc2; + + tcpm_get_cc(port, &cc1, &cc2); + + /* + * Only detect BC1.2 device when USB-C device recognition is + * finished to prevent a potential race condition with USB enumeration. + * If CC exists RP, then it might be a BC12 or a PD capable device. + * Check this later to ensure it's not PD capable. + */ + if (cc_is_rp(cc1) || cc_is_rp(cc2)) + /* delay extra 50 ms to ensure SrcCap received */ + hook_call_deferred(&check_pd_capable_data, + PD_T_SINK_WAIT_CAP + 50 * MSEC); +} +DECLARE_HOOK(HOOK_USB_PD_CONNECT, rt946x_usb_connect, HOOK_PRIO_DEFAULT); + +static void rt946x_pd_disconnect(void) +{ + /* Type-C disconnected, disable deferred check. */ + hook_call_deferred(&check_pd_capable_data, -1); +} +DECLARE_HOOK(HOOK_USB_PD_DISCONNECT, rt946x_pd_disconnect, HOOK_PRIO_DEFAULT); static int rt946x_get_adc(enum rt946x_adc_in_sel adc_sel, int *adc_val) { @@ -1457,7 +1489,6 @@ void usb_charger_task(void *u) charge_manager_update_charge(bc12_type, 0, &chg); bc12_none: rt946x_enable_bc12_detection(0); - hook_notify(HOOK_AC_CHANGE); } /* VBUS detach event */ @@ -1468,11 +1499,6 @@ bc12_none: p9221_notify_vbus_change(0); #endif charge_manager_update_charge(bc12_type, 0, NULL); - - if (!IS_ENABLED(CONFIG_CHARGER_MT6370_BC12_GPIO)) - rt946x_enable_bc12_detection(1); - - hook_notify(HOOK_AC_CHANGE); } wait_event: |