diff options
author | Simon Glass <sjg@chromium.org> | 2012-10-04 09:08:51 -0700 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-10-05 10:41:18 -0700 |
commit | a3a6a9f34b10badef7fd677e0fa45dcd0b00d69c (patch) | |
tree | a4f6a07085b46c43338314c80c18f9df76a02b08 /chip | |
parent | c782abf208511b1c37e88178567788ca1db366a2 (diff) | |
download | chrome-ec-a3a6a9f34b10badef7fd677e0fa45dcd0b00d69c.tar.gz |
stm32: Update keyboard_scan to use run-time configuration
At present the keyboard scan parameters are hard-coded, so changing them
requires a new EC image. This can be problematic if we want to adjust
the behavior of keyboard scanning since we must send an EC update.
Change stm32's keyboard scan to use run-time config. All parameters
and behavior should remain the same with this change.
The configuration is defined by ec_commands.h since we intend to create
a command to allow access to it. It does not seem worth defining a
separate structure within keyboard_scan at present, although if we
add a new version of the command in the future then we may want to
separate these.
BUG=chrome-os-partner:12179
BRANCH=snow
TEST=manual
Boot snow into U-Boot and Linux, try the keyboard, seeing that it seems
to work as before. This is a very subjective test.
Change-Id: Ie6160f1d73b983867b96f8ccb421853f6ec99524
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/34633
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32/keyboard_scan.c | 116 |
1 files changed, 75 insertions, 41 deletions
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c index 8ebb88848d..638098b2b6 100644 --- a/chip/stm32/keyboard_scan.c +++ b/chip/stm32/keyboard_scan.c @@ -33,9 +33,6 @@ enum COL_INDEX { /* 0 ~ 12 for the corresponding column */ }; -#define POLLING_MODE_TIMEOUT 100000 /* 100 ms */ -#define SCAN_LOOP_DELAY 10000 /* 10 ms */ - /* 15:14, 12:8, 2 */ #define IRQ_MASK 0xdf04 @@ -86,6 +83,23 @@ static uint32_t kb_fifo_end; /* last entry */ static uint32_t kb_fifo_entries; /* number of existing entries */ static uint8_t kb_fifo[KB_FIFO_DEPTH][KB_OUTPUTS]; +/* + * Our configuration. The debounce parameters are not yet supported. + */ +static struct ec_mkbp_config config = { + .valid_mask = EC_MKBP_VALID_SCAN_PERIOD | EC_MKBP_VALID_POLL_TIMEOUT | + EC_MKBP_VALID_MIN_POST_SCAN_DELAY | + EC_MKBP_VALID_OUTPUT_SETTLE | EC_MKBP_VALID_DEBOUNCE_DOWN | + EC_MKBP_VALID_DEBOUNCE_UP | EC_MKBP_VALID_FIFO_MAX_DEPTH, + .valid_flags = EC_MKBP_FLAGS_ENABLE, + .flags = EC_MKBP_FLAGS_ENABLE, + .scan_period_us = 10000, + .poll_timeout_us = 100 * 1000, + .min_post_scan_delay_us = 1000, + .output_settle_us = 50, + .fifo_max_depth = KB_FIFO_DEPTH, +}; + /* clear keyboard state variables */ void keyboard_clear_state(void) { @@ -108,8 +122,9 @@ static int kb_fifo_add(uint8_t *buffp) { int ret = EC_SUCCESS; - if (kb_fifo_entries == KB_FIFO_DEPTH) { - CPRINTF("%s: FIFO depth reached\n", __func__); + if (kb_fifo_entries >= config.fifo_max_depth) { + CPRINTF("%s: FIFO depth %d reached\n", __func__, + config.fifo_max_depth); ret = EC_ERROR_OVERFLOW; goto kb_fifo_push_done; } @@ -191,8 +206,8 @@ static void select_column(int col) } } - -void wait_for_interrupt(void) +/* Set up columns so that we will get an interrupt when any key changed */ +void setup_interrupts(void) { uint32_t pr_before, pr_after; @@ -237,7 +252,7 @@ static int check_keys_changed(void) /* Select column, then wait a bit for it to settle */ select_column(c); - udelay(50); + udelay(config.output_settle_us); r = 0; tmp = STM32_GPIO_IDR(C); @@ -365,12 +380,56 @@ int keyboard_scan_init(void) return EC_SUCCESS; } +/* Scan the keyboard until all keys are released */ +static void scan_keyboard(void) +{ + timestamp_t poll_deadline, start; + int keys_changed = 1; + + mutex_lock(&scanning_enabled); + setup_interrupts(); + mutex_unlock(&scanning_enabled); + + /* Wait until we get an interrupt */ + task_wait_event(-1); + + enter_polling_mode(); + + /* Busy polling keyboard state. */ + while (1) { + int wait_time; + + if (!(config.flags & EC_MKBP_FLAGS_ENABLE)) + break; + + /* If we saw any keys pressed, reset deadline */ + start = get_time(); + if (keys_changed) + poll_deadline.val = start.val + config.poll_timeout_us; + else if (timestamp_expired(poll_deadline, &start)) + break; + + /* Scan immediately, with no delay */ + mutex_lock(&scanning_enabled); + keys_changed = check_keys_changed(); + mutex_unlock(&scanning_enabled); + + /* Wait a bit before scanning again */ + wait_time = config.scan_period_us - + (get_time().val - start.val); + if (wait_time < config.min_post_scan_delay_us) + wait_time = config.min_post_scan_delay_us; + task_wait_event(wait_time); + } + /* + * TODO: (crosbug.com/p/7484) A race condition here. + * If a key state is changed here (before interrupt is + * enabled), it will be lost. + */ +} void keyboard_scan_task(void) { - int key_press_timer = 0; - uint8_t keys_changed = 0; - /* Enable interrupts for keyboard matrix inputs */ gpio_enable_interrupt(GPIO_KB_IN00); gpio_enable_interrupt(GPIO_KB_IN01); @@ -382,37 +441,12 @@ void keyboard_scan_task(void) gpio_enable_interrupt(GPIO_KB_IN07); while (1) { - mutex_lock(&scanning_enabled); - wait_for_interrupt(); - mutex_unlock(&scanning_enabled); - - task_wait_event(-1); - - enter_polling_mode(); - /* Busy polling keyboard state. */ - while (1) { - /* sleep for debounce. */ - usleep(SCAN_LOOP_DELAY); - /* Check for keys down */ - - mutex_lock(&scanning_enabled); - keys_changed = check_keys_changed(); - mutex_unlock(&scanning_enabled); - - if (keys_changed) { - key_press_timer = 0; - } else { - if (++key_press_timer >= - (POLLING_MODE_TIMEOUT / SCAN_LOOP_DELAY)) { - key_press_timer = 0; - break; /* exit the while loop */ - } - } + if (config.flags & EC_MKBP_FLAGS_ENABLE) { + scan_keyboard(); + } else { + select_column(COL_TRI_STATE_ALL); + task_wait_event(-1); } - /* TODO: (crosbug.com/p/7484) A race condition here. - * If a key state is changed here (before interrupt is - * enabled), it will be lost. - */ } } |