uboot/drivers/input/cros_ec_keyb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Chromium OS Matrix Keyboard
   4 *
   5 * Copyright (c) 2012 The Chromium OS Authors.
   6 */
   7
   8#include <common.h>
   9#include <cros_ec.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <input.h>
  13#include <keyboard.h>
  14#include <key_matrix.h>
  15#include <log.h>
  16#include <stdio_dev.h>
  17
  18enum {
  19        KBC_MAX_KEYS            = 8,    /* Maximum keys held down at once */
  20        KBC_REPEAT_RATE_MS      = 30,
  21        KBC_REPEAT_DELAY_MS     = 240,
  22};
  23
  24struct cros_ec_keyb_priv {
  25        struct input_config *input;     /* The input layer */
  26        struct key_matrix matrix;       /* The key matrix layer */
  27        int key_rows;                   /* Number of keyboard rows */
  28        int key_cols;                   /* Number of keyboard columns */
  29        int ghost_filter;               /* 1 to enable ghost filter, else 0 */
  30};
  31
  32
  33/**
  34 * Check the keyboard controller and return a list of key matrix positions
  35 * for which a key is pressed
  36 *
  37 * @param dev           Keyboard device
  38 * @param keys          List of keys that we have detected
  39 * @param max_count     Maximum number of keys to return
  40 * @param samep         Set to true if this scan repeats the last, else false
  41 * Return: number of pressed keys, 0 for none, -EIO on error
  42 */
  43static int check_for_keys(struct udevice *dev, struct key_matrix_key *keys,
  44                          int max_count, bool *samep)
  45{
  46        struct cros_ec_keyb_priv *priv = dev_get_priv(dev);
  47        struct key_matrix_key *key;
  48        static struct mbkp_keyscan last_scan;
  49        static bool last_scan_valid;
  50        struct ec_response_get_next_event event;
  51        struct mbkp_keyscan *scan = (struct mbkp_keyscan *)
  52                                    &event.data.key_matrix;
  53        unsigned int row, col, bit, data;
  54        int num_keys;
  55        int ret;
  56
  57        /* Get pending MKBP event. It may not be a key matrix event. */
  58        do {
  59                ret = cros_ec_get_next_event(dev->parent, &event);
  60                /* The EC has no events for us at this time. */
  61                if (ret == -EC_RES_UNAVAILABLE)
  62                        return -EIO;
  63                else if (ret)
  64                        break;
  65        } while (event.event_type != EC_MKBP_EVENT_KEY_MATRIX);
  66
  67        /* Try the old command if the EC doesn't support the above. */
  68        if (ret == -EC_RES_INVALID_COMMAND) {
  69                if (cros_ec_scan_keyboard(dev->parent, scan)) {
  70                        debug("%s: keyboard scan failed\n", __func__);
  71                        return -EIO;
  72                }
  73        } else if (ret) {
  74                debug("%s: Error getting next MKBP event. (%d)\n",
  75                      __func__, ret);
  76                return -EIO;
  77        }
  78        *samep = last_scan_valid && !memcmp(&last_scan, scan, sizeof(*scan));
  79
  80        /*
  81         * This is a bit odd. The EC has no way to tell us that it has run
  82         * out of key scans. It just returns the same scan over and over
  83         * again. So the only way to detect that we have run out is to detect
  84         * that this scan is the same as the last.
  85         */
  86        last_scan_valid = true;
  87        memcpy(&last_scan, scan, sizeof(last_scan));
  88
  89        for (col = num_keys = bit = 0; col < priv->matrix.num_cols;
  90                        col++) {
  91                for (row = 0; row < priv->matrix.num_rows; row++) {
  92                        unsigned int mask = 1 << (bit & 7);
  93
  94                        data = scan->data[bit / 8];
  95                        if ((data & mask) && num_keys < max_count) {
  96                                key = keys + num_keys++;
  97                                key->row = row;
  98                                key->col = col;
  99                                key->valid = 1;
 100                        }
 101                        bit++;
 102                }
 103        }
 104
 105        return num_keys;
 106}
 107
 108/**
 109 * Check the keyboard, and send any keys that are pressed.
 110 *
 111 * This is called by input_tstc() and input_getc() when they need more
 112 * characters
 113 *
 114 * @param input         Input configuration
 115 * Return: 1, to indicate that we have something to look at
 116 */
 117int cros_ec_kbc_check(struct input_config *input)
 118{
 119        struct udevice *dev = input->dev;
 120        struct cros_ec_keyb_priv *priv = dev_get_priv(dev);
 121        static struct key_matrix_key last_keys[KBC_MAX_KEYS];
 122        static int last_num_keys;
 123        struct key_matrix_key keys[KBC_MAX_KEYS];
 124        int keycodes[KBC_MAX_KEYS];
 125        int num_keys, num_keycodes;
 126        int irq_pending, sent;
 127        bool same = false;
 128
 129        /*
 130         * Loop until the EC has no more keyscan records, or we have
 131         * received at least one character. This means we know that tstc()
 132         * will always return non-zero if keys have been pressed.
 133         *
 134         * Without this loop, a key release (which generates no new ascii
 135         * characters) will cause us to exit this function, and just tstc()
 136         * may return 0 before all keys have been read from the EC.
 137         */
 138        do {
 139                irq_pending = cros_ec_interrupt_pending(dev->parent);
 140                if (irq_pending) {
 141                        num_keys = check_for_keys(dev, keys, KBC_MAX_KEYS,
 142                                                  &same);
 143                        if (num_keys < 0)
 144                                return 0;
 145                        last_num_keys = num_keys;
 146                        memcpy(last_keys, keys, sizeof(keys));
 147                } else {
 148                        /*
 149                         * EC doesn't want to be asked, so use keys from last
 150                         * time.
 151                         */
 152                        num_keys = last_num_keys;
 153                        memcpy(keys, last_keys, sizeof(keys));
 154                }
 155
 156                if (num_keys < 0)
 157                        return -1;
 158                num_keycodes = key_matrix_decode(&priv->matrix, keys,
 159                                num_keys, keycodes, KBC_MAX_KEYS);
 160                sent = input_send_keycodes(input, keycodes, num_keycodes);
 161
 162                /*
 163                 * For those ECs without an interrupt, stop scanning when we
 164                 * see that the scan is the same as last time.
 165                 */
 166                if ((irq_pending < 0) && same)
 167                        break;
 168        } while (irq_pending && !sent);
 169
 170        return 1;
 171}
 172
 173/**
 174 * Decode MBKP keyboard details from the device tree
 175 *
 176 * @param blob          Device tree blob
 177 * @param node          Node to decode from
 178 * @param config        Configuration data read from fdt
 179 * Return: 0 if ok, -1 on error
 180 */
 181static int cros_ec_keyb_decode_fdt(struct udevice *dev,
 182                                   struct cros_ec_keyb_priv *config)
 183{
 184        /*
 185         * Get keyboard rows and columns - at present we are limited to
 186         * 8 columns by the protocol (one byte per row scan)
 187         */
 188        config->key_rows = dev_read_u32_default(dev, "keypad,num-rows", 0);
 189        config->key_cols = dev_read_u32_default(dev, "keypad,num-columns", 0);
 190        if (!config->key_rows || !config->key_cols ||
 191                        config->key_rows * config->key_cols / 8
 192                                > CROS_EC_KEYSCAN_COLS) {
 193                debug("%s: Invalid key matrix size %d x %d\n", __func__,
 194                      config->key_rows, config->key_cols);
 195                return -1;
 196        }
 197        config->ghost_filter = dev_read_bool(dev, "google,needs-ghost-filter");
 198
 199        return 0;
 200}
 201
 202static int cros_ec_kbd_probe(struct udevice *dev)
 203{
 204        struct cros_ec_keyb_priv *priv = dev_get_priv(dev);
 205        struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
 206        struct stdio_dev *sdev = &uc_priv->sdev;
 207        struct input_config *input = &uc_priv->input;
 208        int ret;
 209
 210        ret = cros_ec_keyb_decode_fdt(dev, priv);
 211        if (ret) {
 212                debug("%s: Cannot decode node (ret=%d)\n", __func__, ret);
 213                return -EINVAL;
 214        }
 215        input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS);
 216        ret = key_matrix_init(&priv->matrix, priv->key_rows, priv->key_cols,
 217                              priv->ghost_filter);
 218        if (ret) {
 219                debug("%s: cannot init key matrix\n", __func__);
 220                return ret;
 221        }
 222        ret = key_matrix_decode_fdt(dev, &priv->matrix);
 223        if (ret) {
 224                debug("%s: Could not decode key matrix from fdt\n", __func__);
 225                return ret;
 226        }
 227        debug("%s: Matrix keyboard %dx%d ready\n", __func__, priv->key_rows,
 228              priv->key_cols);
 229
 230        priv->input = input;
 231        input->dev = dev;
 232        input_add_tables(input, false);
 233        input->read_keys = cros_ec_kbc_check;
 234        strcpy(sdev->name, "cros-ec-keyb");
 235
 236        /* Register the device. cros_ec_init_keyboard() will be called soon */
 237        return input_stdio_register(sdev);
 238}
 239
 240static const struct keyboard_ops cros_ec_kbd_ops = {
 241};
 242
 243static const struct udevice_id cros_ec_kbd_ids[] = {
 244        { .compatible = "google,cros-ec-keyb" },
 245        { }
 246};
 247
 248U_BOOT_DRIVER(google_cros_ec_keyb) = {
 249        .name   = "google_cros_ec_keyb",
 250        .id     = UCLASS_KEYBOARD,
 251        .of_match = cros_ec_kbd_ids,
 252        .probe = cros_ec_kbd_probe,
 253        .ops    = &cros_ec_kbd_ops,
 254        .priv_auto      = sizeof(struct cros_ec_keyb_priv),
 255};
 256