From 220a5a496d09e36b2281b484d651fd3c379ecf81 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 10 Apr 2012 10:37:29 -0700 Subject: [PATCH] Update keyboard scanning for stm32 to use messages Provide the required plumbing for the stm32 keyboard scan code so that the message layer will pick up keyboard scans. The design is as follows: - When a change in keyboard state is detected, the keyboard matrix scanning code will call the board-specific board_keyboard_scan_ready() function to interrupt the AP. - The AP will initiate a CMDC_KEY_STATE transaction over SPI or I2C - The SPI or I2C driver will call message_process_cmd() to process the command - This in turn will call keyboard_get_scan() to get the latest scan data For SPI: - The AP will initiate an 20-byte (or longer) SPI transaction - The EC will see the command, and provide the keyboard state in response, with the response being part of the same transaction For I2C: - The AP will initiate a 1-byte write to set the EC mode. - The AP will then initiate an 18-byte read, and the EC will send the message including keyboard state BUG=chromium-os:28925 TEST=build on daisy and discovery; run on daisy Change-Id: I905ef9d567e43d85fb851052f67586eff58e1167 Signed-off-by: Simon Glass --- chip/lm4/keyboard_scan.c | 6 ++++++ chip/stm32l/keyboard_scan.c | 31 ++++++++++++++++++++++++++++--- common/message.c | 3 +++ include/keyboard_scan.h | 15 +++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/chip/lm4/keyboard_scan.c b/chip/lm4/keyboard_scan.c index a8d5d47ac0..91e04aac82 100644 --- a/chip/lm4/keyboard_scan.c +++ b/chip/lm4/keyboard_scan.c @@ -455,3 +455,9 @@ void keyboard_put_char(uint8_t chr, int send_irq) #error "keyboard_scan needs to know what bus to use for keyboard interface" #endif } + +/* We don't support this API yet, just return -1 */ +int keyboard_get_scan(uint8_t **buffp, int max_bytes) +{ + return -1; +} diff --git a/chip/stm32l/keyboard_scan.c b/chip/stm32l/keyboard_scan.c index 5223f041d7..4ed2957602 100644 --- a/chip/stm32l/keyboard_scan.c +++ b/chip/stm32l/keyboard_scan.c @@ -73,8 +73,12 @@ enum COL_INDEX { /* 15:14, 12:8, 2 */ #define IRQ_MASK 0xdf04 +/* The keyboard state from the last read */ static uint8_t raw_state[KB_COLS]; +/* The keyboard state we will return when requested */ +static uint8_t saved_state[KB_COLS]; + /* Mask with 1 bits only for keys that actually exist */ static const uint8_t *actual_key_mask; @@ -167,6 +171,15 @@ static const uint32_t ports[] = { GPIO_A, GPIO_B, GPIO_C, GPIO_D }; #error "Need to specify GPIO ports used by keyboard" #endif +/* Provide a default function in case the board doesn't have one */ +void __board_keyboard_scan_ready(void) +{ +} + +void board_keyboard_scan_ready(void) + __attribute__((weak, alias("__board_keyboard_scan_ready"))); + + static void select_column(int col) { int i; @@ -283,9 +296,12 @@ int keyboard_scan_init(void) STM32L_GPIO_PUPDR_OFF(ports[i]) = tmp32; } - /* Initialize raw state */ - for (i = 0; i < KB_COLS; i++) - raw_state[i] = 0; + /* + * Initialize raw state since host may request it before + * a key has been pressed (e.g. during keyboard driver init) + */ + for (i = 0; i < ARRAY_SIZE(raw_state); i++) + raw_state[i] = 0x00; /* TODO: method to set which keyboard we have, so we set the actual * key mask properly */ @@ -395,6 +411,9 @@ static int check_keys_changed(void) } if (change) { + memcpy(saved_state, raw_state, sizeof(saved_state)); + board_keyboard_scan_ready(); + uart_printf("[%d keys pressed: ", num_press); for (c = 0; c < KB_COLS; c++) { if (raw_state[c]) @@ -472,3 +491,9 @@ int keyboard_scan_recovery_pressed(void) /* TODO: (crosbug.com/p/8573) needs to be implemented */ return 0; } + +int keyboard_get_scan(uint8_t **buffp, int max_bytes) +{ + *buffp = saved_state; + return sizeof(saved_state); +} diff --git a/common/message.c b/common/message.c index 6ce74e8776..44fea62648 100644 --- a/common/message.c +++ b/common/message.c @@ -10,6 +10,7 @@ #include "board.h" #include "message.h" +#include "keyboard_scan.h" #include "util.h" /* Our ID message - Matrix KeyBoard Protocol */ @@ -39,6 +40,8 @@ static int message_get_response(int cmd, uint8_t **buffp, int max_len) case CMDC_ID: *buffp = (char *)proto_id; return sizeof(proto_id) - 1; + case CMDC_KEY_STATE: + return keyboard_get_scan(buffp, max_len); default: return -1; } diff --git a/include/keyboard_scan.h b/include/keyboard_scan.h index 31341333c5..6ba01f9d0e 100644 --- a/include/keyboard_scan.h +++ b/include/keyboard_scan.h @@ -16,4 +16,19 @@ int keyboard_scan_init(void); /* Returns non-zero if recovery key was pressed at boot. */ int keyboard_scan_recovery_pressed(void); +/** + * Get the scan data from the keyboard. + * + * This returns the results of the last keyboard scan, by pointing the + * supplied buffer to it, and returning the number of bytes available. + * + * The supplied buffer can be used directly if required, but in that case + * the number of bytes available is limited to 'max_bytes'. + * + * @param buffp Pointer to buffer to contain data + * @param max_bytes Maximum number of bytes available in *buffp + * @return number of bytes available, or -1 for error + */ +int keyboard_get_scan(uint8_t **buffp, int max_bytes); + #endif /* __CROS_KEYBOARD_SCAN_H */