130 lines
3.3 KiB
C
130 lines
3.3 KiB
C
/* Copyright 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 enum ec_status 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));
|