summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/mkbp_event.c121
-rw-r--r--include/ec_commands.h51
-rw-r--r--util/ectool.c72
3 files changed, 242 insertions, 2 deletions
diff --git a/common/mkbp_event.c b/common/mkbp_event.c
index 8e05a17f17..90c1e90b76 100644
--- a/common/mkbp_event.c
+++ b/common/mkbp_event.c
@@ -68,6 +68,14 @@ struct mkbp_state {
static struct mkbp_state state;
uint32_t mkbp_last_event_time;
+#ifdef CONFIG_MKBP_EVENT_WAKEUP_MASK
+static uint32_t mkbp_event_wake_mask = CONFIG_MKBP_EVENT_WAKEUP_MASK;
+#endif /* CONFIG_MKBP_EVENT_WAKEUP_MASK */
+
+#ifdef CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK
+static uint32_t mkbp_host_event_wake_mask = CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK;
+#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
+
#if defined(CONFIG_MKBP_USE_GPIO) || \
defined(CONFIG_MKBP_USE_GPIO_AND_HOST_EVENT)
static int mkbp_set_host_active_via_gpio(int active, uint32_t *timestamp)
@@ -188,14 +196,14 @@ static void activate_mkbp_with_events(uint32_t events_to_add)
/* Check to see if this host event should wake the system. */
skip_interrupt = host_is_sleeping() &&
!(host_get_events() &
- CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK);
+ mkbp_host_event_wake_mask);
#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
#ifdef CONFIG_MKBP_EVENT_WAKEUP_MASK
/* Check to see if this MKBP event should wake the system. */
if (!skip_interrupt)
skip_interrupt = host_is_sleeping() &&
- !(events_to_add & CONFIG_MKBP_EVENT_WAKEUP_MASK);
+ !(events_to_add & mkbp_event_wake_mask);
#endif /* CONFIG_MKBP_EVENT_WAKEUP_MASK */
mutex_lock(&state.lock);
@@ -385,3 +393,112 @@ DECLARE_HOST_COMMAND(EC_CMD_HOST_EVENT_GET_WAKE_MASK,
EC_VER_MASK(0));
#endif /* CONFIG_MKBP_USE_HOST_EVENT */
#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
+
+static int hc_mkbp_wake_mask(struct host_cmd_handler_args *args)
+{
+ struct ec_response_mkbp_event_wake_mask *r = args->response;
+ const struct ec_params_mkbp_event_wake_mask *p = args->params;
+ enum ec_mkbp_event_mask_action action = p->action;
+
+ switch (action) {
+ case GET_WAKE_MASK:
+ switch (p->mask_type) {
+#ifdef CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK
+ case EC_MKBP_HOST_EVENT_WAKE_MASK:
+ r->wake_mask = mkbp_host_event_wake_mask;
+ break;
+#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
+
+#ifdef CONFIG_MKBP_EVENT_WAKEUP_MASK
+ case EC_MKBP_EVENT_WAKE_MASK:
+ r->wake_mask = mkbp_event_wake_mask;
+ break;
+#endif /* CONFIG_MKBP_EVENT_WAKEUP_MASK */
+
+ default:
+ /* Unknown mask, or mask is not in use. */
+ CPRINTF("%s: mask_type=%d is unknown or not used.\n",
+ __func__, p->mask_type);
+ return EC_RES_INVALID_PARAM;
+ }
+
+ args->response_size = sizeof(*r);
+ break;
+
+ case SET_WAKE_MASK:
+ args->response_size = 0;
+
+ switch (p->mask_type) {
+#ifdef CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK
+ case EC_MKBP_HOST_EVENT_WAKE_MASK:
+ CPRINTF("MKBP hostevent mask updated to: 0x%08x "
+ "(was 0x%08x)\n",
+ p->new_wake_mask,
+ mkbp_host_event_wake_mask);
+ mkbp_host_event_wake_mask = p->new_wake_mask;
+ break;
+#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
+
+#ifdef CONFIG_MKBP_EVENT_WAKEUP_MASK
+ case EC_MKBP_EVENT_WAKE_MASK:
+ mkbp_event_wake_mask = p->new_wake_mask;
+ CPRINTF("MKBP event mask updated to: 0x%08x\n",
+ mkbp_event_wake_mask);
+ break;
+#endif /* CONFIG_MKBP_EVENT_WAKEUP_MASK */
+
+ default:
+ /* Unknown mask, or mask is not in use. */
+ CPRINTF("%s: mask_type=%d is unknown or not used.\n",
+ __func__, p->mask_type);
+ return EC_RES_INVALID_PARAM;
+ }
+ break;
+
+ default:
+ return EC_RES_INVALID_PARAM;
+ }
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_MKBP_WAKE_MASK,
+ hc_mkbp_wake_mask,
+ EC_VER_MASK(0));
+
+#if defined(CONFIG_MKBP_EVENT_WAKEUP_MASK) || \
+ defined(CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK)
+static int command_mkbp_wake_mask(int argc, char **argv)
+{
+ if (argc == 3) {
+ char *e;
+ uint32_t new_mask = strtoul(argv[2], &e, 0);
+
+ if (*e)
+ return EC_ERROR_PARAM2;
+
+#ifdef CONFIG_MKBP_EVENT_WAKEUP_MASK
+ if (strncmp(argv[1], "event", 5) == 0)
+ mkbp_event_wake_mask = new_mask;
+#endif /* CONFIG_MKBP_EVENT_WAKEUP_MASK */
+
+#ifdef CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK
+ if (strncmp(argv[1], "hostevent", 9) == 0)
+ mkbp_host_event_wake_mask = new_mask;
+#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
+ } else if (argc != 1) {
+ return EC_ERROR_PARAM_COUNT;
+ }
+
+#ifdef CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK
+ ccprintf("MKBP host event wake mask: 0x%08x\n",
+ mkbp_host_event_wake_mask);
+#endif /* CONFIG_MKBP_HOST_EVENT_WAKEUP_MASK */
+#ifdef CONFIG_MKBP_EVENT_WAKEUP_MASK
+ ccprintf("MKBP event wake mask: 0x%08x\n", mkbp_event_wake_mask);
+#endif /* CONFIG_MKBP_EVENT_WAKEUP_MASK */
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(mkbpwakemask, command_mkbp_wake_mask,
+ "[event | hostevent] [new_mask]",
+ "Show or set MKBP event/hostevent wake mask");
+#endif /* CONFIG_MKBP_(HOST)?EVENT_WAKEUP_MASK */
diff --git a/include/ec_commands.h b/include/ec_commands.h
index cdf7c67c5d..b3f5878030 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -3603,6 +3603,57 @@ struct ec_response_keyboard_factory_test {
#define EC_MKBP_FP_ERR_MATCH_YES_UPDATE_FAILED 5
+#define EC_CMD_MKBP_WAKE_MASK 0x0069
+enum ec_mkbp_event_mask_action {
+ /* Retrieve the value of a wake mask. */
+ GET_WAKE_MASK = 0,
+
+ /* Set the value of a wake mask. */
+ SET_WAKE_MASK,
+};
+
+enum ec_mkbp_mask_type {
+ /*
+ * These are host events sent via MKBP.
+ *
+ * Some examples are:
+ * EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)
+ * EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEY_PRESSED)
+ *
+ * The only things that should be in this mask are:
+ * EC_HOST_EVENT_MASK(EC_HOST_EVENT_*)
+ */
+ EC_MKBP_HOST_EVENT_WAKE_MASK = 0,
+
+ /*
+ * These are MKBP events. Some examples are:
+ *
+ * EC_MKBP_EVENT_KEY_MATRIX
+ * EC_MKBP_EVENT_SWITCH
+ *
+ * The only things that should be in this mask are EC_MKBP_EVENT_*.
+ */
+ EC_MKBP_EVENT_WAKE_MASK,
+};
+
+struct ec_params_mkbp_event_wake_mask {
+ /* One of enum ec_mkbp_event_mask_action */
+ uint8_t action;
+
+ /*
+ * Which MKBP mask are you interested in acting upon? This is one of
+ * ec_mkbp_mask_type.
+ */
+ uint8_t mask_type;
+
+ /* If setting a new wake mask, this contains the mask to set. */
+ uint32_t new_wake_mask;
+};
+
+struct ec_response_mkbp_event_wake_mask {
+ uint32_t wake_mask;
+};
+
/*****************************************************************************/
/* Temperature sensor commands */
diff --git a/util/ectool.c b/util/ectool.c
index 46f98be760..f1e7758dc6 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -188,6 +188,8 @@ const char help_str[] =
" Set the color of an LED or query brightness range\n"
" lightbar [CMDS]\n"
" Various lightbar control commands\n"
+ " mkbpwakemask <get|set> <event|hostevent> [mask]\n"
+ " Get or Set the MKBP event wake mask, or host event wake mask\n"
" motionsense [CMDS]\n"
" Various motion sense control commands\n"
" panicinfo\n"
@@ -7718,6 +7720,75 @@ static int cmd_keyconfig(int argc, char *argv[])
return 0;
}
+static int cmd_mkbp_wake_mask(int argc, char *argv[])
+{
+ struct ec_params_mkbp_event_wake_mask p;
+ struct ec_response_mkbp_event_wake_mask r;
+ int rv;
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s get <event|hostevent>\n"
+ "\t%s set <event|hostevent> <mask>\n", argv[0],
+ argv[0]);
+ return -1;
+ }
+
+ /* Determine if the user want to get or set the wake mask. */
+ if (strncmp(argv[1], "get", 3) == 0) {
+ p.action = GET_WAKE_MASK;
+ } else if (strncmp(argv[1], "set", 3) == 0) {
+ p.action = SET_WAKE_MASK;
+ } else {
+ fprintf(stderr, "Invalid param: '%s'\n", argv[1]);
+ return -1;
+ }
+
+ /* Determine which mask is of interest. */
+ if (strncmp(argv[2], "event", 5) == 0) {
+ p.mask_type = EC_MKBP_EVENT_WAKE_MASK;
+ } else if (strncmp(argv[2], "hostevent", 9) == 0) {
+ p.mask_type = EC_MKBP_HOST_EVENT_WAKE_MASK;
+ } else {
+ fprintf(stderr, "Invalid param: '%s'\n", argv[2]);
+ return -1;
+ }
+
+ if (p.action == SET_WAKE_MASK) {
+ char *e;
+
+ if (argc < 4) {
+ fprintf(stderr, "Missing mask value!");
+ return -1;
+ }
+
+ p.new_wake_mask = strtol(argv[3], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad mask: '%s'", argv[1]);
+ return -1;
+ }
+ }
+
+ rv = ec_command(EC_CMD_MKBP_WAKE_MASK, 0, &p, sizeof(p), &r,
+ sizeof(r));
+ if (rv < 0) {
+ if (rv == -EECRESULT-EC_RES_INVALID_PARAM) {
+ fprintf(stderr, "Unknown mask, or mask is not in use. "
+ "You may need to enable the "
+ "CONFIG_MKBP_%s_WAKEUP_MASK option in the EC.\n"
+ , p.mask_type == EC_MKBP_EVENT_WAKE_MASK ?
+ "EVENT" : "HOSTEVENT");
+ }
+ return rv;
+ }
+
+ if (p.action == GET_WAKE_MASK)
+ printf("MBKP %s wake mask: 0x%08x\n", argv[2], r.wake_mask);
+ else if (p.action == SET_WAKE_MASK)
+ printf("MKBP %s wake mask set.\n", argv[2]);
+
+ return 0;
+}
+
/* Index is already checked. argv[0] is first param value */
static int cmd_tmp006cal_v0(int idx, int argc, char *argv[])
{
@@ -8736,6 +8807,7 @@ const struct command commands[] = {
{"kbpress", cmd_kbpress},
{"keyconfig", cmd_keyconfig},
{"keyscan", cmd_keyscan},
+ {"mkbpwakemask", cmd_mkbp_wake_mask},
{"motionsense", cmd_motionsense},
{"nextevent", cmd_next_event},
{"panicinfo", cmd_panic_info},