diff options
author | Ting Shen <phoenixshen@google.com> | 2022-08-01 18:08:49 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-08-15 15:29:22 +0000 |
commit | fd305e6809233a662c31dae8ca2953271830c958 (patch) | |
tree | 48eaab72b24e907c4a3cc53abc2a5a3b4eee70ff /common/keyboard_scan.c | |
parent | 2e23b2e8bf935cf5000d6016c99a5300c7e53c2c (diff) | |
download | chrome-ec-fd305e6809233a662c31dae8ca2953271830c958.tar.gz |
keyboard_scan: skip ghost key detection at boot
This CL fixed a bug that EC can't detect the boot key correctly if GSC
asserts KSI2/3.
When all columns have row2 or 3 asserted, read_matrix() tries to "fix"
this by adding more keys to the state array. This causes the
check_boot_key() function rejects the adjusted state.
To fix this, add another workaround step before the ghost key detection
to remove the rows affected by GSC.
BUG=b:239674288,b:236580049
TEST=with gsc firmware from b/239674288$comment9,
verify tentacruel able to enter recovery mode
BRANCH=none
Signed-off-by: Ting Shen <phoenixshen@google.com>
Change-Id: I3df2e56e0537446954e2b5de24bf849c2189d211
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3795747
Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
Commit-Queue: Ting Shen <phoenixshen@chromium.org>
Tested-by: Ting Shen <phoenixshen@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'common/keyboard_scan.c')
-rw-r--r-- | common/keyboard_scan.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c index d9f9e16417..117f590d67 100644 --- a/common/keyboard_scan.c +++ b/common/keyboard_scan.c @@ -294,10 +294,11 @@ static void simulate_key(int row, int col, int pressed) * * @param state Destination for new state (must be KEYBOARD_COLS_MAX * long). + * @param at_boot True if we are reading the boot key state. * * @return 1 if at least one key is pressed, else zero. */ -static int read_matrix(uint8_t *state) +static int read_matrix(uint8_t *state, bool at_boot) { int c; int pressed = 0; @@ -332,6 +333,31 @@ static int read_matrix(uint8_t *state) state[c] = keyscan_seq_get_scan(c, state[c]); } +#ifdef KEYBOARD_MASK_PWRBTN + /* + * 2. Boot key workaround. + * + * Check if KSI2 or KSI3 is asserted for all columns due to power + * button hold, and ignore it if so. + */ + if (at_boot) { + for (c = 0; c < keyboard_cols; c++) { + if (!(state[c] & KEYBOARD_MASK_PWRBTN)) + break; + } + + if (c == keyboard_cols) { + for (c = 0; c < keyboard_cols; c++) + state[c] &= ~KEYBOARD_MASK_PWRBTN; +#ifndef CONFIG_KEYBOARD_MULTIPLE + state[KEYBOARD_COL_REFRESH] |= KEYBOARD_MASK_PWRBTN; +#else + state[key_typ.col_refresh] |= KEYBOARD_MASK_PWRBTN; +#endif + } + } +#endif + #ifdef CONFIG_KEYBOARD_SCAN_ADC /* Account for the refresh key */ keyboard_read_refresh_key(state); @@ -341,7 +367,7 @@ static int read_matrix(uint8_t *state) * this check isn't required */ #else - /* 2. Detect transitional ghost */ + /* 3. Detect transitional ghost */ for (c = 0; c < keyboard_cols; c++) { int c2; @@ -366,7 +392,7 @@ static int read_matrix(uint8_t *state) } #endif - /* 3. Fix result */ + /* 4. Fix result */ for (c = 0; c < keyboard_cols; c++) { /* Add in simulated keypresses */ state[c] |= simulated_key[c]; @@ -576,7 +602,7 @@ static int check_keys_changed(uint8_t *state) scan_time[scan_time_index] = tnow; /* Read the raw key state */ - any_pressed = read_matrix(new_state); + any_pressed = read_matrix(new_state, false); if (!IS_ENABLED(CONFIG_KEYBOARD_SCAN_ADC)) { /* Ignore if so many keys are pressed that we're ghosting. */ @@ -703,22 +729,6 @@ static uint32_t check_key_list(const uint8_t *state) /* Make copy of current debounced state. */ memcpy(curr_state, state, sizeof(curr_state)); -#ifdef KEYBOARD_MASK_PWRBTN - /* - * Check if KSI2 or KSI3 is asserted for all columns due to power - * button hold, and ignore it if so. - */ - for (c = 0; c < keyboard_cols; c++) - if ((keyscan_config.actual_key_mask[c] & - KEYBOARD_MASK_PWRBTN) && - !(curr_state[c] & KEYBOARD_MASK_PWRBTN)) - break; - - if (c == keyboard_cols) - for (c = 0; c < keyboard_cols; c++) - curr_state[c] &= ~KEYBOARD_MASK_PWRBTN; -#endif - #ifndef CONFIG_KEYBOARD_MULTIPLE curr_state[KEYBOARD_COL_REFRESH] &= ~keyboard_mask_refresh; #else @@ -854,7 +864,7 @@ void keyboard_scan_init(void) /* Initialize raw state */ #ifndef CONFIG_KEYBOARD_SCAN_ADC - read_matrix(debounced_state); + read_matrix(debounced_state, true); #else read_adc_boot_keys(debounced_state); #endif |