summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-03-20 13:47:35 -0700
committerChromeBot <chrome-bot@google.com>2013-03-22 11:24:28 -0700
commit743c05f01f8f2b19dbf565bee645076fff75c42d (patch)
treecbad9ab036c32b3b4d47ad2ad4ded17f18fb02b6
parentcdb08e12217367f0ac8c6ce0dc1df2e27f80563e (diff)
downloadchrome-ec-743c05f01f8f2b19dbf565bee645076fff75c42d.tar.gz
Add keyboard_raw interface
This is the low-level platform-dependent interface to drive keyboard columns, read rows, and handle keyboard interrupts. Both lm4 and stm32 had something like this before, but the interfaces weren't fully explicit or compatible. BUG=chrome-os-partner:18360 BRANCH=none TEST=manual - Build all platforms. - Boot system and test typing on keyboard. - Hold power+refresh+esc to test boot key detection; should go to recovery. Change-Id: Ie3bcc1d066a4da5204f0e236daeb52c4064a6213 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/46156
-rw-r--r--board/daisy/board.c18
-rw-r--r--board/mccroskey/board.c18
-rw-r--r--board/snow/board.c18
-rw-r--r--board/spring/board.c18
-rw-r--r--chip/lm4/build.mk2
-rw-r--r--chip/lm4/keyboard_raw.c112
-rw-r--r--chip/lm4/keyboard_scan.c63
-rw-r--r--chip/lm4/keyboard_scan_stub.c115
-rw-r--r--chip/lm4/keyboard_scan_stub.h43
-rw-r--r--chip/lm4/mock_keyboard_scan_stub.c55
-rw-r--r--chip/stm32/build.mk2
-rw-r--r--chip/stm32/keyboard_raw.c135
-rw-r--r--chip/stm32/keyboard_scan.c179
-rw-r--r--include/keyboard_raw.h74
-rw-r--r--include/keyboard_scan.h12
15 files changed, 425 insertions, 439 deletions
diff --git a/board/daisy/board.c b/board/daisy/board.c
index 0a7b4bf54e..7052ec68fc 100644
--- a/board/daisy/board.c
+++ b/board/daisy/board.c
@@ -10,7 +10,7 @@
#include "gaia_power.h"
#include "gpio.h"
#include "i2c.h"
-#include "keyboard_scan.h"
+#include "keyboard_raw.h"
#include "pmu_tpschrome.h"
#include "registers.h"
#include "spi.h"
@@ -44,21 +44,21 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"LID_OPEN", GPIO_C, (1<<13), GPIO_INT_RISING, gaia_lid_event},
{"SUSPEND_L", GPIO_A, (1<<7), GPIO_INT_BOTH, gaia_suspend_event},
{"KB_IN00", GPIO_C, (1<<8), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN01", GPIO_C, (1<<9), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN02", GPIO_C, (1<<10), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN03", GPIO_C, (1<<11), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN04", GPIO_C, (1<<12), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN05", GPIO_C, (1<<14), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN06", GPIO_C, (1<<15), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN07", GPIO_D, (1<<2), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
/* Other inputs */
{"AC_PWRBTN_L", GPIO_A, (1<<0), GPIO_INT_BOTH, NULL},
{"SPI1_NSS", GPIO_A, (1<<4), GPIO_PULL_UP, NULL},
diff --git a/board/mccroskey/board.c b/board/mccroskey/board.c
index 1e4d9cfa76..ba18740b24 100644
--- a/board/mccroskey/board.c
+++ b/board/mccroskey/board.c
@@ -11,7 +11,7 @@
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
-#include "keyboard_scan.h"
+#include "keyboard_raw.h"
#include "registers.h"
#include "spi.h"
#include "task.h"
@@ -30,21 +30,21 @@ static void kbd_power_on(enum gpio_signal signal);
const struct gpio_info gpio_list[GPIO_COUNT] = {
/* Inputs with interrupt handlers are first for efficiency */
{"KB_IN00", GPIO_B, (1<<8), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN01", GPIO_B, (1<<9), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN02", GPIO_B, (1<<10), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN03", GPIO_B, (1<<11), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN04", GPIO_B, (1<<12), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN05", GPIO_B, (1<<13), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN06", GPIO_B, (1<<14), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN07", GPIO_B, (1<<15), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KBD_PWR_BUTTON", GPIO_B, (1<<2), GPIO_INPUT, kbd_power_on},
{"OMZO_RDY_L", GPIO_A, (1<<0), GPIO_INPUT, NULL}, /* PA0_WKUP */
diff --git a/board/snow/board.c b/board/snow/board.c
index cebdcab1fe..a70a112b79 100644
--- a/board/snow/board.c
+++ b/board/snow/board.c
@@ -13,7 +13,7 @@
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
-#include "keyboard_scan.h"
+#include "keyboard_raw.h"
#include "pmu_tpschrome.h"
#include "power_led.h"
#include "registers.h"
@@ -41,21 +41,21 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"SUSPEND_L", GPIO_A, (1<<7), INT_BOTH_FLOATING, gaia_suspend_event},
{"WP_L", GPIO_B, (1<<4), GPIO_INPUT, NULL},
{"KB_IN00", GPIO_C, (1<<8), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN01", GPIO_C, (1<<9), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN02", GPIO_C, (1<<10), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN03", GPIO_C, (1<<11), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN04", GPIO_C, (1<<12), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN05", GPIO_C, (1<<14), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN06", GPIO_C, (1<<15), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN07", GPIO_D, (1<<2), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
/* Other inputs */
{"AC_PWRBTN_L", GPIO_A, (1<<0), GPIO_INT_BOTH, NULL},
{"SPI1_NSS", GPIO_A, (1<<4), GPIO_DEFAULT, spi_event},
diff --git a/board/spring/board.c b/board/spring/board.c
index e4d361a8ae..dd597a1a08 100644
--- a/board/spring/board.c
+++ b/board/spring/board.c
@@ -15,7 +15,7 @@
#include "hooks.h"
#include "host_command.h"
#include "i2c.h"
-#include "keyboard_scan.h"
+#include "keyboard_raw.h"
#include "pmu_tpschrome.h"
#include "registers.h"
#include "stm32_adc.h"
@@ -43,21 +43,21 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"SUSPEND_L", GPIO_A, (1<<7), INT_BOTH_FLOATING, gaia_suspend_event},
{"WP_L", GPIO_A, (1<<13), GPIO_INPUT, NULL},
{"KB_IN00", GPIO_C, (1<<8), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN01", GPIO_C, (1<<9), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN02", GPIO_C, (1<<10), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN03", GPIO_C, (1<<11), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN04", GPIO_C, (1<<12), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN05", GPIO_C, (1<<14), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN06", GPIO_C, (1<<15), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"KB_IN07", GPIO_D, (1<<2), GPIO_KB_INPUT,
- keyboard_scan_interrupt},
+ keyboard_raw_gpio_interrupt},
{"USB_CHG_INT", GPIO_A, (1<<6), GPIO_INT_FALLING,
usb_charge_interrupt},
/* Other inputs */
diff --git a/chip/lm4/build.mk b/chip/lm4/build.mk
index 83a97b3ba5..c3ab2bafa5 100644
--- a/chip/lm4/build.mk
+++ b/chip/lm4/build.mk
@@ -22,6 +22,6 @@ chip-$(CONFIG_ONEWIRE)+=onewire.o
chip-$(CONFIG_PECI)+=peci.o
chip-$(CONFIG_PWM)+=pwm.o
chip-$(CONFIG_SPI)+=spi.o
-chip-$(CONFIG_TASK_KEYSCAN)+=keyboard_scan.o keyboard_scan_stub.o
+chip-$(CONFIG_TASK_KEYSCAN)+=keyboard_scan.o keyboard_raw.o
chip-$(CONFIG_TASK_SWITCH)+=switch.o
chip-$(CONFIG_WATCHDOG)+=watchdog.o
diff --git a/chip/lm4/keyboard_raw.c b/chip/lm4/keyboard_raw.c
new file mode 100644
index 0000000000..0db2766773
--- /dev/null
+++ b/chip/lm4/keyboard_raw.c
@@ -0,0 +1,112 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Functions needed by keyboard scanner module for Chrome EC */
+
+#include "common.h"
+#include "keyboard_raw.h"
+#include "keyboard_scan.h"
+#include "registers.h"
+#include "task.h"
+
+void keyboard_raw_init(void)
+{
+ /* Ensure top-level interrupt is disabled */
+ keyboard_raw_enable_interrupt(0);
+
+ /*
+ * Set column outputs as open-drain; we either pull them low or let
+ * them float high.
+ */
+ LM4_GPIO_AFSEL(LM4_GPIO_P) = 0; /* KSO[7:0] */
+ LM4_GPIO_AFSEL(LM4_GPIO_Q) &= ~0x1f; /* KSO[12:8] */
+ LM4_GPIO_DEN(LM4_GPIO_P) = 0xff;
+ LM4_GPIO_DEN(LM4_GPIO_Q) |= 0x1f;
+ LM4_GPIO_DIR(LM4_GPIO_P) = 0xff;
+ LM4_GPIO_DIR(LM4_GPIO_Q) |= 0x1f;
+ LM4_GPIO_ODR(LM4_GPIO_P) = 0xff;
+ LM4_GPIO_ODR(LM4_GPIO_Q) |= 0x1f;
+
+ /* Set row inputs with pull-up */
+ LM4_GPIO_AFSEL(KB_SCAN_ROW_GPIO) &= 0xff;
+ LM4_GPIO_DEN(KB_SCAN_ROW_GPIO) |= 0xff;
+ LM4_GPIO_DIR(KB_SCAN_ROW_GPIO) = 0;
+ LM4_GPIO_PUR(KB_SCAN_ROW_GPIO) = 0xff;
+
+ /* Edge-sensitive on both edges. */
+ LM4_GPIO_IS(KB_SCAN_ROW_GPIO) = 0;
+ LM4_GPIO_IBE(KB_SCAN_ROW_GPIO) = 0xff;
+
+ /*
+ * Enable interrupts for the inputs. The top-level interrupt is still
+ * masked off, so this won't trigger interrupts yet.
+ */
+ LM4_GPIO_IM(KB_SCAN_ROW_GPIO) = 0xff;
+}
+
+void keyboard_raw_task_start(void)
+{
+ task_enable_irq(KB_SCAN_ROW_IRQ);
+}
+
+void keyboard_raw_drive_column(int col)
+{
+ if (col == KEYBOARD_COLUMN_NONE) {
+ /* Tri-state all outputs */
+ LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0xff;
+ LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0x1f;
+ } else if (col == KEYBOARD_COLUMN_ALL) {
+ /* Assert all outputs */
+ LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0;
+ LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0;
+ } else {
+ /* Assert a single output */
+ LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0xff;
+ LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0x1f;
+ if (col < 8)
+ LM4_GPIO_DATA(LM4_GPIO_P, 1 << col) = 0;
+ else
+ LM4_GPIO_DATA(LM4_GPIO_Q, 1 << (col - 8)) = 0;
+ }
+}
+
+int keyboard_raw_read_rows(void)
+{
+ /* Bits are active-low, so invert returned levels */
+ return LM4_GPIO_DATA(KB_SCAN_ROW_GPIO, 0xff) ^ 0xff;
+}
+
+void keyboard_raw_enable_interrupt(int enable)
+{
+ if (enable) {
+ /*
+ * Clear pending interrupts before enabling them, because the
+ * raw interrupt status may have been tripped by keyboard
+ * scanning or, if a key is already pressed, by driving all the
+ * outputs.
+ *
+ * We won't lose keyboard events because the scanning task will
+ * explicitly check the raw row state before waiting for an
+ * interrupt. If a key is pressed, the task won't wait.
+ */
+ LM4_GPIO_ICR(KB_SCAN_ROW_GPIO) = 0xff;
+ LM4_GPIO_IM(KB_SCAN_ROW_GPIO) = 0xff;
+ } else {
+ LM4_GPIO_IM(KB_SCAN_ROW_GPIO) = 0;
+ }
+}
+
+/**
+ * Interrupt handler for the entire GPIO bank of keyboard rows.
+ */
+static void keyboard_raw_interrupt(void)
+{
+ /* Clear all pending keyboard interrupts */
+ LM4_GPIO_ICR(KB_SCAN_ROW_GPIO) = 0xff;
+
+ /* Wake the scan task */
+ task_wake(TASK_ID_KEYSCAN);
+}
+DECLARE_IRQ(KB_SCAN_ROW_IRQ, keyboard_raw_interrupt, 3);
diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c
index fd2f6486b9..0c56738a05 100644
--- a/chip/lm4/keyboard_scan.c
+++ b/chip/lm4/keyboard_scan.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -10,9 +10,8 @@
#include "console.h"
#include "host_command.h"
#include "keyboard.h"
+#include "keyboard_raw.h"
#include "keyboard_scan.h"
-#include "keyboard_scan_stub.h"
-#include "registers.h"
#include "switch.h"
#include "system.h"
#include "task.h"
@@ -83,29 +82,29 @@ static int print_state_changes;
#define MASK_INDEX_KEY_H 6
#define MASK_VALUE_KEY_H 0x02
+static int enable_scanning = 1; /* Must init to 1 for scanning at boot */
+
static void enable_interrupt(void)
{
CPRINTF("[%T KB wait]\n");
- /* Assert all outputs would trigger un-wanted interrupts.
- * Clear them before enable interrupt. */
- lm4_select_column(COLUMN_ASSERT_ALL);
- lm4_clear_matrix_interrupt_status();
+ if (enable_scanning)
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_ALL);
- lm4_enable_matrix_interrupt();
+ keyboard_raw_enable_interrupt(1);
}
static void enter_polling_mode(void)
{
CPRINTF("[%T KB poll]\n");
- lm4_disable_matrix_interrupt();
- lm4_select_column(COLUMN_TRI_STATE_ALL);
+ keyboard_raw_enable_interrupt(0);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
}
static int is_scanning_enabled(void)
{
/* Scan only if enabled AND lid is open. */
- return lm4_get_scanning_enabled() && switch_get_lid_open();
+ return enable_scanning && switch_get_lid_open();
}
/**
@@ -125,14 +124,16 @@ static int read_matrix(uint8_t *state)
int pressed = 0;
for (c = 0; c < KB_COLS; c++) {
+ /* Stop if scanning becomes disabled */
+ if (!enable_scanning)
+ break;
+
/* Select column, then wait a bit for it to settle */
- lm4_select_column(c);
+ keyboard_raw_drive_column(c);
udelay(COLUMN_CHARGE_US);
/* Read the row state */
- r = lm4_read_raw_row_state();
- /* Invert it so 0=not pressed, 1=pressed */
- r ^= 0xff;
+ r = keyboard_raw_read_rows();
/* Mask off keys that don't exist so they never show
* as pressed */
r &= actual_key_mask[c];
@@ -141,7 +142,7 @@ static int read_matrix(uint8_t *state)
pressed |= r;
}
- lm4_select_column(COLUMN_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
return pressed ? 1 : 0;
}
@@ -413,10 +414,10 @@ enum boot_key keyboard_scan_get_boot_key(void)
void keyboard_scan_init(void)
{
/* Configure GPIO */
- lm4_configure_keyboard_gpio();
+ keyboard_raw_init();
/* Tri-state the columns */
- lm4_select_column(COLUMN_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
/* Initialize raw state */
read_matrix(debounced_state);
@@ -436,8 +437,7 @@ void keyboard_scan_task(void)
print_state(debounced_state, "init state");
- /* Enable interrupts */
- task_enable_irq(KB_SCAN_ROW_IRQ);
+ keyboard_raw_task_start();
while (1) {
/* Enable all outputs */
@@ -451,8 +451,7 @@ void keyboard_scan_task(void)
* user pressing a key and enable_interrupt()
* starting to pay attention to edges.
*/
- if ((lm4_read_raw_row_state() == 0xff) ||
- !is_scanning_enabled())
+ if (!keyboard_raw_read_rows() || !is_scanning_enabled())
task_wait_event(-1);
} while (!is_scanning_enabled());
@@ -475,22 +474,10 @@ void keyboard_scan_task(void)
}
}
-static void matrix_interrupt(void)
-{
- uint32_t ris = lm4_clear_matrix_interrupt_status();
-
- if (ris)
- task_wake(TASK_ID_KEYSCAN);
-}
-DECLARE_IRQ(KB_SCAN_ROW_IRQ, matrix_interrupt, 3);
-
-/*
- * The actual implementation is controlling the enable_scanning variable, then
- * that controls whether lm4_select_column() can pull-down columns or not.
- */
void keyboard_enable_scanning(int enable)
{
- lm4_set_scanning_enabled(enable);
+ enable_scanning = enable;
+
if (enable) {
/*
* A power button press had tri-stated all columns (see the
@@ -499,13 +486,13 @@ void keyboard_enable_scanning(int enable)
*/
task_wake(TASK_ID_KEYSCAN);
} else {
- lm4_select_column(COLUMN_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
keyboard_clear_underlying_buffer();
}
}
/*****************************************************************************/
-/* Console commands*/
+/* Console commands */
static int command_ksstate(int argc, char **argv)
{
diff --git a/chip/lm4/keyboard_scan_stub.c b/chip/lm4/keyboard_scan_stub.c
deleted file mode 100644
index 01d1aca8e2..0000000000
--- a/chip/lm4/keyboard_scan_stub.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* Functions needed by keyboard scanner module for Chrome EC */
-
-#include "board.h"
-#include "keyboard_scan.h"
-#include "keyboard_scan_stub.h"
-#include "registers.h"
-
-
-/* Notes:
- *
- * Link proto0 board:
- *
- * Columns (outputs):
- * KSO0 - KSO7 = PP0:7
- * KSO8 - KSO12 = PQ0:4
- *
- * Rows (inputs):
- * KSI0 - KSI7 = PN0:7
- *
- * Other:
- * PWR_BTN# = PK7 (handled by gpio module)
- */
-
-
-static int enable_scanning = 1; /* Must init to 1 for scanning at boot */
-
-
-void lm4_set_scanning_enabled(int enabled)
-{
- enable_scanning = enabled;
-}
-
-
-int lm4_get_scanning_enabled(void)
-{
- return enable_scanning;
-}
-
-
-void lm4_select_column(int col)
-{
- if (col == COLUMN_TRI_STATE_ALL || !enable_scanning) {
- /* Tri-state all outputs */
- LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0xff;
- LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0x1f;
- } else if (col == COLUMN_ASSERT_ALL) {
- /* Assert all outputs */
- LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0;
- LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0;
- } else {
- /* Assert a single output */
- LM4_GPIO_DATA(LM4_GPIO_P, 0xff) = 0xff;
- LM4_GPIO_DATA(LM4_GPIO_Q, 0x1f) = 0x1f;
- if (col < 8)
- LM4_GPIO_DATA(LM4_GPIO_P, 1 << col) = 0;
- else
- LM4_GPIO_DATA(LM4_GPIO_Q, 1 << (col - 8)) = 0;
- }
-}
-
-
-uint32_t lm4_clear_matrix_interrupt_status(void)
-{
- uint32_t ris = LM4_GPIO_RIS(KB_SCAN_ROW_GPIO);
- LM4_GPIO_ICR(KB_SCAN_ROW_GPIO) = ris;
-
- return ris;
-}
-
-
-void lm4_enable_matrix_interrupt(void)
-{
- LM4_GPIO_IM(KB_SCAN_ROW_GPIO) = 0xff; /* 1: enable interrupt */
-}
-
-
-void lm4_disable_matrix_interrupt(void)
-{
- LM4_GPIO_IM(KB_SCAN_ROW_GPIO) = 0; /* 0: disable interrupt */
-}
-
-
-int lm4_read_raw_row_state(void)
-{
- return LM4_GPIO_DATA(KB_SCAN_ROW_GPIO, 0xff);
-}
-
-
-void lm4_configure_keyboard_gpio(void)
-{
- /* Set column outputs as open-drain; we either pull them low or let
- * them float high. */
- LM4_GPIO_AFSEL(LM4_GPIO_P) = 0; /* KSO[7:0] */
- LM4_GPIO_AFSEL(LM4_GPIO_Q) &= ~0x1f; /* KSO[12:8] */
- LM4_GPIO_DEN(LM4_GPIO_P) = 0xff;
- LM4_GPIO_DEN(LM4_GPIO_Q) |= 0x1f;
- LM4_GPIO_DIR(LM4_GPIO_P) = 0xff;
- LM4_GPIO_DIR(LM4_GPIO_Q) |= 0x1f;
- LM4_GPIO_ODR(LM4_GPIO_P) = 0xff;
- LM4_GPIO_ODR(LM4_GPIO_Q) |= 0x1f;
-
- /* Set row inputs with pull-up */
- LM4_GPIO_AFSEL(KB_SCAN_ROW_GPIO) &= 0xff;
- LM4_GPIO_DEN(KB_SCAN_ROW_GPIO) |= 0xff;
- LM4_GPIO_DIR(KB_SCAN_ROW_GPIO) = 0;
- LM4_GPIO_PUR(KB_SCAN_ROW_GPIO) = 0xff;
- /* Edge-sensitive on both edges. Don't enable interrupts yet. */
- LM4_GPIO_IS(KB_SCAN_ROW_GPIO) = 0;
- LM4_GPIO_IBE(KB_SCAN_ROW_GPIO) = 0xff;
-}
diff --git a/chip/lm4/keyboard_scan_stub.h b/chip/lm4/keyboard_scan_stub.h
deleted file mode 100644
index 54ab598180..0000000000
--- a/chip/lm4/keyboard_scan_stub.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Funcitons needed by keyboard scanner module.
- * Abstracted from keyboard_scan.c for stub.
- */
-
-#ifndef __CROS_EC_KEYBOARD_SCAN_STUB_H
-#define __CROS_EC_KEYBOARD_SCAN_STUB_H
-
-/* used for select_column() */
-enum COLUMN_INDEX {
- COLUMN_ASSERT_ALL = -2,
- COLUMN_TRI_STATE_ALL = -1,
- /* 0 ~ 12 for the corresponding column */
-};
-
-/* Set keyboard scanning to enabled/disabled */
-void lm4_set_scanning_enabled(int enabled);
-
-/* Get keyboard scanning enabled/disabled */
-int lm4_get_scanning_enabled(void);
-
-/* Drive the specified column low; other columns are tristated */
-void lm4_select_column(int col);
-
-/* Clear current interrupt status */
-uint32_t lm4_clear_matrix_interrupt_status(void);
-
-/* Enable interrupt from keyboard matrix */
-void lm4_enable_matrix_interrupt(void);
-
-/* Disable interrupt from keyboard matrix */
-void lm4_disable_matrix_interrupt(void);
-
-/* Read raw row state */
-int lm4_read_raw_row_state(void);
-
-/* Configure keyboard matrix GPIO */
-void lm4_configure_keyboard_gpio(void);
-
-#endif /* __CROS_EC_KEYBOARD_SCAN_STUB_H */
diff --git a/chip/lm4/mock_keyboard_scan_stub.c b/chip/lm4/mock_keyboard_scan_stub.c
index 743c20aef4..0c9ecff2f5 100644
--- a/chip/lm4/mock_keyboard_scan_stub.c
+++ b/chip/lm4/mock_keyboard_scan_stub.c
@@ -1,14 +1,14 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Mock functions for keyboard scanner module for Chrome EC */
-#include "board.h"
+#include "common.h"
#include "console.h"
+#include "keyboard_raw.h"
#include "keyboard_scan.h"
-#include "keyboard_scan_stub.h"
#include "task.h"
#include "uart.h"
#include "util.h"
@@ -20,63 +20,36 @@ static int selected_column = -1;
static int interrupt_enabled = 0;
static uint8_t matrix_status[MOCK_COLUMN_COUNT];
-
-void lm4_set_scanning_enabled(int enabled)
+void keyboard_raw_init(void)
{
- enable_scanning = enabled;
- uart_printf("%s keyboard scanning\n", enabled ? "Enable" : "Disable");
+ /* Init matrix status to release all */
+ int i;
+ for (i = 0; i < MOCK_COLUMN_COUNT; ++i)
+ matrix_status[i] = 0xff;
}
-
-int lm4_get_scanning_enabled(void)
+void keyboard_raw_task_start(void)
{
- return enable_scanning;
}
-
-void lm4_select_column(int col)
+void keyboard_raw_drive_column(int col)
{
selected_column = col;
}
-
-uint32_t lm4_clear_matrix_interrupt_status(void)
-{
- /* Not implemented */
- return 0;
-}
-
-
-void lm4_enable_matrix_interrupt(void)
-{
- interrupt_enabled = 1;
-}
-
-
-void lm4_disable_matrix_interrupt(void)
-{
- interrupt_enabled = 0;
-}
-
-
-int lm4_read_raw_row_state(void)
+int keyboard_raw_read_rows(void)
{
if (selected_column >= 0)
- return matrix_status[selected_column];
+ return matrix_status[selected_column] ^ 0xff;
else
return 0;
}
-
-void lm4_configure_keyboard_gpio(void)
+void keyboard_raw_enable_interrupt(int enable)
{
- /* Init matrix status to release all */
- int i;
- for (i = 0; i < MOCK_COLUMN_COUNT; ++i)
- matrix_status[i] = 0xff;
+ interrupt_enabled = enable;
}
-
static int command_mock_matrix(int argc, char **argv)
{
int r, c, p;
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index 36496ba411..0125554a72 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -14,7 +14,7 @@ chip-y+=jtag-$(CHIP_VARIANT).o clock-$(CHIP_VARIANT).o gpio-$(CHIP_VARIANT).o
chip-$(CONFIG_SPI)+=spi.o
chip-$(CONFIG_I2C)+=i2c.o
chip-$(CONFIG_WATCHDOG)+=watchdog.o
-chip-$(CONFIG_TASK_KEYSCAN)+=keyboard_scan.o
+chip-$(CONFIG_TASK_KEYSCAN)+=keyboard_scan.o keyboard_raw.o
chip-$(CONFIG_TASK_POWERLED)+=power_led.o
chip-$(CONFIG_FLASH)+=flash-$(CHIP_VARIANT).o
chip-$(CONFIG_ADC)+=adc.o
diff --git a/chip/stm32/keyboard_raw.c b/chip/stm32/keyboard_raw.c
new file mode 100644
index 0000000000..e6a3dc65eb
--- /dev/null
+++ b/chip/stm32/keyboard_raw.c
@@ -0,0 +1,135 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Raw keyboard I/O layer for STM32
+ *
+ * To make this code portable, we rely heavily on looping over the keyboard
+ * input and output entries in the board's gpio_list[]. Each set of inputs or
+ * outputs must be listed in consecutive, increasing order so that scan loops
+ * can iterate beginning at KB_IN00 or KB_OUT00 for however many GPIOs are
+ * utilized (KB_INPUTS or KB_OUTPUTS).
+ */
+
+#include "gpio.h"
+#include "keyboard_raw.h"
+#include "keyboard_scan.h"
+#include "registers.h"
+#include "task.h"
+#include "util.h"
+
+/* Mask of external interrupts on input lines */
+static unsigned int irq_mask;
+
+static const uint32_t kb_out_ports[] = { KB_OUT_PORT_LIST };
+
+static void set_irq_mask(void)
+{
+ int i;
+
+ for (i = GPIO_KB_IN00; i < GPIO_KB_IN00 + KB_INPUTS; i++)
+ irq_mask |= gpio_list[i].mask;
+}
+
+void keyboard_raw_init(void)
+{
+ /* Determine EXTI_PR mask to use for the board */
+ set_irq_mask();
+
+ /* Ensure interrupts are disabled in EXTI_PR */
+ keyboard_raw_enable_interrupt(0);
+}
+
+void keyboard_raw_task_start(void)
+{
+ /* Enable interrupts for keyboard matrix inputs */
+ gpio_enable_interrupt(GPIO_KB_IN00);
+ gpio_enable_interrupt(GPIO_KB_IN01);
+ gpio_enable_interrupt(GPIO_KB_IN02);
+ gpio_enable_interrupt(GPIO_KB_IN03);
+ gpio_enable_interrupt(GPIO_KB_IN04);
+ gpio_enable_interrupt(GPIO_KB_IN05);
+ gpio_enable_interrupt(GPIO_KB_IN06);
+ gpio_enable_interrupt(GPIO_KB_IN07);
+}
+
+void keyboard_raw_drive_column(int out)
+{
+ int i, done = 0;
+
+ for (i = 0; i < ARRAY_SIZE(kb_out_ports); i++) {
+ uint32_t bsrr = 0;
+ int j;
+
+ for (j = GPIO_KB_OUT00; j <= GPIO_KB_OUT12; j++) {
+ if (gpio_list[j].port != kb_out_ports[i])
+ continue;
+
+ if (out == KEYBOARD_COLUMN_ALL) {
+ /* drive low (clear bit) */
+ bsrr |= gpio_list[j].mask << 16;
+ } else if (out == KEYBOARD_COLUMN_NONE) {
+ /* put output in hi-Z state (set bit) */
+ bsrr |= gpio_list[j].mask;
+ } else if (j - GPIO_KB_OUT00 == out) {
+ /*
+ * Drive specified output low, others => hi-Z.
+ *
+ * To avoid conflict, tri-state all outputs
+ * first, then assert specified output.
+ */
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
+ bsrr |= gpio_list[j].mask << 16;
+ done = 1;
+ break;
+ }
+ }
+
+ if (bsrr)
+ STM32_GPIO_BSRR_OFF(kb_out_ports[i]) = bsrr;
+
+ if (done)
+ break;
+ }
+}
+
+int keyboard_raw_read_rows(void)
+{
+ int i;
+ unsigned int port, prev_port = 0;
+ int state = 0;
+ uint16_t port_val = 0;
+
+ for (i = 0; i < KB_INPUTS; i++) {
+ port = gpio_list[GPIO_KB_IN00 + i].port;
+ if (port != prev_port) {
+ port_val = STM32_GPIO_IDR_OFF(port);
+ prev_port = port;
+ }
+
+ if (port_val & gpio_list[GPIO_KB_IN00 + i].mask)
+ state |= 1 << i;
+ }
+
+ /* Invert it so 0=not pressed, 1=pressed */
+ return state ^ 0xff;
+}
+
+void keyboard_raw_enable_interrupt(int enable)
+{
+ if (enable) {
+ /*
+ * Assert all outputs would trigger un-wanted interrupts.
+ * Clear them before enable interrupt.
+ */
+ STM32_EXTI_PR |= irq_mask;
+ STM32_EXTI_IMR |= irq_mask; /* 1: unmask interrupt */
+ } else {
+ STM32_EXTI_IMR &= ~irq_mask; /* 0: mask interrupts */
+ }
+}
+
+void keyboard_raw_gpio_interrupt(enum gpio_signal signal)
+{
+ task_wake(TASK_ID_KEYSCAN);
+}
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c
index c8ca6b0698..7839a5d1d7 100644
--- a/chip/stm32/keyboard_scan.c
+++ b/chip/stm32/keyboard_scan.c
@@ -1,16 +1,8 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
- */
-
-/*
- * Keyboard scanner module for Chrome EC
*
- * To make this code portable, we rely heavily on looping over the keyboard
- * input and output entries in the board's gpio_list[]. Each set of inputs or
- * outputs must be listed in consecutive, increasing order so that scan loops
- * can iterate beginning at KB_IN00 or KB_OUT00 for however many GPIOs are
- * utilized (KB_INPUTS or KB_OUTPUTS).
+ * Keyboard scanner module for Chrome EC STM32
*/
#include "atomic.h"
@@ -19,9 +11,9 @@
#include "gpio.h"
#include "host_command.h"
#include "keyboard.h"
+#include "keyboard_raw.h"
#include "keyboard_scan.h"
#include "keyboard_test.h"
-#include "registers.h"
#include "system.h"
#include "task.h"
#include "timer.h"
@@ -31,16 +23,6 @@
#define CPUTS(outstr) cputs(CC_KEYSCAN, outstr)
#define CPRINTF(format, args...) cprintf(CC_KEYSCAN, format, ## args)
-/* used for assert_output() */
-enum {
- OUTPUT_ASSERT_ALL = -2,
- OUTPUT_TRI_STATE_ALL = -1,
- /* 0 ~ 12 for the corresponding output */
-};
-
-/* Mask of external interrupts on input lines */
-static unsigned int irq_mask;
-
#define SCAN_TIME_COUNT 32
static struct mutex scanning_enabled;
@@ -69,7 +51,7 @@ static uint8_t scan_edge_index[KB_OUTPUTS][KB_INPUTS];
#define MASK_INDEX_LEFT_ALT 10
#define MASK_VALUE_LEFT_ALT 0x40
-static const uint32_t kb_out_ports[] = { KB_OUT_PORT_LIST };
+/*****************************************************************************/
/* Provide a default function in case the board doesn't have one */
void __board_keyboard_suppress_noise(void)
@@ -171,45 +153,6 @@ static int kb_fifo_remove(uint8_t *buffp)
return EC_SUCCESS;
}
-static void assert_output(int out)
-{
- int i, done = 0;
-
- for (i = 0; i < ARRAY_SIZE(kb_out_ports); i++) {
- uint32_t bsrr = 0;
- int j;
-
- for (j = GPIO_KB_OUT00; j <= GPIO_KB_OUT12; j++) {
- if (gpio_list[j].port != kb_out_ports[i])
- continue;
-
- if (out == OUTPUT_ASSERT_ALL) {
- /* drive low (clear bit) */
- bsrr |= gpio_list[j].mask << 16;
- } else if (out == OUTPUT_TRI_STATE_ALL) {
- /* put output in hi-Z state (set bit) */
- bsrr |= gpio_list[j].mask;
- } else {
- /* drive specified output low, others => hi-Z */
- if (j - GPIO_KB_OUT00 == out) {
- /* to avoid conflict, tri-state all
- * outputs first, then assert output */
- assert_output(OUTPUT_TRI_STATE_ALL);
- bsrr |= gpio_list[j].mask << 16;
- done = 1;
- break;
- }
- }
- }
-
- if (bsrr)
- STM32_GPIO_BSRR_OFF(kb_out_ports[i]) = bsrr;
-
- if (done)
- break;
- }
-}
-
/**
* Assert host keyboard interrupt line.
*/
@@ -219,28 +162,6 @@ static void set_host_interrupt(int active)
gpio_set_level(GPIO_EC_INT, !active);
}
-/* Set up outputs so that we will get an interrupt when any key changed */
-void setup_interrupts(void)
-{
- uint32_t pr_before, pr_after;
-
- /* Assert all outputs would trigger un-wanted interrupts.
- * Clear them before enable interrupt. */
- pr_before = STM32_EXTI_PR;
- assert_output(OUTPUT_ASSERT_ALL);
- pr_after = STM32_EXTI_PR;
- STM32_EXTI_PR |= ((pr_after & ~pr_before) & irq_mask);
-
- STM32_EXTI_IMR |= irq_mask; /* 1: unmask interrupt */
-}
-
-
-void enter_polling_mode(void)
-{
- STM32_EXTI_IMR &= ~irq_mask; /* 0: mask interrupts */
- assert_output(OUTPUT_TRI_STATE_ALL);
-}
-
/**
* Check special runtime key combinations.
*
@@ -289,38 +210,6 @@ static void print_state(const uint8_t *state, const char *msg)
}
/**
- * Read the raw input state for the currently selected output
- *
- * It is assumed that the output is already selected by the scanning
- * hardware. The output number is only used by test code.
- *
- * @return input state, one bit for each input
- */
-static uint8_t read_raw_input_state(void)
-{
- int i;
- unsigned int port, prev_port = 0;
- uint8_t state = 0;
- uint16_t port_val = 0;
-
- for (i = 0; i < KB_INPUTS; i++) {
- port = gpio_list[GPIO_KB_IN00 + i].port;
- if (port != prev_port) {
- port_val = STM32_GPIO_IDR_OFF(port);
- prev_port = port;
- }
-
- if (port_val & gpio_list[GPIO_KB_IN00 + i].mask)
- state |= 1 << i;
- }
-
- /* Invert it so 0=not pressed, 1=pressed */
- state ^= 0xff;
-
- return state;
-}
-
-/**
* Read the raw keyboard matrix state.
*
* Used in pre-init, so must not make task-switching-dependent calls; udelay()
@@ -338,10 +227,10 @@ static int read_matrix(uint8_t *state)
for (c = 0; c < KB_OUTPUTS; c++) {
/* Assert output, then wait a bit for it to settle */
- assert_output(c);
+ keyboard_raw_drive_column(c);
udelay(config.output_settle_us);
- r = read_raw_input_state();
+ r = keyboard_raw_read_rows();
#ifdef CONFIG_KEYBOARD_TEST
/* Use simulated keyscan sequence instead if testing active */
@@ -357,7 +246,7 @@ static int read_matrix(uint8_t *state)
state[c] = r;
pressed |= r;
}
- assert_output(OUTPUT_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
return pressed ? 1 : 0;
}
@@ -499,11 +388,12 @@ static int check_recovery_key(const uint8_t *state)
return 1;
}
-
void keyboard_scan_init(void)
{
+ keyboard_raw_init();
+
/* Tri-state (put into Hi-Z) the outputs */
- assert_output(OUTPUT_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
/* Initialize raw state */
read_matrix(debounced_state);
@@ -520,7 +410,8 @@ static void scan_keyboard(void)
int keys_changed = 1;
mutex_lock(&scanning_enabled);
- setup_interrupts();
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_ALL);
+ keyboard_raw_enable_interrupt(1);
mutex_unlock(&scanning_enabled);
/*
@@ -528,7 +419,7 @@ static void scan_keyboard(void)
* re-start immediatly polling instead of waiting
* for the next interrupt.
*/
- if (!read_raw_input_state()) {
+ if (!keyboard_raw_read_rows()) {
#ifdef CONFIG_KEYBOARD_TEST
task_wait_event(keyscan_seq_next_event_delay());
#else
@@ -536,7 +427,8 @@ static void scan_keyboard(void)
#endif
}
- enter_polling_mode();
+ keyboard_raw_enable_interrupt(0);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
/* Busy polling keyboard state. */
while (1) {
@@ -566,47 +458,22 @@ static void scan_keyboard(void)
}
}
-static void set_irq_mask(void)
-{
- int i;
-
- for (i = GPIO_KB_IN00; i < GPIO_KB_IN00 + KB_INPUTS; i++)
- irq_mask |= gpio_list[i].mask;
-}
-
void keyboard_scan_task(void)
{
- /* Enable interrupts for keyboard matrix inputs */
- gpio_enable_interrupt(GPIO_KB_IN00);
- gpio_enable_interrupt(GPIO_KB_IN01);
- gpio_enable_interrupt(GPIO_KB_IN02);
- gpio_enable_interrupt(GPIO_KB_IN03);
- gpio_enable_interrupt(GPIO_KB_IN04);
- gpio_enable_interrupt(GPIO_KB_IN05);
- gpio_enable_interrupt(GPIO_KB_IN06);
- gpio_enable_interrupt(GPIO_KB_IN07);
-
- /* Determine EXTI_PR mask to use for the board */
- set_irq_mask();
-
print_state(debounced_state, "init state");
+ keyboard_raw_task_start();
+
while (1) {
if (config.flags & EC_MKBP_FLAGS_ENABLE) {
scan_keyboard();
} else {
- assert_output(OUTPUT_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
task_wait_event(-1);
}
}
}
-
-void keyboard_scan_interrupt(enum gpio_signal signal)
-{
- task_wake(TASK_ID_KEYSCAN);
-}
-
int keyboard_has_char(void)
{
/* TODO: needs to be implemented */
@@ -660,8 +527,16 @@ void keyboard_enable_scanning(int enable)
mutex_unlock(&scanning_enabled);
task_wake(TASK_ID_KEYSCAN);
} else {
+ /*
+ * TODO: using a mutex to control scanning isn't very
+ * responsive. If we just started scanning the matrix, the
+ * mutex will already be locked, and we'll finish the entire
+ * matrix scan before we stop driving columns. We should
+ * instead do something like link, where disabling scanning
+ * immediately stops driving the columns.
+ */
mutex_lock(&scanning_enabled);
- assert_output(OUTPUT_TRI_STATE_ALL);
+ keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
}
}
diff --git a/include/keyboard_raw.h b/include/keyboard_raw.h
new file mode 100644
index 0000000000..6432335a52
--- /dev/null
+++ b/include/keyboard_raw.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Raw access to keyboard GPIOs.
+ *
+ * The keyboard matrix is read by driving output signals on the column lines
+ * and reading the row lines.
+ */
+
+#ifndef __CROS_EC_KEYBOARD_RAW_H
+#define __CROS_EC_KEYBOARD_RAW_H
+
+#include "common.h"
+#include "gpio.h"
+
+/* used for select_column() */
+enum keyboard_column_index {
+ KEYBOARD_COLUMN_ALL = -2, /* Drive all columns */
+ KEYBOARD_COLUMN_NONE = -1, /* Drive no columns (tri-state all) */
+ /* 0 ~ 12 for the corresponding column */
+};
+
+/**
+ * Initialize the raw keyboard interface.
+ *
+ * Must be called before any other functions in this interface.
+ */
+void keyboard_raw_init(void);
+
+/**
+ * Finish intitialization after task scheduling has started.
+ *
+ * Call from the keyboard scan task.
+ */
+void keyboard_raw_task_start(void);
+
+/**
+ * Drive the specified column low.
+ *
+ * Other columns are tristated. See enum keyboard_column_index for special
+ * values for <col>.
+ */
+void keyboard_raw_drive_column(int col);
+
+/**
+ * Read raw row state.
+ *
+ * Bits are 1 if signal is present, 0 if not present.
+ */
+int keyboard_raw_read_rows(void);
+
+/**
+ * Enable or disable keyboard interrupts.
+ *
+ * Enabling interrupts will clear any pending interrupt bits. To avoid missing
+ * any interrupts that occur between the end of scanning and then, you should
+ * call keyboard_raw_read_rows() after this. If it returns non-zero, disable
+ * interrupts and go back to polling mode instead of waiting for an interrupt.
+ */
+void keyboard_raw_enable_interrupt(int enable);
+
+#ifdef CONFIG_TASK_KEYSCAN
+
+/**
+ * GPIO interrupt for raw keyboard input
+ */
+void keyboard_raw_gpio_interrupt(enum gpio_signal signal);
+
+#else
+#define keyboard_raw_gpio_interrupt NULL
+#endif
+
+#endif /* __CROS_EC_KEYBOARD_RAW_H */
diff --git a/include/keyboard_scan.h b/include/keyboard_scan.h
index 54e7259c21..e0f883375a 100644
--- a/include/keyboard_scan.h
+++ b/include/keyboard_scan.h
@@ -9,7 +9,6 @@
#define __CROS_EC_KEYBOARD_SCAN_H
#include "common.h"
-#include "gpio.h"
/**
* Initializes the module.
@@ -52,15 +51,4 @@ void keyboard_enable_scanning(int enable);
*/
void keyboard_send_battery_key(void);
-#ifdef CONFIG_TASK_KEYSCAN
-
-/**
- * Keyboard scan GPIO interrupt.
- */
-void keyboard_scan_interrupt(enum gpio_signal signal);
-
-#else
-#define keyboard_scan_interrupt NULL
-#endif
-
#endif /* __CROS_EC_KEYBOARD_SCAN_H */