summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2012-10-16 16:08:44 -0700
committerSimon Glass <sjg@chromium.org>2012-10-29 14:47:14 -0700
commit64bb173c0cd57aff75067b10e3cd99e51f27e120 (patch)
tree497bf539e9a810d8555fdba8fd882b62c92b96f3
parentdcc92c72cf5350a02387770b4ecf9dbeb02699dd (diff)
downloadchrome-ec-64bb173c0cd57aff75067b10e3cd99e51f27e120.tar.gz
Revert "Revert "stm32: Update keyboard_scan to use run-time configuration""
This reverts commit 7e0be8cb9ef4041b8e5775be6aec24a913e73b28. This brings the ToT code back into the branch. BUG=chrome-os-partner:12179 BRANCH=snow TEST=manual Use keyboard in U-Boot, browser, gmail and write a paragraph of text. Try pressing keys quickly. See that things seem to work correctly. Change-Id: I30bcad9478550fae7934e4659922f1a8e842cfc9 Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/36076 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: David Hendricks <dhendrix@chromium.org>
-rw-r--r--chip/stm32/keyboard_scan.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c
index 9e75e7a92d..a3bb056810 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.
- */
}
}