summaryrefslogtreecommitdiff
path: root/test/kb_8042.c
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-07-08 09:54:36 +0800
committerChromeBot <chrome-bot@google.com>2013-07-11 22:32:52 -0700
commit2475cce9ad0e505a45562189e5427683d4ebd65c (patch)
tree1110f516e9d50900ce1cb4492f2743f1639cd8e2 /test/kb_8042.c
parentb2bc8aaa20479a87261aed8611367f11cf33c909 (diff)
downloadchrome-ec-2475cce9ad0e505a45562189e5427683d4ebd65c.tar.gz
Add I8042 keyboard unit test
This tests I8042 scancode and typematic. BUG=chrome-os-partner:19236 TEST=Pass all tests many times. BRANCH=None Change-Id: I8457b7b807b694b0bae32abf1647961f946dc5e1 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/61553 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'test/kb_8042.c')
-rw-r--r--test/kb_8042.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/test/kb_8042.c b/test/kb_8042.c
new file mode 100644
index 0000000000..8fa3158dd7
--- /dev/null
+++ b/test/kb_8042.c
@@ -0,0 +1,206 @@
+/* Copyright (c) 2013 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.
+ *
+ * Tests for keyboard MKBP protocol
+ */
+
+#include "common.h"
+#include "console.h"
+#include "ec_commands.h"
+#include "gpio.h"
+#include "i8042_protocol.h"
+#include "keyboard_8042.h"
+#include "keyboard_protocol.h"
+#include "keyboard_scan.h"
+#include "lpc.h"
+#include "test_util.h"
+#include "timer.h"
+#include "util.h"
+
+static const char *action[2] = {"release", "press"};
+
+#define BUF_SIZE 16
+static char lpc_char_buf[BUF_SIZE];
+static unsigned int lpc_char_cnt;
+
+/*****************************************************************************/
+/* Mock functions */
+
+int lid_is_open(void)
+{
+ return 1;
+}
+
+void lpc_keyboard_put_char(uint8_t chr, int send_irq)
+{
+ lpc_char_buf[lpc_char_cnt++] = chr;
+}
+
+/*****************************************************************************/
+/* Test utilities */
+
+static void press_key(int c, int r, int pressed)
+{
+ ccprintf("Input %s (%d, %d)\n", action[pressed], c, r);
+ keyboard_state_changed(r, c, pressed);
+}
+
+static void enable_keystroke(int enabled)
+{
+ uint8_t data = enabled ? I8042_CMD_ENABLE : I8042_CMD_RESET_DIS;
+ keyboard_host_write(data, 0);
+ msleep(30);
+}
+
+static void reset_8042(void)
+{
+ keyboard_host_write(I8042_CMD_RESET_DEF, 0);
+ msleep(30);
+}
+
+static void set_typematic(uint8_t val)
+{
+ keyboard_host_write(I8042_CMD_SETREP, 0);
+ msleep(30);
+ keyboard_host_write(val, 0);
+ msleep(30);
+}
+
+static void set_scancode(uint8_t s)
+{
+ keyboard_host_write(I8042_CMD_SSCANSET, 0);
+ msleep(30);
+ keyboard_host_write(s, 0);
+ msleep(30);
+}
+
+static void write_cmd_byte(uint8_t val)
+{
+ keyboard_host_write(I8042_WRITE_CMD_BYTE, 1);
+ msleep(30);
+ keyboard_host_write(val, 0);
+ msleep(30);
+}
+
+static uint8_t read_cmd_byte(void)
+{
+ lpc_char_cnt = 0;
+ keyboard_host_write(I8042_READ_CMD_BYTE, 1);
+ msleep(30);
+ return lpc_char_buf[0];
+}
+
+static int __verify_lpc_char(char *arr, unsigned int sz, int delay_ms)
+{
+ int i;
+
+ lpc_char_cnt = 0;
+ for (i = 0; i < sz; ++i)
+ lpc_char_buf[i] = 0;
+ msleep(delay_ms);
+ TEST_ASSERT_ARRAY_EQ(arr, lpc_char_buf, sz);
+ return EC_SUCCESS;
+}
+
+#define VERIFY_LPC_CHAR(s) \
+ TEST_ASSERT(__verify_lpc_char(s, strlen(s), 30) == EC_SUCCESS)
+#define VERIFY_LPC_CHAR_DELAY(s, t) \
+ TEST_ASSERT(__verify_lpc_char(s, strlen(s), t) == EC_SUCCESS)
+
+static int __verify_no_char(void)
+{
+ lpc_char_cnt = 0;
+ msleep(30);
+ TEST_CHECK(lpc_char_cnt == 0);
+}
+
+#define VERIFY_NO_CHAR() TEST_ASSERT(__verify_no_char() == EC_SUCCESS)
+
+/*****************************************************************************/
+/* Tests */
+
+static int test_single_key_press(void)
+{
+ enable_keystroke(1);
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR("\x01");
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR("\x81");
+
+ press_key(12, 6, 1);
+ VERIFY_LPC_CHAR("\xe0\x4d");
+ press_key(12, 6, 0);
+ VERIFY_LPC_CHAR("\xe0\xcd");
+
+ return EC_SUCCESS;
+}
+
+static int test_disable_keystroke(void)
+{
+ enable_keystroke(0);
+ press_key(1, 1, 1);
+ VERIFY_NO_CHAR();
+ press_key(1, 1, 0);
+ VERIFY_NO_CHAR();
+
+ return EC_SUCCESS;
+}
+
+static int test_typematic(void)
+{
+ enable_keystroke(1);
+
+ /*
+ * 250ms delay, 8 chars / sec.
+ */
+ set_typematic(0xf);
+
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR_DELAY("\x01\x01\x01\x01\x01", 650);
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR_DELAY("\x81", 300);
+
+ /*
+ * 500ms delay, 10.9 chars / sec.
+ */
+ reset_8042();
+
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR_DELAY("\x01\x01\x01", 650);
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR_DELAY("\x81", 200);
+
+ return EC_SUCCESS;
+}
+
+static int test_scancode_set2(void)
+{
+ set_scancode(2);
+
+ write_cmd_byte(read_cmd_byte() | I8042_XLATE);
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR("\x01");
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR("\x81");
+
+ write_cmd_byte(read_cmd_byte() & ~I8042_XLATE);
+ press_key(1, 1, 1);
+ VERIFY_LPC_CHAR("\x76");
+ press_key(1, 1, 0);
+ VERIFY_LPC_CHAR("\xf0\x76");
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_single_key_press);
+ RUN_TEST(test_disable_keystroke);
+ RUN_TEST(test_typematic);
+ RUN_TEST(test_scancode_set2);
+
+ test_print_result();
+}