summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/build.mk1
-rw-r--r--common/device_event.c129
-rw-r--r--common/host_command.c3
-rw-r--r--include/config.h4
-rw-r--r--include/device_event.h44
-rw-r--r--include/ec_commands.h35
6 files changed, 215 insertions, 1 deletions
diff --git a/common/build.mk b/common/build.mk
index cc190e08d6..d264c6c2e5 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -45,6 +45,7 @@ common-$(CONFIG_COMMON_RUNTIME)+=hooks.o main.o system.o
common-$(CONFIG_COMMON_TIMER)+=timer.o
common-$(CONFIG_CRC8)+= crc8.o
common-$(CONFIG_CURVE25519)+=curve25519.o
+common-$(CONFIG_DEVICE_EVENT)+=device_event.o
common-$(CONFIG_DEVICE_STATE)+=device_state.o
common-$(CONFIG_DPTF)+=dptf.o
common-$(CONFIG_EXTENSION_COMMAND)+=extension.o
diff --git a/common/device_event.c b/common/device_event.c
new file mode 100644
index 0000000000..4b4e37724c
--- /dev/null
+++ b/common/device_event.c
@@ -0,0 +1,129 @@
+/* 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));
diff --git a/common/host_command.c b/common/host_command.c
index 06d687f51e..825515a66f 100644
--- a/common/host_command.c
+++ b/common/host_command.c
@@ -805,6 +805,9 @@ static int host_command_get_features(struct host_cmd_handler_args *args)
#ifdef HAS_TASK_RWSIG
| EC_FEATURE_MASK_0(EC_FEATURE_RWSIG)
#endif
+#ifdef CONFIG_DEVICE_EVENT
+ | EC_FEATURE_MASK_0(EC_FEATURE_DEVICE_EVENT)
+#endif
;
return EC_RES_SUCCESS;
}
diff --git a/include/config.h b/include/config.h
index 49f3c8c96f..5d41162d04 100644
--- a/include/config.h
+++ b/include/config.h
@@ -677,6 +677,7 @@
#undef CONFIG_CMD_CLOCKGATES
#undef CONFIG_CMD_COMXTEST
#define CONFIG_CMD_CRASH
+#define CONFIG_CMD_DEVICE_EVENT
#undef CONFIG_CMD_ECTEMP
#define CONFIG_CMD_FASTCHARGE
#undef CONFIG_CMD_FLASH
@@ -941,6 +942,9 @@
/*****************************************************************************/
+/* Support events from devices attached to the EC */
+#undef CONFIG_DEVICE_EVENT
+
/* Monitor the states of other devices */
#undef CONFIG_DEVICE_STATE
diff --git a/include/device_event.h b/include/device_event.h
new file mode 100644
index 0000000000..40d4114b16
--- /dev/null
+++ b/include/device_event.h
@@ -0,0 +1,44 @@
+/* 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 module for Chrome EC */
+
+#ifndef __CROS_EC_DEVICE_EVENT_H
+#define __CROS_EC_DEVICE_EVENT_H
+
+#include "common.h"
+#include "ec_commands.h"
+
+/**
+ * Return the raw device event state.
+ */
+uint32_t device_get_events(void);
+
+/**
+ * Set one or more device event bits.
+ *
+ * @param mask Event bits to set (use EC_DEVICE_EVENT_MASK()).
+ */
+void device_set_events(uint32_t mask);
+
+/**
+ * Clear one or more device event bits.
+ *
+ * @param mask Event bits to clear (use EC_DEVICE_EVENT_MASK()).
+ * Write 1 to a bit to clear it.
+ */
+void device_clear_events(uint32_t mask);
+
+/**
+ * Set a single device event.
+ *
+ * @param event Event to set (EC_DEVICE_EVENT_*).
+ */
+static inline void device_set_single_event(int event)
+{
+ device_set_events(EC_DEVICE_EVENT_MASK(event));
+}
+
+#endif /* __CROS_EC_DEVICE_EVENT_H */
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 61bfa345fe..3bc98ae31a 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -502,7 +502,8 @@ enum host_event_code {
EC_HOST_EVENT_BATTERY_CRITICAL = 7,
EC_HOST_EVENT_BATTERY = 8,
EC_HOST_EVENT_THERMAL_THRESHOLD = 9,
- EC_HOST_EVENT_THERMAL_OVERLOAD = 10,
+ /* Event generated by a device attached to the EC */
+ EC_HOST_EVENT_DEVICE = 10,
EC_HOST_EVENT_THERMAL = 11,
EC_HOST_EVENT_USB_CHARGER = 12,
EC_HOST_EVENT_KEY_PRESSED = 13,
@@ -1086,6 +1087,8 @@ enum ec_feature_code {
EC_FEATURE_TOUCHPAD = 29,
/* The MCU has RWSIG task enabled */
EC_FEATURE_RWSIG = 30,
+ /* EC has device events support */
+ EC_FEATURE_DEVICE_EVENT = 31,
};
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
@@ -3525,6 +3528,36 @@ struct __ec_align1 ec_params_host_sleep_event {
};
/*****************************************************************************/
+/* Device events */
+#define EC_CMD_DEVICE_EVENT 0x00AA
+
+enum ec_device_event {
+ EC_DEVICE_EVENT_TRACKPAD,
+ EC_DEVICE_EVENT_DSP,
+ EC_DEVICE_EVENT_WIFI,
+};
+
+enum ec_device_event_param {
+ /* Get and clear pending device events */
+ EC_DEVICE_EVENT_PARAM_GET_CURRENT_EVENTS,
+ /* Get device event mask */
+ EC_DEVICE_EVENT_PARAM_GET_ENABLED_EVENTS,
+ /* Set device event mask */
+ EC_DEVICE_EVENT_PARAM_SET_ENABLED_EVENTS,
+};
+
+#define EC_DEVICE_EVENT_MASK(event_code) (1UL << (event_code % 32))
+
+struct __ec_align_size1 ec_params_device_event {
+ uint32_t event_mask;
+ uint8_t param;
+};
+
+struct __ec_align4 ec_response_device_event {
+ uint32_t event_mask;
+};
+
+/*****************************************************************************/
/* Smart battery pass-through */
/* Get / Set 16-bit smart battery registers */