summaryrefslogtreecommitdiff
path: root/common/keyboard.c
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2012-04-03 13:13:38 +0800
committerLouis Yung-Chieh Lo <yjlou@chromium.org>2012-04-17 17:09:46 +0800
commit12753d10f2bd7b9cfe6077db46f925ece335bcc7 (patch)
treecfd7f990c82bb28a9a6f88c2bcee85fb31ebd337 /common/keyboard.c
parentf3301b4944e322afe48cb271ed5d47256e110072 (diff)
downloadchrome-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.c74
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;