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
This commit is contained in:
Alec Berg
2014-08-05 16:22:14 -07:00
committed by chrome-internal-fetch
parent 68916bc7d8
commit bebad665af
3 changed files with 57 additions and 5 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */