From 79a661d00c31937bff2018afef1ebb41c8b5ec14 Mon Sep 17 00:00:00 2001 From: Louis Yung-Chieh Lo Date: Thu, 27 Oct 2011 16:31:08 +0800 Subject: 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 --- .gitignore | 2 +- Makefile | 6 ++- board/Makefile | 30 +++++++++++++ board/board.c | 56 ++++++++++++++++++++++++ board/board_interface.h | 20 +++++++++ chip_interface/keyboard.h | 10 +++-- cros_ec/Makefile | 3 +- cros_ec/chip_stub/host.c | 83 ++++++++++++++++++++++++++++++++++++ cros_ec/chip_stub/include/host.h | 26 +++++++++++ cros_ec/chip_stub/include/keyboard.h | 14 ++++++ cros_ec/chip_stub/keyboard.c | 10 ++--- cros_ec/chip_stub/keyboard.h | 14 ------ cros_ec/include/ec_common.h | 11 ++++- cros_ec/include/ec_keyboard.h | 28 +++++++----- cros_ec/lib/ec_keyboard.c | 38 +++++++++++++++-- cros_ec/main.c | 20 ++++++--- cros_ec/test/Makefile | 2 +- cros_ec/test/ec_keyboard_test.c | 54 ++++++++++++++++++++--- host_interface/ec_command.h | 55 +++++++++++++++++++++--- host_interface/i8042.h | 48 +++++++++++++++++++++ 20 files changed, 468 insertions(+), 62 deletions(-) create mode 100644 board/Makefile create mode 100644 board/board.c create mode 100644 board/board_interface.h create mode 100644 cros_ec/chip_stub/host.c create mode 100644 cros_ec/chip_stub/include/host.h create mode 100644 cros_ec/chip_stub/include/keyboard.h delete mode 100644 cros_ec/chip_stub/keyboard.h create mode 100644 host_interface/i8042.h 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 /* 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/include/keyboard.h b/cros_ec/chip_stub/include/keyboard.h new file mode 100644 index 0000000000..274e90b414 --- /dev/null +++ b/cros_ec/chip_stub/include/keyboard.h @@ -0,0 +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 keyboard stub header file for test code to include. + */ + + +#ifndef __EC_CHIP_STUB_KEYBOARD_H_ +#define __EC_CHIP_STUB_KEYBOARD_H_ + +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/chip_stub/keyboard.h b/cros_ec/chip_stub/keyboard.h deleted file mode 100644 index a3357eec4f..0000000000 --- a/cros_ec/chip_stub/keyboard.h +++ /dev/null @@ -1,14 +0,0 @@ -/* 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 keyboard stub header file for test code to include. - */ - - -#ifndef __EC_CHIP_STUB_KEYBOARD_H_ -#define __EC_CHIP_STUB_KEYBOARD_H_ - -EcError SimulateKeyStateChange(int col, int row, int state); - -#endif /* __EC_CHIP_STUB_KEYBOARD_H_ */ 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 */ -- cgit v1.2.1