diff options
-rw-r--r-- | common/mkbp_event.c | 121 | ||||
-rw-r--r-- | include/ec_commands.h | 51 | ||||
-rw-r--r-- | util/ectool.c | 72 |
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}, |