summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/stm32/keyboard_scan.c87
-rw-r--r--include/keyboard_scan.h3
2 files changed, 87 insertions, 3 deletions
diff --git a/chip/stm32/keyboard_scan.c b/chip/stm32/keyboard_scan.c
index 1338f1b889..14bb331b1b 100644
--- a/chip/stm32/keyboard_scan.c
+++ b/chip/stm32/keyboard_scan.c
@@ -9,6 +9,7 @@
* TODO: Finish cleaning up nomenclature (cols/rows/inputs/outputs),
*/
+#include "atomic.h"
#include "board.h"
#include "console.h"
#include "gpio.h"
@@ -76,6 +77,82 @@ void __board_keyboard_suppress_noise(void)
void board_keyboard_suppress_noise(void)
__attribute__((weak, alias("__board_keyboard_suppress_noise")));
+#define KB_FIFO_DEPTH 16 /* FIXME: this is pretty huge */
+static int kb_fifo_start; /* first entry */
+static int kb_fifo_end; /* last entry */
+static uint32_t kb_fifo_entries; /* number of existing entries */
+static uint8_t kb_fifo[KB_FIFO_DEPTH][KB_OUTPUTS];
+
+/* clear keyboard state variables */
+void keyboard_clear_state(void)
+{
+ int i;
+
+ CPRINTF("clearing keyboard fifo\n");
+ kb_fifo_start = 0;
+ kb_fifo_end = 0;
+ kb_fifo_entries = 0;
+ for (i = 0; i < KB_FIFO_DEPTH; i++)
+ memset(kb_fifo[i], 0, KB_OUTPUTS);
+}
+
+/**
+ * Add keyboard state into FIFO
+ *
+ * @return EC_SUCCESS if entry added, EC_ERROR_OVERFLOW if FIFO is full
+ */
+static int kb_fifo_add(uint8_t *buffp)
+{
+ int ret = EC_SUCCESS;
+
+ if (kb_fifo_entries == KB_FIFO_DEPTH) {
+ CPRINTF("%s: FIFO depth reached\n", __func__);
+ ret = EC_ERROR_OVERFLOW;
+ goto kb_fifo_push_done;
+ }
+
+ memcpy(kb_fifo[kb_fifo_end], buffp, KB_OUTPUTS);
+
+ if (kb_fifo_end == KB_FIFO_DEPTH - 1)
+ kb_fifo_end = 0;
+ else
+ kb_fifo_end++;
+
+ atomic_add(&kb_fifo_entries, 1);
+
+kb_fifo_push_done:
+ return ret;
+}
+
+/**
+ * Pop keyboard state from FIFO
+ *
+ * @return EC_SUCCESS if entry popped, EC_ERROR_UNKNOWN if FIFO is empty
+ */
+static int kb_fifo_remove(uint8_t *buffp)
+{
+ memcpy(buffp, kb_fifo[kb_fifo_start], KB_OUTPUTS);
+
+ if (!kb_fifo_entries) {
+ CPRINTF("%s: No entries remaining in FIFO\n", __func__);
+ /*
+ * Bail out without changing any FIFO indices and let the
+ * caller know something strange happened. The buffer will
+ * will contain the last known state of the keyboard.
+ */
+ return EC_ERROR_UNKNOWN;
+ }
+
+ if (kb_fifo_start == KB_FIFO_DEPTH - 1)
+ kb_fifo_start = 0;
+ else
+ kb_fifo_start++;
+
+ atomic_sub(&kb_fifo_entries, 1);
+
+ return EC_SUCCESS;
+}
+
static void select_column(int col)
{
int i, done = 0;
@@ -224,9 +301,7 @@ static int check_keys_changed(void)
}
if (change) {
- memcpy(saved_state, raw_state, sizeof(saved_state));
board_keyboard_suppress_noise();
- board_interrupt_host();
CPRINTF("[%d keys pressed: ", num_press);
for (c = 0; c < KB_OUTPUTS; c++) {
@@ -236,6 +311,11 @@ static int check_keys_changed(void)
CPUTS(" --");
}
CPUTS("]\n");
+
+ if (kb_fifo_add(raw_state) == EC_SUCCESS)
+ board_interrupt_host();
+ else
+ CPRINTF("dropped keystroke\n");
}
return num_press ? 1 : 0;
@@ -308,6 +388,7 @@ int keyboard_scan_recovery_pressed(void)
int keyboard_get_scan(uint8_t **buffp, int max_bytes)
{
+ kb_fifo_remove(saved_state);
*buffp = saved_state;
- return sizeof(saved_state);
+ return KB_OUTPUTS;
}
diff --git a/include/keyboard_scan.h b/include/keyboard_scan.h
index 6ba01f9d0e..895fdfd2b8 100644
--- a/include/keyboard_scan.h
+++ b/include/keyboard_scan.h
@@ -31,4 +31,7 @@ int keyboard_scan_recovery_pressed(void);
*/
int keyboard_get_scan(uint8_t **buffp, int max_bytes);
+/* clear any saved keyboard state (empty FIFO, etc) */
+void keyboard_clear_state(void);
+
#endif /* __CROS_KEYBOARD_SCAN_H */