summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-08-05 16:22:14 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-08-07 22:41:40 +0000
commitbebad665af4d4f56e4ed1939adfb2e68b62c8f97 (patch)
tree94f835caf0070a23f0a9d83c99c5ae9072267e56
parent68916bc7d8ec14f6703478e0f86b0c9fce40b8a8 (diff)
downloadchrome-ec-bebad665af4d4f56e4ed1939adfb2e68b62c8f97.tar.gz
pd: add PD communication enable flag
Add PD communication enable flag. When disabled, the ports will still detect source/sink connect and disconnect, and will provide VBUS to a device, but will not send or respond to any PD communication. Use the CONFIG_USB_PD_COMM_ENABLED macro to define the default state of PD communication enabled flag which may vary board to board. BUG=chrome-os-partner:31125 BRANCH=none TEST=load onto samus. use "pd 0 enable" console command to toggle between enabled and disabled. when disabled, test that plugging in a zinger only gets you the default VBUS 5V and that no negotiation takes place. when enabled, test that plugging in zinger negotiates successfully. Change-Id: I78ac3091f12d9699b19647be48ab7b6f434f5d7d Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/211045
-rw-r--r--common/usb_pd_protocol.c50
-rw-r--r--include/config.h3
-rw-r--r--include/usb_pd.h9
3 files changed, 57 insertions, 5 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index 45a5f9a1c5..202fd490ff 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -245,6 +245,13 @@ static struct pd_protocol {
uint64_t timeout;
} pd[PD_PORT_COUNT];
+/*
+ * PD communication enabled flag. When false, PD state machine still
+ * detects source/sink connection and disconnection, and will still
+ * provide VBUS, but never sends any PD communication.
+ */
+static uint8_t pd_comm_enabled = CONFIG_USB_PD_COMM_ENABLED;
+
struct mutex pd_crc_lock;
static inline void set_state_timeout(int port,
@@ -327,6 +334,10 @@ static void send_hard_reset(int port)
{
int off;
+ /* If PD communication is disabled, return */
+ if (!pd_comm_enabled)
+ return;
+
/* 64-bit preamble */
off = pd_write_preamble(port);
/* Hard-Reset: 3x RST-1 + 1x RST-2 */
@@ -347,6 +358,10 @@ static int send_validate_message(int port, uint16_t header,
int r;
static uint32_t payload[7];
+ /* If PD communication is disabled, return error */
+ if (!pd_comm_enabled)
+ return -2;
+
/* retry 3 times if we are not getting a valid answer */
for (r = 0; r <= PD_RETRY_COUNT; r++) {
int bit_len, head;
@@ -407,6 +422,10 @@ static void send_goodcrc(int port, int id)
uint16_t header = PD_HEADER(PD_CTRL_GOOD_CRC, pd[port].role, id, 0);
int bit_len = prepare_message(port, header, 0, NULL);
+ /* If PD communication is disabled, return */
+ if (!pd_comm_enabled)
+ return;
+
pd_start_tx(port, pd[port].polarity, bit_len);
pd_tx_done(port, pd[port].polarity);
}
@@ -477,6 +496,10 @@ static void bist_mode_2_tx(int port)
{
int bit;
+ /* If PD communication is not allowed, return */
+ if (!pd_comm_enabled)
+ return;
+
CPRINTF("BIST carrier 2 - sending on port %d\n", port);
/*
@@ -941,6 +964,11 @@ int pd_get_polarity(int port)
return pd[port].polarity;
}
+void pd_comm_enable(int enable)
+{
+ pd_comm_enabled = enable;
+}
+
void pd_task(void)
{
int head;
@@ -970,7 +998,7 @@ void pd_task(void)
while (1) {
/* monitor for incoming packet if in a connected state */
- if (pd_is_connected(port))
+ if (pd_is_connected(port) && pd_comm_enabled)
pd_rx_enable_monitoring(port);
else
pd_rx_disable_monitoring(port);
@@ -986,7 +1014,7 @@ void pd_task(void)
/* wait for next event/packet or timeout expiration */
task_wait_event(timeout);
/* incoming packet ? */
- if (pd_rx_started(port)) {
+ if (pd_rx_started(port) && pd_comm_enabled) {
head = analyze_rx(port, payload);
pd_rx_complete(port);
if (head > 0)
@@ -1385,6 +1413,17 @@ static int command_pd(int argc, char **argv)
ccprintf("set TX frequency to %d Hz\n", freq);
} else if (!strcasecmp(argv[2], "dump")) {
debug_dump = !debug_dump;
+ } else if (!strcasecmp(argv[2], "enable")) {
+ int enable;
+
+ if (argc < 3)
+ return EC_ERROR_PARAM_COUNT;
+
+ enable = strtoi(argv[3], &e, 10);
+ if (*e)
+ return EC_ERROR_PARAM3;
+ pd_comm_enable(enable);
+ ccprintf("Ports %s\n", enable ? "enabled" : "disabled");
} else if (!strncasecmp(argv[2], "hard", 4)) {
set_state(port, PD_STATE_HARD_RESET);
task_wake(PORT_TO_TASK_ID(port));
@@ -1433,8 +1472,9 @@ static int command_pd(int argc, char **argv)
"SRC_ACCEPTED", "SRC_TRANSITION", "SRC_READY",
"HARD_RESET", "BIST",
};
- ccprintf("Port C%d - Role: %s Polarity: CC%d State: %s\n",
- port, pd[port].role == PD_ROLE_SOURCE ? "SRC" : "SNK",
+ ccprintf("Port C%d, %s - Role: %s Polarity: CC%d State: %s\n",
+ port, pd_comm_enabled ? "Enabled" : "Disabled",
+ pd[port].role == PD_ROLE_SOURCE ? "SRC" : "SNK",
pd[port].polarity + 1,
state_names[pd[port].task_state]);
} else {
@@ -1445,7 +1485,7 @@ static int command_pd(int argc, char **argv)
}
DECLARE_CONSOLE_COMMAND(pd, command_pd,
"<port> "
- "[tx|bist|charger|dev|dump|dualrole"
+ "[tx|bist|charger|dev|dump|dualrole|enable"
"|hard|clock|ping|state]",
"USB PD",
NULL);
diff --git a/include/config.h b/include/config.h
index 7a2627d1af..f52ba372d8 100644
--- a/include/config.h
+++ b/include/config.h
@@ -908,6 +908,9 @@
/* Include all USB Power Delivery modules */
#undef CONFIG_USB_POWER_DELIVERY
+/* Default state of PD communication enabled flag */
+#define CONFIG_USB_PD_COMM_ENABLED 1
+
/* Respond to custom vendor-defined messages over PD */
#undef CONFIG_USB_PD_CUSTOM_VDM
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 4703c8dcb0..a20664ba8a 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -412,4 +412,13 @@ void pd_hw_init(int port);
*/
int pd_get_polarity(int port);
+/**
+ * Set the PD communication enabled flag. When communication is disabled,
+ * the port can still detect connection and source power but will not
+ * send or respond to any PD communication.
+ *
+ * @param enable Enable flag to set
+ */
+void pd_comm_enable(int enable);
+
#endif /* __USB_PD_H */