/***********************************************************************
 *
 * (C) Copyright 2004
 * DENX Software Engineering
 * Wolfgang Denk, wd@denx.de
 * All rights reserved.
 *
 * PS/2 keyboard driver
 *
 * Originally from linux source (drivers/char/pc_keyb.c)
 *
 ***********************************************************************/

#include <common.h>

#ifdef CONFIG_PS2KBD

#include <keyboard.h>
#include <pc_keyb.h>

#undef KBG_DEBUG

#ifdef KBG_DEBUG
#define	PRINTF(fmt,args...)	printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif


/*
 * This reads the keyboard status port, and does the
 * appropriate action.
 *
 */
static unsigned char handle_kbd_event(void)
{
	unsigned char status = kbd_read_status();
	unsigned int work = 10000;

	while ((--work > 0) && (status & KBD_STAT_OBF)) {
		unsigned char scancode;

		scancode = kbd_read_input();

		/* Error bytes must be ignored to make the
		   Synaptics touchpads compaq use work */
		/* Ignore error bytes */
		if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
			if (status & KBD_STAT_MOUSE_OBF)
				; /* not supported: handle_mouse_event(scancode); */
			else
				handle_scancode(scancode);
		}
		status = kbd_read_status();
	}
	if (!work)
		PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
	return status;
}


static int kbd_read_data(void)
{
	int val;
	unsigned char status;

	val = -1;
	status = kbd_read_status();
	if (status & KBD_STAT_OBF) {
		val = kbd_read_input();
		if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
			val = -2;
	}
	return val;
}

static int kbd_wait_for_input(void)
{
	unsigned long timeout;
	int val;

	timeout = KBD_TIMEOUT;
	val=kbd_read_data();
	while(val < 0) {
		if(timeout--==0)
			return -1;
		udelay(1000);
		val=kbd_read_data();
	}
	return val;
}


static int kb_wait(void)
{
	unsigned long timeout = KBC_TIMEOUT * 10;

	do {
		unsigned char status = handle_kbd_event();
		if (!(status & KBD_STAT_IBF))
			return 0; /* ok */
		udelay(1000);
		timeout--;
	} while (timeout);
	return 1;
}

static void kbd_write_command_w(int data)
{
	if(kb_wait())
		PRINTF("timeout in kbd_write_command_w\n");
	kbd_write_command(data);
}

static void kbd_write_output_w(int data)
{
	if(kb_wait())
		PRINTF("timeout in kbd_write_output_w\n");
	kbd_write_output(data);
}

static void kbd_send_data(unsigned char data)
{
	kbd_write_output_w(data);
	kbd_wait_for_input();
}


static char * kbd_initialize(void)
{
	int status;

	/*
	 * Test the keyboard interface.
	 * This seems to be the only way to get it going.
	 * If the test is successful a x55 is placed in the input buffer.
	 */
	kbd_write_command_w(KBD_CCMD_SELF_TEST);
	if (kbd_wait_for_input() != 0x55)
		return "Kbd:   failed self test";
	/*
	 * Perform a keyboard interface test.  This causes the controller
	 * to test the keyboard clock and data lines.  The results of the
	 * test are placed in the input buffer.
	 */
	kbd_write_command_w(KBD_CCMD_KBD_TEST);
	if (kbd_wait_for_input() != 0x00)
		return "Kbd:   interface failed self test";
	/*
	 * Enable the keyboard by allowing the keyboard clock to run.
	 */
	kbd_write_command_w(KBD_CCMD_KBD_ENABLE);

	/*
	 * Reset keyboard. If the read times out
	 * then the assumption is that no keyboard is
	 * plugged into the machine.
	 * This defaults the keyboard to scan-code set 2.
	 *
	 * Set up to try again if the keyboard asks for RESEND.
	 */
	do {
		kbd_write_output_w(KBD_CMD_RESET);
		status = kbd_wait_for_input();
		if (status == KBD_REPLY_ACK)
			break;
		if (status != KBD_REPLY_RESEND) {
			PRINTF("status: %X\n",status);
			return "Kbd:   reset failed, no ACK";
		}
	} while (1);
	if (kbd_wait_for_input() != KBD_REPLY_POR)
		return "Kbd:   reset failed, no POR";

	/*
	 * Set keyboard controller mode. During this, the keyboard should be
	 * in the disabled state.
	 *
	 * Set up to try again if the keyboard asks for RESEND.
	 */
	do {
		kbd_write_output_w(KBD_CMD_DISABLE);
		status = kbd_wait_for_input();
		if (status == KBD_REPLY_ACK)
			break;
		if (status != KBD_REPLY_RESEND)
			return "Kbd:   disable keyboard: no ACK";
	} while (1);

	kbd_write_command_w(KBD_CCMD_WRITE_MODE);
	kbd_write_output_w(KBD_MODE_KBD_INT
			      | KBD_MODE_SYS
			      | KBD_MODE_DISABLE_MOUSE
			      | KBD_MODE_KCC);

	/* AMCC powerpc portables need this to use scan-code set 1 -- Cort */
	kbd_write_command_w(KBD_CCMD_READ_MODE);
	if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
		/*
		 * If the controller does not support conversion,
		 * Set the keyboard to scan-code set 1.
		 */
		kbd_write_output_w(0xF0);
		kbd_wait_for_input();
		kbd_write_output_w(0x01);
		kbd_wait_for_input();
	}
	kbd_write_output_w(KBD_CMD_ENABLE);
	if (kbd_wait_for_input() != KBD_REPLY_ACK)
		return "Kbd:   enable keyboard: no ACK";

	/*
	 * Finally, set the typematic rate to maximum.
	 */
	kbd_write_output_w(KBD_CMD_SET_RATE);
	if (kbd_wait_for_input() != KBD_REPLY_ACK)
		return "Kbd:   Set rate: no ACK";
	kbd_write_output_w(0x00);
	if (kbd_wait_for_input() != KBD_REPLY_ACK)
		return "Kbd:   Set rate: no ACK";
	return NULL;
}

static void kbd_interrupt(void *dev_id)
{
	handle_kbd_event();
}

/******************************************************************
 * Init
 ******************************************************************/

int kbd_init_hw(void)
{
	char* result;

	kbd_request_region();

	result=kbd_initialize();
	if (result==NULL) {
		PRINTF("AT Keyboard initialized\n");
		kbd_request_irq(kbd_interrupt);
		return (1);
	} else {
		printf("%s\n",result);
		return (-1);
	}
}

void pckbd_leds(unsigned char leds)
{
	kbd_send_data(KBD_CMD_SET_LEDS);
	kbd_send_data(leds);
}

#endif /* CONFIG_PS2KBD */
