diff options
-rw-r--r-- | common/usb_pd_protocol.c | 4 | ||||
-rw-r--r-- | common/usb_pd_tcpc.c | 42 |
2 files changed, 43 insertions, 3 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 4cc0e0259a..fc063d24b9 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1952,8 +1952,8 @@ void pd_task(void) break; case PD_STATE_SNK_DISCONNECTED: #ifdef CONFIG_USB_PD_LOW_POWER - timeout = drp_state == PD_DRP_TOGGLE_OFF ? MINUTE - : 10*MSEC; + timeout = drp_state != PD_DRP_TOGGLE_ON ? SECOND + : 10*MSEC; #else timeout = 10*MSEC; #endif diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c index 99867e338a..0b13fb2c77 100644 --- a/common/usb_pd_tcpc.c +++ b/common/usb_pd_tcpc.c @@ -198,6 +198,14 @@ enum pd_tx_errors { }; /* + * If TCPM is not on this chip, and PD low power is defined, then use low + * power task delay logic. + */ +#if !defined(CONFIG_USB_POWER_DELIVERY) && defined(CONFIG_USB_PD_LOW_POWER) +#define TCPC_LOW_POWER +#endif + +/* * Receive message buffer size. Buffer physical size is RX_BUFFER_SIZE + 1, * but only RX_BUFFER_SIZE of that memory is used to store messages that can * be retrieved from TCPM. The last slot is a temporary buffer for collecting @@ -229,6 +237,11 @@ static struct pd_port_controller { uint8_t power_status; uint8_t power_status_mask; +#ifdef TCPC_LOW_POWER + /* Timestamp beyond which we allow low power task sampling */ + timestamp_t low_power_ts; +#endif + /* Last received */ int rx_head[RX_BUFFER_SIZE+1]; uint32_t rx_payload[RX_BUFFER_SIZE+1][7]; @@ -821,8 +834,21 @@ int tcpc_run(int port, int evt) if (pd[port].rx_enabled) pd_rx_enable_monitoring(port); - /* TODO: adjust timeout based on how often to sample CC */ +#ifdef TCPC_LOW_POWER + /* + * If we are presenting Rd with no connection, and timestamp is + * past the low power timestamp, then we don't need to sample + * CC lines as often. In this case, our connection delay should not + * actually increased because we will get an interrupt on VBUS detect. + */ + return (get_time().val >= pd[port].low_power_ts.val && + pd[port].cc_pull == TYPEC_CC_RD && + pd[port].cc_status[0] == TYPEC_CC_VOLT_OPEN && + pd[port].cc_status[1] == TYPEC_CC_VOLT_OPEN) ? 200 * MSEC : + 10 * MSEC; +#else return 10*MSEC; +#endif } #ifndef CONFIG_USB_POWER_DELIVERY @@ -906,6 +932,16 @@ int tcpc_set_cc(int port, int pull) pd_set_host_mode(port, pull == TYPEC_CC_RP); #endif +#ifdef TCPC_LOW_POWER + /* + * Reset the low power timestamp every time CC termination toggles, + * because we only want to go into low power mode when we are not + * dual-role toggling. + */ + pd[port].low_power_ts.val = get_time().val + + 2*(PD_T_DRP_SRC + PD_T_DRP_SNK); +#endif + /* * Before CC pull can be changed and the task can read the new * status, we should set the CC status to open, in case TCPM @@ -1050,6 +1086,10 @@ void tcpc_init(int port) pd_hw_init(port, PD_ROLE_DEFAULT); pd[port].cc_pull = PD_ROLE_DEFAULT == PD_ROLE_SOURCE ? TYPEC_CC_RP : TYPEC_CC_RD; +#ifdef TCPC_LOW_POWER + /* Don't use low power immediately after boot */ + pd[port].low_power_ts.val = get_time().val + SECOND; +#endif /* make sure PD monitoring is disabled initially */ pd[port].rx_enabled = 0; |