1*713cb680SHung-ying Tyan /* 2*713cb680SHung-ying Tyan * Chromium OS Matrix Keyboard 3*713cb680SHung-ying Tyan * 4*713cb680SHung-ying Tyan * Copyright (c) 2012 The Chromium OS Authors. 5*713cb680SHung-ying Tyan * See file CREDITS for list of people who contributed to this 6*713cb680SHung-ying Tyan * project. 7*713cb680SHung-ying Tyan * 8*713cb680SHung-ying Tyan * This program is free software; you can redistribute it and/or 9*713cb680SHung-ying Tyan * modify it under the terms of the GNU General Public License as 10*713cb680SHung-ying Tyan * published by the Free Software Foundation; either version 2 of 11*713cb680SHung-ying Tyan * the License, or (at your option) any later version. 12*713cb680SHung-ying Tyan * 13*713cb680SHung-ying Tyan * This program is distributed in the hope that it will be useful, 14*713cb680SHung-ying Tyan * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*713cb680SHung-ying Tyan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*713cb680SHung-ying Tyan * GNU General Public License for more details. 17*713cb680SHung-ying Tyan * 18*713cb680SHung-ying Tyan * You should have received a copy of the GNU General Public License 19*713cb680SHung-ying Tyan * along with this program; if not, write to the Free Software 20*713cb680SHung-ying Tyan * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21*713cb680SHung-ying Tyan * MA 02111-1307 USA 22*713cb680SHung-ying Tyan */ 23*713cb680SHung-ying Tyan 24*713cb680SHung-ying Tyan #include <common.h> 25*713cb680SHung-ying Tyan #include <cros_ec.h> 26*713cb680SHung-ying Tyan #include <fdtdec.h> 27*713cb680SHung-ying Tyan #include <input.h> 28*713cb680SHung-ying Tyan #include <key_matrix.h> 29*713cb680SHung-ying Tyan #include <stdio_dev.h> 30*713cb680SHung-ying Tyan 31*713cb680SHung-ying Tyan DECLARE_GLOBAL_DATA_PTR; 32*713cb680SHung-ying Tyan 33*713cb680SHung-ying Tyan enum { 34*713cb680SHung-ying Tyan KBC_MAX_KEYS = 8, /* Maximum keys held down at once */ 35*713cb680SHung-ying Tyan }; 36*713cb680SHung-ying Tyan 37*713cb680SHung-ying Tyan static struct keyb { 38*713cb680SHung-ying Tyan struct cros_ec_dev *dev; /* The CROS_EC device */ 39*713cb680SHung-ying Tyan struct input_config input; /* The input layer */ 40*713cb680SHung-ying Tyan struct key_matrix matrix; /* The key matrix layer */ 41*713cb680SHung-ying Tyan int key_rows; /* Number of keyboard rows */ 42*713cb680SHung-ying Tyan int key_cols; /* Number of keyboard columns */ 43*713cb680SHung-ying Tyan unsigned int repeat_delay_ms; /* Time before autorepeat starts */ 44*713cb680SHung-ying Tyan unsigned int repeat_rate_ms; /* Autorepeat rate in ms */ 45*713cb680SHung-ying Tyan int ghost_filter; /* 1 to enable ghost filter, else 0 */ 46*713cb680SHung-ying Tyan int inited; /* 1 if keyboard is ready */ 47*713cb680SHung-ying Tyan } config; 48*713cb680SHung-ying Tyan 49*713cb680SHung-ying Tyan 50*713cb680SHung-ying Tyan /** 51*713cb680SHung-ying Tyan * Check the keyboard controller and return a list of key matrix positions 52*713cb680SHung-ying Tyan * for which a key is pressed 53*713cb680SHung-ying Tyan * 54*713cb680SHung-ying Tyan * @param config Keyboard config 55*713cb680SHung-ying Tyan * @param keys List of keys that we have detected 56*713cb680SHung-ying Tyan * @param max_count Maximum number of keys to return 57*713cb680SHung-ying Tyan * @return number of pressed keys, 0 for none 58*713cb680SHung-ying Tyan */ 59*713cb680SHung-ying Tyan static int check_for_keys(struct keyb *config, 60*713cb680SHung-ying Tyan struct key_matrix_key *keys, int max_count) 61*713cb680SHung-ying Tyan { 62*713cb680SHung-ying Tyan struct key_matrix_key *key; 63*713cb680SHung-ying Tyan struct mbkp_keyscan scan; 64*713cb680SHung-ying Tyan unsigned int row, col, bit, data; 65*713cb680SHung-ying Tyan int num_keys; 66*713cb680SHung-ying Tyan 67*713cb680SHung-ying Tyan if (cros_ec_scan_keyboard(config->dev, &scan)) { 68*713cb680SHung-ying Tyan debug("%s: keyboard scan failed\n", __func__); 69*713cb680SHung-ying Tyan return -1; 70*713cb680SHung-ying Tyan } 71*713cb680SHung-ying Tyan 72*713cb680SHung-ying Tyan for (col = num_keys = bit = 0; col < config->matrix.num_cols; 73*713cb680SHung-ying Tyan col++) { 74*713cb680SHung-ying Tyan for (row = 0; row < config->matrix.num_rows; row++) { 75*713cb680SHung-ying Tyan unsigned int mask = 1 << (bit & 7); 76*713cb680SHung-ying Tyan 77*713cb680SHung-ying Tyan data = scan.data[bit / 8]; 78*713cb680SHung-ying Tyan if ((data & mask) && num_keys < max_count) { 79*713cb680SHung-ying Tyan key = keys + num_keys++; 80*713cb680SHung-ying Tyan key->row = row; 81*713cb680SHung-ying Tyan key->col = col; 82*713cb680SHung-ying Tyan key->valid = 1; 83*713cb680SHung-ying Tyan } 84*713cb680SHung-ying Tyan bit++; 85*713cb680SHung-ying Tyan } 86*713cb680SHung-ying Tyan } 87*713cb680SHung-ying Tyan 88*713cb680SHung-ying Tyan return num_keys; 89*713cb680SHung-ying Tyan } 90*713cb680SHung-ying Tyan 91*713cb680SHung-ying Tyan /** 92*713cb680SHung-ying Tyan * Test if keys are available to be read 93*713cb680SHung-ying Tyan * 94*713cb680SHung-ying Tyan * @return 0 if no keys available, 1 if keys are available 95*713cb680SHung-ying Tyan */ 96*713cb680SHung-ying Tyan static int kbd_tstc(void) 97*713cb680SHung-ying Tyan { 98*713cb680SHung-ying Tyan /* Just get input to do this for us */ 99*713cb680SHung-ying Tyan return config.inited ? input_tstc(&config.input) : 0; 100*713cb680SHung-ying Tyan } 101*713cb680SHung-ying Tyan 102*713cb680SHung-ying Tyan /** 103*713cb680SHung-ying Tyan * Read a key 104*713cb680SHung-ying Tyan * 105*713cb680SHung-ying Tyan * @return ASCII key code, or 0 if no key, or -1 if error 106*713cb680SHung-ying Tyan */ 107*713cb680SHung-ying Tyan static int kbd_getc(void) 108*713cb680SHung-ying Tyan { 109*713cb680SHung-ying Tyan /* Just get input to do this for us */ 110*713cb680SHung-ying Tyan return config.inited ? input_getc(&config.input) : 0; 111*713cb680SHung-ying Tyan } 112*713cb680SHung-ying Tyan 113*713cb680SHung-ying Tyan /** 114*713cb680SHung-ying Tyan * Check the keyboard, and send any keys that are pressed. 115*713cb680SHung-ying Tyan * 116*713cb680SHung-ying Tyan * This is called by input_tstc() and input_getc() when they need more 117*713cb680SHung-ying Tyan * characters 118*713cb680SHung-ying Tyan * 119*713cb680SHung-ying Tyan * @param input Input configuration 120*713cb680SHung-ying Tyan * @return 1, to indicate that we have something to look at 121*713cb680SHung-ying Tyan */ 122*713cb680SHung-ying Tyan int cros_ec_kbc_check(struct input_config *input) 123*713cb680SHung-ying Tyan { 124*713cb680SHung-ying Tyan static struct key_matrix_key last_keys[KBC_MAX_KEYS]; 125*713cb680SHung-ying Tyan static int last_num_keys; 126*713cb680SHung-ying Tyan struct key_matrix_key keys[KBC_MAX_KEYS]; 127*713cb680SHung-ying Tyan int keycodes[KBC_MAX_KEYS]; 128*713cb680SHung-ying Tyan int num_keys, num_keycodes; 129*713cb680SHung-ying Tyan int irq_pending, sent; 130*713cb680SHung-ying Tyan 131*713cb680SHung-ying Tyan /* 132*713cb680SHung-ying Tyan * Loop until the EC has no more keyscan records, or we have 133*713cb680SHung-ying Tyan * received at least one character. This means we know that tstc() 134*713cb680SHung-ying Tyan * will always return non-zero if keys have been pressed. 135*713cb680SHung-ying Tyan * 136*713cb680SHung-ying Tyan * Without this loop, a key release (which generates no new ascii 137*713cb680SHung-ying Tyan * characters) will cause us to exit this function, and just tstc() 138*713cb680SHung-ying Tyan * may return 0 before all keys have been read from the EC. 139*713cb680SHung-ying Tyan */ 140*713cb680SHung-ying Tyan do { 141*713cb680SHung-ying Tyan irq_pending = cros_ec_interrupt_pending(config.dev); 142*713cb680SHung-ying Tyan if (irq_pending) { 143*713cb680SHung-ying Tyan num_keys = check_for_keys(&config, keys, KBC_MAX_KEYS); 144*713cb680SHung-ying Tyan last_num_keys = num_keys; 145*713cb680SHung-ying Tyan memcpy(last_keys, keys, sizeof(keys)); 146*713cb680SHung-ying Tyan } else { 147*713cb680SHung-ying Tyan /* 148*713cb680SHung-ying Tyan * EC doesn't want to be asked, so use keys from last 149*713cb680SHung-ying Tyan * time. 150*713cb680SHung-ying Tyan */ 151*713cb680SHung-ying Tyan num_keys = last_num_keys; 152*713cb680SHung-ying Tyan memcpy(keys, last_keys, sizeof(keys)); 153*713cb680SHung-ying Tyan } 154*713cb680SHung-ying Tyan 155*713cb680SHung-ying Tyan if (num_keys < 0) 156*713cb680SHung-ying Tyan return -1; 157*713cb680SHung-ying Tyan num_keycodes = key_matrix_decode(&config.matrix, keys, 158*713cb680SHung-ying Tyan num_keys, keycodes, KBC_MAX_KEYS); 159*713cb680SHung-ying Tyan sent = input_send_keycodes(input, keycodes, num_keycodes); 160*713cb680SHung-ying Tyan } while (irq_pending && !sent); 161*713cb680SHung-ying Tyan 162*713cb680SHung-ying Tyan return 1; 163*713cb680SHung-ying Tyan } 164*713cb680SHung-ying Tyan 165*713cb680SHung-ying Tyan /** 166*713cb680SHung-ying Tyan * Decode MBKP keyboard details from the device tree 167*713cb680SHung-ying Tyan * 168*713cb680SHung-ying Tyan * @param blob Device tree blob 169*713cb680SHung-ying Tyan * @param node Node to decode from 170*713cb680SHung-ying Tyan * @param config Configuration data read from fdt 171*713cb680SHung-ying Tyan * @return 0 if ok, -1 on error 172*713cb680SHung-ying Tyan */ 173*713cb680SHung-ying Tyan static int cros_ec_keyb_decode_fdt(const void *blob, int node, 174*713cb680SHung-ying Tyan struct keyb *config) 175*713cb680SHung-ying Tyan { 176*713cb680SHung-ying Tyan /* 177*713cb680SHung-ying Tyan * Get keyboard rows and columns - at present we are limited to 178*713cb680SHung-ying Tyan * 8 columns by the protocol (one byte per row scan) 179*713cb680SHung-ying Tyan */ 180*713cb680SHung-ying Tyan config->key_rows = fdtdec_get_int(blob, node, "google,key-rows", 0); 181*713cb680SHung-ying Tyan config->key_cols = fdtdec_get_int(blob, node, "google,key-columns", 0); 182*713cb680SHung-ying Tyan if (!config->key_rows || !config->key_cols || 183*713cb680SHung-ying Tyan config->key_rows * config->key_cols / 8 184*713cb680SHung-ying Tyan > CROS_EC_KEYSCAN_COLS) { 185*713cb680SHung-ying Tyan debug("%s: Invalid key matrix size %d x %d\n", __func__, 186*713cb680SHung-ying Tyan config->key_rows, config->key_cols); 187*713cb680SHung-ying Tyan return -1; 188*713cb680SHung-ying Tyan } 189*713cb680SHung-ying Tyan config->repeat_delay_ms = fdtdec_get_int(blob, node, 190*713cb680SHung-ying Tyan "google,repeat-delay-ms", 0); 191*713cb680SHung-ying Tyan config->repeat_rate_ms = fdtdec_get_int(blob, node, 192*713cb680SHung-ying Tyan "google,repeat-rate-ms", 0); 193*713cb680SHung-ying Tyan config->ghost_filter = fdtdec_get_bool(blob, node, 194*713cb680SHung-ying Tyan "google,ghost-filter"); 195*713cb680SHung-ying Tyan return 0; 196*713cb680SHung-ying Tyan } 197*713cb680SHung-ying Tyan 198*713cb680SHung-ying Tyan /** 199*713cb680SHung-ying Tyan * Set up the keyboard. This is called by the stdio device handler. 200*713cb680SHung-ying Tyan * 201*713cb680SHung-ying Tyan * We want to do this init when the keyboard is actually used rather than 202*713cb680SHung-ying Tyan * at start-up, since keyboard input may not currently be selected. 203*713cb680SHung-ying Tyan * 204*713cb680SHung-ying Tyan * @return 0 if ok, -1 on error 205*713cb680SHung-ying Tyan */ 206*713cb680SHung-ying Tyan static int cros_ec_init_keyboard(void) 207*713cb680SHung-ying Tyan { 208*713cb680SHung-ying Tyan const void *blob = gd->fdt_blob; 209*713cb680SHung-ying Tyan int node; 210*713cb680SHung-ying Tyan 211*713cb680SHung-ying Tyan config.dev = board_get_cros_ec_dev(); 212*713cb680SHung-ying Tyan if (!config.dev) { 213*713cb680SHung-ying Tyan debug("%s: no cros_ec device: cannot init keyboard\n", 214*713cb680SHung-ying Tyan __func__); 215*713cb680SHung-ying Tyan return -1; 216*713cb680SHung-ying Tyan } 217*713cb680SHung-ying Tyan node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB); 218*713cb680SHung-ying Tyan if (node < 0) { 219*713cb680SHung-ying Tyan debug("%s: Node not found\n", __func__); 220*713cb680SHung-ying Tyan return -1; 221*713cb680SHung-ying Tyan } 222*713cb680SHung-ying Tyan if (cros_ec_keyb_decode_fdt(blob, node, &config)) 223*713cb680SHung-ying Tyan return -1; 224*713cb680SHung-ying Tyan input_set_delays(&config.input, config.repeat_delay_ms, 225*713cb680SHung-ying Tyan config.repeat_rate_ms); 226*713cb680SHung-ying Tyan if (key_matrix_init(&config.matrix, config.key_rows, 227*713cb680SHung-ying Tyan config.key_cols, config.ghost_filter)) { 228*713cb680SHung-ying Tyan debug("%s: cannot init key matrix\n", __func__); 229*713cb680SHung-ying Tyan return -1; 230*713cb680SHung-ying Tyan } 231*713cb680SHung-ying Tyan if (key_matrix_decode_fdt(&config.matrix, gd->fdt_blob, node)) { 232*713cb680SHung-ying Tyan debug("%s: Could not decode key matrix from fdt\n", __func__); 233*713cb680SHung-ying Tyan return -1; 234*713cb680SHung-ying Tyan } 235*713cb680SHung-ying Tyan config.inited = 1; 236*713cb680SHung-ying Tyan debug("%s: Matrix keyboard %dx%d ready\n", __func__, config.key_rows, 237*713cb680SHung-ying Tyan config.key_cols); 238*713cb680SHung-ying Tyan 239*713cb680SHung-ying Tyan return 0; 240*713cb680SHung-ying Tyan } 241*713cb680SHung-ying Tyan 242*713cb680SHung-ying Tyan int drv_keyboard_init(void) 243*713cb680SHung-ying Tyan { 244*713cb680SHung-ying Tyan struct stdio_dev dev; 245*713cb680SHung-ying Tyan 246*713cb680SHung-ying Tyan if (input_init(&config.input, 0)) { 247*713cb680SHung-ying Tyan debug("%s: Cannot set up input\n", __func__); 248*713cb680SHung-ying Tyan return -1; 249*713cb680SHung-ying Tyan } 250*713cb680SHung-ying Tyan config.input.read_keys = cros_ec_kbc_check; 251*713cb680SHung-ying Tyan 252*713cb680SHung-ying Tyan memset(&dev, '\0', sizeof(dev)); 253*713cb680SHung-ying Tyan strcpy(dev.name, "cros-ec-keyb"); 254*713cb680SHung-ying Tyan dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; 255*713cb680SHung-ying Tyan dev.getc = kbd_getc; 256*713cb680SHung-ying Tyan dev.tstc = kbd_tstc; 257*713cb680SHung-ying Tyan dev.start = cros_ec_init_keyboard; 258*713cb680SHung-ying Tyan 259*713cb680SHung-ying Tyan /* Register the device. cros_ec_init_keyboard() will be called soon */ 260*713cb680SHung-ying Tyan return input_stdio_register(&dev); 261*713cb680SHung-ying Tyan } 262