/*
 *
 * BRIEF MODULE DESCRIPTION
 *	Qtronix 990P infrared keyboard driver.
 *
 *
 * Copyright 2001 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         	ppopov@mvista.com or source@mvista.com
 *
 *
 *  The bottom portion of this driver was take from 
 *  pc_keyb.c  Please see that file for copyrights.
 *
 *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */


/* 
 * NOTE:  
 *
 *	This driver has only been tested with the Consumer IR
 *	port of the ITE 8172 system controller.
 *
 *	You do not need this driver if you are using the ps/2 or
 *	USB adapter that the keyboard ships with.  You only need 
 *	this driver if your board has a IR port and the keyboard
 *	data is being sent directly to the IR.  In that case,
 *	you also need some low-level IR support. See it8172_cir.c.
 *	
 */

#ifdef CONFIG_QTRONIX_KEYBOARD

#include <linux/module.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>

#include <asm/it8172/it8172.h>
#include <asm/it8172/it8172_int.h>
#include <asm/it8172/it8172_cir.h>

#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/signal.h>
#include <linux/init.h>
#include <linux/kbd_ll.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <linux/pc_keyb.h>

#include <asm/keyboard.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/system.h>

#define leading1 0
#define leading2 0xF

#define KBD_CIR_PORT 0
#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */

static int data_index;
struct cir_port *cir;
static unsigned char kbdbytes[5];
static unsigned char cir_data[32]; /* we only need 16 chars */

static void kbd_int_handler(int irq, void *dev_id);
static int handle_data(unsigned char *p_data);
static inline void handle_mouse_event(unsigned char scancode);
static inline void handle_keyboard_event(unsigned char scancode, int down);
static int __init psaux_init(void);

static struct aux_queue *queue;	/* Mouse data buffer. */
static int aux_count = 0;

/*
 * Keys accessed through the 'Fn' key
 * The Fn key does not produce a key-up sequence. So, the first
 * time the user presses it, it will be key-down event. The key
 * stays down until the user presses it again.
 */
#define NUM_FN_KEYS 56
static unsigned char fn_keys[NUM_FN_KEYS] = {
	0,0,0,0,0,0,0,0,        /* 0 7   */
	8,9,10,93,0,0,0,0,      /* 8 15  */
	0,0,0,0,0,0,0,5,        /* 16 23 */
	6,7,91,0,0,0,0,0,       /* 24 31 */
	0,0,0,0,0,2,3,4,        /* 32 39 */
	92,0,0,0,0,0,0,0,       /* 40 47 */
	0,0,0,0,11,0,94,95        /* 48 55 */

};

void __init init_qtronix_990P_kbd(void)
{
	int retval;

	cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL);
	if (!cir) {
		printk("Unable to initialize Qtronix keyboard\n");
		return;
	}

	/* 
	 * revisit
	 * this should be programmable, somehow by the, by the user.
	 */
	cir->port = KBD_CIR_PORT;
	cir->baud_rate = 0x1d;
	cir->rdwos = 0;
	cir->rxdcr = 0x3;
	cir->hcfs = 0;
	cir->fifo_tl = 0;
	cir->cfq = 0x1d;
	cir_port_init(cir);

	retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler, 
			(unsigned long )(IRQF_DISABLED|IRQF_SHARED),
			(const char *)"Qtronix IR Keyboard", (void *)cir);

	if (retval) {
		printk("unable to allocate cir %d irq %d\n", 
				cir->port, IT8172_CIR0_IRQ);
	}
#ifdef CONFIG_PSMOUSE
	psaux_init();
#endif
}

static inline unsigned char BitReverse(unsigned short key)
{
	unsigned char rkey = 0;
	rkey |= (key & 0x1) << 7;
	rkey |= (key & 0x2) << 5;
	rkey |= (key & 0x4) << 3;
	rkey |= (key & 0x8) << 1;
	rkey |= (key & 0x10) >> 1;
	rkey |= (key & 0x20) >> 3;
	rkey |= (key & 0x40) >> 5;
	rkey |= (key & 0x80) >> 7;
	return rkey;

}


static inline u_int8_t UpperByte(u_int8_t data)
{
	return (data >> 4);
}


static inline u_int8_t LowerByte(u_int8_t data)
{
	return (data & 0xF);
}


int CheckSumOk(u_int8_t byte1, u_int8_t byte2, 
		u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
{
	u_int8_t CheckSum;

	CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5;
	if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) )
		return 0;
	else
		return 1;
}


static void kbd_int_handler(int irq, void *dev_id)
{
	struct cir_port *cir;
	int j;
	unsigned char int_status;

	cir = (struct cir_port *)dev_id;
	int_status = get_int_status(cir);
	if (int_status & 0x4) {
		clear_fifo(cir);
		return;
	}

	while (cir_get_rx_count(cir)) {

		cir_data[data_index] = cir_read_data(cir);

		if (data_index == 0) {/* expecting first byte */
			if (cir_data[data_index] != leading1) {
				//printk("!leading byte %x\n", cir_data[data_index]);
				set_rx_active(cir);
				clear_fifo(cir);
				continue;
			}
		}
		if (data_index == 1) {
			if ((cir_data[data_index] & 0xf) != leading2) {
				set_rx_active(cir);
				data_index = 0; /* start over */
				clear_fifo(cir);
				continue;
			}
		}

		if ( (cir_data[data_index] == 0xff)) { /* last byte */
			//printk("data_index %d\n", data_index);
			set_rx_active(cir);
#if 0
			for (j=0; j<=data_index; j++) {
				printk("rx_data %d:  %x\n", j, cir_data[j]);
			}
#endif
			data_index = 0;
			handle_data(cir_data);
			return;
		}
		else if (data_index>16) {
			set_rx_active(cir);
#if 0
			printk("warning: data_index %d\n", data_index);
			for (j=0; j<=data_index; j++) {
				printk("rx_data %d:  %x\n", j, cir_data[j]);
			}
#endif
			data_index = 0;
			clear_fifo(cir);
			return;
		}
		data_index++;
	}
}


#define NUM_KBD_BYTES 5
static int handle_data(unsigned char *p_data)
{
	u_int32_t bit_bucket;
	u_int32_t i, j;
	u_int32_t got_bits, next_byte;
	int down = 0;

	/* Reorganize the bit stream */
	for (i=0; i<16; i++)
		p_data[i] = BitReverse(~p_data[i]);

	/* 
	 * We've already previously checked that p_data[0]
	 * is equal to leading1 and that (p_data[1] & 0xf)
	 * is equal to leading2. These twelve bits are the
	 * leader code.  We can now throw them away (the 12
	 * bits) and continue parsing the stream.
	 */
	bit_bucket = p_data[1] << 12;
	got_bits = 4;
	next_byte = 2;

	/* 
	 * Process four bits at a time
	 */
	for (i=0; i<NUM_KBD_BYTES; i++) {

		kbdbytes[i]=0;

		for (j=0; j<8; j++) /* 8 bits per byte */
		{
			if (got_bits < 4) {
				bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
				got_bits += 8;
			}

			if ((bit_bucket & 0xF000) == 0x8000) { 
				/* Convert 1000b to 1 */
				kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
				got_bits -= 4;
				bit_bucket = bit_bucket << 4;
			}
			else if ((bit_bucket & 0xC000) == 0x8000) {
				/* Convert 10b to 0 */
				kbdbytes[i] =  kbdbytes[i] >> 1;
				got_bits -= 2;
				bit_bucket = bit_bucket << 2;
			}
			else {
				/* bad serial stream */
				return 1;
			}

			if (next_byte > 16) {
				//printk("error: too many bytes\n");
				return 1;
			}
		}
	}


	if (!CheckSumOk(kbdbytes[0], kbdbytes[1], 
				kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
		//printk("checksum failed\n");
		return 1;
	}

	if (kbdbytes[1] & 0x08) {
		//printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
		handle_mouse_event(kbdbytes[1]);
		handle_mouse_event(kbdbytes[2]);
		handle_mouse_event(kbdbytes[3]);
	}
	else {
		if (kbdbytes[2] == 0) down = 1;
#if 0
		if (down)
			printk("down %d\n", kbdbytes[3]);
		else
			printk("up %d\n", kbdbytes[3]);
#endif
		handle_keyboard_event(kbdbytes[3], down);
	}
	return 0;
}


DEFINE_SPINLOCK(kbd_controller_lock);
static unsigned char handle_kbd_event(void);


int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
{
	printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
	return 0;
}

int kbd_getkeycode(unsigned int scancode)
{
	return scancode;
}


int kbd_translate(unsigned char scancode, unsigned char *keycode,
		    char raw_mode)
{
	static int prev_scancode = 0;

	if (scancode == 0x00 || scancode == 0xff) {
		prev_scancode = 0;
		return 0;
	}

	/* todo */
	if (!prev_scancode && scancode == 160) { /* Fn key down */
		//printk("Fn key down\n");
		prev_scancode = 160;
		return 0;
	}
	else if (prev_scancode && scancode == 160) { /* Fn key up */
		//printk("Fn key up\n");
		prev_scancode = 0;
		return 0;
	}

	/* todo */
	if (prev_scancode == 160) {
		if (scancode <= NUM_FN_KEYS) {
			*keycode = fn_keys[scancode];
			//printk("fn keycode %d\n", *keycode);
		}
		else
			return 0;
	} 
	else if (scancode <= 127) {
		*keycode = scancode;
	}
	else
		return 0;


 	return 1;
}

char kbd_unexpected_up(unsigned char keycode)
{
	//printk("kbd_unexpected_up\n");
	return 0;
}

static unsigned char kbd_exists = 1;

static inline void handle_keyboard_event(unsigned char scancode, int down)
{
	kbd_exists = 1;
	handle_scancode(scancode, down);
	tasklet_schedule(&keyboard_tasklet);
}	


void kbd_leds(unsigned char leds)
{
}

/* dummy */
void kbd_init_hw(void)
{
}



static inline void handle_mouse_event(unsigned char scancode)
{
	if(scancode == AUX_RECONNECT){
		queue->head = queue->tail = 0;  /* Flush input queue */
	//	__aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
		return;
	}

	if (aux_count) {
		int head = queue->head;

		queue->buf[head] = scancode;
		head = (head + 1) & (AUX_BUF_SIZE-1);
		if (head != queue->tail) {
			queue->head = head;
			kill_fasync(&queue->fasync, SIGIO, POLL_IN);
			wake_up_interruptible(&queue->proc_list);
		}
	}
}

static unsigned char get_from_queue(void)
{
	unsigned char result;
	unsigned long flags;

	spin_lock_irqsave(&kbd_controller_lock, flags);
	result = queue->buf[queue->tail];
	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
	spin_unlock_irqrestore(&kbd_controller_lock, flags);
	return result;
}


static inline int queue_empty(void)
{
	return queue->head == queue->tail;
}

static int fasync_aux(int fd, struct file *filp, int on)
{
	int retval;

	//printk("fasync_aux\n");
	retval = fasync_helper(fd, filp, on, &queue->fasync);
	if (retval < 0)
		return retval;
	return 0;
}


/*
 * Random magic cookie for the aux device
 */
#define AUX_DEV ((void *)queue)

static int release_aux(struct inode * inode, struct file * file)
{
	fasync_aux(-1, file, 0);
	aux_count--;
	return 0;
}

static int open_aux(struct inode * inode, struct file * file)
{
	if (aux_count++) {
		return 0;
	}
	queue->head = queue->tail = 0;		/* Flush input queue */
	return 0;
}

/*
 * Put bytes from input queue to buffer.
 */

static ssize_t read_aux(struct file * file, char * buffer,
			size_t count, loff_t *ppos)
{
	DECLARE_WAITQUEUE(wait, current);
	ssize_t i = count;
	unsigned char c;

	if (queue_empty()) {
		if (file->f_flags & O_NONBLOCK)
			return -EAGAIN;
		add_wait_queue(&queue->proc_list, &wait);
repeat:
		set_current_state(TASK_INTERRUPTIBLE);
		if (queue_empty() && !signal_pending(current)) {
			schedule();
			goto repeat;
		}
		current->state = TASK_RUNNING;
		remove_wait_queue(&queue->proc_list, &wait);
	}
	while (i > 0 && !queue_empty()) {
		c = get_from_queue();
		put_user(c, buffer++);
		i--;
	}
	if (count-i) {
		struct inode *inode = file->f_dentry->d_inode;
		inode->i_atime = current_fs_time(inode->i_sb);
		return count-i;
	}
	if (signal_pending(current))
		return -ERESTARTSYS;
	return 0;
}

/*
 * Write to the aux device.
 */

static ssize_t write_aux(struct file * file, const char * buffer,
			 size_t count, loff_t *ppos)
{
	/*
	 * The ITE boards this was tested on did not have the
	 * transmit wires connected.
	 */
	return count;
}

static unsigned int aux_poll(struct file *file, poll_table * wait)
{
	poll_wait(file, &queue->proc_list, wait);
	if (!queue_empty())
		return POLLIN | POLLRDNORM;
	return 0;
}

struct file_operations psaux_fops = {
	.read		= read_aux,
	.write		= write_aux,
	.poll		= aux_poll,
	.open		= open_aux,
	.release	= release_aux,
	.fasync		= fasync_aux,
};

/*
 * Initialize driver.
 */
static struct miscdevice psaux_mouse = {
	PSMOUSE_MINOR, "psaux", &psaux_fops
};

static int __init psaux_init(void)
{
	int retval;

	retval = misc_register(&psaux_mouse);
	if(retval < 0)
		return retval;

	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
	if (!queue) {
		misc_deregister(&psaux_mouse);
		return -ENOMEM;
	}
		
	memset(queue, 0, sizeof(*queue));
	queue->head = queue->tail = 0;
	init_waitqueue_head(&queue->proc_list);

	return 0;
}
module_init(init_qtronix_990P_kbd);
#endif
