diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-03-02 11:29:06 +0800 |
---|---|---|
committer | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-03-02 11:29:06 +0800 |
commit | 763af1f695eb9c6407f83bbe16e37165498a71bc (patch) | |
tree | ade118bf0755e53f730d30626139f1954e51047d | |
parent | 5cd0f292e9c769264c5fa1f0fe262c910a9194ec (diff) | |
download | chrome-ec-763af1f695eb9c6407f83bbe16e37165498a71bc.tar.gz |
Handle ghost key in matrix scanner.
implement actual_key_masks[]. A ghost key exists if two columns share
more than one row (after ANDed actual_key_masks[]).
BUG=chrome-os-partner:7485
TEST=on bds. test cases:
single press of all keys.
~ 1 4 5: later 2 keys should be ignored (ghost).
h j k: all keys should work.
u R-shift 0 P: p should be ignored (ghost).
i R-shift ' p: P should show up.
Change-Id: I1ac105874a5327e839a5240ccbdd6304637ad404
-rw-r--r-- | chip/lm4/keyboard_scan.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c index 3da4cbbf13..3729a304f5 100644 --- a/chip/lm4/keyboard_scan.c +++ b/chip/lm4/keyboard_scan.c @@ -70,8 +70,8 @@ static const uint8_t *actual_key_mask; /* TODO: (crosbug.com/p/7485) fill in real key mask with 0-bits for coords that aren't keys */ static const uint8_t actual_key_masks[4][KB_COLS] = { - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x14, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, + 0xa4, 0xff, 0xf6, 0x55, 0xfa, 0xc8}, /* full set */ {0}, {0}, {0}, @@ -224,10 +224,11 @@ static void print_raw_state(const char *msg) /* Returns 1 if any key is still pressed. 0 if no key is pressed. */ static int check_keys_changed(void) { - int c; + int c, c2; uint8_t r; int change = 0; int num_press = 0; + uint8_t keys[KB_COLS]; for (c = 0; c < KB_COLS; c++) { /* Select column, then wait a bit for it to settle */ @@ -247,7 +248,22 @@ static int check_keys_changed(void) r |= raw_state[c]; #endif - /* Check for changes */ + keys[c] = r; + } + select_column(COLUMN_TRI_STATE_ALL); + + /* ignore if a ghost key appears. */ + for (c = 0; c < KB_COLS; c++) { + if (!keys[c]) continue; + for (c2 = c + 1; c2 < KB_COLS; c2++) { + uint8_t common = keys[c] & keys[c2]; + if (common & (common - 1)) goto out; + } + } + + /* Check for changes */ + for (c = 0; c < KB_COLS; c++) { + r = keys[c]; if (r != raw_state[c]) { int i; for (i = 0; i < 8; ++i) { @@ -261,11 +277,11 @@ static int check_keys_changed(void) change = 1; } } - select_column(COLUMN_TRI_STATE_ALL); if (change) print_raw_state("KB raw state"); +out: /* Count number of key pressed */ for (c = 0; c < KB_COLS; c++) { if (raw_state[c]) ++num_press; |