diff options
-rw-r--r-- | board/plankton/board.c | 6 | ||||
-rw-r--r-- | board/plankton/board.h | 2 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 126 | ||||
-rw-r--r-- | include/config.h | 4 | ||||
-rw-r--r-- | include/usb_pd.h | 3 | ||||
-rw-r--r-- | util/ectool.c | 11 |
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); |