blob: 709ca8000ca9f0b308268fc9e266d31be804f6fe [file] [log] [blame]
/*
* Copyright (c) 2011-2012 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*/
#include <common.h>
#include <fdtdec.h>
#include <cros/gbb.h>
#include <cros/keyboard.h>
/* Import the header files from vboot_reference. */
#include <vboot_api.h>
#include <gbb_header.h>
DECLARE_GLOBAL_DATA_PTR;
static struct remap_key remap_keys[KEY_TYPE_COUNT];
int vboot_keymap_init(void)
{
int croscfg_node = cros_fdtdec_config_node(gd->fdt_blob);
if (croscfg_node < 0)
return -1;
if (!fdtdec_get_int_array(gd->fdt_blob, croscfg_node,
"faft-key-remap-special",
remap_keys[KEY_TYPE_SPECIAL].array,
KEY_ARRAY_SIZE)) {
remap_keys[KEY_TYPE_SPECIAL].array_ptr =
remap_keys[KEY_TYPE_SPECIAL].array;
}
if (!fdtdec_get_int_array(gd->fdt_blob, croscfg_node,
"faft-key-remap-ascii",
remap_keys[KEY_TYPE_ASCII].array,
KEY_ARRAY_SIZE)) {
remap_keys[KEY_TYPE_ASCII].array_ptr =
remap_keys[KEY_TYPE_ASCII].array;
}
return 0;
}
/**
* Replace normal ascii keys and special keys if the mainboard
* fdt has either an ascii or a special key remap array.
*
* @param *c pointer to key to be checked and possibly remapped
* @param keytype KEY_TYPE_ASCII or KEY_TYPE_SPECIAL
*
* @return -1 on error, 0 on success with update int key in c
*/
static int faft_key_remap(int *c, unsigned char keytype)
{
int i;
uint32_t gbb_flags = gbb_get_flags();
if ((gbb_flags & GBB_FLAG_FAFT_KEY_OVERIDE) == 0)
return -1;
if (remap_keys[keytype].array_ptr) {
for (i = 0; i < KEY_ARRAY_SIZE; i += 2) {
if (*c == remap_keys[keytype].array_ptr[i]) {
*c = remap_keys[keytype].array_ptr[i + 1];
return 0;
}
}
}
return -1;
}
uint32_t VbExKeyboardRead(void)
{
int c = 0;
/* No input available. */
if (!tstc())
goto out;
/* Read a non-Escape character or a standalone Escape character. */
c = getc();
if (c != CSI_0 || !tstc()) {
/* Handle normal asci keys for FAFT keyboard matrix */
if (faft_key_remap(&c, KEY_TYPE_ASCII) >= 0)
goto out;
/*
* Special handle of Ctrl-Enter, which is converted into '\n'
* by i8042 driver.
*/
if (c == '\n')
c = VB_KEY_CTRL_ENTER;
goto out;
}
/* Filter out non- Escape-[ sequence. */
if (getc() != CSI_1) {
c = 0;
goto out;
}
/* Get special keys */
c = getc();
/* Handle special keys for FAFT keyboard matrix */
if (faft_key_remap(&c, KEY_TYPE_SPECIAL) >= 0)
goto out;
/* Special values for arrow up/down/left/right. */
switch (c) {
case 'A':
c = VB_KEY_UP;
break;
case 'B':
c = VB_KEY_DOWN;
break;
case 'C':
c = VB_KEY_RIGHT;
break;
case 'D':
c = VB_KEY_LEFT;
break;
default:
/* Filter out speical keys that we do not recognize. */
c = 0;
break;
}
out:
return c;
}
uint32_t VbExKeyboardReadWithFlags(uint32_t *flags_ptr)
{
if (flags_ptr)
/* We trust keyboards on u-boot legacy devices */
*flags_ptr = VB_KEY_FLAG_TRUSTED_KEYBOARD;
return VbExKeyboardRead();
}