/* Copyright (c) 2017 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ /* Device event commands for Chrome EC */ #include "atomic.h" #include "common.h" #include "console.h" #include "host_command.h" #include "lpc.h" #include "mkbp_event.h" #include "util.h" /* Console output macros */ #define CPUTS(outstr) cputs(CC_EVENTS, outstr) #define CPRINTS(format, args...) cprints(CC_EVENTS, format, ## args) static uint32_t device_current_events; static uint32_t device_enabled_events; uint32_t device_get_current_events(void) { return device_current_events; } static uint32_t device_get_and_clear_events(void) { return atomic_read_clear(&device_current_events); } static uint32_t device_get_enabled_events(void) { return device_enabled_events; } void device_set_events(uint32_t mask) { /* Ignore events that are not enabled */ mask &= device_enabled_events; if ((device_current_events & mask) != mask) CPRINTS("device event set 0x%08x", mask); atomic_or(&device_current_events, mask); /* Signal host that a device event is pending */ host_set_single_event(EC_HOST_EVENT_DEVICE); } void device_clear_events(uint32_t mask) { /* Only print if something's about to change */ if (device_current_events & mask) CPRINTS("device event clear 0x%08x", mask); atomic_clear(&device_current_events, mask); } static void device_set_enabled_events(uint32_t mask) { if ((device_enabled_events & mask) != mask) CPRINTS("device enabled events set 0x%08x", mask); device_enabled_events = mask; } /*****************************************************************************/ /* Console commands */ #ifdef CONFIG_CMD_DEVICE_EVENT static int command_device_event(int argc, char **argv) { /* Handle sub-commands */ if (argc == 3) { char *e; int i = strtoi(argv[2], &e, 0); if (*e) return EC_ERROR_PARAM2; else if (!strcasecmp(argv[1], "set")) device_set_events(i); else if (!strcasecmp(argv[1], "clear")) device_clear_events(i); else if (!strcasecmp(argv[1], "enable")) device_set_enabled_events(i); else return EC_ERROR_PARAM1; } ccprintf("Enabled Events: 0x%08x\n", device_get_enabled_events()); ccprintf("Current Events: 0x%08x\n", device_get_current_events()); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(deviceevent, command_device_event, "[set | clear | enable] [mask]", "Print / set device event state"); #endif /*****************************************************************************/ /* Host commands */ static int device_event_cmd(struct host_cmd_handler_args *args) { const struct ec_params_device_event *p = args->params; struct ec_response_device_event *r = args->response; switch (p->param) { case EC_DEVICE_EVENT_PARAM_GET_CURRENT_EVENTS: r->event_mask = device_get_and_clear_events(); break; case EC_DEVICE_EVENT_PARAM_GET_ENABLED_EVENTS: r->event_mask = device_get_enabled_events(); break; case EC_DEVICE_EVENT_PARAM_SET_ENABLED_EVENTS: device_set_enabled_events(p->event_mask); r->event_mask = device_get_enabled_events(); break; default: return EC_RES_INVALID_PARAM; } args->response_size = sizeof(*r); return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_DEVICE_EVENT, device_event_cmd, EC_VER_MASK(0));