diff options
-rw-r--r-- | test/kb_8042.c | 220 |
1 files changed, 219 insertions, 1 deletions
diff --git a/test/kb_8042.c b/test/kb_8042.c index 36970564b2..6ca67b56ab 100644 --- a/test/kb_8042.c +++ b/test/kb_8042.c @@ -240,7 +240,7 @@ static int _read_cmd_byte(uint8_t *cmd) return EC_SUCCESS; } -#define READ_CMD_BYTE(cmd_ptr) \ +#define READ_CMD_BYTE() \ ({ \ uint8_t cmd; \ TEST_EQ(_read_cmd_byte(&cmd), EC_SUCCESS, "%d"); \ @@ -368,6 +368,22 @@ static int test_8042_aux_test_command(void) return EC_SUCCESS; } +static int test_8042_self_test(void) +{ + i8042_write_cmd(I8042_RESET_SELF_TEST); + VERIFY_LPC_CHAR("\x55"); + + return EC_SUCCESS; +} + +static int test_8042_keyboard_test_command(void) +{ + i8042_write_cmd(I8042_TEST_KB_PORT); + VERIFY_LPC_CHAR("\x00"); /* Data and Clock are not stuck */ + + return EC_SUCCESS; +} + static int test_8042_keyboard_controller_commands(void) { uint8_t ctrl; @@ -594,6 +610,197 @@ static int test_typematic(void) return EC_SUCCESS; } +static int test_atkbd_get_scancode(void) +{ + SET_SCANCODE(1); + + keyboard_host_write(ATKBD_CMD_GSCANSET, 0); + VERIFY_ATKBD_ACK(); + + /* Writing a 0 scan code will return the current scan code. */ + keyboard_host_write(0, 0); + VERIFY_ATKBD_ACK(); + VERIFY_LPC_CHAR("\x01"); + + SET_SCANCODE(2); + + keyboard_host_write(ATKBD_CMD_GSCANSET, 0); + VERIFY_ATKBD_ACK(); + + /* Writing a 0 scan code will return the current scan code. */ + keyboard_host_write(0, 0); + VERIFY_ATKBD_ACK(); + VERIFY_LPC_CHAR("\x02"); + + return EC_SUCCESS; +} + +static int test_atkbd_set_scancode_with_keystroke_disabled(void) +{ + ENABLE_KEYSTROKE(0); + + SET_SCANCODE(1); + + press_key(1, 1, 1); + VERIFY_NO_CHAR(); + + return EC_SUCCESS; +} + +static int test_atkbd_set_scancode_with_key_press_before_set(void) +{ + ENABLE_KEYSTROKE(0); + ENABLE_KEYSTROKE(1); + + /* Push data into the output buffer and keyboard queue */ + press_key(1, 1, 1); + press_key(1, 1, 0); + + /* + * ATKBD_CMD_SSCANSET should cause the keyboard to stop scanning, flush + * the keyboards output queue, and reset the typematic key. + */ + keyboard_host_write(ATKBD_CMD_SSCANSET, 0); + /* Read out the scan code that got pushed into the output buffer before + * the command was sent. + */ + VERIFY_LPC_CHAR("\x01"); + + /* + * FIXME: This is wrong. The keyboard's output queue should have been + * flushed when it received the `ATKBD_CMD_SSCANSET` command. + */ + VERIFY_LPC_CHAR("\x81"); + + /* This is the ACK for `ATKBD_CMD_SSCANSET`. */ + VERIFY_ATKBD_ACK(); + + /* The keyboard has flushed the buffer so no more keys. */ + VERIFY_NO_CHAR(); + + /* Finish setting scan code 1 */ + keyboard_host_write(1, 0); + VERIFY_ATKBD_ACK(); + + /* Key scanning should be restored. */ + press_key(1, 1, 1); + press_key(1, 1, 0); + VERIFY_LPC_CHAR("\x01\x81"); + + return EC_SUCCESS; +} + +static int test_atkbd_set_scancode_with_key_press_during_set(void) +{ + ENABLE_KEYSTROKE(1); + + /* + * ATKBD_CMD_SSCANSET should cause the keyboard to stop scanning, flush + * the keyboards output queue, and reset the typematic key. + */ + keyboard_host_write(ATKBD_CMD_SSCANSET, 0); + VERIFY_ATKBD_ACK(); + + /* These keypresses should be dropped. */ + press_key(1, 1, 1); + press_key(1, 1, 0); + /* + * FIXME: So this is wrong. scanning should be stopped while waiting + * for the scan code to be sent. + */ + VERIFY_LPC_CHAR("\x01\x81"); + + /* Finish setting scan code 1 */ + keyboard_host_write(1, 0); + VERIFY_ATKBD_ACK(); + + /* Key scanning should be restored. */ + press_key(1, 1, 1); + press_key(1, 1, 0); + VERIFY_LPC_CHAR("\x01\x81"); + + return EC_SUCCESS; +} + +static int test_atkbd_echo(void) +{ + i8042_write_data(ATKBD_CMD_DIAG_ECHO); + VERIFY_ATKBD_ACK(); + + VERIFY_LPC_CHAR("\xee"); + + return EC_SUCCESS; +} + +static int test_atkbd_get_id(void) +{ + i8042_write_data(ATKBD_CMD_GETID); + VERIFY_ATKBD_ACK(); + + VERIFY_LPC_CHAR("\xab\x83"); + + i8042_write_data(ATKBD_CMD_OK_GETID); + VERIFY_ATKBD_ACK(); + + VERIFY_LPC_CHAR("\xab\x83"); + + return EC_SUCCESS; +} + +static int test_atkbd_set_leds_keypress_during(void) +{ + /* This should pause scanning. */ + i8042_write_data(ATKBD_CMD_SETLEDS); + VERIFY_ATKBD_ACK(); + + /* Simulate keypress while keyboard is waiting for option byte */ + press_key(1, 1, 1); + press_key(1, 1, 0); + /* FIXME: This is wrong, we shouldn't have any key strokes */ + VERIFY_LPC_CHAR("\x01\x81"); + + i8042_write_data(0x01); + VERIFY_ATKBD_ACK(); + + return EC_SUCCESS; +} + +static int test_atkbd_set_leds_abort_set(void) +{ + i8042_write_data(ATKBD_CMD_SETLEDS); + VERIFY_ATKBD_ACK(); + + /* + * The spec says if we send a command instead of the option byte, the + * keyboard will abort the SETLEDS command and processes the new + * command. The way we can differentiate between a command and the + * option byte is the option byte must have the top 5 bits set to 0. + */ + i8042_write_data(ATKBD_CMD_DIAG_ECHO); + VERIFY_ATKBD_ACK(); + + /* FIXME: This is wrong. We are expecting the 0xee echo byte. */ + VERIFY_NO_CHAR(); + + return EC_SUCCESS; +} + +static int test_atkbd_set_ex_leds(void) +{ + i8042_write_data(ATKBD_CMD_EX_SETLEDS); + VERIFY_ATKBD_ACK(); + + /* The extra set led command expects two option bytes. */ + + i8042_write_data(0x1); + VERIFY_ATKBD_ACK(); + + i8042_write_data(0x2); + VERIFY_ATKBD_ACK(); + + return EC_SUCCESS; +} + static int test_scancode_set2(void) { SET_SCANCODE(2); @@ -757,6 +964,8 @@ void run_test(int argc, char **argv) RUN_TEST(test_8042_aux_inhibit); RUN_TEST(test_8042_aux_controller_commands); RUN_TEST(test_8042_aux_test_command); + RUN_TEST(test_8042_self_test); + RUN_TEST(test_8042_keyboard_test_command); RUN_TEST(test_8042_keyboard_controller_commands); RUN_TEST(test_8042_keyboard_key_pressed_while_inhibited); RUN_TEST( @@ -765,6 +974,15 @@ void run_test(int argc, char **argv) test_8042_keyboard_key_pressed_before_inhibit_using_cmd_byte_with_read); RUN_TEST( test_8042_keyboard_key_pressed_before_inhibit_using_cmd); + RUN_TEST(test_atkbd_get_scancode); + RUN_TEST(test_atkbd_set_scancode_with_keystroke_disabled); + RUN_TEST(test_atkbd_set_scancode_with_key_press_before_set); + RUN_TEST(test_atkbd_set_scancode_with_key_press_during_set); + RUN_TEST(test_atkbd_echo); + RUN_TEST(test_atkbd_get_id); + RUN_TEST(test_atkbd_set_leds_keypress_during); + RUN_TEST(test_atkbd_set_leds_abort_set); + RUN_TEST(test_atkbd_set_ex_leds); RUN_TEST(test_single_key_press); RUN_TEST(test_disable_keystroke); RUN_TEST(test_typematic); |