summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2012-04-30 17:55:42 +0800
committerLouis Yung-Chieh Lo <yjlou@chromium.org>2012-05-24 13:32:35 +0800
commit29d25d807c18330c1426425e8c53af1067be7640 (patch)
tree3a5c5538b97e74433d6ab6ea189180f696ce5289 /chip
parenteb7765c0c41986e225506447de0d9f722c66e32b (diff)
downloadchrome-ec-29d25d807c18330c1426425e8c53af1067be7640.tar.gz
Keyboard scan must stop driving columns when power button is pressed.
Tristage all columns as soon as possible right after the power button is pressed. This can avoid the silego chip to reset the EC. Resume the interrupt mode after power button is released so that the deasserted columns doesn't trigger EC reset. Also change some function names for export. BUG=chrome-os-partner:7486 TEST= press g first, then power button. repeat many times. system is not rebooted. press power button first, then g. repeat many times. system is not rebooted. ESC+power is still reseting system. The long press power button still shutdowns system. Change-Id: Ie5dec20ec3d3c4ffbd4acf5a4dd7f63eec38af56
Diffstat (limited to 'chip')
-rw-r--r--chip/lm4/keyboard_scan.c41
-rw-r--r--chip/lm4/power_button.c7
2 files changed, 41 insertions, 7 deletions
diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c
index bb92ad2689..2faa2a88f6 100644
--- a/chip/lm4/keyboard_scan.c
+++ b/chip/lm4/keyboard_scan.c
@@ -63,6 +63,8 @@ enum COLUMN_INDEX {
#define KB_COLS 13
+
+static int enable_scanning = 1;
static uint8_t raw_state[KB_COLS];
static uint8_t raw_state_at_boot[KB_COLS];
static int recovery_key_pressed;
@@ -95,6 +97,8 @@ static const uint8_t actual_key_masks[4][KB_COLS] = {
static void select_column(int col)
{
if (col == COLUMN_ASSERT_ALL) {
+ if (!enable_scanning)
+ return;
LM4_GPIO_DIR(LM4_GPIO_P) = 0xff;
LM4_GPIO_DIR(LM4_GPIO_Q) |= 0x1f;
LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0;
@@ -102,7 +106,11 @@ static void select_column(int col)
} else {
LM4_GPIO_DIR(LM4_GPIO_P) = 0;
LM4_GPIO_DIR(LM4_GPIO_Q) &= ~0x1f;
- if (col < 8) {
+ /* Return after the above TRI_STATE_ALL has be run. */
+ if (!enable_scanning)
+ return;
+
+ if (col >= 0 && col < 8) {
LM4_GPIO_DIR(LM4_GPIO_P) |= 1 << col;
LM4_GPIO_DATA(LM4_GPIO_P, 1 << col) = 0;
} else if (col != COLUMN_TRI_STATE_ALL) {
@@ -232,7 +240,7 @@ static int check_keys_changed(void)
for (i = 0; i < 8; ++i) {
uint8_t prev = (raw_state[c] >> i) & 1;
uint8_t now = (r >> i) & 1;
- if (prev != now) {
+ if (prev != now && enable_scanning) {
keyboard_state_changed(i, c, now);
}
}
@@ -360,6 +368,7 @@ void keyboard_scan_task(void)
/* Enable interrupts */
task_enable_irq(KB_SCAN_ROW_IRQ);
+ enable_scanning = 1;
while (1) {
wait_for_interrupt();
@@ -367,7 +376,7 @@ void keyboard_scan_task(void)
enter_polling_mode();
/* Busy polling keyboard state. */
- while (1) {
+ while (enable_scanning) {
/* sleep for debounce. */
usleep(SCAN_LOOP_DELAY);
/* Check for keys down */
@@ -381,10 +390,10 @@ void keyboard_scan_task(void)
}
}
}
- /* TODO: (crosbug.com/p/7484) A race condition here.
- * If a key state is changed here (before interrupt is
- * enabled), it will be lost.
- */
+ /* Don't continue if the power button is not released yet. */
+ while (!enable_scanning) {
+ usleep(SCAN_LOOP_DELAY);
+ }
}
}
@@ -441,3 +450,21 @@ int keyboard_get_scan(uint8_t **buffp, int max_bytes)
{
return -1;
}
+
+
+/* The actuall implementation is controlling the enable_scanning variable,
+ * then that controls whether select_column() can pull-down columns or not.
+ */
+void keyboard_enable_scanning(int enable)
+{
+ enable_scanning = enable;
+ if (enable) {
+ /* A power button press had tri-stated all columns (see the
+ * 'else' statement below), we need a wake-up to unlock
+ * the task_wait_event() loop after wait_for_interrupt(). */
+ task_wake(TASK_ID_KEYSCAN);
+ } else {
+ select_column(COLUMN_TRI_STATE_ALL);
+ keyboard_clear_underlying_buffer();
+ }
+}
diff --git a/chip/lm4/power_button.c b/chip/lm4/power_button.c
index 66505d3e59..66fc7b7589 100644
--- a/chip/lm4/power_button.c
+++ b/chip/lm4/power_button.c
@@ -200,6 +200,7 @@ static void power_button_released(uint64_t tnow)
tnext_state = tnow;
*memmap_switches &= ~EC_SWITCH_POWER_BUTTON_PRESSED;
keyboard_set_power_button(0);
+ keyboard_enable_scanning(1);
}
@@ -528,6 +529,12 @@ void power_button_interrupt(enum gpio_signal signal)
case GPIO_POWER_BUTTONn:
/* Reset power button debounce time */
tdebounce_pwr = get_time().val + PWRBTN_DEBOUNCE_US;
+ if (get_power_button_pressed()) {
+ /* We want to disable the matrix scan as soon as
+ * possible to reduce the risk of false-reboot triggered
+ * by those keys on the same column with ESC key. */
+ keyboard_enable_scanning(0);
+ }
break;
case GPIO_PCH_BKLTEN:
update_backlight();