1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 *	Qtronix 990P infrared keyboard driver.
5 *
6 *
7 * Copyright 2001 MontaVista Software Inc.
8 * Author: MontaVista Software, Inc.
9 *         	ppopov@mvista.com or source@mvista.com
10 *
11 *
12 *  The bottom portion of this driver was take from
13 *  pc_keyb.c  Please see that file for copyrights.
14 *
15 *  This program is free software; you can redistribute  it and/or modify it
16 *  under  the terms of  the GNU General  Public License as published by the
17 *  Free Software Foundation;  either version 2 of the  License, or (at your
18 *  option) any later version.
19 *
20 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
21 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
22 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
23 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
24 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
26 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
28 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 *  You should have received a copy of the  GNU General Public License along
32 *  with this program; if not, write  to the Free Software Foundation, Inc.,
33 *  675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35
36#include <linux/config.h>
37
38/*
39 * NOTE:
40 *
41 *	This driver has only been tested with the Consumer IR
42 *	port of the ITE 8172 system controller.
43 *
44 *	You do not need this driver if you are using the ps/2 or
45 *	USB adapter that the keyboard ships with.  You only need
46 *	this driver if your board has a IR port and the keyboard
47 *	data is being sent directly to the IR.  In that case,
48 *	you also need some low-level IR support. See it8172_cir.c.
49 *
50 */
51
52#ifdef CONFIG_QTRONIX_KEYBOARD
53
54#include <linux/module.h>
55#include <linux/types.h>
56#include <linux/pci.h>
57#include <linux/kernel.h>
58
59#include <asm/it8172/it8172.h>
60#include <asm/it8172/it8172_int.h>
61#include <asm/it8172/it8172_cir.h>
62
63#include <linux/spinlock.h>
64#include <linux/sched.h>
65#include <linux/interrupt.h>
66#include <linux/tty.h>
67#include <linux/mm.h>
68#include <linux/signal.h>
69#include <linux/init.h>
70#include <linux/kbd_ll.h>
71#include <linux/delay.h>
72#include <linux/random.h>
73#include <linux/poll.h>
74#include <linux/miscdevice.h>
75#include <linux/slab.h>
76#include <linux/kbd_kern.h>
77#include <linux/smp_lock.h>
78#include <asm/io.h>
79#include <linux/pc_keyb.h>
80
81#include <asm/keyboard.h>
82#include <asm/bitops.h>
83#include <asm/uaccess.h>
84#include <asm/irq.h>
85#include <asm/system.h>
86
87#define leading1 0
88#define leading2 0xF
89
90#define KBD_CIR_PORT 0
91#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */
92
93static int data_index;
94struct cir_port *cir;
95static unsigned char kbdbytes[5];
96static unsigned char cir_data[32]; /* we only need 16 chars */
97
98static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs);
99static int handle_data(unsigned char *p_data);
100static inline void handle_mouse_event(unsigned char scancode);
101static inline void handle_keyboard_event(unsigned char scancode, int down);
102static int __init psaux_init(void);
103
104static struct aux_queue *queue;	/* Mouse data buffer. */
105static int aux_count = 0;
106
107/*
108 * Keys accessed through the 'Fn' key
109 * The Fn key does not produce a key-up sequence. So, the first
110 * time the user presses it, it will be key-down event. The key
111 * stays down until the user presses it again.
112 */
113#define NUM_FN_KEYS 56
114static unsigned char fn_keys[NUM_FN_KEYS] = {
115	0,0,0,0,0,0,0,0,        /* 0 7   */
116	8,9,10,93,0,0,0,0,      /* 8 15  */
117	0,0,0,0,0,0,0,5,        /* 16 23 */
118	6,7,91,0,0,0,0,0,       /* 24 31 */
119	0,0,0,0,0,2,3,4,        /* 32 39 */
120	92,0,0,0,0,0,0,0,       /* 40 47 */
121	0,0,0,0,11,0,94,95        /* 48 55 */
122
123};
124
125void __init init_qtronix_990P_kbd(void)
126{
127	int retval;
128
129	cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL);
130	if (!cir) {
131		printk("Unable to initialize Qtronix keyboard\n");
132		return;
133	}
134
135	/*
136	 * revisit
137	 * this should be programmable, somehow by the, by the user.
138	 */
139	cir->port = KBD_CIR_PORT;
140	cir->baud_rate = 0x1d;
141	cir->rdwos = 0;
142	cir->rxdcr = 0x3;
143	cir->hcfs = 0;
144	cir->fifo_tl = 0;
145	cir->cfq = 0x1d;
146	cir_port_init(cir);
147
148	retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler,
149			(unsigned long )(SA_INTERRUPT|SA_SHIRQ),
150			(const char *)"Qtronix IR Keyboard", (void *)cir);
151
152	if (retval) {
153		printk("unable to allocate cir %d irq %d\n",
154				cir->port, IT8172_CIR0_IRQ);
155	}
156#ifdef CONFIG_PSMOUSE
157	psaux_init();
158#endif
159}
160
161static inline unsigned char BitReverse(unsigned short key)
162{
163	unsigned char rkey = 0;
164	rkey |= (key & 0x1) << 7;
165	rkey |= (key & 0x2) << 5;
166	rkey |= (key & 0x4) << 3;
167	rkey |= (key & 0x8) << 1;
168	rkey |= (key & 0x10) >> 1;
169	rkey |= (key & 0x20) >> 3;
170	rkey |= (key & 0x40) >> 5;
171	rkey |= (key & 0x80) >> 7;
172	return rkey;
173
174}
175
176
177static inline u_int8_t UpperByte(u_int8_t data)
178{
179	return (data >> 4);
180}
181
182
183static inline u_int8_t LowerByte(u_int8_t data)
184{
185	return (data & 0xF);
186}
187
188
189int CheckSumOk(u_int8_t byte1, u_int8_t byte2,
190		u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
191{
192	u_int8_t CheckSum;
193
194	CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5;
195	if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) )
196		return 0;
197	else
198		return 1;
199}
200
201
202static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs)
203{
204	struct cir_port *cir;
205	int j;
206	unsigned char int_status;
207
208	cir = (struct cir_port *)dev_id;
209	int_status = get_int_status(cir);;
210	if (int_status & 0x4) {
211		clear_fifo(cir);
212		return;
213	}
214
215	while (cir_get_rx_count(cir)) {
216
217		cir_data[data_index] = cir_read_data(cir);
218
219		if (data_index == 0) {/* expecting first byte */
220			if (cir_data[data_index] != leading1) {
221				//printk("!leading byte %x\n", cir_data[data_index]);
222				set_rx_active(cir);
223				clear_fifo(cir);
224				continue;
225			}
226		}
227		if (data_index == 1) {
228			if ((cir_data[data_index] & 0xf) != leading2) {
229				set_rx_active(cir);
230				data_index = 0; /* start over */
231				clear_fifo(cir);
232				continue;
233			}
234		}
235
236		if ( (cir_data[data_index] == 0xff)) { /* last byte */
237			//printk("data_index %d\n", data_index);
238			set_rx_active(cir);
239			data_index = 0;
240			handle_data(cir_data);
241			return;
242		}
243		else if (data_index>16) {
244			set_rx_active(cir);
245			data_index = 0;
246			clear_fifo(cir);
247			return;
248		}
249		data_index++;
250	}
251}
252
253
254#define NUM_KBD_BYTES 5
255static int handle_data(unsigned char *p_data)
256{
257	u_int32_t bit_bucket;
258	u_int32_t i, j;
259	u_int32_t got_bits, next_byte;
260	int down = 0;
261
262	/* Reorganize the bit stream */
263	for (i=0; i<16; i++)
264		p_data[i] = BitReverse(~p_data[i]);
265
266	/*
267	 * We've already previously checked that p_data[0]
268	 * is equal to leading1 and that (p_data[1] & 0xf)
269	 * is equal to leading2. These twelve bits are the
270	 * leader code.  We can now throw them away (the 12
271	 * bits) and continue parsing the stream.
272	 */
273	bit_bucket = p_data[1] << 12;
274	got_bits = 4;
275	next_byte = 2;
276
277	/*
278	 * Process four bits at a time
279	 */
280	for (i=0; i<NUM_KBD_BYTES; i++) {
281
282		kbdbytes[i]=0;
283
284		for (j=0; j<8; j++) /* 8 bits per byte */
285		{
286			if (got_bits < 4) {
287				bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
288				got_bits += 8;
289			}
290
291			if ((bit_bucket & 0xF000) == 0x8000) {
292				/* Convert 1000b to 1 */
293				kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
294				got_bits -= 4;
295				bit_bucket = bit_bucket << 4;
296			}
297			else if ((bit_bucket & 0xC000) == 0x8000) {
298				/* Convert 10b to 0 */
299				kbdbytes[i] =  kbdbytes[i] >> 1;
300				got_bits -= 2;
301				bit_bucket = bit_bucket << 2;
302			}
303			else {
304				/* bad serial stream */
305				return 1;
306			}
307
308			if (next_byte > 16) {
309				//printk("error: too many bytes\n");
310				return 1;
311			}
312		}
313	}
314
315
316	if (!CheckSumOk(kbdbytes[0], kbdbytes[1],
317				kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
318		//printk("checksum failed\n");
319		return 1;
320	}
321
322	if (kbdbytes[1] & 0x08) {
323		//printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
324		handle_mouse_event(kbdbytes[1]);
325		handle_mouse_event(kbdbytes[2]);
326		handle_mouse_event(kbdbytes[3]);
327	}
328	else {
329		if (kbdbytes[2] == 0) down = 1;
330		handle_keyboard_event(kbdbytes[3], down);
331	}
332	return 0;
333}
334
335
336spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
337static unsigned char handle_kbd_event(void);
338
339
340int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
341{
342	printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
343	return 0;
344}
345
346int kbd_getkeycode(unsigned int scancode)
347{
348	return scancode;
349}
350
351
352int kbd_translate(unsigned char scancode, unsigned char *keycode,
353		    char raw_mode)
354{
355	static int prev_scancode = 0;
356
357	if (scancode == 0x00 || scancode == 0xff) {
358		prev_scancode = 0;
359		return 0;
360	}
361
362	/* todo */
363	if (!prev_scancode && scancode == 160) { /* Fn key down */
364		//printk("Fn key down\n");
365		prev_scancode = 160;
366		return 0;
367	}
368	else if (prev_scancode && scancode == 160) { /* Fn key up */
369		//printk("Fn key up\n");
370		prev_scancode = 0;
371		return 0;
372	}
373
374	/* todo */
375	if (prev_scancode == 160) {
376		if (scancode <= NUM_FN_KEYS) {
377			*keycode = fn_keys[scancode];
378			//printk("fn keycode %d\n", *keycode);
379		}
380		else
381			return 0;
382	}
383	else if (scancode <= 127) {
384		*keycode = scancode;
385	}
386	else
387		return 0;
388
389
390 	return 1;
391}
392
393char kbd_unexpected_up(unsigned char keycode)
394{
395	//printk("kbd_unexpected_up\n");
396	return 0;
397}
398
399static unsigned char kbd_exists = 1;
400
401static inline void handle_keyboard_event(unsigned char scancode, int down)
402{
403	kbd_exists = 1;
404	handle_scancode(scancode, down);
405	tasklet_schedule(&keyboard_tasklet);
406}
407
408
409void kbd_leds(unsigned char leds)
410{
411}
412
413/* dummy */
414void kbd_init_hw(void)
415{
416}
417
418
419
420static inline void handle_mouse_event(unsigned char scancode)
421{
422	if(scancode == AUX_RECONNECT){
423		queue->head = queue->tail = 0;  /* Flush input queue */
424	//	__aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
425		return;
426	}
427
428	add_mouse_randomness(scancode);
429	if (aux_count) {
430		int head = queue->head;
431
432		queue->buf[head] = scancode;
433		head = (head + 1) & (AUX_BUF_SIZE-1);
434		if (head != queue->tail) {
435			queue->head = head;
436			kill_fasync(&queue->fasync, SIGIO, POLL_IN);
437			wake_up_interruptible(&queue->proc_list);
438		}
439	}
440}
441
442static unsigned char get_from_queue(void)
443{
444	unsigned char result;
445	unsigned long flags;
446
447	spin_lock_irqsave(&kbd_controller_lock, flags);
448	result = queue->buf[queue->tail];
449	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
450	spin_unlock_irqrestore(&kbd_controller_lock, flags);
451	return result;
452}
453
454
455static inline int queue_empty(void)
456{
457	return queue->head == queue->tail;
458}
459
460static int fasync_aux(int fd, struct file *filp, int on)
461{
462	int retval;
463
464	//printk("fasync_aux\n");
465	retval = fasync_helper(fd, filp, on, &queue->fasync);
466	if (retval < 0)
467		return retval;
468	return 0;
469}
470
471
472/*
473 * Random magic cookie for the aux device
474 */
475#define AUX_DEV ((void *)queue)
476
477static int release_aux(struct inode * inode, struct file * file)
478{
479	lock_kernel();
480	fasync_aux(-1, file, 0);
481	aux_count--;
482	unlock_kernel();
483	return 0;
484}
485
486static int open_aux(struct inode * inode, struct file * file)
487{
488	if (aux_count++) {
489		return 0;
490	}
491	queue->head = queue->tail = 0;		/* Flush input queue */
492	return 0;
493}
494
495/*
496 * Put bytes from input queue to buffer.
497 */
498
499static ssize_t read_aux(struct file * file, char * buffer,
500			size_t count, loff_t *ppos)
501{
502	DECLARE_WAITQUEUE(wait, current);
503	ssize_t i = count;
504	unsigned char c;
505
506	if (queue_empty()) {
507		if (file->f_flags & O_NONBLOCK)
508			return -EAGAIN;
509		add_wait_queue(&queue->proc_list, &wait);
510repeat:
511		set_current_state(TASK_INTERRUPTIBLE);
512		if (queue_empty() && !signal_pending(current)) {
513			schedule();
514			goto repeat;
515		}
516		current->state = TASK_RUNNING;
517		remove_wait_queue(&queue->proc_list, &wait);
518	}
519	while (i > 0 && !queue_empty()) {
520		c = get_from_queue();
521		put_user(c, buffer++);
522		i--;
523	}
524	if (count-i) {
525		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
526		return count-i;
527	}
528	if (signal_pending(current))
529		return -ERESTARTSYS;
530	return 0;
531}
532
533/*
534 * Write to the aux device.
535 */
536
537static ssize_t write_aux(struct file * file, const char * buffer,
538			 size_t count, loff_t *ppos)
539{
540	/*
541	 * The ITE boards this was tested on did not have the
542	 * transmit wires connected.
543	 */
544	return count;
545}
546
547static unsigned int aux_poll(struct file *file, poll_table * wait)
548{
549	poll_wait(file, &queue->proc_list, wait);
550	if (!queue_empty())
551		return POLLIN | POLLRDNORM;
552	return 0;
553}
554
555struct file_operations psaux_fops = {
556	read:		read_aux,
557	write:		write_aux,
558	poll:		aux_poll,
559	open:		open_aux,
560	release:	release_aux,
561	fasync:		fasync_aux,
562};
563
564/*
565 * Initialize driver.
566 */
567static struct miscdevice psaux_mouse = {
568	PSMOUSE_MINOR, "psaux", &psaux_fops
569};
570
571static int __init psaux_init(void)
572{
573	misc_register(&psaux_mouse);
574	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
575	memset(queue, 0, sizeof(*queue));
576	queue->head = queue->tail = 0;
577	init_waitqueue_head(&queue->proc_list);
578
579	return 0;
580}
581module_init(init_qtronix_990P_kbd);
582#endif
583