summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/dingdong/usb_pd_policy.c4
-rw-r--r--board/firefly/usb_pd_policy.c4
-rw-r--r--board/fruitpie/usb_pd_policy.c4
-rw-r--r--board/hoho/usb_pd_policy.c4
-rw-r--r--board/honeybuns/usb_pd_policy.c4
-rw-r--r--board/host/usb_pd_policy.c4
-rw-r--r--board/plankton/usb_pd_policy.c7
-rw-r--r--board/ryu/usb_pd_policy.c4
-rw-r--r--board/samus_pd/usb_pd_policy.c26
-rw-r--r--board/twinkie/usb_pd_policy.c4
-rw-r--r--board/zinger/usb_pd_policy.c6
-rw-r--r--common/usb_pd_protocol.c79
-rw-r--r--include/usb_pd.h33
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.