diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-04-03 13:13:38 +0800 |
---|---|---|
committer | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-04-17 17:09:46 +0800 |
commit | 12753d10f2bd7b9cfe6077db46f925ece335bcc7 (patch) | |
tree | cfd7f990c82bb28a9a6f88c2bcee85fb31ebd337 /common/keyboard.c | |
parent | f3301b4944e322afe48cb271ed5d47256e110072 (diff) | |
download | chrome-ec-12753d10f2bd7b9cfe6077db46f925ece335bcc7.tar.gz |
Support keyboard typematic.
Mainly add a typematic task that counts down the delay. Set the initial delay
in the keyboard_state_changed() when key pressed and clean it when released.
BUS=chrome-os-partner:8463
TEST=press on a particular key and screen shows that key is repeating.
Change-Id: Ic8432f8b38b514476588e0b7ad8fdc8a0b0c0b51
Diffstat (limited to 'common/keyboard.c')
-rw-r--r-- | common/keyboard.c | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/common/keyboard.c b/common/keyboard.c index 9c47e21332..65e9b45d40 100644 --- a/common/keyboard.c +++ b/common/keyboard.c @@ -13,6 +13,7 @@ #include "lpc.h" #include "lpc_commands.h" #include "registers.h" +#include "task.h" #include "timer.h" #include "uart.h" #include "util.h" @@ -63,11 +64,13 @@ static enum scancode_set_list scancode_set = SCANCODE_SET_2; #define DEFAULT_TYPEMATIC_VALUE ((1 << 5) || (1 << 3) || (3 << 0)) #define DEFAULT_FIRST_DELAY 500 #define DEFAULT_INTER_DELAY 91 +#define TYPEMATIC_DELAY_UNIT 1000 /* 1ms = 1000us */ static uint8_t typematic_value_from_host = DEFAULT_TYPEMATIC_VALUE; static int refill_first_delay = DEFAULT_FIRST_DELAY; /* unit: ms */ -static int counter_first_delay; static int refill_inter_delay = DEFAULT_INTER_DELAY; /* unit: ms */ -static int counter_inter_delay; +static int typematic_delay; /* unit: us */ +static int typematic_len = 0; /* length of typematic_scan_code */ +static uint8_t typematic_scan_code[MAX_SCAN_CODE_LEN]; /* The standard Chrome OS keyboard matrix table. */ @@ -252,6 +255,13 @@ void keyboard_state_changed(int row, int col, int is_pressed) { if (is_pressed) { keyboard_wakeup(); + + typematic_delay = refill_first_delay * 1000; + memcpy(typematic_scan_code, scan_code, len); + typematic_len = len; + task_wake(TASK_ID_TYPEMATIC); + } else { + typematic_len = 0; } } @@ -390,8 +400,7 @@ int handle_keyboard_data(uint8_t data, uint8_t *output) { uart_printf("[Eaten by STATE_SETREP: 0x%02x]\n", data); #endif typematic_value_from_host = data; - refill_first_delay = counter_first_delay + counter_inter_delay; - refill_first_delay = ((typematic_value_from_host & 0x60) >> 5) * 250; + refill_first_delay = (((typematic_value_from_host & 0x60) >> 5) + 1) * 250; refill_inter_delay = 1000 * /* ms */ (1 << ((typematic_value_from_host & 0x18) >> 3)) * ((typematic_value_from_host & 0x7) + 8) / @@ -620,6 +629,63 @@ void keyboard_set_power_button(int pressed) } + +void keyboard_typematic_task(void) +{ + while (1) { + task_wait_event(-1); + + while (typematic_len) { + usleep(TYPEMATIC_DELAY_UNIT); + typematic_delay -= TYPEMATIC_DELAY_UNIT; + + if (typematic_delay <= 0) { + /* re-send to host */ + i8042_send_to_host(typematic_len, typematic_scan_code); + typematic_delay = refill_inter_delay * 1000; + } + } + } +} + + +static int command_typematic(int argc, char **argv) +{ + if (argc == 1) { + int i; + + uart_printf("Value set from host: 0x%02x\n", + typematic_value_from_host); + uart_printf("Refill first delay : %d (ms)\n", + refill_first_delay); + uart_printf(" inter delay : %d (ms)\n", + refill_inter_delay); + uart_printf("Current delay : %d (us)\n", + typematic_delay); + + uart_puts("Repeat scan code : "); + for (i = 0; i < typematic_len; ++i) { + uart_printf("0x%02x ", typematic_scan_code[i]); + } + uart_puts("\n"); + } else if (argc == 3) { + refill_first_delay = strtoi(argv[1], NULL, 0); + refill_inter_delay = strtoi(argv[2], NULL, 0); + uart_puts("New typematic delays:\n"); + uart_printf(" Refill first delay : %d (ms)\n", + refill_first_delay); + uart_printf(" Refill inter delay : %d (ms)\n", + refill_inter_delay); + } else { + uart_puts("Usage: typematic [<first> <inter>]\n"); + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(typematic, command_typematic); + + static int command_codeset(int argc, char **argv) { int set; |