diff options
-rw-r--r-- | board/dingdong/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/firefly/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/fruitpie/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/hoho/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/honeybuns/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/host/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/plankton/usb_pd_policy.c | 7 | ||||
-rw-r--r-- | board/ryu/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/samus_pd/usb_pd_policy.c | 26 | ||||
-rw-r--r-- | board/twinkie/usb_pd_policy.c | 4 | ||||
-rw-r--r-- | board/zinger/usb_pd_policy.c | 6 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 79 | ||||
-rw-r--r-- | include/usb_pd.h | 33 |
13 files changed, 105 insertions, 78 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c index 10f920b237..3d14329e59 100644 --- a/board/dingdong/usb_pd_policy.c +++ b/board/dingdong/usb_pd_policy.c @@ -91,11 +91,11 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } /* ----------------- Vendor Defined Messages ------------------ */ diff --git a/board/firefly/usb_pd_policy.c b/board/firefly/usb_pd_policy.c index 44ccfe418b..2784f7799a 100644 --- a/board/firefly/usb_pd_policy.c +++ b/board/firefly/usb_pd_policy.c @@ -130,11 +130,11 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } diff --git a/board/fruitpie/usb_pd_policy.c b/board/fruitpie/usb_pd_policy.c index 96668ff015..bf49a0ce64 100644 --- a/board/fruitpie/usb_pd_policy.c +++ b/board/fruitpie/usb_pd_policy.c @@ -117,11 +117,11 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } /* ----------------- Vendor Defined Messages ------------------ */ diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c index dc6eb7fc84..fff0399184 100644 --- a/board/hoho/usb_pd_policy.c +++ b/board/hoho/usb_pd_policy.c @@ -91,11 +91,11 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } /* ----------------- Vendor Defined Messages ------------------ */ diff --git a/board/honeybuns/usb_pd_policy.c b/board/honeybuns/usb_pd_policy.c index 7e45a0cc87..67d39cbf68 100644 --- a/board/honeybuns/usb_pd_policy.c +++ b/board/honeybuns/usb_pd_policy.c @@ -116,11 +116,11 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } diff --git a/board/host/usb_pd_policy.c b/board/host/usb_pd_policy.c index 9d108bf2cc..a515f58800 100644 --- a/board/host/usb_pd_policy.c +++ b/board/host/usb_pd_policy.c @@ -101,11 +101,11 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } diff --git a/board/plankton/usb_pd_policy.c b/board/plankton/usb_pd_policy.c index f007cd4b91..59a37c6922 100644 --- a/board/plankton/usb_pd_policy.c +++ b/board/plankton/usb_pd_policy.c @@ -143,14 +143,15 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { /* If Plankton is in USB hub mode, always act as UFP */ - if (board_in_hub_mode() && dr_role == PD_ROLE_DFP && partner_dr_swap) + if (board_in_hub_mode() && dr_role == PD_ROLE_DFP && + (flags & PD_FLAGS_PARTNER_DR_DATA)) pd_request_data_swap(port); } diff --git a/board/ryu/usb_pd_policy.c b/board/ryu/usb_pd_policy.c index 454a3523e1..b7550b1480 100644 --- a/board/ryu/usb_pd_policy.c +++ b/board/ryu/usb_pd_policy.c @@ -119,11 +119,11 @@ int pd_check_data_swap(int port, int data_role) return 1; } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } diff --git a/board/samus_pd/usb_pd_policy.c b/board/samus_pd/usb_pd_policy.c index d9477a9da5..85e3244527 100644 --- a/board/samus_pd/usb_pd_policy.c +++ b/board/samus_pd/usb_pd_policy.c @@ -157,18 +157,30 @@ void pd_execute_data_swap(int port, int data_role) set_usb_switches(port, (data_role == PD_ROLE_UFP)); } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { - /* If sink, and dual role toggling is on, then switch to source */ - if (partner_pr_swap && pr_role == PD_ROLE_SINK && - pd_get_dual_role() == PD_DRP_TOGGLE_ON) - pd_request_power_swap(port); + /* + * If partner is dual-role power and dualrole toggling is on, consider + * if a power swap is necessary. + */ + if ((flags & PD_FLAGS_PARTNER_DR_POWER) && + pd_get_dual_role() == PD_DRP_TOGGLE_ON) { + /* + * If we are a sink and partner is not externally powered, then + * swap to become a source. If we are source and partner is + * externally powered, swap to become a sink. + */ + int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER; + if ((!partner_extpower && pr_role == PD_ROLE_SINK) || + (partner_extpower && pr_role == PD_ROLE_SOURCE)) + pd_request_power_swap(port); + } } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { /* If UFP, try to switch to DFP */ - if (partner_dr_swap && dr_role == PD_ROLE_UFP) + if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP) pd_request_data_swap(port); } /* ----------------- Vendor Defined Messages ------------------ */ diff --git a/board/twinkie/usb_pd_policy.c b/board/twinkie/usb_pd_policy.c index b1e4c064da..8b19031f32 100644 --- a/board/twinkie/usb_pd_policy.c +++ b/board/twinkie/usb_pd_policy.c @@ -106,11 +106,11 @@ int pd_check_data_swap(int port, int data_role) return 1; } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { } diff --git a/board/zinger/usb_pd_policy.c b/board/zinger/usb_pd_policy.c index cb1e3b743a..2f5b6c3e99 100644 --- a/board/zinger/usb_pd_policy.c +++ b/board/zinger/usb_pd_policy.c @@ -299,14 +299,14 @@ void pd_execute_data_swap(int port, int data_role) /* Do nothing */ } -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap) +void pd_check_pr_role(int port, int pr_role, int flags) { } -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap) +void pd_check_dr_role(int port, int dr_role, int flags) { /* If DFP, try to switch to UFP */ - if (partner_dr_swap && dr_role == PD_ROLE_DFP) + if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP) pd_request_data_swap(port); } diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 639de2c287..01da41cdaa 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -217,28 +217,6 @@ static uint32_t pd_src_caps[PD_PORT_COUNT][PDO_MAX_OBJECTS]; static int pd_src_cap_cnt[PD_PORT_COUNT]; #endif -#define PD_FLAGS_PING_ENABLED (1 << 0) /* SRC_READY pings enabled */ -#define PD_FLAGS_PARTNER_DR_POWER (1 << 1) /* port partner is dualrole power */ -#define PD_FLAGS_PARTNER_DR_DATA (1 << 2) /* port partner is dualrole data */ -#define PD_FLAGS_DATA_SWAPPED (1 << 3) /* data swap complete */ -#define PD_FLAGS_SNK_CAP_RECVD (1 << 4) /* sink capabilities received */ -#define PD_FLAGS_GET_SNK_CAP_SENT (1 << 5) /* get sink cap sent */ -#define PD_FLAGS_EXPLICIT_CONTRACT (1 << 6) /* explicit pwr contract in place */ -#define PD_FLAGS_SFT_RST_DIS_COMM (1 << 7) /* disable comms after soft reset */ -#define PD_FLAGS_PREVIOUS_PD_CONN (1 << 8) /* previously PD connected */ -#define PD_FLAGS_CHECK_PR_ROLE (1 << 9) /* check power role in READY */ -#define PD_FLAGS_CHECK_DR_ROLE (1 << 10)/* check data role in READY */ -/* Flags to clear on a disconnect */ -#define PD_FLAGS_RESET_ON_DISCONNECT_MASK (PD_FLAGS_PARTNER_DR_POWER | \ - PD_FLAGS_PARTNER_DR_DATA | \ - PD_FLAGS_DATA_SWAPPED | \ - PD_FLAGS_SNK_CAP_RECVD | \ - PD_FLAGS_GET_SNK_CAP_SENT | \ - PD_FLAGS_EXPLICIT_CONTRACT | \ - PD_FLAGS_PREVIOUS_PD_CONN | \ - PD_FLAGS_CHECK_PR_ROLE | \ - PD_FLAGS_CHECK_DR_ROLE) - static struct pd_protocol { /* current port power role (SOURCE or SINK) */ uint8_t power_role; @@ -967,24 +945,39 @@ static void pd_send_request_msg(int port, int always_send_request) static void pd_update_pdo_flags(int port, uint32_t pdo) { /* can only parse PDO flags if type is fixed */ - if ((pdo & PDO_TYPE_MASK) == PDO_TYPE_FIXED) { - if (pdo & PDO_FIXED_DUAL_ROLE) { - pd[port].flags |= PD_FLAGS_PARTNER_DR_POWER; -#ifdef CONFIG_CHARGE_MANAGER - charge_manager_update_dualrole(port, CAP_DUALROLE); -#endif - } else { - pd[port].flags &= ~PD_FLAGS_PARTNER_DR_POWER; -#ifdef CONFIG_CHARGE_MANAGER - charge_manager_update_dualrole(port, CAP_DEDICATED); + if ((pdo & PDO_TYPE_MASK) != PDO_TYPE_FIXED) + return; + +#ifdef CONFIG_USB_PD_DUAL_ROLE + if (pdo & PDO_FIXED_DUAL_ROLE) + pd[port].flags |= PD_FLAGS_PARTNER_DR_POWER; + else + pd[port].flags &= ~PD_FLAGS_PARTNER_DR_POWER; + + if (pdo & PDO_FIXED_EXTERNAL) + pd[port].flags |= PD_FLAGS_PARTNER_EXTPOWER; + else + pd[port].flags &= ~PD_FLAGS_PARTNER_EXTPOWER; #endif - } - if (pdo & PDO_FIXED_DATA_SWAP) - pd[port].flags |= PD_FLAGS_PARTNER_DR_DATA; - else - pd[port].flags &= ~PD_FLAGS_PARTNER_DR_DATA; + if (pdo & PDO_FIXED_DATA_SWAP) + pd[port].flags |= PD_FLAGS_PARTNER_DR_DATA; + else + pd[port].flags &= ~PD_FLAGS_PARTNER_DR_DATA; + +#ifdef CONFIG_CHARGE_MANAGER + /* + * If partner supports power swap and is NOT externally powered, then + * treat this as a dualrole device. Otherwise, treat this as a + * dedicated charger. + */ + if ((pd[port].flags & PD_FLAGS_PARTNER_DR_POWER) && + !(pd[port].flags & PD_FLAGS_PARTNER_EXTPOWER)) { + charge_manager_update_dualrole(port, CAP_DUALROLE); + } else { + charge_manager_update_dualrole(port, CAP_DEDICATED); } +#endif } static void handle_data_request(int port, uint16_t head, @@ -2129,8 +2122,7 @@ void pd_task(void) /* Check power role policy, which may trigger a swap */ if (pd[port].flags & PD_FLAGS_CHECK_PR_ROLE) { pd_check_pr_role(port, PD_ROLE_SOURCE, - pd[port].flags & - PD_FLAGS_PARTNER_DR_POWER); + pd[port].flags); pd[port].flags &= ~PD_FLAGS_CHECK_PR_ROLE; break; } @@ -2138,8 +2130,7 @@ void pd_task(void) /* Check data role policy, which may trigger a swap */ if (pd[port].flags & PD_FLAGS_CHECK_DR_ROLE) { pd_check_dr_role(port, pd[port].data_role, - pd[port].flags & - PD_FLAGS_PARTNER_DR_DATA); + pd[port].flags); pd[port].flags &= ~PD_FLAGS_CHECK_DR_ROLE; break; } @@ -2496,8 +2487,7 @@ void pd_task(void) /* Check power role policy, which may trigger a swap */ if (pd[port].flags & PD_FLAGS_CHECK_PR_ROLE) { pd_check_pr_role(port, PD_ROLE_SINK, - pd[port].flags & - PD_FLAGS_PARTNER_DR_POWER); + pd[port].flags); pd[port].flags &= ~PD_FLAGS_CHECK_PR_ROLE; break; } @@ -2505,8 +2495,7 @@ void pd_task(void) /* Check data role policy, which may trigger a swap */ if (pd[port].flags & PD_FLAGS_CHECK_DR_ROLE) { pd_check_dr_role(port, pd[port].data_role, - pd[port].flags & - PD_FLAGS_PARTNER_DR_DATA); + pd[port].flags); pd[port].flags &= ~PD_FLAGS_CHECK_DR_ROLE; break; } diff --git a/include/usb_pd.h b/include/usb_pd.h index cf8dffc41f..ebed5c3554 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -630,6 +630,31 @@ enum pd_states { PD_STATE_COUNT, }; +#define PD_FLAGS_PING_ENABLED (1 << 0) /* SRC_READY pings enabled */ +#define PD_FLAGS_PARTNER_DR_POWER (1 << 1) /* port partner is dualrole power */ +#define PD_FLAGS_PARTNER_DR_DATA (1 << 2) /* port partner is dualrole data */ +#define PD_FLAGS_DATA_SWAPPED (1 << 3) /* data swap complete */ +#define PD_FLAGS_SNK_CAP_RECVD (1 << 4) /* sink capabilities received */ +#define PD_FLAGS_GET_SNK_CAP_SENT (1 << 5) /* get sink cap sent */ +#define PD_FLAGS_EXPLICIT_CONTRACT (1 << 6) /* explicit pwr contract in place */ +#define PD_FLAGS_SFT_RST_DIS_COMM (1 << 7) /* disable comms after soft reset */ +#define PD_FLAGS_PREVIOUS_PD_CONN (1 << 8) /* previously PD connected */ +#define PD_FLAGS_CHECK_PR_ROLE (1 << 9) /* check power role in READY */ +#define PD_FLAGS_CHECK_DR_ROLE (1 << 10)/* check data role in READY */ +#define PD_FLAGS_PARTNER_EXTPOWER (1 << 11)/* port partner has external pwr */ +/* Flags to clear on a disconnect */ +#define PD_FLAGS_RESET_ON_DISCONNECT_MASK (PD_FLAGS_PARTNER_DR_POWER | \ + PD_FLAGS_PARTNER_DR_DATA | \ + PD_FLAGS_DATA_SWAPPED | \ + PD_FLAGS_SNK_CAP_RECVD | \ + PD_FLAGS_GET_SNK_CAP_SENT | \ + PD_FLAGS_EXPLICIT_CONTRACT | \ + PD_FLAGS_PREVIOUS_PD_CONN | \ + PD_FLAGS_CHECK_PR_ROLE | \ + PD_FLAGS_CHECK_DR_ROLE | \ + PD_FLAGS_PARTNER_EXTPOWER) + + enum pd_cc_states { PD_CC_NONE, @@ -883,18 +908,18 @@ int pd_check_data_swap(int port, int data_role); * * @param port USB-C port number * @param pr_role Our power role - * @param partner_pr_swap Partner supports PR_SWAP + * @param flags PD flags */ -void pd_check_pr_role(int port, int pr_role, int partner_pr_swap); +void pd_check_pr_role(int port, int pr_role, int flags); /** * Check current data role for potential data swap * * @param port USB-C port number * @param dr_role Our data role - * @param partner_dr_swap Partner supports DR_SWAP + * @param flags PD flags */ -void pd_check_dr_role(int port, int dr_role, int partner_dr_swap); +void pd_check_dr_role(int port, int dr_role, int flags); /** * Execute data swap. |