/*
 *
 * 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, 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 )(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 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
