cros_ec: Change keyboard scanning method.
authorAseda Aboagye <aaboagye@google.com>
Sat, 9 Jul 2016 01:20:32 +0000 (18:20 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Wed, 20 Jul 2016 01:33:41 +0000 (18:33 -0700)
The Matrix KeyBoard Protocol (MKBP) was recently extended to support
reporting button and switch events. Consequently, support for the
EC_CMD_MKBP_GET_STATE host command was dropped since the keyboard FIFO
became a general MKBP events FIFO and that host command assumed that the
FIFO was strictly for keyboard matrices.  This has been superseded by the
EC_CMD_GET_NEXT_EVENT host command.

Currently, button and switch events may be present in the FIFO, but we
will just ignore those and drop them on the floor.  For those buttons
and switches that we care about, they are handled in different ways.

This commit introduces a new Kconfig:

    CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND

This config option should be used to enable retrieving of key matrix
changes via EC_CMD_MKBP_GET_STATE. This is for legacy Chrome ECs where
the MKBP FIFO was solely just a key matrix FIFO.

BUG=chromium:626863
BRANCH=None
TEST=Verify that keypresses are recognized during FW screens on kevin.
TEST=Verify that button presses and other events are ignored during FW
screens on kevin.

CQ-DEPEND=CL:358926

Change-Id: Ia9cf29b063178b9eca20e9d2602dc91308e56d4a
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/358989
Commit-Ready: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
23 files changed:
board/daisy/defconfig
board/elm/defconfig
board/nyan/defconfig
board/nyan_big/defconfig
board/nyan_blaze/defconfig
board/oak/defconfig
board/peach_pit/defconfig
board/rush/defconfig
board/veyron_gus/defconfig
board/veyron_jaq/defconfig
board/veyron_jerry/defconfig
board/veyron_mighty/defconfig
board/veyron_minnie/defconfig
board/veyron_nicky/defconfig
board/veyron_pinky/defconfig
board/veyron_shark/defconfig
board/veyron_speedy/defconfig
board/veyron_thea/defconfig
src/drivers/ec/cros/commands.h
src/drivers/ec/cros/ec.c
src/drivers/ec/cros/ec.h
src/drivers/input/mkbp/Kconfig
src/drivers/input/mkbp/keyboard.c

index 6361ce6..8000b2c 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_GPIO_EXYNOS5250=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_EXYNOS=y
 CONFIG_DRIVER_SOUND_I2S=y
index 4988b44..0e69fa3 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_DRIVER_EC_CROS_SPI=y
 CONFIG_DRIVER_GPIO_MT8173=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_MT6397=y
 CONFIG_DRIVER_SOUND_I2S=y
index e3abcfe..66bf044 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_GPIO_TEGRA=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_AS3722=y
 CONFIG_DRIVER_SOUND_I2S=y
index be8ad86..77a5727 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_GPIO_TEGRA=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_AS3722=y
 CONFIG_DRIVER_SOUND_I2S=y
index 4cade0f..1aaa9b1 100644 (file)
@@ -32,6 +32,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_GPIO_TEGRA=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_AS3722=y
 CONFIG_DRIVER_SOUND_I2S=y
index 734f965..ea491d7 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_DRIVER_EC_CROS_SPI=y
 CONFIG_DRIVER_GPIO_MT8173=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_MT6397=y
 CONFIG_DRIVER_SOUND_I2S=y
index 6f0e178..3480603 100644 (file)
@@ -31,6 +31,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_GPIO_EXYNOS5420=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_EXYNOS=y
 CONFIG_DRIVER_SOUND_I2S=y
index 25a7015..04cba00 100644 (file)
@@ -33,6 +33,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_GPIO_TEGRA=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_POWER_AS3722=y
 CONFIG_DRIVER_SOUND_I2S=y
index 421fdd9..bebc946 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index 25285d4..4226c49 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index 898b957..dcf4f83 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index 72c14f7..f3e6996 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index bcb2eb2..db09c03 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index fbc3237..57415a8 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index 366efc2..a2dcfb0 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index 3cd1772..87f725b 100644 (file)
@@ -41,6 +41,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index ccc82e7..e1d9b36 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index ecfbede..31bae8c 100644 (file)
@@ -37,6 +37,7 @@ CONFIG_DRIVER_FLASH_SPI=y
 CONFIG_DRIVER_POWER_RK808=y
 CONFIG_DRIVER_INPUT_MKBP=y
 CONFIG_DRIVER_INPUT_MKBP_KEYMATRIX_STANDARD=y
+CONFIG_DRIVER_INPUT_MKBP_OLD_COMMAND=y
 CONFIG_DRIVER_INPUT_USB=y
 CONFIG_DRIVER_SOUND_I2S=y
 CONFIG_DRIVER_SOUND_MAX98090=y
index 95549a3..1bf07de 100644 (file)
@@ -2351,18 +2351,69 @@ struct ec_response_tmp006_get_raw {
  *
  * Returns raw data for keyboard cols; see ec_response_mkbp_info.cols for
  * expected response size.
+ *
+ * NOTE: This has been superseded by EC_CMD_MKBP_GET_NEXT_EVENT.  If you wish
+ * to obtain the instantaneous state, use EC_CMD_MKBP_INFO with the type
+ * EC_MKBP_INFO_CURRENT and event EC_MKBP_EVENT_KEY_MATRIX.
  */
 #define EC_CMD_MKBP_STATE 0x60
 
-/* Provide information about the matrix : number of rows and columns */
+/*
+ * Provide information about various MKBP things.  See enum ec_mkbp_info_type.
+ */
 #define EC_CMD_MKBP_INFO 0x61
 
 struct ec_response_mkbp_info {
        uint32_t rows;
        uint32_t cols;
-       uint8_t switches;
+       /* Formerly "switches", which was 0. */
+       uint8_t reserved;
 } __packed;
 
+struct ec_params_mkbp_info {
+       uint8_t info_type;
+       uint8_t event_type;
+} __packed;
+
+enum ec_mkbp_info_type {
+       /*
+        * Info about the keyboard matrix: number of rows and columns.
+        *
+        * Returns struct ec_response_mkbp_info.
+        */
+       EC_MKBP_INFO_KBD = 0,
+
+       /*
+        * For buttons and switches, info about which specifically are
+        * supported.  event_type must be set to one of the values in enum
+        * ec_mkbp_event.
+        *
+        * For EC_MKBP_EVENT_BUTTON and EC_MKBP_EVENT_SWITCH, returns a 4 byte
+        * bitmask indicating which buttons or switches are present.  See the
+        * bit inidices below.
+        */
+       EC_MKBP_INFO_SUPPORTED = 1,
+
+       /*
+        * Instantaneous state of buttons and switches.
+        *
+        * event_type must be set to one of the values in enum ec_mkbp_event.
+        *
+        * For EC_MKBP_EVENT_KEY_MATRIX, returns uint8_t key_matrix[13]
+        * indicating the current state of the keyboard matrix.
+        *
+        * For EC_MKBP_EVENT_HOST_EVENT, return uint32_t host_event, the raw
+        * event state.
+        *
+        * For EC_MKBP_EVENT_BUTTON, returns uint32_t buttons, indicating the
+        * state of supported buttons.
+        *
+        * For EC_MKBP_EVENT_SWITCH, returns uint32_t switches, indicating the
+        * state of supported switches.
+        */
+       EC_MKBP_INFO_CURRENT = 2,
+};
+
 /* Simulate key press */
 #define EC_CMD_MKBP_SIMULATE_KEY 0x62
 
@@ -2495,6 +2546,12 @@ enum ec_mkbp_event {
        /* New Sensor FIFO data. The event data is fifo_info structure. */
        EC_MKBP_EVENT_SENSOR_FIFO = 2,
 
+       /* The state of the non-matrixed buttons have changed. */
+       EC_MKBP_EVENT_BUTTON = 3,
+
+       /* The state of the switches have changed. */
+       EC_MKBP_EVENT_SWITCH = 4,
+
        /* Number of MKBP events */
        EC_MKBP_EVENT_COUNT,
 };
@@ -2510,6 +2567,10 @@ union ec_response_get_next_data {
                uint8_t rsvd[3];
                struct ec_response_motion_sense_fifo_info info;
        }        sensor_fifo;
+
+       uint32_t   buttons;
+
+       uint32_t   switches;
 } __packed;
 
 struct ec_response_get_next_event {
@@ -2518,6 +2579,15 @@ struct ec_response_get_next_event {
        union ec_response_get_next_data data;
 } __packed;
 
+/* Bit indices for buttons and switches.*/
+/* Buttons */
+#define EC_MKBP_POWER_BUTTON   0
+#define EC_MKBP_VOL_UP         1
+#define EC_MKBP_VOL_DOWN       2
+
+/* Switches */
+#define EC_MKBP_LID_OPEN       0
+
 /* Run keyboard factory test scanning */
 #define EC_CMD_KEYBOARD_FACTORY_TEST 0x68
 
index 6836f49..5003942 100644 (file)
@@ -412,6 +412,14 @@ int cros_ec_scan_keyboard(struct cros_ec_keyscan *scan)
        return 0;
 }
 
+int cros_ec_get_next_event(struct ec_response_get_next_event *e)
+{
+       int rv = ec_command(get_main_ec(), EC_CMD_GET_NEXT_EVENT, 0, NULL, 0, e,
+                           sizeof(*e));
+
+       return rv < 0 ? rv : 0;
+}
+
 static int ec_read_id(CrosEc *me, char *id, int maxlen)
 {
        struct ec_response_get_version r;
index eb89cb2..91a2de9 100644 (file)
@@ -126,6 +126,16 @@ struct cros_ec_keyscan {
 int cros_ec_scan_keyboard(struct cros_ec_keyscan *scan);
 
 /**
+ * Get the next pending MKBP event from the ChromeOS EC device.
+ *
+ * Send a message requesting the next event and return the result.
+ *
+ * @param event                Place to put the event.
+ * @return number of bytes received if ok, else EC error response code.
+ */
+int cros_ec_get_next_event(struct ec_response_get_next_event *event);
+
+/**
  * Check if the ChromeOS EC device has an interrupt pending.
  *
  * Read the status of the external interrupt connected to the ChromeOS EC
index 8a61d23..8327df1 100644 (file)
 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ## GNU General Public License for more details.
 
+config DRIVER_INPUT_MKBP_OLD_COMMAND
+       bool "Old method of retrieving keyscans via the ChromeOS EC MKBP."
+       default n
+       help
+         In older ChromeOS EC images, the MKBP FIFO only contains key matrix
+         changes.  Therefore, retrieving the MKBP state will always be a key
+         matrix and the EC_CMD_MKBP_STATE host command is supported.  This is
+         not the case for newer EC images.
+
 source src/drivers/input/mkbp/keymatrix/Kconfig
 source src/drivers/input/mkbp/layout/Kconfig
index 8e8610b..6709219 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdint.h>
 
 #include "base/init_funcs.h"
+#include "config.h"
 #include "drivers/ec/cros/ec.h"
 #include "drivers/input/input.h"
 #include "drivers/input/mkbp/keymatrix.h"
@@ -38,7 +39,7 @@ typedef enum Modifier {
 static int read_scancodes(Modifier *modifiers, uint8_t *codes, int max_codes)
 {
        static struct cros_ec_keyscan last_scan;
-       static struct cros_ec_keyscan scan;
+       static struct ec_response_get_next_event event;
 
        assert(modifiers);
        *modifiers = ModifierNone;
@@ -47,9 +48,25 @@ static int read_scancodes(Modifier *modifiers, uint8_t *codes, int max_codes)
        if (!cros_ec_interrupt_pending())
                return -1;
 
-       if (cros_ec_scan_keyboard(&scan)) {
-               printf("Key matrix scan failed.\n");
-               return -1;
+       if (IS_ENABLED(CONFIG_DRIVER_INPUT_MKBP_HAS_KEYMATRIX_ONLY)) {
+               if (cros_ec_scan_keyboard((struct cros_ec_keyscan *)
+                                         &event.data.key_matrix)) {
+                       printf("Key matrix scan failed.\n");
+                       return -1;
+               }
+       } else {
+               // Get pending MKBP event.  It may not be a key matrix event.
+               do {
+                       int rv = cros_ec_get_next_event(&event);
+                       // The EC has no events for us at this time.
+                       if (rv == -EC_RES_UNAVAILABLE) {
+                               return -1;
+                       } else if (rv < 0) {
+                               printf("Error getting next MKBP event. (%d)\n",
+                                      rv);
+                               return -1;
+                       }
+               } while (event.event_type != EC_MKBP_EVENT_KEY_MATRIX);
        }
 
        int total = 0;
@@ -72,7 +89,7 @@ static int read_scancodes(Modifier *modifiers, uint8_t *codes, int max_codes)
                int byte = pos / 8;
 
                uint8_t last_data = last_scan.data[byte];
-               uint8_t data = scan.data[byte];
+               uint8_t data = event.data.key_matrix[byte];
                last_scan.data[byte] = data;
 
                if (last_data != data)