summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2016-05-19 08:49:34 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-06-07 08:21:34 -0700
commitd766e4cf4ea81d9b1269c8007e9be39758426447 (patch)
treeeb088dc5c3fa3c945553bd7ddb0fb00b329fedf4 /common
parent091eea69da7a743035cb6c30d0883f6057007066 (diff)
downloadchrome-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.c42
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 */