summaryrefslogtreecommitdiff
path: root/board/ryu/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/ryu/usb_pd_policy.c')
-rw-r--r--board/ryu/usb_pd_policy.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/board/ryu/usb_pd_policy.c b/board/ryu/usb_pd_policy.c
index d423fe22f0..b171e3e9aa 100644
--- a/board/ryu/usb_pd_policy.c
+++ b/board/ryu/usb_pd_policy.c
@@ -114,27 +114,58 @@ int pd_board_checks(void)
int pd_check_power_swap(int port)
{
/* TODO: use battery level to decide to accept/reject power swap */
- /* Always allow power swap */
- return 1;
+ /*
+ * Allow power swap as long as we are acting as a dual role device,
+ * otherwise assume our role is fixed (not in S0 or console command
+ * to fix our role).
+ */
+ return pd_get_dual_role() == PD_DRP_TOGGLE_ON ? 1 : 0;
}
int pd_check_data_swap(int port, int data_role)
{
- /* Always allow data swap */
+ /* Always allow data swap: we can be DFP or UFP for USB */
return 1;
}
-void pd_check_pr_role(int port, int pr_role, int flags)
+int pd_check_vconn_swap(int port)
{
+ /*
+ * VCONN is provided directly by the battery(PPVAR_SYS)
+ * but use the same rules as power swap
+ */
+ return pd_get_dual_role() == PD_DRP_TOGGLE_ON ? 1 : 0;
}
-void pd_check_dr_role(int port, int dr_role, int flags)
+void pd_execute_data_swap(int port, int data_role)
{
+ /* inform the host controller to change role */
+ pd_send_host_event(PD_EVENT_DATA_SWAP);
}
-void pd_execute_data_swap(int port, int data_role)
+void pd_check_pr_role(int port, int pr_role, int flags)
+{
+ /*
+ * 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 source and partner is externally powered,
+ * swap to become a sink.
+ */
+ if ((flags & PD_FLAGS_PARTNER_EXTPOWER) &&
+ pr_role == PD_ROLE_SOURCE)
+ pd_request_power_swap(port);
+ }
+}
+
+void pd_check_dr_role(int port, int dr_role, int flags)
{
- /* TODO: what do we need to do to change host controller data role? */
+ /* if the partner is a DRP (e.g. laptop), try to switch to UFP */
+ if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_DFP)
+ pd_request_data_swap(port);
}
/* ----------------- Vendor Defined Messages ------------------ */