/*
 * (C) Copyright 2007
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * (C) Copyright 2001, 2002
 * DENX Software Engineering
 * Wolfgang Denk, wd@denx.de
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/* define DEBUG for debugging output (obviously ;-)) */
#if 0
#define DEBUG
#endif

#include <common.h>
#include <i2c.h>
#include <command.h>
#include <post.h>
#include <serial.h>
#include <malloc.h>

#include <linux/types.h>
#include <linux/string.h>	/* for strdup */

DECLARE_GLOBAL_DATA_PTR;

static void kbd_init (void);
static int compare_magic (uchar *kbd_data, uchar *str);

/*--------------------- Local macros and constants --------------------*/
#define	_NOT_USED_	0xFFFFFFFF

/*------------------------- dspic io expander -----------------------*/
#define DSPIC_PON_STATUS_REG	0x80A
#define DSPIC_PON_INV_STATUS_REG 0x80C
#define DSPIC_PON_KEY_REG	0x810
/*------------------------- Keyboard controller -----------------------*/
/* command codes */
#define	KEYBD_CMD_READ_KEYS	0x01
#define KEYBD_CMD_READ_VERSION	0x02
#define KEYBD_CMD_READ_STATUS	0x03
#define KEYBD_CMD_RESET_ERRORS	0x10

/* status codes */
#define KEYBD_STATUS_MASK	0x3F
#define	KEYBD_STATUS_H_RESET	0x20
#define KEYBD_STATUS_BROWNOUT	0x10
#define KEYBD_STATUS_WD_RESET	0x08
#define KEYBD_STATUS_OVERLOAD	0x04
#define KEYBD_STATUS_ILLEGAL_WR	0x02
#define KEYBD_STATUS_ILLEGAL_RD	0x01

/* Number of bytes returned from Keyboard Controller */
#define KEYBD_VERSIONLEN	2	/* version information */

/*
 * This is different from the "old" lwmon dsPIC kbd controller
 * implementation. Now the controller still answers with 9 bytes,
 * but the last 3 bytes are always "0x06 0x07 0x08". So we just
 * set the length to compare to 6 instead of 9.
 */
#define	KEYBD_DATALEN		6	/* normal key scan data */

/* maximum number of "magic" key codes that can be assigned */

static uchar kbd_addr = CONFIG_SYS_I2C_KEYBD_ADDR;
static uchar dspic_addr = CONFIG_SYS_I2C_DSPIC_IO_ADDR;

static uchar *key_match (uchar *);

#define	KEYBD_SET_DEBUGMODE	'#'	/* Magic key to enable debug output */

/***********************************************************************
F* Function:     int board_postclk_init (void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  int
P*                - 0 is always returned.
 *
Z* Intention:    This function is the board_postclk_init() method implementation
Z*               for the lwmon board.
 *
 ***********************************************************************/
int board_postclk_init (void)
{
	kbd_init();

	return (0);
}

static void kbd_init (void)
{
	uchar kbd_data[KEYBD_DATALEN];
	uchar tmp_data[KEYBD_DATALEN];
	uchar val, errcd;
	int i;

	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);

	gd->kbd_status = 0;

	/* Forced by PIC. Delays <= 175us loose */
	udelay(1000);

	/* Read initial keyboard error code */
	val = KEYBD_CMD_READ_STATUS;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	i2c_read (kbd_addr, 0, 0, &errcd, 1);
	/* clear unused bits */
	errcd &= KEYBD_STATUS_MASK;
	/* clear "irrelevant" bits. Recommended by Martin Rajek, LWN */
	errcd &= ~(KEYBD_STATUS_H_RESET|KEYBD_STATUS_BROWNOUT);
	if (errcd) {
		gd->kbd_status |= errcd << 8;
	}
	/* Reset error code and verify */
	val = KEYBD_CMD_RESET_ERRORS;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	udelay(1000);	/* delay NEEDED by keyboard PIC !!! */

	val = KEYBD_CMD_READ_STATUS;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	i2c_read (kbd_addr, 0, 0, &val, 1);

	val &= KEYBD_STATUS_MASK;	/* clear unused bits */
	if (val) {			/* permanent error, report it */
		gd->kbd_status |= val;
		return;
	}

	/*
	 * Read current keyboard state.
	 *
	 * After the error reset it may take some time before the
	 * keyboard PIC picks up a valid keyboard scan - the total
	 * scan time is approx. 1.6 ms (information by Martin Rajek,
	 * 28 Sep 2002). We read a couple of times for the keyboard
	 * to stabilize, using a big enough delay.
	 * 10 times should be enough. If the data is still changing,
	 * we use what we get :-(
	 */

	memset (tmp_data, 0xFF, KEYBD_DATALEN);	/* impossible value */
	for (i=0; i<10; ++i) {
		val = KEYBD_CMD_READ_KEYS;
		i2c_write (kbd_addr, 0, 0, &val, 1);
		i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);

		if (memcmp(kbd_data, tmp_data, KEYBD_DATALEN) == 0) {
			/* consistent state, done */
			break;
		}
		/* remeber last state, delay, and retry */
		memcpy (tmp_data, kbd_data, KEYBD_DATALEN);
		udelay (5000);
	}
}


/* Read a register from the dsPIC. */
int _dspic_read(ushort reg, ushort *data)
{
	uchar buf[sizeof(*data)];
	int rval;

	if (i2c_read(dspic_addr, reg, 2, buf, 2))
		return -1;

	rval = i2c_read(dspic_addr, reg, sizeof(reg), buf, sizeof(*data));
	*data = (buf[0] << 8) | buf[1];

	return rval;
}


/***********************************************************************
F* Function:     int misc_init_r (void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  int
P*                - 0 is always returned, even in the case of a keyboard
P*                    error.
 *
Z* Intention:    This function is the misc_init_r() method implementation
Z*               for the lwmon board.
Z*               The keyboard controller is initialized and the result
Z*               of a read copied to the environment variable "keybd".
Z*               If KEYBD_SET_DEBUGMODE is defined, a check is made for
Z*               this key, and if found display to the LCD will be enabled.
Z*               The keys in "keybd" are checked against the magic
Z*               keycommands defined in the environment.
Z*               See also key_match().
 *
D* Design:       wd@denx.de
C* Coding:       wd@denx.de
V* Verification: dzu@denx.de
 ***********************************************************************/
int misc_init_r_kbd (void)
{
	uchar kbd_data[KEYBD_DATALEN];
	char keybd_env[2 * KEYBD_DATALEN + 1];
	uchar kbd_init_status = gd->kbd_status >> 8;
	uchar kbd_status = gd->kbd_status;
	uchar val;
	ushort data, inv_data;
	char *str;
	int i;

	if (kbd_init_status) {
		printf ("KEYBD: Error %02X\n", kbd_init_status);
	}
	if (kbd_status) {		/* permanent error, report it */
		printf ("*** Keyboard error code %02X ***\n", kbd_status);
		sprintf (keybd_env, "%02X", kbd_status);
		setenv ("keybd", keybd_env);
		return 0;
	}

	/*
	 * Now we know that we have a working  keyboard,  so  disable
	 * all output to the LCD except when a key press is detected.
	 */

	if ((console_assign (stdout, "serial") < 0) ||
		(console_assign (stderr, "serial") < 0)) {
		printf ("Can't assign serial port as output device\n");
	}

	/* Read Version */
	val = KEYBD_CMD_READ_VERSION;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN);
	printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]);

	/* Read current keyboard state */
	val = KEYBD_CMD_READ_KEYS;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);

	/* read out start key from bse01 received via can */
	_dspic_read(DSPIC_PON_STATUS_REG, &data);
	/* check highbyte from status register */
	if (data > 0xFF) {
		_dspic_read(DSPIC_PON_INV_STATUS_REG, &inv_data);

		/* check inverse data */
		if ((data+inv_data) == 0xFFFF) {
			/* don't overwrite local key */
			if (kbd_data[1] == 0) {
				/* read key value */
				_dspic_read(DSPIC_PON_KEY_REG, &data);
				str = (char *)&data;
				/* swap bytes */
				kbd_data[1] = str[1];
				kbd_data[2] = str[0];
				printf("CAN received startkey: 0x%X\n", data);
			}
		}
	}

	for (i = 0; i < KEYBD_DATALEN; ++i) {
		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
	}

	setenv ("keybd", keybd_env);

	str = strdup ((char *)key_match (kbd_data));	/* decode keys */
#ifdef KEYBD_SET_DEBUGMODE
	if (kbd_data[0] == KEYBD_SET_DEBUGMODE) {	/* set debug mode */
		if ((console_assign (stdout, "lcd") < 0) ||
			(console_assign (stderr, "lcd") < 0)) {
			printf ("Can't assign LCD display as output device\n");
		}
	}
#endif /* KEYBD_SET_DEBUGMODE */
#ifdef CONFIG_PREBOOT	/* automatically configure "preboot" command on key match */
	setenv ("preboot", str);	/* set or delete definition */
#endif /* CONFIG_PREBOOT */
	if (str != NULL) {
		free (str);
	}
	return (0);
}

#ifdef CONFIG_PREBOOT

static uchar kbd_magic_prefix[] = "key_magic";
static uchar kbd_command_prefix[] = "key_cmd";

static int compare_magic (uchar *kbd_data, uchar *str)
{
	uchar compare[KEYBD_DATALEN-1];
	char *nxt;
	int i;

	/* Don't include modifier byte */
	memcpy (compare, kbd_data+1, KEYBD_DATALEN-1);

	for (; str != NULL; str = (*nxt) ? (uchar *)(nxt+1) : (uchar *)nxt) {
		uchar c;
		int k;

		c = (uchar) simple_strtoul ((char *)str, (char **) (&nxt), 16);

		if (str == (uchar *)nxt) {	/* invalid character */
			break;
		}

		/*
		 * Check if this key matches the input.
		 * Set matches to zero, so they match only once
		 * and we can find duplicates or extra keys
		 */
		for (k = 0; k < sizeof(compare); ++k) {
			if (compare[k] == '\0')	/* only non-zero entries */
				continue;
			if (c == compare[k]) {	/* found matching key */
				compare[k] = '\0';
				break;
			}
		}
		if (k == sizeof(compare)) {
			return -1;		/* unmatched key */
		}
	}

	/*
	 * A full match leaves no keys in the `compare' array,
	 */
	for (i = 0; i < sizeof(compare); ++i) {
		if (compare[i])
		{
			return -1;
		}
	}

	return 0;
}

/***********************************************************************
F* Function:     static uchar *key_match (uchar *kbd_data) P*A*Z*
 *
P* Parameters:   uchar *kbd_data
P*                - The keys to match against our magic definitions
P*
P* Returnvalue:  uchar *
P*                - != NULL: Pointer to the corresponding command(s)
P*                     NULL: No magic is about to happen
 *
Z* Intention:    Check if pressed key(s) match magic sequence,
Z*               and return the command string associated with that key(s).
Z*
Z*               If no key press was decoded, NULL is returned.
Z*
Z*               Note: the first character of the argument will be
Z*                     overwritten with the "magic charcter code" of the
Z*                     decoded key(s), or '\0'.
Z*
Z*               Note: the string points to static environment data
Z*                     and must be saved before you call any function that
Z*                     modifies the environment.
 *
D* Design:       wd@denx.de
C* Coding:       wd@denx.de
V* Verification: dzu@denx.de
 ***********************************************************************/
static uchar *key_match (uchar *kbd_data)
{
	char magic[sizeof (kbd_magic_prefix) + 1];
	uchar *suffix;
	char *kbd_magic_keys;

	/*
	 * The following string defines the characters that can pe appended
	 * to "key_magic" to form the names of environment variables that
	 * hold "magic" key codes, i. e. such key codes that can cause
	 * pre-boot actions. If the string is empty (""), then only
	 * "key_magic" is checked (old behaviour); the string "125" causes
	 * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
	 */
	if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
		kbd_magic_keys = "";

	/* loop over all magic keys;
	 * use '\0' suffix in case of empty string
	 */
	for (suffix=(uchar *)kbd_magic_keys; *suffix || suffix==(uchar *)kbd_magic_keys; ++suffix) {
		sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
		debug ("### Check magic \"%s\"\n", magic);
		if (compare_magic(kbd_data, (uchar *)getenv(magic)) == 0) {
			char cmd_name[sizeof (kbd_command_prefix) + 1];
			char *cmd;

			sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);

			cmd = getenv (cmd_name);
			debug ("### Set PREBOOT to $(%s): \"%s\"\n",
					cmd_name, cmd ? cmd : "<<NULL>>");
			*kbd_data = *suffix;
			return ((uchar *)cmd);
		}
	}
	debug ("### Delete PREBOOT\n");
	*kbd_data = '\0';
	return (NULL);
}
#endif /* CONFIG_PREBOOT */

/***********************************************************************
F* Function:     int do_kbd (cmd_tbl_t *cmdtp, int flag,
F*                           int argc, char * const argv[]) P*A*Z*
 *
P* Parameters:   cmd_tbl_t *cmdtp
P*                - Pointer to our command table entry
P*               int flag
P*                - If the CMD_FLAG_REPEAT bit is set, then this call is
P*                  a repetition
P*               int argc
P*                - Argument count
P*               char * const argv[]
P*                - Array of the actual arguments
P*
P* Returnvalue:  int
P*                - 0 is always returned.
 *
Z* Intention:    Implement the "kbd" command.
Z*               The keyboard status is read.  The result is printed on
Z*               the console and written into the "keybd" environment
Z*               variable.
 *
D* Design:       wd@denx.de
C* Coding:       wd@denx.de
V* Verification: dzu@denx.de
 ***********************************************************************/
int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	uchar kbd_data[KEYBD_DATALEN];
	char keybd_env[2 * KEYBD_DATALEN + 1];
	uchar val;
	int i;

#if 0 /* Done in kbd_init */
	i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
#endif

	/* Read keys */
	val = KEYBD_CMD_READ_KEYS;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);

	puts ("Keys:");
	for (i = 0; i < KEYBD_DATALEN; ++i) {
		sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
		printf (" %02x", kbd_data[i]);
	}
	putc ('\n');
	setenv ("keybd", keybd_env);
	return 0;
}

U_BOOT_CMD(
	kbd,	1,	1,	do_kbd,
	"read keyboard status",
	""
);

/*----------------------------- Utilities -----------------------------*/

#ifdef CONFIG_POST
/*
 * Returns 1 if keys pressed to start the power-on long-running tests
 * Called from board_init_f().
 */
int post_hotkeys_pressed(void)
{
	uchar kbd_data[KEYBD_DATALEN];
	uchar val;

	/* Read keys */
	val = KEYBD_CMD_READ_KEYS;
	i2c_write (kbd_addr, 0, 0, &val, 1);
	i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);

	return (compare_magic(kbd_data, (uchar *)CONFIG_POST_KEY_MAGIC) == 0);
}
#endif
