From 763af1f695eb9c6407f83bbe16e37165498a71bc Mon Sep 17 00:00:00 2001 From: Louis Yung-Chieh Lo Date: Fri, 2 Mar 2012 11:29:06 +0800 Subject: [PATCH] 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 --- chip/lm4/keyboard_scan.c | 26 +++++++++++++++++++++----- 1 file 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;