summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 994fb98c76..590c6ef7f3 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 b7b825dcb9..90db784d2c 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);
@@ -1484,28 +1488,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
@@ -1597,6 +1598,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)
@@ -1612,15 +1615,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;
}
@@ -1917,7 +1921,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
@@ -1994,7 +1998,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 */
@@ -2418,7 +2422,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 */
@@ -2504,7 +2508,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 */
@@ -2522,7 +2526,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
@@ -3315,19 +3319,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;
@@ -3390,6 +3381,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));
@@ -3462,7 +3461,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" : "",
@@ -3475,9 +3474,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");
@@ -3550,14 +3549,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) ?
@@ -3800,13 +3800,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 */
@@ -3819,11 +3820,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();
@@ -3834,6 +3833,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 19a6653161..b998fde1ed 100644
--- a/include/config.h
+++ b/include/config.h
@@ -2158,8 +2158,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 23909e6ac7..01b4ed5358 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1555,9 +1555,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 5180a1a85b..10a178c942 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -6870,7 +6870,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);