summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2017-02-28 15:33:00 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-03-07 22:43:15 +0000
commit63735a7debe30e941e9ab117869373b3005bca84 (patch)
tree9b3b92fc909e6af6c47291887560ffb66091c6e9
parent84a823a080da7ee1466e7e295c4be50481b04a77 (diff)
downloadchrome-ec-63735a7debe30e941e9ab117869373b3005bca84.tar.gz
pdcontrol: Suspend port individually
pdcontrol suspend command will be used to prevent tcpm from putting the chip into sleep while firmware update is taking place. Currently the command suspends or resumes port 0. This patch makes the command apply to ports individually. pd enable console command now takes a port number: pd <port> enable/disable. This patch also replaces CONFIG_USB_PD_COMM_ENABLED with _DISABLED. When it's defined, PD communication is disabled at startup. Plankton undefines CONFIG_USB_PD_COMM_ENABLED enable, intending to disable PD communication at startup. Therefore, this patch defines CONFIG_USB_PD_COMM_DISABLED in its board.h. BUG=b:35586859 BRANCH=none TEST=From AP console: localhost # /tmp/ectool pdcontrol suspend 1 [600.188013 TCPC p1 suspended!] > pd 1 state Port C1 CC1, Dis - Role: SNK-UFP State: SUSPENDED, Flags: 0x0020 localhost # /tmp/ectool pdcontrol resume 1 [678.516613 TCPC p1 resumed!] > pd 1 state Port C1 CC1, Ena - Role: SNK-UFP State: DRP_AUTO_TOGGLE, Flags: 0x0020 From ec console: > pd 1 disable Port C1 disable > pd 1 state Port C1 CC1, Dis - Role: SNK-UFP State: DRP_AUTO_TOGGLE, Flags: 0x0020 > pd 1 enable Port C1 enabled > pd 1 state Port C1 CC1, Ena - Role: SNK-UFP State: DRP_AUTO_TOGGLE, Flags: 0x0020 Change-Id: Ia0cc4904ac52adc4b89de20918968c8df78b9c80 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/447968 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> (cherry picked from commit ad089de4b0430e5d997b9f6d6f187daae1fb11dc) Reviewed-on: https://chromium-review.googlesource.com/450990 Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--board/plankton/board.c6
-rw-r--r--board/plankton/board.h2
-rw-r--r--common/usb_pd_protocol.c126
-rw-r--r--include/config.h4
-rw-r--r--include/usb_pd.h3
-rw-r--r--util/ectool.c11
6 files changed, 82 insertions, 70 deletions
diff --git a/board/plankton/board.c b/board/plankton/board.c
index 5bc6b776a3..b725989047 100644
--- a/board/plankton/board.c
+++ b/board/plankton/board.c
@@ -203,14 +203,14 @@ static void detect_cc_cable(void)
TYPEC_CABLE_SINGLE_CC;
/* Flip back to original polarity and enable PD comms */
set_active_cc(!active_cc);
- pd_comm_enable(1);
+ pd_comm_enable(0, 1);
break;
case TYPEC_CABLE_SINGLE_CC:
case TYPEC_CABLE_DOUBLE_CC:
/* Check for disconnection and disable PD comms */
if (!pd_is_connected(0)) {
cable = TYPEC_CABLE_NONE;
- pd_comm_enable(0);
+ pd_comm_enable(0, 0);
}
break;
}
@@ -269,7 +269,7 @@ static void update_usbc_dual_role(int dual_role)
/* Need to make sure both CC lines are set for SNK or SRC. */
set_active_cc(host_mode);
/* Ensure that PD communication is enabled. */
- pd_comm_enable(1);
+ pd_comm_enable(0, 1);
} else {
drp_enable = 0;
/*
diff --git a/board/plankton/board.h b/board/plankton/board.h
index 749a3e8cd6..8e39de702c 100644
--- a/board/plankton/board.h
+++ b/board/plankton/board.h
@@ -19,7 +19,7 @@
#define CONFIG_STM_HWTIMER32
#define CONFIG_USB_POWER_DELIVERY
#define CONFIG_USB_PD_ALT_MODE
-#undef CONFIG_USB_PD_COMM_ENABLED
+#define CONFIG_USB_PD_COMM_DISABLED
#define CONFIG_USB_PD_CUSTOM_VDM
#define CONFIG_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_DYNAMIC_SRC_CAP
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index dd3bf07ba6..5b94bd4562 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -54,16 +54,11 @@ static int debug_level;
* detects source/sink connection and disconnection, and will still
* provide VBUS, but never sends any PD communication.
*/
-#if !defined(CONFIG_USB_PD_COMM_ENABLED) || defined(CONFIG_USB_PD_COMM_LOCKED)
-static uint8_t pd_comm_enabled;
-#else
-static uint8_t pd_comm_enabled = 1;
-#endif
+static uint8_t pd_comm_enabled[CONFIG_USB_PD_PORT_COUNT];
#else /* CONFIG_COMMON_RUNTIME */
#define CPRINTF(format, args...)
#define CPRINTS(format, args...)
static const int debug_level;
-static const uint8_t pd_comm_enabled = 1;
#endif
#ifdef CONFIG_USB_PD_DUAL_ROLE
@@ -204,6 +199,15 @@ BUILD_ASSERT(ARRAY_SIZE(pd_state_names) == PD_STATE_COUNT);
static struct ec_params_usb_pd_rw_hash_entry rw_hash_table[RW_HASH_ENTRIES];
#endif
+static inline int pd_comm_is_enabled(int port)
+{
+#ifdef CONFIG_COMMON_RUNTIME
+ return pd_comm_enabled[port];
+#else
+ return 1;
+#endif
+}
+
static inline void set_state_timeout(int port,
uint64_t timeout,
enum pd_states timeout_state)
@@ -393,7 +397,7 @@ static int pd_transmit(int port, enum tcpm_transmit_type type,
int evt;
/* If comms are disabled, do not transmit, return error */
- if (!pd_comm_enabled)
+ if (!pd_comm_is_enabled(port))
return -1;
tcpm_transmit(port, type, header, data);
@@ -1469,28 +1473,25 @@ int pd_get_partner_data_swap_capable(int port)
}
#ifdef CONFIG_COMMON_RUNTIME
-void pd_comm_enable(int enable)
+void pd_comm_enable(int port, int enable)
{
- int i;
-
- pd_comm_enabled = enable;
+ /* We don't check port >= CONFIG_USB_PD_PORT_COUNT deliberately */
+ pd_comm_enabled[port] = enable;
- for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
- /* If type-C connection, then update the TCPC RX enable */
- if (pd_is_connected(i))
- tcpm_set_rx_enable(i, enable);
+ /* If type-C connection, then update the TCPC RX enable */
+ if (pd_is_connected(port))
+ tcpm_set_rx_enable(port, enable);
#ifdef CONFIG_USB_PD_DUAL_ROLE
- /*
- * If communications are enabled, start hard reset timer for
- * any port in PD_SNK_DISCOVERY.
- */
- if (enable && pd[i].task_state == PD_STATE_SNK_DISCOVERY)
- set_state_timeout(i,
- get_time().val + PD_T_SINK_WAIT_CAP,
- PD_STATE_HARD_RESET_SEND);
+ /*
+ * If communications are enabled, start hard reset timer for
+ * any port in PD_SNK_DISCOVERY.
+ */
+ if (enable && pd[port].task_state == PD_STATE_SNK_DISCOVERY)
+ set_state_timeout(port,
+ get_time().val + PD_T_SINK_WAIT_CAP,
+ PD_STATE_HARD_RESET_SEND);
#endif
- }
}
#endif
@@ -1582,6 +1583,8 @@ void pd_set_new_power_request(int port)
static void pd_init_tasks(void)
{
static int initialized;
+ int enable = 1;
+ int i;
/* Initialize globals once, for all PD tasks. */
if (initialized)
@@ -1597,15 +1600,16 @@ static void pd_init_tasks(void)
drp_state = PD_DRP_TOGGLE_ON;
#endif
-#if !defined(CONFIG_USB_PD_COMM_ENABLED) || defined(CONFIG_USB_PD_COMM_LOCKED)
- /* Enable PD communication at init if we're in RW or unlocked. */
- if (system_get_image_copy() != SYSTEM_IMAGE_RW && system_is_locked()) {
- pd_comm_enabled = 0;
- ccprintf("[%T PD comm disabled]\n");
- } else {
- pd_comm_enabled = 1;
- }
+#if defined(CONFIG_USB_PD_COMM_DISABLED)
+ enable = 0;
+#elif defined(CONFIG_USB_PD_COMM_LOCKED)
+ /* Disable PD communication at init if we're in RO and locked. */
+ if (system_get_image_copy() != SYSTEM_IMAGE_RW && system_is_locked())
+ enable = 0;
#endif
+ for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++)
+ pd_comm_enabled[i] = enable;
+ CPRINTS("PD comm %sabled", enable ? "en" : "dis");
initialized = 1;
}
@@ -1904,7 +1908,7 @@ void pd_task(void)
}
#endif
/* If PD comm is enabled, enable TCPC RX */
- if (pd_comm_enabled)
+ if (pd_comm_is_enabled(port))
tcpm_set_rx_enable(port, 1);
#ifdef CONFIG_USBC_VCONN
@@ -1978,7 +1982,7 @@ void pd_task(void)
* to RECEIVE_DETECT register to enable
* PD message passing.
*/
- if (pd_comm_enabled)
+ if (pd_comm_is_enabled(port))
tcpm_set_rx_enable(port, 1);
#endif /* CONFIG_USB_PD_TCPM_TCPCI */
@@ -2402,7 +2406,7 @@ void pd_task(void)
port, typec_curr, TYPE_C_VOLTAGE);
#endif
/* If PD comm is enabled, enable TCPC RX */
- if (pd_comm_enabled)
+ if (pd_comm_is_enabled(port))
tcpm_set_rx_enable(port, 1);
/* DFP is attached */
@@ -2488,7 +2492,7 @@ defined(CONFIG_CASE_CLOSED_DEBUG_EXTERNAL)
* to RECEIVE_MESSAGE register to enable
* PD message passing.
*/
- if (pd_comm_enabled)
+ if (pd_comm_is_enabled(port))
tcpm_set_rx_enable(port, 1);
#endif /* CONFIG_USB_PD_TCPM_TCPCI */
@@ -2506,7 +2510,7 @@ defined(CONFIG_CASE_CLOSED_DEBUG_EXTERNAL)
case PD_STATE_SNK_DISCOVERY:
/* Wait for source cap expired only if we are enabled */
if ((pd[port].last_state != pd[port].task_state)
- && pd_comm_enabled) {
+ && pd_comm_is_enabled(port)) {
/*
* If VBUS has never been low, and we timeout
* waiting for source cap, try a soft reset
@@ -3298,19 +3302,6 @@ static int command_pd(int argc, char **argv)
return EC_SUCCESS;
}
#ifdef CONFIG_CMD_PD
- else if (!strcasecmp(argv[1], "enable")) {
- int enable;
-
- if (argc < 3)
- return EC_ERROR_PARAM_COUNT;
-
- enable = strtoi(argv[2], &e, 10);
- if (*e)
- return EC_ERROR_PARAM3;
- pd_comm_enable(enable);
- ccprintf("Ports %s\n", enable ? "enabled" : "disabled");
- return EC_SUCCESS;
- }
#ifdef CONFIG_CMD_PD_DEV_DUMP_INFO
else if (!strncasecmp(argv[1], "rwhashtable", 3)) {
int i;
@@ -3373,6 +3364,14 @@ static int command_pd(int argc, char **argv)
pd_request_source_voltage(port, max_volt);
ccprintf("max req: %dmV\n", max_volt);
+ } else if (!strcasecmp(argv[2], "disable")) {
+ pd_comm_enable(port, 0);
+ ccprintf("Port C%d disable\n", port);
+ return EC_SUCCESS;
+ } else if (!strcasecmp(argv[2], "enable")) {
+ pd_comm_enable(port, 1);
+ ccprintf("Port C%d enabled\n", port);
+ return EC_SUCCESS;
} else if (!strncasecmp(argv[2], "hard", 4)) {
set_state(port, PD_STATE_HARD_RESET_SEND);
task_wake(PD_PORT_TO_TASK_ID(port));
@@ -3445,7 +3444,7 @@ static int command_pd(int argc, char **argv)
ccprintf("Port C%d CC%d, %s - Role: %s-%s%s "
"State: %s, Flags: 0x%04x\n",
port, pd[port].polarity + 1,
- pd_comm_enabled ? "Ena" : "Dis",
+ pd_comm_is_enabled(port) ? "Ena" : "Dis",
pd[port].power_role == PD_ROLE_SOURCE ? "SRC" : "SNK",
pd[port].data_role == PD_ROLE_DFP ? "DFP" : "UFP",
(pd[port].flags & PD_FLAGS_VCONN_ON) ? "-VC" : "",
@@ -3458,9 +3457,9 @@ static int command_pd(int argc, char **argv)
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(pd, command_pd,
- "dualrole|dump|enable [0|1]|rwhashtable"
- "trysrc [0|1]\n\t<port> "
- "[tx|bist_rx|bist_tx|charger|clock|dev"
+ "dualrole|dump|rwhashtable"
+ "|trysrc [0|1]\n\t<port> "
+ "[tx|bist_rx|bist_tx|charger|clock|dev|disable|enable"
"|soft|hash|hard|ping|state|swap [power|data]|"
"vdm [ping | curr | vers]]",
"USB PD");
@@ -3533,14 +3532,15 @@ static int hc_usb_pd_control(struct host_cmd_handler_args *args)
#endif
if (args->version == 0) {
- r->enabled = pd_comm_enabled;
+ r->enabled = pd_comm_is_enabled(p->port);
r->role = pd[p->port].power_role;
r->polarity = pd[p->port].polarity;
r->state = pd[p->port].task_state;
args->response_size = sizeof(*r);
} else {
r_v1->enabled =
- (pd_comm_enabled ? PD_CTRL_RESP_ENABLED_COMMS : 0) |
+ (pd_comm_is_enabled(p->port) ?
+ PD_CTRL_RESP_ENABLED_COMMS : 0) |
(pd_is_connected(p->port) ?
PD_CTRL_RESP_ENABLED_CONNECTED : 0) |
((pd[p->port].flags & PD_FLAGS_PREVIOUS_PD_CONN) ?
@@ -3783,13 +3783,14 @@ DECLARE_HOST_COMMAND(EC_CMD_USB_PD_SET_AMODE,
#endif /* HAS_TASK_HOSTCMD */
#ifdef CONFIG_CMD_PD_CONTROL
-static int pd_control_disabled;
static int pd_control(struct host_cmd_handler_args *args)
{
+ static int pd_control_disabled;
const struct ec_params_pd_control *cmd = args->params;
+ int enable;
- if (cmd->chip != 0)
+ if (cmd->chip >= CONFIG_USB_PD_PORT_COUNT)
return EC_RES_INVALID_PARAM;
/* Always allow disable command */
@@ -3802,11 +3803,9 @@ static int pd_control(struct host_cmd_handler_args *args)
return EC_RES_ACCESS_DENIED;
if (cmd->subcmd == PD_SUSPEND) {
- pd_comm_enable(0);
- pd_set_suspend(0, 1);
+ enable = 0;
} else if (cmd->subcmd == PD_RESUME) {
- pd_comm_enable(1);
- pd_set_suspend(0, 0);
+ enable = 1;
} else if (cmd->subcmd == PD_RESET) {
#ifdef HAS_TASK_PDCMD
board_reset_pd_mcu();
@@ -3817,6 +3816,9 @@ static int pd_control(struct host_cmd_handler_args *args)
return EC_RES_INVALID_COMMAND;
}
+ pd_comm_enable(cmd->chip, enable);
+ pd_set_suspend(cmd->chip, !enable);
+
return EC_RES_SUCCESS;
}
diff --git a/include/config.h b/include/config.h
index ed971ddc27..cd0ac388df 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2065,8 +2065,8 @@
/* Check if max voltage request is allowed before each request */
#undef CONFIG_USB_PD_CHECK_MAX_REQUEST_ALLOWED
-/* Default state of PD communication enabled flag */
-#define CONFIG_USB_PD_COMM_ENABLED
+/* Default state of PD communication disabled flag */
+#undef CONFIG_USB_PD_COMM_DISABLED
/*
* Do not enable PD communication in RO as a security measure.
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 4eef319ae2..8a45b1fbf9 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1534,9 +1534,10 @@ void pd_request_data_swap(int port);
* the port can still detect connection and source power but will not
* send or respond to any PD communication.
*
+ * @param port USB-C port number
* @param enable Enable flag to set
*/
-void pd_comm_enable(int enable);
+void pd_comm_enable(int port, int enable);
/**
* Set the PD pings enabled flag. When source has negotiated power over
diff --git a/util/ectool.c b/util/ectool.c
index fbccae0f82..e47c56ff62 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -6786,7 +6786,16 @@ int cmd_pd_control(int argc, char *argv[])
return -1;
}
- p.chip = 0;
+ if (argc == 2) {
+ p.chip = 0;
+ } else {
+ char *e;
+ p.chip = strtol(argv[2], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad port number '%s'.\n", argv[2]);
+ return -1;
+ }
+ }
rv = ec_command(EC_CMD_PD_CONTROL, 0, &p, sizeof(p), NULL, 0);
return (rv < 0 ? rv : 0);