summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2015-05-07 08:43:07 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-05-08 00:52:46 +0000
commitd7d6e7e660901fb73275ca41090115bed590e137 (patch)
tree009f97413c3ec37ad557afa8709d3e045fca94ea
parentdbf027f2f78f696b909dd2d70c8bf5439171befd (diff)
downloadchrome-ec-d7d6e7e660901fb73275ca41090115bed590e137.tar.gz
ryu: update PD swaps configuration
- allow power swap only when we are dual-role toggling (ie in S0). - enable the VCONN swap feature to support more type-C dongles. and allow it using the same rule as power swap. - become a power sink when we are connected to an externally powered DRP. - by default, try to be a data UFP for USB. so Dual Role Device such as laptops can get our data. - add a message to inform the AP that our USB role has changed (but the host events are fully wired yet on Ryu) Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=none TEST=make buildall Change-Id: Id0f9027b140cb20f105bcdbc00cac5cb5f44c9e0 Reviewed-on: https://chromium-review.googlesource.com/269857 Reviewed-by: Alec Berg <alecaberg@chromium.org> Trybot-Ready: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/ryu/board.h1
-rw-r--r--board/ryu/usb_pd_config.h3
-rw-r--r--board/ryu/usb_pd_policy.c45
-rw-r--r--board/ryu_p4p5/board.c6
-rw-r--r--board/ryu_p4p5/board.h4
-rw-r--r--board/ryu_p4p5/usb_pd_config.h3
-rw-r--r--board/ryu_p4p5/usb_pd_policy.c45
-rw-r--r--include/ec_commands.h1
8 files changed, 94 insertions, 14 deletions
diff --git a/board/ryu/board.h b/board/ryu/board.h
index f0210f8f5d..ad017a48b6 100644
--- a/board/ryu/board.h
+++ b/board/ryu/board.h
@@ -33,6 +33,7 @@
#define CONFIG_USB_SWITCH_PI3USB9281
#define CONFIG_USBC_SS_MUX
#define CONFIG_USBC_VCONN
+#define CONFIG_USBC_VCONN_SWAP
#define CONFIG_ADC
#define CONFIG_ADC_SAMPLE_TIME 3
#define CONFIG_HW_CRC
diff --git a/board/ryu/usb_pd_config.h b/board/ryu/usb_pd_config.h
index 9d6784beb4..c6d6882b0f 100644
--- a/board/ryu/usb_pd_config.h
+++ b/board/ryu/usb_pd_config.h
@@ -220,6 +220,9 @@ static inline int pd_snk_is_vbus_provided(int port)
#define PD_POWER_SUPPLY_TURN_ON_DELAY 40000 /* us */
#define PD_POWER_SUPPLY_TURN_OFF_DELAY 20000 /* us */
+/* delay to turn on/off vconn */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+
/* Define typical operating power and max power */
#define PD_OPERATING_POWER_MW 10000
#define PD_MAX_POWER_MW 24000
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 ------------------ */
diff --git a/board/ryu_p4p5/board.c b/board/ryu_p4p5/board.c
index e00dec962d..6694612210 100644
--- a/board/ryu_p4p5/board.c
+++ b/board/ryu_p4p5/board.c
@@ -585,6 +585,12 @@ void board_set_charge_limit(int charge_ma)
CPRINTS("Failed to set input current limit for PD");
}
+/* Send host event up to AP */
+void pd_send_host_event(int mask)
+{
+ /* TODO(crosbug.com/p/33194): implement host events */
+}
+
/**
* Return whether ramping is allowed for given supplier
*/
diff --git a/board/ryu_p4p5/board.h b/board/ryu_p4p5/board.h
index 104e3d0fb9..6c5479d49a 100644
--- a/board/ryu_p4p5/board.h
+++ b/board/ryu_p4p5/board.h
@@ -32,6 +32,7 @@
#define CONFIG_USB_SWITCH_PI3USB9281
#define CONFIG_USBC_SS_MUX
#define CONFIG_USBC_VCONN
+#define CONFIG_USBC_VCONN_SWAP
#define CONFIG_ADC
#define CONFIG_ADC_SAMPLE_TIME 3
#define CONFIG_HW_CRC
@@ -194,6 +195,9 @@ int board_discharge_on_ac(int enable);
/* Set the charge current limit. */
void board_set_charge_limit(int charge_ma);
+/* Send host event to AP */
+void pd_send_host_event(int mask);
+
/* PP1800 transition GPIO interrupt handler */
void pp1800_on_off_evt(enum gpio_signal signal);
diff --git a/board/ryu_p4p5/usb_pd_config.h b/board/ryu_p4p5/usb_pd_config.h
index a100ddb2ac..bb7392f450 100644
--- a/board/ryu_p4p5/usb_pd_config.h
+++ b/board/ryu_p4p5/usb_pd_config.h
@@ -215,6 +215,9 @@ static inline int pd_snk_is_vbus_provided(int port)
#define PD_POWER_SUPPLY_TURN_ON_DELAY 20000 /* us */
#define PD_POWER_SUPPLY_TURN_OFF_DELAY 20000 /* us */
+/* delay to turn on/off vconn */
+#define PD_VCONN_SWAP_DELAY 5000 /* us */
+
/* Define typical operating power and max power */
#define PD_OPERATING_POWER_MW 10000
#define PD_MAX_POWER_MW 24000
diff --git a/board/ryu_p4p5/usb_pd_policy.c b/board/ryu_p4p5/usb_pd_policy.c
index b7550b1480..b20c0774cc 100644
--- a/board/ryu_p4p5/usb_pd_policy.c
+++ b/board/ryu_p4p5/usb_pd_policy.c
@@ -109,27 +109,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);
}
int pd_custom_vdm(int port, int cnt, uint32_t *payload,
diff --git a/include/ec_commands.h b/include/ec_commands.h
index cb064b9588..ad3056e3e8 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2927,6 +2927,7 @@ struct ec_response_pd_status {
#define PD_EVENT_UPDATE_DEVICE (1 << 0)
#define PD_EVENT_POWER_CHANGE (1 << 1)
#define PD_EVENT_IDENTITY_RECEIVED (1 << 2)
+#define PD_EVENT_DATA_SWAP (1 << 3)
struct ec_response_host_event_status {
uint32_t status; /* PD MCU host event status */
} __packed;