diff options
author | Alec Berg <alecaberg@chromium.org> | 2014-11-18 15:06:27 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-11-21 04:37:55 +0000 |
commit | 88d63dcc6e6107818b6cc6437636eaac36a60949 (patch) | |
tree | 2295a85369f4e43b4979e1355b9bc4928cbb223b | |
parent | 2a9a859655689246630de3c86c7a254e611c1718 (diff) | |
download | chrome-ec-88d63dcc6e6107818b6cc6437636eaac36a60949.tar.gz |
pd: dynamically adjust current limit based on CC pull-up
Without a PD contract, regularly monitor CC line voltage to determine
if CC pull-up has changed its current advertisement.
BUG=chrome-os-partner:33682
BRANCH=samus
TEST=test with donette prototype: plug in one donette port to a samus,
see it set current limit to 3A, then plug in another port to a different
samus and see the first samus lower the current limit to 1.5A.
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Change-Id: I965ab5fde7a67025f3f7ea34eb86fa35187080a6
Reviewed-on: https://chromium-review.googlesource.com/230594
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index aecb9ee4e3..ce54da3a34 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -190,6 +190,8 @@ static const uint8_t dec4b5b[] = { /* DRP_SNK + DRP_SRC must be between 50ms and 100ms with 30%-70% duty cycle */ #define PD_T_DRP_SNK (40*MSEC) /* toggle time for sink DRP */ #define PD_T_DRP_SRC (30*MSEC) /* toggle time for source DRP */ +#define PD_T_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ +#define PD_T_SINK_ADJ (55*MSEC) /* between PD_T_DEBOUNCE and 60ms */ #define PD_T_SRC_RECOVER (760*MSEC) /* between 660ms and 1000ms */ /* from USB Type-C Specification Table 5-1 */ @@ -1454,6 +1456,7 @@ void pd_task(void) int hard_reset_count = 0; #ifdef CONFIG_CHARGE_MANAGER static int initialized[PD_PORT_COUNT]; + int typec_curr = 0, typec_curr_change = 0; #endif /* CONFIG_CHARGE_MANAGER */ #endif /* CONFIG_USB_PD_DUAL_ROLE */ enum pd_states this_state; @@ -1812,13 +1815,11 @@ void pd_task(void) pd[port].data_role = PD_ROLE_UFP; #ifdef CONFIG_CHARGE_MANAGER initialized[port] = 1; + typec_curr = get_typec_current_limit( + pd[port].polarity ? cc2_volt : + cc1_volt); typec_set_input_current_limit( - port, - get_typec_current_limit(pd[port]. - polarity ? - cc2_volt : - cc1_volt), - TYPE_C_VOLTAGE); + port, typec_curr, TYPE_C_VOLTAGE); #endif set_state(port, PD_STATE_SNK_DISCOVERY); timeout = 10*MSEC; @@ -1876,6 +1877,29 @@ void pd_task(void) PD_T_SINK_WAIT_CAP, PD_STATE_HARD_RESET); } + +#ifdef CONFIG_CHARGE_MANAGER + timeout = PD_T_SINK_ADJ - PD_T_DEBOUNCE; + + /* Check if CC pull-up has changed */ + cc1_volt = pd_adc_read(port, pd[port].polarity); + if (typec_curr != get_typec_current_limit(cc1_volt)) { + /* debounce signal by requiring two reads */ + if (typec_curr_change) { + /* set new input current limit */ + typec_curr = get_typec_current_limit( + cc1_volt); + typec_set_input_current_limit( + port, typec_curr, TYPE_C_VOLTAGE); + } else { + /* delay for debounce */ + timeout = PD_T_DEBOUNCE; + } + typec_curr_change = !typec_curr_change; + } else { + typec_curr_change = 0; + } +#endif break; case PD_STATE_SNK_REQUESTED: /* Wait for ACCEPT or REJECT */ |