summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/host/build.mk3
-rw-r--r--chip/host/clock.c13
-rw-r--r--common/keyboard_scan.c27
-rw-r--r--include/config.h7
4 files changed, 49 insertions, 1 deletions
diff --git a/chip/host/build.mk b/chip/host/build.mk
index 177246a925..56b091b8cf 100644
--- a/chip/host/build.mk
+++ b/chip/host/build.mk
@@ -8,5 +8,6 @@
CORE:=host
-chip-y=system.o gpio.o uart.o persistence.o flash.o lpc.o reboot.o i2c.o
+chip-y=system.o gpio.o uart.o persistence.o flash.o lpc.o reboot.o i2c.o \
+ clock.o
chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
diff --git a/chip/host/clock.c b/chip/host/clock.c
new file mode 100644
index 0000000000..89391c0028
--- /dev/null
+++ b/chip/host/clock.c
@@ -0,0 +1,13 @@
+/* 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.
+ *
+ * Dummy clock driver for unit test.
+ */
+
+#include "clock.h"
+
+int clock_get_freq(void)
+{
+ return 16000000;
+}
diff --git a/common/keyboard_scan.c b/common/keyboard_scan.c
index 8214d7c415..9641ff6ca9 100644
--- a/common/keyboard_scan.c
+++ b/common/keyboard_scan.c
@@ -6,6 +6,7 @@
/* Keyboard scanner module for Chrome EC */
#include "chipset.h"
+#include "clock.h"
#include "common.h"
#include "console.h"
#include "hooks.h"
@@ -27,6 +28,15 @@
#define SCAN_TIME_COUNT 32 /* Number of last scan times to track */
+#ifndef CONFIG_KEYBOARD_POST_SCAN_CLOCKS
+/*
+ * Default delay in clocks; this was experimentally determined to be long
+ * enough to avoid watchdog warnings or I2C errors on a typical notebook
+ * config on STM32.
+ */
+#define CONFIG_KEYBOARD_POST_SCAN_CLOCKS 16000
+#endif
+
#ifndef CONFIG_KEYBOARD_BOARD_CONFIG
/* Use default keyboard scan config, because board didn't supply one */
struct keyboard_scan_config keyscan_config = {
@@ -62,9 +72,13 @@ static uint8_t simulated_key[KEYBOARD_COLS]; /* Keys simulated-pressed */
static uint32_t scan_time[SCAN_TIME_COUNT]; /* Times of last scans */
static int scan_time_index; /* Current scan_time[] index */
+
/* Index into scan_time[] when each key started debouncing */
static uint8_t scan_edge_index[KEYBOARD_COLS][KEYBOARD_ROWS];
+/* Minimum delay between keyboard scans based on current clock frequency */
+static uint32_t post_scan_clock_us;
+
/*
* Print all keyboard scan state changes? Off by default because it generates
* a lot of debug output, which makes the saved EC console data less useful.
@@ -443,6 +457,13 @@ static enum boot_key check_boot_key(const uint8_t *state)
return BOOT_KEY_OTHER;
}
+static void keyboard_freq_change(void)
+{
+ post_scan_clock_us = (CONFIG_KEYBOARD_POST_SCAN_CLOCKS * 1000) /
+ (clock_get_freq() / 1000);
+}
+DECLARE_HOOK(HOOK_FREQ_CHANGE, keyboard_freq_change, HOOK_PRIO_DEFAULT);
+
/*****************************************************************************/
/* Interface */
@@ -490,6 +511,9 @@ void keyboard_scan_task(void)
keyboard_raw_task_start();
+ /* Set initial clock frequency-based minimum delay between scans */
+ keyboard_freq_change();
+
while (1) {
/* Enable all outputs */
CPRINTF("[%T KB wait]\n");
@@ -534,6 +558,9 @@ void keyboard_scan_task(void)
wait_time =
keyscan_config.min_post_scan_delay_us;
+ if (wait_time < post_scan_clock_us)
+ wait_time = post_scan_clock_us;
+
usleep(wait_time);
}
}
diff --git a/include/config.h b/include/config.h
index ce1147a9d6..72dffe49c2 100644
--- a/include/config.h
+++ b/include/config.h
@@ -451,6 +451,13 @@
#undef CONFIG_KEYBOARD_BOARD_CONFIG
/*
+ * Minimum CPU clocks between scans. This ensures that keyboard scanning
+ * doesn't starve the other EC tasks of CPU when running at a decreased system
+ * clock.
+ */
+#undef CONFIG_KEYBOARD_POST_SCAN_CLOCKS
+
+/*
* Call board-supplied keyboard_suppress_noise() function when the debounced
* keyboard state changes. Some boards use this to send a signal to the audio
* codec to suppress typing noise picked up by the microphone.