summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2011-10-27 16:31:08 +0800
committerLouis Yung-Chieh Lo <yjlou@chromium.org>2011-10-28 01:15:18 +0800
commit79a661d00c31937bff2018afef1ebb41c8b5ec14 (patch)
treeab2b44384f2ed40bbac6f57e5993af6783bd8200
parentaa8ecb2b65bd501567d00cc320e33eead4a91b6b (diff)
downloadchrome-ec-79a661d00c31937bff2018afef1ebb41c8b5ec14.tar.gz
Link keyboard-related code together.
Added i8042 interface and matrix code. Demonstrate a key is pressed and passed to host through the board-dependent matrix code. BUG=None TEST=make && make runtests Change-Id: I6a9f5e621d9e93e5c16384afebf4d665000e81a6
-rw-r--r--.gitignore2
-rw-r--r--Makefile6
-rw-r--r--board/Makefile30
-rw-r--r--board/board.c56
-rw-r--r--board/board_interface.h20
-rw-r--r--chip_interface/keyboard.h10
-rw-r--r--cros_ec/Makefile3
-rw-r--r--cros_ec/chip_stub/host.c83
-rw-r--r--cros_ec/chip_stub/include/host.h26
-rw-r--r--cros_ec/chip_stub/include/keyboard.h (renamed from cros_ec/chip_stub/keyboard.h)2
-rw-r--r--cros_ec/chip_stub/keyboard.c10
-rw-r--r--cros_ec/include/ec_common.h11
-rw-r--r--cros_ec/include/ec_keyboard.h28
-rw-r--r--cros_ec/lib/ec_keyboard.c38
-rw-r--r--cros_ec/main.c20
-rw-r--r--cros_ec/test/Makefile2
-rw-r--r--cros_ec/test/ec_keyboard_test.c54
-rw-r--r--host_interface/ec_command.h55
-rw-r--r--host_interface/i8042.h48
19 files changed, 455 insertions, 49 deletions
diff --git a/.gitignore b/.gitignore
index 598dd8d7cb..0aa56f6908 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-board/
+board/*/
build/
vendor/
diff --git a/Makefile b/Makefile
index 58696c285f..313a0a0f53 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,7 @@ endif
export TOP = $(shell pwd)
export CROS_EC_DIR=$(TOP)/cros_ec
export CHIP_STUB_DIR=$(CROS_EC_DIR)/chip_stub
+export BOARD_DIR=$(TOP)/board
INCLUDES = -I$(TOP)/chip_interface -I$(CROS_EC_DIR)/include
@@ -42,11 +43,12 @@ export INCLUDES
export BUILD = ${TOP}/build
export CROS_EC_LIB = ${BUILD}/cros_ec.a
export CHIP_STUB_LIB = ${BUILD}/chip_stub.a
+export BOARD_LIB = ${BUILD}/board.a
ifeq ($(FIRMWARE_ARCH),)
-SUBDIRS = cros_ec cros_ec/test utility
+SUBDIRS = board cros_ec cros_ec/test utility
else
-SUBDIRS = cros_ec
+SUBDIRS = board cros_ec
endif
all:
diff --git a/board/Makefile b/board/Makefile
new file mode 100644
index 0000000000..ebce089249
--- /dev/null
+++ b/board/Makefile
@@ -0,0 +1,30 @@
+# Copyright (c) 2011 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.
+
+CROS_EC_TOP := $(shell pwd)
+BUILD_ROOT := ${BUILD}/$(shell basename ${CROS_EC_TOP})
+
+INCLUDES += \
+ -I$(TOP)
+
+ifeq ($(FIRMWARE_ARCH),)
+INCLUDES += -I$(STUBDIR)/include
+else
+INCLUDES += -I$(FWDIR)/arch/$(FIRMWARE_ARCH)/include
+endif
+
+BOARD_SRCS = \
+ board.c
+
+BOARD_OBJS = $(BOARD_SRCS:%.c=${BUILD_ROOT}/%.o)
+
+ALL_SRCS = ${BOARD_SRCS}
+
+all : $(BOARD_LIB)
+
+include ../common.mk
+
+$(BOARD_LIB) : $(BOARD_OBJS)
+ rm -f $@
+ ar qc $@ $^
diff --git a/board/board.c b/board/board.c
new file mode 100644
index 0000000000..16b10b3a42
--- /dev/null
+++ b/board/board.c
@@ -0,0 +1,56 @@
+/* Copyright (c) 2011 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.
+ *
+ * main.c -- the main function of board-specific code.
+ */
+
+#include "cros_ec/include/ec_common.h"
+#include "board/board_interface.h"
+#include "cros_ec/include/ec_keyboard.h"
+
+#define CROS_ROW_NUM 8 /* TODO: +1 for power button. */
+#define CROS_COL_NUM 13
+
+/* The standard Chrome OS keyboard matrix table. */
+static uint8_t maxtri_table[CROS_ROW_NUM][CROS_COL_NUM] = {
+ /* FIXME: waiting for approval to open-source this table. */
+};
+
+static EcError MatrixCallback(
+ int8_t row, int8_t col, int8_t pressed,
+ uint8_t *scan_code, int32_t* len) {
+
+ uint8_t make_code;
+
+ EC_ASSERT(scan_code);
+ EC_ASSERT(len);
+
+ if (row > CROS_ROW_NUM ||
+ col > CROS_COL_NUM) {
+ return EC_ERROR_INVALID_PARAMETER;
+ }
+
+ make_code = maxtri_table[row][col];
+ make_code = row * 13 + col; /* FIXME: remove this after we can open-source
+ * the matrix table. */
+
+ if (pressed) {
+ *scan_code = make_code;
+ *len = 1;
+ } else {
+ *scan_code = make_code | 0x80;
+ *len = 1;
+ }
+
+ return EC_SUCCESS;
+}
+
+
+EcError BoardInit() {
+ EC_ASSERT(EC_SUCCESS ==
+ EcKeyboardMatrixRegisterCallback(
+ CROS_ROW_NUM, CROS_COL_NUM, MatrixCallback));
+
+ return EC_SUCCESS;
+}
diff --git a/board/board_interface.h b/board/board_interface.h
new file mode 100644
index 0000000000..6d63b8cec2
--- /dev/null
+++ b/board/board_interface.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2011 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.
+ *
+ * board.h -- defines the board interface. The implementation will be under
+ * board/your_board_name/main.c.
+ */
+
+#ifndef __BOARD_BOARD_INTERFACE_H
+#define __BOARD_BOARD_INTERFACE_H
+
+#include "cros_ec/include/ec_common.h"
+
+/* The initialize function of a board. Called by the EC core at start.
+ * The main mission is to register its callback function to the EC core.
+ */
+EcError BoardInit();
+
+
+#endif /* __BOARD_BOARD_INTERFACE_H */
diff --git a/chip_interface/keyboard.h b/chip_interface/keyboard.h
index 78828678f3..591cae0e17 100644
--- a/chip_interface/keyboard.h
+++ b/chip_interface/keyboard.h
@@ -2,7 +2,9 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
- * keyboard.h - Keyboard interface between EC core and EC Lib.
+ * keyboard.h - Keyboard interface between EC core and EC Lib. Both would
+ * include this file. And, it is EC lib to provides the real implementation
+ * (wrapping the low-level driver).
*/
#ifndef __CHIP_INTERFACE_KEYBOARD_H
@@ -10,10 +12,10 @@
#include "cros_ec/include/ec_common.h"
-#define MAX_KEYBOARD_MATRIX_COLS 16
#define MAX_KEYBOARD_MATRIX_ROWS 8
+#define MAX_KEYBOARD_MATRIX_COLS 16
-typedef void (*EcKeyboardCallback)(int col, int row, int is_pressed);
+typedef void (*EcKeyboardCallback)(int row, int col, int is_pressed);
/* Registers a callback function to underlayer EC lib. So that any key state
* change would notify the upper EC main code.
@@ -25,7 +27,7 @@ EcError EcKeyboardRegisterCallback(EcKeyboardCallback cb);
/* Asks the underlayer EC lib what keys are pressed right now.
*
* Sets bit_array to a debounced array of which keys are currently pressed,
- * where a 1-bit means the key is pressed. For example, if only col=2 row=3
+ * where a 1-bit means the key is pressed. For example, if only row=2 col=3
* is pressed, it would set bit_array to {0, 0, 0x08, 0, ...}
*
* bit_array must be at least MAX_KEYBOARD_MATRIX_COLS bytes long.
diff --git a/cros_ec/Makefile b/cros_ec/Makefile
index ac2ac5b264..39e06d26b4 100644
--- a/cros_ec/Makefile
+++ b/cros_ec/Makefile
@@ -35,7 +35,8 @@ LIB_OBJS = $(LIB_SRCS:%.c=${BUILD_ROOT}/%.o)
STUB_SRCS = \
./chip_stub/ec_os.c \
./chip_stub/ec_uart.c \
- ./chip_stub/keyboard.c
+ ./chip_stub/keyboard.c \
+ ./chip_stub/host.c
STUB_OBJS = $(STUB_SRCS:%.c=${BUILD_ROOT}/%.o)
diff --git a/cros_ec/chip_stub/host.c b/cros_ec/chip_stub/host.c
new file mode 100644
index 0000000000..bc6ae3d326
--- /dev/null
+++ b/cros_ec/chip_stub/host.c
@@ -0,0 +1,83 @@
+/* Copyright (c) 2011 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.
+ *
+ * host.c -- implements the LPC driver of EC lib and provides simulation
+ * functions.
+ */
+
+#include <string.h> /* FIXME: remove after we have our-own mem*(). */
+#include "cros_ec/include/ec_common.h"
+#include "cros_ec/chip_stub/include/keyboard.h"
+#include "host_interface/ec_command.h"
+#include "host_interface/i8042.h"
+
+
+static EcAcpiCallback acpi_callback;
+static EcI8042Callback i8042_callback;
+#define SCAN_CODE_QUEUE_LEN 16
+static int scan_code_queue_len = 0;
+static uint8_t scan_code_queue[SCAN_CODE_QUEUE_LEN];
+
+
+EcError EcAcpiRegisterCallback(EcAcpiCallback callback) {
+ acpi_callback = callback;
+
+ return EC_SUCCESS;
+}
+
+
+EcError EcI8042RegisterCallback(EcI8042Callback callback) {
+ i8042_callback = callback;
+
+ return EC_SUCCESS;
+}
+
+
+EcError EcI8042SendScanCode(int len, uint8_t *scan_code) {
+ if ((scan_code_queue_len + len) > SCAN_CODE_QUEUE_LEN) {
+ return EC_ERROR_BUFFER_FULL;
+ }
+
+ memcpy(&scan_code_queue[scan_code_queue_len], scan_code, len);
+ scan_code_queue_len += len;
+
+ return EC_SUCCESS;
+}
+
+
+
+/************* Simulation functions ***************/
+int SimulateAcpiCommand(
+ uint8_t command,
+ uint8_t data,
+ uint8_t *mailbox,
+ uint8_t *output) {
+
+ EC_ASSERT(acpi_callback);
+
+ return acpi_callback(command, data, mailbox, output);
+}
+
+int SimulateI8042Command(
+ uint8_t command,
+ uint8_t data,
+ uint8_t *output) {
+
+ EC_ASSERT(i8042_callback);
+
+ return i8042_callback(command, data, output);
+}
+
+EcError PullI8042ScanCode(uint8_t *buf) {
+ EC_ASSERT(buf);
+
+ if (scan_code_queue_len <= 0) {
+ return EC_ERROR_BUFFER_EMPTY;
+ }
+
+ *buf = scan_code_queue[0];
+ memmove(&scan_code_queue[0], &scan_code_queue[1], --scan_code_queue_len);
+
+ return EC_SUCCESS;
+}
diff --git a/cros_ec/chip_stub/include/host.h b/cros_ec/chip_stub/include/host.h
new file mode 100644
index 0000000000..a07210e2f6
--- /dev/null
+++ b/cros_ec/chip_stub/include/host.h
@@ -0,0 +1,26 @@
+/* Copyright (c) 2011 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.
+ *
+ * host.h -- defines the API provided by chip_stub/host.c.
+ */
+
+#ifndef __CROS_EC_CHIP_STUB_INCLUDE_HOST_H
+#define __CROS_EC_CHIP_STUB_INCLUDE_HOST_H
+
+#include "cros_ec/include/ec_common.h"
+
+int SimulateAcpiCommand(
+ uint8_t command,
+ uint8_t data,
+ uint8_t *mailbox,
+ uint8_t *output);
+
+int SimulateI8042Command(
+ uint8_t command,
+ uint8_t data,
+ uint8_t *output);
+
+EcError PullI8042ScanCode(uint8_t *buf);
+
+#endif /* __CROS_EC_CHIP_STUB_INCLUDE_HOST_H */
diff --git a/cros_ec/chip_stub/keyboard.h b/cros_ec/chip_stub/include/keyboard.h
index a3357eec4f..274e90b414 100644
--- a/cros_ec/chip_stub/keyboard.h
+++ b/cros_ec/chip_stub/include/keyboard.h
@@ -9,6 +9,6 @@
#ifndef __EC_CHIP_STUB_KEYBOARD_H_
#define __EC_CHIP_STUB_KEYBOARD_H_
-EcError SimulateKeyStateChange(int col, int row, int state);
+EcError SimulateKeyStateChange(int row, int col, int state);
#endif /* __EC_CHIP_STUB_KEYBOARD_H_ */
diff --git a/cros_ec/chip_stub/keyboard.c b/cros_ec/chip_stub/keyboard.c
index 547df3614f..6f59d11bd5 100644
--- a/cros_ec/chip_stub/keyboard.c
+++ b/cros_ec/chip_stub/keyboard.c
@@ -26,9 +26,9 @@ EcError EcKeyboardGetState(uint8_t *bit_array) {
/* Called by test code. This simulates a key press or release.
* Usually, the test code would expect a scan code is received at host side.
*/
-EcError SimulateKeyStateChange(int col, int row, int state) {
- ASSERT(col < MAX_KEYBOARD_MATRIX_COLS);
- ASSERT(row < MAX_KEYBOARD_MATRIX_ROWS);
+EcError SimulateKeyStateChange(int row, int col, int state) {
+ EC_ASSERT(row < MAX_KEYBOARD_MATRIX_ROWS);
+ EC_ASSERT(col < MAX_KEYBOARD_MATRIX_COLS);
if (!core_keyboard_callback) return EC_ERROR_UNKNOWN;
@@ -38,10 +38,10 @@ EcError SimulateKeyStateChange(int col, int row, int state) {
if (state && !current_state) {
/* key is just pressed down */
virtual_matrix[col] |= 1 << row;
- core_keyboard_callback(col, row, state);
+ core_keyboard_callback(row, col, state);
} else if (!state && current_state) {
virtual_matrix[col] &= ~(1 << row);
- core_keyboard_callback(col, row, state);
+ core_keyboard_callback(row, col, state);
} else {
/* Nothing happens if a key has been pressed or released. */
}
diff --git a/cros_ec/include/ec_common.h b/cros_ec/include/ec_common.h
index 1a40958509..79afe43793 100644
--- a/cros_ec/include/ec_common.h
+++ b/cros_ec/include/ec_common.h
@@ -28,6 +28,12 @@ enum EcErrorList {
EC_ERROR_OVERFLOW = 3,
/* Timeout */
EC_ERROR_TIMEOUT = 4,
+ /* Invalid parameter */
+ EC_ERROR_INVALID_PARAMETER,
+ /* Buffer is full, for output. */
+ EC_ERROR_BUFFER_FULL,
+ /* Buffer is empty, for input. */
+ EC_ERROR_BUFFER_EMPTY,
/* Module-internal error codes may use this range. */
EC_ERROR_INTERNAL_FIRST = 0x10000,
@@ -39,10 +45,11 @@ enum EcErrorList {
#define PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
/* TODO: move to a proper .h file */
-#define ASSERT(expr) do { \
+#define EC_ASSERT(expr) do { \
if (!(expr)) { \
- PRINTF("ASSERT(%s) failed at file %s:%d.\n", \
+ PRINTF("\n*** EC_ASSERT(%s) failed at file %s:%d.\n", \
#expr, __FILE__, __LINE__); \
+ while (1); \
} \
} while (0)
diff --git a/cros_ec/include/ec_keyboard.h b/cros_ec/include/ec_keyboard.h
index 4f00209953..2c8290fa0b 100644
--- a/cros_ec/include/ec_keyboard.h
+++ b/cros_ec/include/ec_keyboard.h
@@ -1,13 +1,14 @@
/* Copyright (c) 2011 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.
+ *
+ * The functions implemented by keyboard component of EC core.
*/
-/* Keyboard emulation */
-
-#ifndef __CROS_EC_KEYBOARD_H
-#define __CROS_EC_KEYBOARD_H
+#ifndef __CROS_INCLUDE_EC_KEYBOARD_H
+#define __CROS_INCLUDE_EC_KEYBOARD_H
+#include "cros_ec/include/ec_common.h"
/* The initialize code of keyboard lib. Called by core main. */
EcError EcKeyboardInit();
@@ -15,12 +16,19 @@ EcError EcKeyboardInit();
/* Register the board-specific keyboard matrix translation function.
* The callback function accepts col/row and returns the scan code.
+ *
+ * Note that *scan_code must be at least 4 bytes long to store maximum
+ * possible sequence.
*/
-EcError EcKeyboardMatrixRegister(
- int8_t col_num, int8_t row_num,
- EcError (*callback)(
- int8_t column, int8_t row, int8_t pressed,
- uint8_t *scan_code, int32_t* len));
+typedef EcError (*EcKeyboardMatrixCallback)(
+ int8_t row, int8_t col, int8_t pressed,
+ uint8_t *scan_code, int32_t* len);
+
+EcError EcKeyboardMatrixRegisterCallback(
+ int8_t row_num, int8_t col_num,
+ EcKeyboardMatrixCallback callback);
+
+#define MAX_SCAN_CODE_LEN 4
-#endif /* __CROS_EC_KEYBOARD_H */
+#endif /* __CROS_INCLUDE_EC_KEYBOARD_H */
diff --git a/cros_ec/lib/ec_keyboard.c b/cros_ec/lib/ec_keyboard.c
index f126f9eed8..4e4b9d91e4 100644
--- a/cros_ec/lib/ec_keyboard.c
+++ b/cros_ec/lib/ec_keyboard.c
@@ -6,11 +6,43 @@
*/
#include "cros_ec/include/ec_common.h"
+#include "cros_ec/include/ec_keyboard.h"
#include "chip_interface/keyboard.h"
+#include "host_interface/i8042.h"
-static void KeyboardStateChanged(int col, int row, int is_pressed) {
- PRINTF("File %s:%s(): col=%d row=%d is_pressed=%d\n",
- __FILE__, __FUNCTION__, col, row, is_pressed);
+
+static EcKeyboardMatrixCallback matrix_callback;
+
+static void KeyboardStateChanged(int row, int col, int is_pressed) {
+ uint8_t scan_code[MAX_SCAN_CODE_LEN];
+ int len;
+ EcError ret;
+
+ PRINTF("File %s:%s(): row=%d col=%d is_pressed=%d\n",
+ __FILE__, __FUNCTION__, row, col, is_pressed);
+
+ EC_ASSERT(matrix_callback);
+
+ ret = matrix_callback(row, col, is_pressed, scan_code, &len);
+ if (ret == EC_SUCCESS) {
+ EC_ASSERT(len > 0);
+
+ EcI8042SendScanCode(len, scan_code);
+ } else {
+ /* FIXME: long-term solution is to ignore this key. However, keep
+ * assertion in the debug stage. */
+ EC_ASSERT(ret == EC_SUCCESS);
+ }
+}
+
+
+EcError EcKeyboardMatrixRegisterCallback(
+ int8_t row_num, int8_t col_num,
+ EcKeyboardMatrixCallback callback) {
+
+ matrix_callback = callback;
+
+ return EC_SUCCESS;
}
diff --git a/cros_ec/main.c b/cros_ec/main.c
index 1a4dd78787..ff14b22b5e 100644
--- a/cros_ec/main.c
+++ b/cros_ec/main.c
@@ -9,16 +9,24 @@
#include "cros_ec/include/core.h"
#include "cros_ec/include/ec_common.h"
#include "cros_ec/include/ec_keyboard.h"
+#include "board/board_interface.h"
+
+
+#define ReturnIfInitFailed(func) \
+ do { \
+ EcError ret; \
+ ret = func(); \
+ if (ret != EC_SUCCESS) { \
+ printf("%s() failed at %s:%d: %d\n", #func, __FILE__, __LINE__, ret); \
+ return ret; \
+ } \
+ } while (0)
EcError CoreMain() {
- EcError ret;
- ret = EcKeyboardInit();
- if (ret != EC_SUCCESS) {
- printf("EcKeyboardInit() failed: %d\n", ret);
- return ret;
- }
+ ReturnIfInitFailed(EcKeyboardInit);
+ ReturnIfInitFailed(BoardInit);
return EC_SUCCESS;
}
diff --git a/cros_ec/test/Makefile b/cros_ec/test/Makefile
index 84c766495d..edad222b43 100644
--- a/cros_ec/test/Makefile
+++ b/cros_ec/test/Makefile
@@ -20,7 +20,7 @@ TEST_BINS = $(addprefix ${BUILD_ROOT}/,$(TEST_NAMES))
# Allow multiple definitions, so tests can mock functions from other libraries
CFLAGS += -MMD -MF $@.d -Xlinker --allow-multiple-definition
-LIBS := ${TEST_LIB} $(CROS_EC_LIB) $(CHIP_STUB_LIB)
+LIBS := ${TEST_LIB} $(CROS_EC_LIB) $(CHIP_STUB_LIB) $(BOARD_LIB)
.SUFFIXES:
.SUFFIXES: .o .c
diff --git a/cros_ec/test/ec_keyboard_test.c b/cros_ec/test/ec_keyboard_test.c
index bcdb83cc6d..a425c0781a 100644
--- a/cros_ec/test/ec_keyboard_test.c
+++ b/cros_ec/test/ec_keyboard_test.c
@@ -5,21 +5,63 @@
* Testing code. Running at Linux environment.
*/
#include "cros_ec/include/ec_common.h"
+#include "chip_interface/ec_uart.h"
#include "cros_ec/include/core.h"
-#include "cros_ec/chip_stub/keyboard.h"
+#include "cros_ec/chip_stub/include/host.h"
+#include "cros_ec/chip_stub/include/keyboard.h"
+#define RUN_TEST(func) do { \
+ int ret; \
+ ret = func(); \
+ if (ret != EC_SUCCESS) { \
+ EcUartPrintf("Test %s() failed, retval = %d\n", #func, ret); \
+ return ret; \
+ } \
+ } while (0)
-int run_test_cases() {
- /* Just a simple test */
+
+EcError testKeyMade() {
+ uint8_t buf;
+
+ SimulateKeyStateChange(2, 3, 1);
+ EC_ASSERT(EC_SUCCESS == PullI8042ScanCode(&buf));
+ EC_ASSERT(buf == 2 * 13 + 3);
+
+ /* The duplicate press event will be ignored. */
SimulateKeyStateChange(2, 3, 1);
- /* Expect KeyboardStateChanged() in cros_ec/keyboard.c shows something. */
+ EC_ASSERT(EC_ERROR_BUFFER_EMPTY == PullI8042ScanCode(&buf));
- return 0;
+ return EC_SUCCESS;
}
+EcError testKeyReleased() {
+ uint8_t buf;
-int main(int argc, char **argv) {
+ /* The key is not pressed yet. A release event doesn't send out a code. */
+ SimulateKeyStateChange(7, 12, 0);
+ EC_ASSERT(EC_ERROR_BUFFER_EMPTY == PullI8042ScanCode(&buf));
+
+ /* Press and release it. Expect a release code. */
+ SimulateKeyStateChange(7, 12, 1);
+ SimulateKeyStateChange(7, 12, 0);
+ EC_ASSERT(EC_SUCCESS == PullI8042ScanCode(&buf));
+ EC_ASSERT(buf == 7 * 13 + 12);
+ EC_ASSERT(EC_SUCCESS == PullI8042ScanCode(&buf));
+ EC_ASSERT(buf == 7 * 13 + 12 + 0x80);
+
+ return EC_SUCCESS;
+}
+
+
+int run_test_cases() {
+ RUN_TEST(testKeyMade);
+ RUN_TEST(testKeyReleased);
+ return EC_SUCCESS;
+}
+
+
+int main(int argc, char **argv) {
EcError ret;
/* Call Google EC core initial code. */
diff --git a/host_interface/ec_command.h b/host_interface/ec_command.h
index 3d42a87c53..ddfcf4860d 100644
--- a/host_interface/ec_command.h
+++ b/host_interface/ec_command.h
@@ -2,9 +2,8 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
- * This file defines the EC commands used in mailbox between host and EC.
- *
- * This file is included by both BIOS/OS and EC firmware.
+ * This file defines the EC commands used in mailbox between host and EC, and
+ * is included by both BIOS/OS and EC firmware.
*/
#ifndef __HOST_INTERFACE_EC_COMMAND_H
@@ -13,6 +12,29 @@
#include "cros_ec/include/ec_common.h"
+/*
+ * Register ACPI callback to EC lib. The EC lib would then invoke this callback
+ * when port ACPI command is written by the host.
+ *
+ * The command would contain the value just written in 0x66 while the data would
+ * hold the value in 0x62.
+ *
+ * The callback function would return an integer to indicate how many bytes
+ * contain in output (max len is MAX_ACPI_OUTPUT_LEN defined below).
+ * Then the EC lib would output those bytes via port 0x62 one-by-one.
+ *
+ * Registering a NULL pointer can remove any registered callback.
+ */
+typedef int (*EcAcpiCallback)(
+ uint8_t command, /* just written in port 0x66 */
+ uint8_t data, /* just written in port 0x62 */
+ uint8_t *mailbox,
+ uint8_t* output);
+
+EcError EcAcpiRegisterCallback(EcAcpiCallback callback);
+#define MAX_ACPI_OUTPUT_LEN 4
+
+
enum EcCommand {
/*------------------------------------------------------------------------*/
/* Version and boot information */
@@ -127,7 +149,6 @@ enum EcCommand {
* - host gets the return value and reads parameters from to_host range.
*/
-
/* When host writes this value to port 0x66 (ACPI command port),
* the EC firmware would read the EcCommand in port 0x62 and execute
* the corresponding function.
@@ -152,15 +173,35 @@ enum EcMailboxError {
EC_MAILBOX_ERROR_UNIMPLEMENTED = 2,
};
-/* The callback function can return a value which will be put at port 0x62. */
+
+/* FIXME: move to EC core internal. */
+#if 0
+/* This function is implemented by EC lib, which communicates with low level
+ * LPC driver. The EC core would register a callback function to handle
+ * the EC commands from host.
+ *
+ * When the callback function is invoked, the ec_command would store the
+ * value that was just written to port 0x62. In addition, the to_ec would
+ * point to the starting address of mailbox. If the mailbox is not direct-
+ * accessible, the EC lib needs copying to a buffer and prepare a buffer
+ * for to_host too. to_ec and to_host can be overlapped in memory.
+ *
+ * At final, the callback function can return a value which will be put at
+ * port 0x62. The EC lib (or the underlying hardware) needs to handle the
+ * IBF flags in port 0x66 so that the host knows the EC has completed the
+ * command.
+ *
+ * Registering a NULL pointer can remove any registered callback.
+*/
typedef enum EcMailboxError (*EcMailboxCallback)(
uint8_t ec_command,
uint8_t *to_ec, /* pointer to input parameter */
uint8_t *to_host /* pointer to output buffer */);
-
-/* Registering NULL can remove any registered callback. */
EcError EcMailboxRegisterCallback(EcMailboxCallback callback);
+#endif
+
+
#endif /* __HOST_INTERFACE_EC_COMMAND_H */
diff --git a/host_interface/i8042.h b/host_interface/i8042.h
new file mode 100644
index 0000000000..a3b2475785
--- /dev/null
+++ b/host_interface/i8042.h
@@ -0,0 +1,48 @@
+/* Copyright (c) 2011 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.
+ *
+ * i8042.h -- defines the interface between EC core and the EC lib, which
+ * talks to the LPC driver (on the EC side) peering to the keyboard driver
+ * (on the host side).
+ *
+ * The EC lib implements this interface.
+ */
+
+#ifndef __HOST_INTERFACE_I8042_H
+#define __HOST_INTERFACE_I8042_H
+
+#include "cros_ec/include/ec_common.h"
+
+
+
+/*
+ * Register the i8042 callback to EC lib.
+ *
+ * The callback function would return an integer to indicate how many bytes
+ * contain in output (max len is MAX_I8042_OUTPUT_LEN defined below).
+ * Then the EC lib would output those bytes via port 0x60 one-by-one.
+ *
+ * Registering a NULL pointer can remove any registered callback.
+ */
+typedef int (*EcI8042Callback) (
+ uint8_t command,
+ uint8_t data,
+ uint8_t *output);
+
+EcError EcI8042RegisterCallback(EcI8042Callback callback);
+#define MAX_I8042_OUTPUT_LEN 4
+
+
+/* Send the scan code to the host. The EC lib will push the scan code bytes
+ * to host via port 0x60 and assert the IBF flag to trigger an interrupt.
+ * The EC lib must queue them if the host cannot read the previous byte away
+ * in time.
+ *
+ * Return:
+ * EC_ERROR_BUFFER_FULL -- the queue to host is full. Try again?
+ */
+EcError EcI8042SendScanCode(int len, uint8_t *scan_code);
+
+
+#endif /* __HOST_INTERFACE_I8042_H */