diff options
-rw-r--r-- | common/usb_pd_protocol.c | 42 | ||||
-rw-r--r-- | include/config.h | 1 | ||||
-rw-r--r-- | include/ec_commands.h | 15 | ||||
-rw-r--r-- | util/ectool.c | 33 |
4 files changed, 91 insertions, 0 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 094f104ba7..84186ed754 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -3369,4 +3369,46 @@ static void pd_comm_init(void) } DECLARE_HOOK(HOOK_INIT, pd_comm_init, HOOK_PRIO_LAST); #endif /* CONFIG_USB_PD_COMM_LOCKED */ + +#ifdef CONFIG_CMD_PD_CONTROL +static int pd_control_disabled; + +static int pd_control(struct host_cmd_handler_args *args) +{ + const struct ec_params_pd_control *cmd = args->params; + + if (cmd->chip != 0) + return EC_RES_INVALID_PARAM; + + /* Always allow disable command */ + if (cmd->subcmd == PD_CONTROL_DISABLE) { + pd_control_disabled = 1; + return EC_RES_SUCCESS; + } + + if (pd_control_disabled) + return EC_RES_ACCESS_DENIED; + + if (cmd->subcmd == PD_SUSPEND) { + pd_comm_enable(0); + pd_set_suspend(0, 1); + } else if (cmd->subcmd == PD_RESUME) { + pd_comm_enable(1); + pd_set_suspend(0, 0); + } else if (cmd->subcmd == PD_RESET) { +#ifdef HAS_TASK_PDCMD + board_reset_pd_mcu(); +#else + return EC_RES_INVALID_COMMAND; +#endif + } else { + return EC_RES_INVALID_COMMAND; + } + + return EC_RES_SUCCESS; +} + +DECLARE_HOST_COMMAND(EC_CMD_PD_CONTROL, pd_control, EC_VER_MASK(0)); +#endif /* CONFIG_CMD_PD_CONTROL */ + #endif /* CONFIG_COMMON_RUNTIME */ diff --git a/include/config.h b/include/config.h index c7862fdae5..d149d2eb2e 100644 --- a/include/config.h +++ b/include/config.h @@ -556,6 +556,7 @@ #undef CONFIG_CMD_MCDP #define CONFIG_CMD_MD #define CONFIG_CMD_PD +#undef CONFIG_CMD_PD_CONTROL #undef CONFIG_CMD_PD_DEV_DUMP_INFO #undef CONFIG_CMD_PD_FLASH #undef CONFIG_CMD_PLL diff --git a/include/ec_commands.h b/include/ec_commands.h index d58c560d62..f14e6a0fa8 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -3647,6 +3647,21 @@ struct ec_params_pd_write_log_entry { #endif /* !__ACPI__ */ +/* Control USB-PD chip */ +#define EC_CMD_PD_CONTROL 0x119 + +enum ec_pd_control_cmd { + PD_SUSPEND = 0, /* Suspend the PD chip (EC: stop talking to PD) */ + PD_RESUME, /* Resume the PD chip (EC: start talking to PD) */ + PD_RESET, /* Force reset the PD chip */ + PD_CONTROL_DISABLE /* Disable further calls to this command */ +}; + +struct ec_params_pd_control { + uint8_t chip; /* chip id (should be 0) */ + uint8_t subcmd; +} __packed; + /*****************************************************************************/ /* * Blob commands are just opaque chunks of data, sent with proto v3. diff --git a/util/ectool.c b/util/ectool.c index ab4fdcccd1..8de07f9eee 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -147,6 +147,8 @@ const char help_str[] = " Prints saved panic info\n" " pause_in_s5 [on|off]\n" " Whether or not the AP should pause in S5 on shutdown\n" + " pdcontrol [suspend|resume|reset|disable]\n" + " Controls the PD chip\n" " pdlog\n" " Prints the PD event log entries\n" " pdwritelog <type> <port>\n" @@ -6688,6 +6690,36 @@ int cmd_pd_log(int argc, char *argv[]) return 0; } +int cmd_pd_control(int argc, char *argv[]) +{ + struct ec_params_pd_control p; + int rv; + + if (argc < 2) { + fprintf(stderr, "Missing parameter\n"); + return -1; + } + + /* Parse command */ + if (!strcmp(argv[1], "reset")) + p.subcmd = PD_RESET; + else if (!strcmp(argv[1], "suspend")) + p.subcmd = PD_SUSPEND; + else if (!strcmp(argv[1], "resume")) + p.subcmd = PD_RESUME; + else if (!strcmp(argv[1], "disable")) + p.subcmd = PD_CONTROL_DISABLE; + else { + fprintf(stderr, "Unknown command: %s\n", argv[1]); + return -1; + } + + p.chip = 0; + + rv = ec_command(EC_CMD_PD_CONTROL, 0, &p, sizeof(p), NULL, 0); + return (rv < 0 ? rv : 0); +} + int cmd_pd_write_log(int argc, char *argv[]) { struct ec_params_pd_write_log_entry p; @@ -6778,6 +6810,7 @@ const struct command commands[] = { {"pdsetmode", cmd_pd_set_amode}, {"port80read", cmd_port80_read}, {"pdlog", cmd_pd_log}, + {"pdcontrol", cmd_pd_control}, {"pdwritelog", cmd_pd_write_log}, {"powerinfo", cmd_power_info}, {"protoinfo", cmd_proto_info}, |