diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2016-05-19 08:49:34 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-06-07 08:21:34 -0700 |
commit | d766e4cf4ea81d9b1269c8007e9be39758426447 (patch) | |
tree | eb088dc5c3fa3c945553bd7ddb0fb00b329fedf4 /common | |
parent | 091eea69da7a743035cb6c30d0883f6057007066 (diff) | |
download | chrome-ec-d766e4cf4ea81d9b1269c8007e9be39758426447.tar.gz |
ec_commands: Add new EC_CMD_PD_CONTROL command
This commands makes it possible to control the PD chip (or
the interaction between EC and PD), from the AP.
- PD_SUSPEND: Suspends the PD chip: EC needs to stop talking
to PD chip. Useful at beginning of PD FW update.
- PD_RESUME: Resumes the PD chip: EC can start talking to PD
chip again. Useful at end of PD FW update.
- PD_RESET: Resets the PD chip (called at the end of the update).
- PD_CONTROL_DISABLE: Prevents further calls to this command
(for security reason, we do not want the AP to be able to
call the other subcommands after the update has been performed).
BRANCH=none
BUG=chrome-os-partner:52433
TEST=ectool pdcontrol {suspend,resume,reset,disable}
Change-Id: I7a955dd27b65086c21d195a6504aa7392eb0406d
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/342584
Reviewed-by: Randall Spangler <rspangler@google.com>
Diffstat (limited to 'common')
-rw-r--r-- | common/usb_pd_protocol.c | 42 |
1 files changed, 42 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 */ |