diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2011-07-19 11:21:32 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-08-29 10:59:04 -0700 |
commit | 9c5a50547aa58c7e95443572aba3f2ff14e5c2e7 (patch) | |
tree | 58336693be7822d8eeeecee8b51a173a68e2681c /drivers/input | |
parent | 3506df3c4347902f224b17b9a437bd74d6b1b515 (diff) |
arm: tegra: fix modifier+key detection
When the user presses Ctrl+D, the top of the keyboard controller FIFO is usually
filled with several "Ctrl" only keycodes. The modifier keys handling code
would remove the keycode and return 0. So, the "tstc" will indicate
that no key is pressed.
The correct behaviour for "tstc" is to check all the entries of the FIFO until
we find a significant one or return 0 if there is none.
BUG=chromium-os:17781
TEST=On Aebl, when the developer screen is displayed, check that the
first Ctrl+D key press is taken into account.
Change-Id: I0d1b4b8928951bac2fc05730083d956642ff4d3e
Reviewed-on: http://gerrit.chromium.org/gerrit/4327
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Anton Staaf <robotboy@chromium.org>
Diffstat (limited to 'drivers/input')
-rwxr-xr-x | drivers/input/tegra-kbc.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c index 9a2740c3afb..d32dfe18084 100755 --- a/drivers/input/tegra-kbc.c +++ b/drivers/input/tegra-kbc.c @@ -179,41 +179,45 @@ static int tegra_kbc_get_single_char(u32 fifo_cnt) char key = 0; if (fifo_cnt) { - cnt = tegra_kbc_find_keys(fifo); - /* If this is a ghost key combination report no change. */ - key = prev_key; - if (cnt <= KBC_MAX_KPENT) { - int prev_key_in_fifo = 0; - /* - * If multiple keys are pressed such that it results in - * 2 or more unmodified keys, we will determine the - * newest key and report that to the upper layer. - */ - for (i = 0; i < cnt; i++) { - for (j = 0; j < prev_cnt; j++) { - if (fifo[i] == prev_fifo[j]) + do { + cnt = tegra_kbc_find_keys(fifo); + /* If this is a ghost key combination report no change. */ + key = prev_key; + if (cnt <= KBC_MAX_KPENT) { + int prev_key_in_fifo = 0; + /* + * If multiple keys are pressed such that it + * results in * 2 or more unmodified keys, we + * will determine the newest key and report + * that to the upper layer. + */ + for (i = 0; i < cnt; i++) { + for (j = 0; j < prev_cnt; j++) { + if (fifo[i] == prev_fifo[j]) + break; + } + /* Found a new key. */ + if (j == prev_cnt) { + key = fifo[i]; break; + } + if (prev_key == fifo[i]) + prev_key_in_fifo = 1; } - /* Found a new key. */ - if (j == prev_cnt) { - key = fifo[i]; - break; - } - if (prev_key == fifo[i]) - prev_key_in_fifo = 1; + /* + * Keys were released and FIFO does not contain + * the previous reported key. So report a null + * key. + */ + if (i == cnt && !prev_key_in_fifo) + key = 0; + + for (i = 0; i < cnt; i++) + prev_fifo[i] = fifo[i]; + prev_cnt = cnt; + prev_key = key; } - /* - * Keys were released and FIFO does not contain the - * previous reported key. So report a null key. - */ - if (i == cnt && !prev_key_in_fifo) - key = 0; - - for (i = 0; i < cnt; i++) - prev_fifo[i] = fifo[i]; - prev_cnt = cnt; - prev_key = key; - } + } while (!key && --fifo_cnt); } else { prev_cnt = 0; prev_key = 0; |