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 
93 static int data_index;
94 struct cir_port *cir;
95 static unsigned char kbdbytes[5];
96 static unsigned char cir_data[32]; /* we only need 16 chars */
97 
98 static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs);
99 static int handle_data(unsigned char *p_data);
100 static inline void handle_mouse_event(unsigned char scancode);
101 static inline void handle_keyboard_event(unsigned char scancode, int down);
102 static int __init psaux_init(void);
103 
104 static struct aux_queue *queue;	/* Mouse data buffer. */
105 static 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
114 static 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 
init_qtronix_990P_kbd(void)125 void __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 
BitReverse(unsigned short key)161 static 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 
UpperByte(u_int8_t data)177 static inline u_int8_t UpperByte(u_int8_t data)
178 {
179 	return (data >> 4);
180 }
181 
182 
LowerByte(u_int8_t data)183 static inline u_int8_t LowerByte(u_int8_t data)
184 {
185 	return (data & 0xF);
186 }
187 
188 
CheckSumOk(u_int8_t byte1,u_int8_t byte2,u_int8_t byte3,u_int8_t byte4,u_int8_t byte5)189 int 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 
kbd_int_handler(int irq,void * dev_id,struct pt_regs * regs)202 static 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 #if 0
240 			for (j=0; j<=data_index; j++) {
241 				printk("rx_data %d:  %x\n", j, cir_data[j]);
242 			}
243 #endif
244 			data_index = 0;
245 			handle_data(cir_data);
246 			return;
247 		}
248 		else if (data_index>16) {
249 			set_rx_active(cir);
250 #if 0
251 			printk("warning: data_index %d\n", data_index);
252 			for (j=0; j<=data_index; j++) {
253 				printk("rx_data %d:  %x\n", j, cir_data[j]);
254 			}
255 #endif
256 			data_index = 0;
257 			clear_fifo(cir);
258 			return;
259 		}
260 		data_index++;
261 	}
262 }
263 
264 
265 #define NUM_KBD_BYTES 5
handle_data(unsigned char * p_data)266 static int handle_data(unsigned char *p_data)
267 {
268 	u_int32_t bit_bucket;
269 	u_int32_t i, j;
270 	u_int32_t got_bits, next_byte;
271 	int down = 0;
272 
273 	/* Reorganize the bit stream */
274 	for (i=0; i<16; i++)
275 		p_data[i] = BitReverse(~p_data[i]);
276 
277 	/*
278 	 * We've already previously checked that p_data[0]
279 	 * is equal to leading1 and that (p_data[1] & 0xf)
280 	 * is equal to leading2. These twelve bits are the
281 	 * leader code.  We can now throw them away (the 12
282 	 * bits) and continue parsing the stream.
283 	 */
284 	bit_bucket = p_data[1] << 12;
285 	got_bits = 4;
286 	next_byte = 2;
287 
288 	/*
289 	 * Process four bits at a time
290 	 */
291 	for (i=0; i<NUM_KBD_BYTES; i++) {
292 
293 		kbdbytes[i]=0;
294 
295 		for (j=0; j<8; j++) /* 8 bits per byte */
296 		{
297 			if (got_bits < 4) {
298 				bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
299 				got_bits += 8;
300 			}
301 
302 			if ((bit_bucket & 0xF000) == 0x8000) {
303 				/* Convert 1000b to 1 */
304 				kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
305 				got_bits -= 4;
306 				bit_bucket = bit_bucket << 4;
307 			}
308 			else if ((bit_bucket & 0xC000) == 0x8000) {
309 				/* Convert 10b to 0 */
310 				kbdbytes[i] =  kbdbytes[i] >> 1;
311 				got_bits -= 2;
312 				bit_bucket = bit_bucket << 2;
313 			}
314 			else {
315 				/* bad serial stream */
316 				return 1;
317 			}
318 
319 			if (next_byte > 16) {
320 				//printk("error: too many bytes\n");
321 				return 1;
322 			}
323 		}
324 	}
325 
326 
327 	if (!CheckSumOk(kbdbytes[0], kbdbytes[1],
328 				kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
329 		//printk("checksum failed\n");
330 		return 1;
331 	}
332 
333 	if (kbdbytes[1] & 0x08) {
334 		//printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
335 		handle_mouse_event(kbdbytes[1]);
336 		handle_mouse_event(kbdbytes[2]);
337 		handle_mouse_event(kbdbytes[3]);
338 	}
339 	else {
340 		if (kbdbytes[2] == 0) down = 1;
341 #if 0
342 		if (down)
343 			printk("down %d\n", kbdbytes[3]);
344 		else
345 			printk("up %d\n", kbdbytes[3]);
346 #endif
347 		handle_keyboard_event(kbdbytes[3], down);
348 	}
349 	return 0;
350 }
351 
352 
353 spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
354 static unsigned char handle_kbd_event(void);
355 
356 
kbd_setkeycode(unsigned int scancode,unsigned int keycode)357 int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
358 {
359 	printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
360 	return 0;
361 }
362 
kbd_getkeycode(unsigned int scancode)363 int kbd_getkeycode(unsigned int scancode)
364 {
365 	return scancode;
366 }
367 
368 
kbd_translate(unsigned char scancode,unsigned char * keycode,char raw_mode)369 int kbd_translate(unsigned char scancode, unsigned char *keycode,
370 		    char raw_mode)
371 {
372 	static int prev_scancode = 0;
373 
374 	if (scancode == 0x00 || scancode == 0xff) {
375 		prev_scancode = 0;
376 		return 0;
377 	}
378 
379 	/* todo */
380 	if (!prev_scancode && scancode == 160) { /* Fn key down */
381 		//printk("Fn key down\n");
382 		prev_scancode = 160;
383 		return 0;
384 	}
385 	else if (prev_scancode && scancode == 160) { /* Fn key up */
386 		//printk("Fn key up\n");
387 		prev_scancode = 0;
388 		return 0;
389 	}
390 
391 	/* todo */
392 	if (prev_scancode == 160) {
393 		if (scancode <= NUM_FN_KEYS) {
394 			*keycode = fn_keys[scancode];
395 			//printk("fn keycode %d\n", *keycode);
396 		}
397 		else
398 			return 0;
399 	}
400 	else if (scancode <= 127) {
401 		*keycode = scancode;
402 	}
403 	else
404 		return 0;
405 
406 
407  	return 1;
408 }
409 
kbd_unexpected_up(unsigned char keycode)410 char kbd_unexpected_up(unsigned char keycode)
411 {
412 	//printk("kbd_unexpected_up\n");
413 	return 0;
414 }
415 
416 static unsigned char kbd_exists = 1;
417 
handle_keyboard_event(unsigned char scancode,int down)418 static inline void handle_keyboard_event(unsigned char scancode, int down)
419 {
420 	kbd_exists = 1;
421 	handle_scancode(scancode, down);
422 	tasklet_schedule(&keyboard_tasklet);
423 }
424 
425 
kbd_leds(unsigned char leds)426 void kbd_leds(unsigned char leds)
427 {
428 }
429 
430 /* dummy */
kbd_init_hw(void)431 void kbd_init_hw(void)
432 {
433 }
434 
435 
436 
handle_mouse_event(unsigned char scancode)437 static inline void handle_mouse_event(unsigned char scancode)
438 {
439 	if(scancode == AUX_RECONNECT){
440 		queue->head = queue->tail = 0;  /* Flush input queue */
441 	//	__aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
442 		return;
443 	}
444 
445 	add_mouse_randomness(scancode);
446 	if (aux_count) {
447 		int head = queue->head;
448 
449 		queue->buf[head] = scancode;
450 		head = (head + 1) & (AUX_BUF_SIZE-1);
451 		if (head != queue->tail) {
452 			queue->head = head;
453 			kill_fasync(&queue->fasync, SIGIO, POLL_IN);
454 			wake_up_interruptible(&queue->proc_list);
455 		}
456 	}
457 }
458 
get_from_queue(void)459 static unsigned char get_from_queue(void)
460 {
461 	unsigned char result;
462 	unsigned long flags;
463 
464 	spin_lock_irqsave(&kbd_controller_lock, flags);
465 	result = queue->buf[queue->tail];
466 	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
467 	spin_unlock_irqrestore(&kbd_controller_lock, flags);
468 	return result;
469 }
470 
471 
queue_empty(void)472 static inline int queue_empty(void)
473 {
474 	return queue->head == queue->tail;
475 }
476 
fasync_aux(int fd,struct file * filp,int on)477 static int fasync_aux(int fd, struct file *filp, int on)
478 {
479 	int retval;
480 
481 	//printk("fasync_aux\n");
482 	retval = fasync_helper(fd, filp, on, &queue->fasync);
483 	if (retval < 0)
484 		return retval;
485 	return 0;
486 }
487 
488 
489 /*
490  * Random magic cookie for the aux device
491  */
492 #define AUX_DEV ((void *)queue)
493 
release_aux(struct inode * inode,struct file * file)494 static int release_aux(struct inode * inode, struct file * file)
495 {
496 	lock_kernel();
497 	fasync_aux(-1, file, 0);
498 	aux_count--;
499 	unlock_kernel();
500 	return 0;
501 }
502 
open_aux(struct inode * inode,struct file * file)503 static int open_aux(struct inode * inode, struct file * file)
504 {
505 	if (aux_count++) {
506 		return 0;
507 	}
508 	queue->head = queue->tail = 0;		/* Flush input queue */
509 	return 0;
510 }
511 
512 /*
513  * Put bytes from input queue to buffer.
514  */
515 
read_aux(struct file * file,char * buffer,size_t count,loff_t * ppos)516 static ssize_t read_aux(struct file * file, char * buffer,
517 			size_t count, loff_t *ppos)
518 {
519 	DECLARE_WAITQUEUE(wait, current);
520 	ssize_t i = count;
521 	unsigned char c;
522 
523 	if (queue_empty()) {
524 		if (file->f_flags & O_NONBLOCK)
525 			return -EAGAIN;
526 		add_wait_queue(&queue->proc_list, &wait);
527 repeat:
528 		set_current_state(TASK_INTERRUPTIBLE);
529 		if (queue_empty() && !signal_pending(current)) {
530 			schedule();
531 			goto repeat;
532 		}
533 		current->state = TASK_RUNNING;
534 		remove_wait_queue(&queue->proc_list, &wait);
535 	}
536 	while (i > 0 && !queue_empty()) {
537 		c = get_from_queue();
538 		put_user(c, buffer++);
539 		i--;
540 	}
541 	if (count-i) {
542 		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
543 		return count-i;
544 	}
545 	if (signal_pending(current))
546 		return -ERESTARTSYS;
547 	return 0;
548 }
549 
550 /*
551  * Write to the aux device.
552  */
553 
write_aux(struct file * file,const char * buffer,size_t count,loff_t * ppos)554 static ssize_t write_aux(struct file * file, const char * buffer,
555 			 size_t count, loff_t *ppos)
556 {
557 	/*
558 	 * The ITE boards this was tested on did not have the
559 	 * transmit wires connected.
560 	 */
561 	return count;
562 }
563 
aux_poll(struct file * file,poll_table * wait)564 static unsigned int aux_poll(struct file *file, poll_table * wait)
565 {
566 	poll_wait(file, &queue->proc_list, wait);
567 	if (!queue_empty())
568 		return POLLIN | POLLRDNORM;
569 	return 0;
570 }
571 
572 struct file_operations psaux_fops = {
573 	read:		read_aux,
574 	write:		write_aux,
575 	poll:		aux_poll,
576 	open:		open_aux,
577 	release:	release_aux,
578 	fasync:		fasync_aux,
579 };
580 
581 /*
582  * Initialize driver.
583  */
584 static struct miscdevice psaux_mouse = {
585 	PSMOUSE_MINOR, "psaux", &psaux_fops
586 };
587 
psaux_init(void)588 static int __init psaux_init(void)
589 {
590 	int retval;
591 
592 	retval = misc_register(&psaux_mouse);
593 	if(retval < 0)
594 		return retval;
595 
596 	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
597 	memset(queue, 0, sizeof(*queue));
598 	queue->head = queue->tail = 0;
599 	init_waitqueue_head(&queue->proc_list);
600 
601 	return 0;
602 }
603 module_init(init_qtronix_990P_kbd);
604 #endif
605