/*
 * Translate key codes into ASCII
 *
 * Copyright (c) 2011 The Chromium OS Authors.
 * (C) Copyright 2004 DENX Software Engineering, Wolfgang Denk, wd@denx.de
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <errno.h>
#include <stdio_dev.h>
#include <input.h>
#include <linux/input.h>

enum {
	/* These correspond to the lights on the keyboard */
	FLAG_NUM_LOCK		= 1 << 0,
	FLAG_CAPS_LOCK		= 1 << 1,
	FLAG_SCROLL_LOCK	= 1 << 2,

	/* Special flag ORed with key code to indicate release */
	KEY_RELEASE		= 1 << 15,
	KEY_MASK		= 0xfff,
};

/*
 * These takes map key codes to ASCII. 0xff means no key, or special key.
 * Three tables are provided - one for plain keys, one for when the shift
 * 'modifier' key is pressed and one for when the ctrl modifier key is
 * pressed.
 */
static const uchar kbd_plain_xlate[] = {
	0xff, 0x1b, '1',  '2',  '3',  '4',  '5',  '6',
	'7',  '8',  '9',  '0',  '-',  '=', '\b', '\t',	/* 0x00 - 0x0f */
	'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
	'o',  'p',  '[',  ']', '\r', 0xff,  'a',  's',  /* 0x10 - 0x1f */
	'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
	'\'',  '`', 0xff, '\\', 'z',  'x',  'c',  'v',	/* 0x20 - 0x2f */
	'b',  'n',  'm',  ',' ,  '.', '/', 0xff, 0xff, 0xff,
	' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 0x30 - 0x3f */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  '7',
	'8',  '9',  '-',  '4',  '5',  '6',  '+',  '1',	/* 0x40 - 0x4f */
	'2',  '3',  '0',  '.', 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 0x50 - 0x5F */
	'\r', 0xff, '/',  '*',
};

static unsigned char kbd_shift_xlate[] = {
	0xff, 0x1b, '!', '@', '#', '$', '%', '^',
	'&', '*', '(', ')', '_', '+', '\b', '\t',	/* 0x00 - 0x0f */
	'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
	'O', 'P', '{', '}', '\r', 0xff, 'A', 'S',	/* 0x10 - 0x1f */
	'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
	'"', '~', 0xff, '|', 'Z', 'X', 'C', 'V',	/* 0x20 - 0x2f */
	'B', 'N', 'M', '<', '>', '?', 0xff, 0xff, 0xff,
	' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 0x30 - 0x3f */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
	'8', '9', '-', '4', '5', '6', '+', '1',	/* 0x40 - 0x4f */
	'2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 0x50 - 0x5F */
	'\r', 0xff, '/',  '*',
};

static unsigned char kbd_ctrl_xlate[] = {
	0xff, 0x1b, '1', 0x00, '3', '4', '5', 0x1E,
	'7', '8', '9', '0', 0x1F, '=', '\b', '\t',	/* 0x00 - 0x0f */
	0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09,
	0x0f, 0x10, 0x1b, 0x1d, '\n', 0xff, 0x01, 0x13,	/* 0x10 - 0x1f */
	0x04, 0x06, 0x08, 0x09, 0x0a, 0x0b, 0x0c, ';',
	'\'', '~', 0x00, 0x1c, 0x1a, 0x18, 0x03, 0x16,	/* 0x20 - 0x2f */
	0x02, 0x0e, 0x0d, '<', '>', '?', 0xff, 0xff,
	0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 0x30 - 0x3f */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '7',
	'8', '9', '-', '4', '5', '6', '+', '1',		/* 0x40 - 0x4f */
	'2', '3', '0', '.', 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,	/* 0x50 - 0x5F */
	'\r', 0xff, '/',  '*',
};

static const uchar kbd_plain_xlate_german[] = {
	0xff, 0x1b,  '1',  '2',  '3',  '4',  '5',  '6', /* scan 00-07 */
	 '7',  '8',  '9',  '0', 0xe1, '\'', 0x08, '\t', /* scan 08-0F */
	 'q',  'w',  'e',  'r',  't',  'z',  'u',  'i', /* scan 10-17 */
	 'o',  'p', 0x81,  '+', '\r', 0xff,  'a',  's', /* scan 18-1F */
	 'd',  'f',  'g',  'h',  'j',  'k',  'l', 0x94, /* scan 20-27 */
	0x84,  '^', 0xff,  '#',  'y',  'x',  'c',  'v', /* scan 28-2F */
	 'b',  'n',  'm',  ',',  '.',  '-', 0xff,  '*', /* scan 30-37 */
	 ' ',  ' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  '7', /* scan 40-47 */
	 '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1', /* scan 48-4F */
	 '2',  '3',  '0',  ',', 0xff, 0xff,  '<', 0xff, /* scan 50-57 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
	'\r', 0xff,  '/',  '*',
};

static unsigned char kbd_shift_xlate_german[] = {
	   0xff, 0x1b,  '!',  '"', 0x15,  '$',  '%',  '&', /* scan 00-07 */
	 '/',  '(',  ')',  '=',  '?',  '`', 0x08, '\t', /* scan 08-0F */
	 'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I', /* scan 10-17 */
	 'O',  'P', 0x9a,  '*', '\r', 0xff,  'A',  'S', /* scan 18-1F */
	 'D',  'F',  'G',  'H',  'J',  'K',  'L', 0x99, /* scan 20-27 */
	0x8e, 0xf8, 0xff, '\'',  'Y',  'X',  'C',  'V', /* scan 28-2F */
	 'B',  'N',  'M',  ';',  ':',  '_', 0xff,  '*', /* scan 30-37 */
	 ' ',  ' ', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  '7', /* scan 40-47 */
	 '8',  '9',  '-',  '4',  '5',  '6',  '+',  '1', /* scan 48-4F */
	 '2',  '3',  '0',  ',', 0xff, 0xff,  '>', 0xff, /* scan 50-57 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */
	'\r', 0xff,  '/',  '*',
};

static unsigned char kbd_right_alt_xlate_german[] = {
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 00-07 */
	 '{',  '[',  ']',  '}', '\\', 0xff, 0xff, 0xff, /* scan 08-0F */
	 '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10-17 */
	0xff, 0xff, 0xff,  '~', 0xff, 0xff, 0xff, 0xff, /* scan 18-1F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20-27 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28-2F */
	0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30-37 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40-47 */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff,  '|', 0xff, /* scan 50-57 */
};

enum kbd_mask {
	KBD_ENGLISH	= 1 << 0,
	KBD_GERMAN	= 1 << 1,
};

static struct kbd_entry {
	int kbd_mask;		/* Which languages this is for */
	int left_keycode;	/* Left keycode to select this map */
	int right_keycode;	/* Right keycode to select this map */
	const uchar *xlate;	/* Ascii code for each keycode */
	int num_entries;	/* Number of entries in xlate */
} kbd_entry[] = {
	{ KBD_ENGLISH, -1, -1,
		kbd_plain_xlate, ARRAY_SIZE(kbd_plain_xlate) },
	{ KBD_GERMAN, -1, -1,
		kbd_plain_xlate_german, ARRAY_SIZE(kbd_plain_xlate_german) },
	{ KBD_ENGLISH, KEY_LEFTSHIFT, KEY_RIGHTSHIFT,
		kbd_shift_xlate, ARRAY_SIZE(kbd_shift_xlate) },
	{ KBD_GERMAN, KEY_LEFTSHIFT, KEY_RIGHTSHIFT,
		kbd_shift_xlate_german, ARRAY_SIZE(kbd_shift_xlate_german) },
	{ KBD_ENGLISH | KBD_GERMAN, KEY_LEFTCTRL, KEY_RIGHTCTRL,
		kbd_ctrl_xlate, ARRAY_SIZE(kbd_ctrl_xlate) },
	{ KBD_GERMAN, -1, KEY_RIGHTALT,
		kbd_right_alt_xlate_german,
		ARRAY_SIZE(kbd_right_alt_xlate_german) },
	{},
};

/*
 * Scan key code to ANSI 3.64 escape sequence table.  This table is
 * incomplete in that it does not include all possible extra keys.
 */
static struct {
	int kbd_scan_code;
	char *escape;
} kbd_to_ansi364[] = {
	{ KEY_UP, "\033[A"},
	{ KEY_DOWN, "\033[B"},
	{ KEY_RIGHT, "\033[C"},
	{ KEY_LEFT, "\033[D"},
};

/* Maximum number of output characters that an ANSI sequence expands to */
#define ANSI_CHAR_MAX	3

static int input_queue_ascii(struct input_config *config, int ch)
{
	if (config->fifo_in + 1 == INPUT_BUFFER_LEN) {
		if (!config->fifo_out)
			return -1; /* buffer full */
		else
			config->fifo_in = 0;
	} else {
		if (config->fifo_in + 1 == config->fifo_out)
			return -1; /* buffer full */
		config->fifo_in++;
	}
	debug(" {%02x} ", ch);
	config->fifo[config->fifo_in] = (uchar)ch;

	return 0;
}

int input_tstc(struct input_config *config)
{
	if (config->fifo_in == config->fifo_out && config->read_keys) {
		if (!(*config->read_keys)(config))
			return 0;
	}
	return config->fifo_in != config->fifo_out;
}

int input_getc(struct input_config *config)
{
	int err = 0;

	while (config->fifo_in == config->fifo_out) {
		if (config->read_keys)
			err = (*config->read_keys)(config);
		if (err)
			return -1;
	}

	if (++config->fifo_out == INPUT_BUFFER_LEN)
		config->fifo_out = 0;

	return config->fifo[config->fifo_out];
}

/**
 * Process a modifier/special key press or release and decide which key
 * translation array should be used as a result.
 *
 * TODO: Should keep track of modifier press/release
 *
 * @param config	Input state
 * @param key		Key code to process
 * @param release	0 if a press, 1 if a release
 * @return pointer to keycode->ascii translation table that should be used
 */
static struct input_key_xlate *process_modifier(struct input_config *config,
						int key, int release)
{
	struct input_key_xlate *table;
	int i;

	/* Start with the main table, and see what modifiers change it */
	assert(config->num_tables > 0);
	table = &config->table[0];
	for (i = 1; i < config->num_tables; i++) {
		struct input_key_xlate *tab = &config->table[i];

		if (key == tab->left_keycode || key == tab->right_keycode)
			table = tab;
	}

	/* Handle the lighted keys */
	if (!release) {
		int flip = -1;

		switch (key) {
		case KEY_SCROLLLOCK:
			flip = FLAG_SCROLL_LOCK;
			break;
		case KEY_NUMLOCK:
			flip = FLAG_NUM_LOCK;
			break;
		case KEY_CAPSLOCK:
			flip = FLAG_CAPS_LOCK;
			break;
		}

		if (flip != -1) {
			int leds = 0;

			config->flags ^= flip;
			if (config->flags & FLAG_NUM_LOCK)
				leds |= INPUT_LED_NUM;
			if (config->flags & FLAG_CAPS_LOCK)
				leds |= INPUT_LED_CAPS;
			if (config->flags & FLAG_SCROLL_LOCK)
				leds |= INPUT_LED_SCROLL;
			config->leds = leds;
			config->leds_changed = flip;
		}
	}

	return table;
}

/**
 * Search an int array for a key value
 *
 * @param array	Array to search
 * @param count	Number of elements in array
 * @param key	Key value to find
 * @return element where value was first found, -1 if none
 */
static int array_search(int *array, int count, int key)
{
	int i;

	for (i = 0; i < count; i++) {
		if (array[i] == key)
			return i;
	}

	return -1;
}

/**
 * Sort an array so that those elements that exist in the ordering are
 * first in the array, and in the same order as the ordering. The algorithm
 * is O(count * ocount) and designed for small arrays.
 *
 * TODO: Move this to common / lib?
 *
 * @param dest		Array with elements to sort, also destination array
 * @param count		Number of elements to sort
 * @param order		Array containing ordering elements
 * @param ocount	Number of ordering elements
 * @return number of elements in dest that are in order (these will be at the
 *	start of dest).
 */
static int sort_array_by_ordering(int *dest, int count, int *order,
				   int ocount)
{
	int temp[count];
	int dest_count;
	int same;	/* number of elements which are the same */
	int i;

	/* setup output items, copy items to be sorted into our temp area */
	memcpy(temp, dest, count * sizeof(*dest));
	dest_count = 0;

	/* work through the ordering, move over the elements we agree on */
	for (i = 0; i < ocount; i++) {
		if (array_search(temp, count, order[i]) != -1)
			dest[dest_count++] = order[i];
	}
	same = dest_count;

	/* now move over the elements that are not in the ordering */
	for (i = 0; i < count; i++) {
		if (array_search(order, ocount, temp[i]) == -1)
			dest[dest_count++] = temp[i];
	}
	assert(dest_count == count);
	return same;
}

/**
 * Check a list of key codes against the previous key scan
 *
 * Given a list of new key codes, we check how many of these are the same
 * as last time.
 *
 * @param config	Input state
 * @param keycode	List of key codes to examine
 * @param num_keycodes	Number of key codes
 * @param same		Returns number of key codes which are the same
 */
static int input_check_keycodes(struct input_config *config,
			   int keycode[], int num_keycodes, int *same)
{
	/* Select the 'plain' xlate table to start with */
	if (!config->num_tables) {
		debug("%s: No xlate tables: cannot decode keys\n", __func__);
		return -1;
	}

	/* sort the keycodes into the same order as the previous ones */
	*same = sort_array_by_ordering(keycode, num_keycodes,
			config->prev_keycodes, config->num_prev_keycodes);

	memcpy(config->prev_keycodes, keycode, num_keycodes * sizeof(int));
	config->num_prev_keycodes = num_keycodes;

	return *same != num_keycodes;
}

/**
 * Checks and converts a special key code into ANSI 3.64 escape sequence.
 *
 * @param config	Input state
 * @param keycode	Key code to examine
 * @param output_ch	Buffer to place output characters into. It should
 *			be at least ANSI_CHAR_MAX bytes long, to allow for
 *			an ANSI sequence.
 * @param max_chars	Maximum number of characters to add to output_ch
 * @return number of characters output, if the key was converted, otherwise 0.
 *	This may be larger than max_chars, in which case the overflow
 *	characters are not output.
 */
static int input_keycode_to_ansi364(struct input_config *config,
		int keycode, char output_ch[], int max_chars)
{
	const char *escape;
	int ch_count;
	int i;

	for (i = ch_count = 0; i < ARRAY_SIZE(kbd_to_ansi364); i++) {
		if (keycode != kbd_to_ansi364[i].kbd_scan_code)
			continue;
		for (escape = kbd_to_ansi364[i].escape; *escape; escape++) {
			if (ch_count < max_chars)
				output_ch[ch_count] = *escape;
			ch_count++;
		}
		return ch_count;
	}

	return 0;
}

/**
 * Converts and queues a list of key codes in escaped ASCII string form
 * Convert a list of key codes into ASCII
 *
 * You must call input_check_keycodes() before this. It turns the keycode
 * list into a list of ASCII characters and sends them to the input layer.
 *
 * Characters which were seen last time do not generate fresh ASCII output.
 * The output (calls to queue_ascii) may be longer than num_keycodes, if the
 * keycode contains special keys that was encoded to longer escaped sequence.
 *
 * @param config	Input state
 * @param keycode	List of key codes to examine
 * @param num_keycodes	Number of key codes
 * @param output_ch	Buffer to place output characters into. It should
 *			be at last ANSI_CHAR_MAX * num_keycodes, to allow for
 *			ANSI sequences.
 * @param max_chars	Maximum number of characters to add to output_ch
 * @param same		Number of key codes which are the same
 * @return number of characters written into output_ch, or -1 if we would
 *	exceed max_chars chars.
 */
static int input_keycodes_to_ascii(struct input_config *config,
		int keycode[], int num_keycodes, char output_ch[],
		int max_chars, int same)
{
	struct input_key_xlate *table;
	int ch_count = 0;
	int i;

	table = &config->table[0];

	/* deal with modifiers first */
	for (i = 0; i < num_keycodes; i++) {
		int key = keycode[i] & KEY_MASK;

		if (key >= table->num_entries || table->xlate[key] == 0xff) {
			table = process_modifier(config, key,
					keycode[i] & KEY_RELEASE);
		}
	}

	/* Start conversion by looking for the first new keycode (by same). */
	for (i = same; i < num_keycodes; i++) {
		int key = keycode[i];
		int ch;

		/*
		 * For a normal key (with an ASCII value), add it; otherwise
		 * translate special key to escape sequence if possible.
		 */
		if (key < table->num_entries) {
			ch = table->xlate[key];
			if ((config->flags & FLAG_CAPS_LOCK) &&
			    ch >= 'a' && ch <= 'z')
				ch -= 'a' - 'A';
			if (ch_count < max_chars && ch != 0xff)
				output_ch[ch_count++] = (uchar)ch;
		} else {
			ch_count += input_keycode_to_ansi364(config, key,
						output_ch, max_chars);
		}
	}

	if (ch_count > max_chars) {
		debug("%s: Output char buffer overflow size=%d, need=%d\n",
		      __func__, max_chars, ch_count);
		return -1;
	}

	/* ok, so return keys */
	return ch_count;
}

static int _input_send_keycodes(struct input_config *config, int keycode[],
				int num_keycodes, bool do_send)
{
	char ch[num_keycodes * ANSI_CHAR_MAX];
	int count, i, same = 0;
	int is_repeat = 0;
	unsigned delay_ms;

	config->modifiers = 0;
	if (!input_check_keycodes(config, keycode, num_keycodes, &same)) {
		/*
		 * Same as last time - is it time for another repeat?
		 * TODO(sjg@chromium.org) We drop repeats here and since
		 * the caller may not call in again for a while, our
		 * auto-repeat speed is not quite correct. We should
		 * insert another character if we later realise that we
		 * have missed a repeat slot.
		 */
		is_repeat = config->allow_repeats || (config->repeat_rate_ms &&
			(int)get_timer(config->next_repeat_ms) >= 0);
		if (!is_repeat)
			return 0;
	}

	count = input_keycodes_to_ascii(config, keycode, num_keycodes,
					ch, sizeof(ch), is_repeat ? 0 : same);
	if (do_send) {
		for (i = 0; i < count; i++)
			input_queue_ascii(config, ch[i]);
	}
	delay_ms = is_repeat ?
			config->repeat_rate_ms :
			config->repeat_delay_ms;

	config->next_repeat_ms = get_timer(0) + delay_ms;

	return count;
}

int input_send_keycodes(struct input_config *config, int keycode[],
			int num_keycodes)
{
	return _input_send_keycodes(config, keycode, num_keycodes, true);
}

int input_add_keycode(struct input_config *config, int new_keycode,
		      bool release)
{
	int keycode[INPUT_MAX_MODIFIERS + 1];
	int count, i;

	/* Add the old keycodes which are not removed by this new one */
	for (i = 0, count = 0; i < config->num_prev_keycodes; i++) {
		int code = config->prev_keycodes[i];

		if (new_keycode == code) {
			if (release)
				continue;
			new_keycode = -1;
		}
		keycode[count++] = code;
	}

	if (!release && new_keycode != -1)
		keycode[count++] = new_keycode;
	debug("\ncodes for %02x/%d: ", new_keycode, release);
	for (i = 0; i < count; i++)
		debug("%02x ", keycode[i]);
	debug("\n");

	/* Don't output any ASCII characters if this is a key release */
	return _input_send_keycodes(config, keycode, count, !release);
}

int input_add_table(struct input_config *config, int left_keycode,
		    int right_keycode, const uchar *xlate, int num_entries)
{
	struct input_key_xlate *table;

	if (config->num_tables == INPUT_MAX_MODIFIERS) {
		debug("%s: Too many modifier tables\n", __func__);
		return -1;
	}

	table = &config->table[config->num_tables++];
	table->left_keycode = left_keycode;
	table->right_keycode = right_keycode;
	table->xlate = xlate;
	table->num_entries = num_entries;

	return 0;
}

void input_set_delays(struct input_config *config, int repeat_delay_ms,
	       int repeat_rate_ms)
{
	config->repeat_delay_ms = repeat_delay_ms;
	config->repeat_rate_ms = repeat_rate_ms;
}

void input_allow_repeats(struct input_config *config, bool allow_repeats)
{
	config->allow_repeats = allow_repeats;
}

int input_leds_changed(struct input_config *config)
{
	if (config->leds_changed)
		return config->leds;

	return -1;
}

int input_add_tables(struct input_config *config, bool german)
{
	struct kbd_entry *entry;
	int mask;
	int ret;

	mask = german ? KBD_GERMAN : KBD_ENGLISH;
	for (entry = kbd_entry; entry->kbd_mask; entry++) {
		if (!(mask & entry->kbd_mask))
			continue;
		ret = input_add_table(config, entry->left_keycode,
				      entry->right_keycode, entry->xlate,
				      entry->num_entries);
		if (ret)
			return ret;
	}

	return 0;
}

int input_init(struct input_config *config, int leds)
{
	memset(config, '\0', sizeof(*config));
	config->leds = leds;

	return 0;
}

int input_stdio_register(struct stdio_dev *dev)
{
	int error;

	error = stdio_register(dev);

	/* check if this is the standard input device */
	if (!error && strcmp(getenv("stdin"), dev->name) == 0) {
		/* reassign the console */
		if (OVERWRITE_CONSOLE ||
				console_assign(stdin, dev->name))
			return -1;
	}

	return 0;
}
