/*
 *
 * 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.
 */

#include <linux/config.h>

/* 
 * 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, struct pt_regs *regs);
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 )(SA_INTERRUPT|SA_SHIRQ), 
			(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 pt_regs *regs)
{
	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
