[NETFILTER]: ip6table_mangle: reroute when nfmark changes in NF_IP6_LOCAL_OUT
[hh.org.git] / drivers / char / qtronix.c
blob9d134e98d2a0daa347ca72259579ddb7333b2083
1 /*
3 * BRIEF MODULE DESCRIPTION
4 * Qtronix 990P infrared keyboard driver.
7 * Copyright 2001 MontaVista Software Inc.
8 * Author: MontaVista Software, Inc.
9 * ppopov@mvista.com or source@mvista.com
12 * The bottom portion of this driver was take from
13 * pc_keyb.c Please see that file for copyrights.
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.
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.
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.
37 /*
38 * NOTE:
40 * This driver has only been tested with the Consumer IR
41 * port of the ITE 8172 system controller.
43 * You do not need this driver if you are using the ps/2 or
44 * USB adapter that the keyboard ships with. You only need
45 * this driver if your board has a IR port and the keyboard
46 * data is being sent directly to the IR. In that case,
47 * you also need some low-level IR support. See it8172_cir.c.
51 #ifdef CONFIG_QTRONIX_KEYBOARD
53 #include <linux/module.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kernel.h>
58 #include <asm/it8172/it8172.h>
59 #include <asm/it8172/it8172_int.h>
60 #include <asm/it8172/it8172_cir.h>
62 #include <linux/spinlock.h>
63 #include <linux/sched.h>
64 #include <linux/interrupt.h>
65 #include <linux/tty.h>
66 #include <linux/mm.h>
67 #include <linux/signal.h>
68 #include <linux/init.h>
69 #include <linux/kbd_ll.h>
70 #include <linux/delay.h>
71 #include <linux/poll.h>
72 #include <linux/miscdevice.h>
73 #include <linux/slab.h>
74 #include <linux/kbd_kern.h>
75 #include <linux/smp_lock.h>
76 #include <asm/io.h>
77 #include <linux/pc_keyb.h>
79 #include <asm/keyboard.h>
80 #include <linux/bitops.h>
81 #include <asm/uaccess.h>
82 #include <asm/irq.h>
83 #include <asm/system.h>
85 #define leading1 0
86 #define leading2 0xF
88 #define KBD_CIR_PORT 0
89 #define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */
91 static int data_index;
92 struct cir_port *cir;
93 static unsigned char kbdbytes[5];
94 static unsigned char cir_data[32]; /* we only need 16 chars */
96 static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs);
97 static int handle_data(unsigned char *p_data);
98 static inline void handle_mouse_event(unsigned char scancode);
99 static inline void handle_keyboard_event(unsigned char scancode, int down);
100 static int __init psaux_init(void);
102 static struct aux_queue *queue; /* Mouse data buffer. */
103 static int aux_count = 0;
106 * Keys accessed through the 'Fn' key
107 * The Fn key does not produce a key-up sequence. So, the first
108 * time the user presses it, it will be key-down event. The key
109 * stays down until the user presses it again.
111 #define NUM_FN_KEYS 56
112 static unsigned char fn_keys[NUM_FN_KEYS] = {
113 0,0,0,0,0,0,0,0, /* 0 7 */
114 8,9,10,93,0,0,0,0, /* 8 15 */
115 0,0,0,0,0,0,0,5, /* 16 23 */
116 6,7,91,0,0,0,0,0, /* 24 31 */
117 0,0,0,0,0,2,3,4, /* 32 39 */
118 92,0,0,0,0,0,0,0, /* 40 47 */
119 0,0,0,0,11,0,94,95 /* 48 55 */
123 void __init init_qtronix_990P_kbd(void)
125 int retval;
127 cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL);
128 if (!cir) {
129 printk("Unable to initialize Qtronix keyboard\n");
130 return;
134 * revisit
135 * this should be programmable, somehow by the, by the user.
137 cir->port = KBD_CIR_PORT;
138 cir->baud_rate = 0x1d;
139 cir->rdwos = 0;
140 cir->rxdcr = 0x3;
141 cir->hcfs = 0;
142 cir->fifo_tl = 0;
143 cir->cfq = 0x1d;
144 cir_port_init(cir);
146 retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler,
147 (unsigned long )(IRQF_DISABLED|IRQF_SHARED),
148 (const char *)"Qtronix IR Keyboard", (void *)cir);
150 if (retval) {
151 printk("unable to allocate cir %d irq %d\n",
152 cir->port, IT8172_CIR0_IRQ);
154 #ifdef CONFIG_PSMOUSE
155 psaux_init();
156 #endif
159 static inline unsigned char BitReverse(unsigned short key)
161 unsigned char rkey = 0;
162 rkey |= (key & 0x1) << 7;
163 rkey |= (key & 0x2) << 5;
164 rkey |= (key & 0x4) << 3;
165 rkey |= (key & 0x8) << 1;
166 rkey |= (key & 0x10) >> 1;
167 rkey |= (key & 0x20) >> 3;
168 rkey |= (key & 0x40) >> 5;
169 rkey |= (key & 0x80) >> 7;
170 return rkey;
175 static inline u_int8_t UpperByte(u_int8_t data)
177 return (data >> 4);
181 static inline u_int8_t LowerByte(u_int8_t data)
183 return (data & 0xF);
187 int CheckSumOk(u_int8_t byte1, u_int8_t byte2,
188 u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
190 u_int8_t CheckSum;
192 CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5;
193 if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) )
194 return 0;
195 else
196 return 1;
200 static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs)
202 struct cir_port *cir;
203 int j;
204 unsigned char int_status;
206 cir = (struct cir_port *)dev_id;
207 int_status = get_int_status(cir);
208 if (int_status & 0x4) {
209 clear_fifo(cir);
210 return;
213 while (cir_get_rx_count(cir)) {
215 cir_data[data_index] = cir_read_data(cir);
217 if (data_index == 0) {/* expecting first byte */
218 if (cir_data[data_index] != leading1) {
219 //printk("!leading byte %x\n", cir_data[data_index]);
220 set_rx_active(cir);
221 clear_fifo(cir);
222 continue;
225 if (data_index == 1) {
226 if ((cir_data[data_index] & 0xf) != leading2) {
227 set_rx_active(cir);
228 data_index = 0; /* start over */
229 clear_fifo(cir);
230 continue;
234 if ( (cir_data[data_index] == 0xff)) { /* last byte */
235 //printk("data_index %d\n", data_index);
236 set_rx_active(cir);
237 #if 0
238 for (j=0; j<=data_index; j++) {
239 printk("rx_data %d: %x\n", j, cir_data[j]);
241 #endif
242 data_index = 0;
243 handle_data(cir_data);
244 return;
246 else if (data_index>16) {
247 set_rx_active(cir);
248 #if 0
249 printk("warning: data_index %d\n", data_index);
250 for (j=0; j<=data_index; j++) {
251 printk("rx_data %d: %x\n", j, cir_data[j]);
253 #endif
254 data_index = 0;
255 clear_fifo(cir);
256 return;
258 data_index++;
263 #define NUM_KBD_BYTES 5
264 static int handle_data(unsigned char *p_data)
266 u_int32_t bit_bucket;
267 u_int32_t i, j;
268 u_int32_t got_bits, next_byte;
269 int down = 0;
271 /* Reorganize the bit stream */
272 for (i=0; i<16; i++)
273 p_data[i] = BitReverse(~p_data[i]);
276 * We've already previously checked that p_data[0]
277 * is equal to leading1 and that (p_data[1] & 0xf)
278 * is equal to leading2. These twelve bits are the
279 * leader code. We can now throw them away (the 12
280 * bits) and continue parsing the stream.
282 bit_bucket = p_data[1] << 12;
283 got_bits = 4;
284 next_byte = 2;
287 * Process four bits at a time
289 for (i=0; i<NUM_KBD_BYTES; i++) {
291 kbdbytes[i]=0;
293 for (j=0; j<8; j++) /* 8 bits per byte */
295 if (got_bits < 4) {
296 bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
297 got_bits += 8;
300 if ((bit_bucket & 0xF000) == 0x8000) {
301 /* Convert 1000b to 1 */
302 kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1);
303 got_bits -= 4;
304 bit_bucket = bit_bucket << 4;
306 else if ((bit_bucket & 0xC000) == 0x8000) {
307 /* Convert 10b to 0 */
308 kbdbytes[i] = kbdbytes[i] >> 1;
309 got_bits -= 2;
310 bit_bucket = bit_bucket << 2;
312 else {
313 /* bad serial stream */
314 return 1;
317 if (next_byte > 16) {
318 //printk("error: too many bytes\n");
319 return 1;
325 if (!CheckSumOk(kbdbytes[0], kbdbytes[1],
326 kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
327 //printk("checksum failed\n");
328 return 1;
331 if (kbdbytes[1] & 0x08) {
332 //printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]);
333 handle_mouse_event(kbdbytes[1]);
334 handle_mouse_event(kbdbytes[2]);
335 handle_mouse_event(kbdbytes[3]);
337 else {
338 if (kbdbytes[2] == 0) down = 1;
339 #if 0
340 if (down)
341 printk("down %d\n", kbdbytes[3]);
342 else
343 printk("up %d\n", kbdbytes[3]);
344 #endif
345 handle_keyboard_event(kbdbytes[3], down);
347 return 0;
351 DEFINE_SPINLOCK(kbd_controller_lock);
352 static unsigned char handle_kbd_event(void);
355 int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
357 printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
358 return 0;
361 int kbd_getkeycode(unsigned int scancode)
363 return scancode;
367 int kbd_translate(unsigned char scancode, unsigned char *keycode,
368 char raw_mode)
370 static int prev_scancode = 0;
372 if (scancode == 0x00 || scancode == 0xff) {
373 prev_scancode = 0;
374 return 0;
377 /* todo */
378 if (!prev_scancode && scancode == 160) { /* Fn key down */
379 //printk("Fn key down\n");
380 prev_scancode = 160;
381 return 0;
383 else if (prev_scancode && scancode == 160) { /* Fn key up */
384 //printk("Fn key up\n");
385 prev_scancode = 0;
386 return 0;
389 /* todo */
390 if (prev_scancode == 160) {
391 if (scancode <= NUM_FN_KEYS) {
392 *keycode = fn_keys[scancode];
393 //printk("fn keycode %d\n", *keycode);
395 else
396 return 0;
398 else if (scancode <= 127) {
399 *keycode = scancode;
401 else
402 return 0;
405 return 1;
408 char kbd_unexpected_up(unsigned char keycode)
410 //printk("kbd_unexpected_up\n");
411 return 0;
414 static unsigned char kbd_exists = 1;
416 static inline void handle_keyboard_event(unsigned char scancode, int down)
418 kbd_exists = 1;
419 handle_scancode(scancode, down);
420 tasklet_schedule(&keyboard_tasklet);
424 void kbd_leds(unsigned char leds)
428 /* dummy */
429 void kbd_init_hw(void)
435 static inline void handle_mouse_event(unsigned char scancode)
437 if(scancode == AUX_RECONNECT){
438 queue->head = queue->tail = 0; /* Flush input queue */
439 // __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */
440 return;
443 if (aux_count) {
444 int head = queue->head;
446 queue->buf[head] = scancode;
447 head = (head + 1) & (AUX_BUF_SIZE-1);
448 if (head != queue->tail) {
449 queue->head = head;
450 kill_fasync(&queue->fasync, SIGIO, POLL_IN);
451 wake_up_interruptible(&queue->proc_list);
456 static unsigned char get_from_queue(void)
458 unsigned char result;
459 unsigned long flags;
461 spin_lock_irqsave(&kbd_controller_lock, flags);
462 result = queue->buf[queue->tail];
463 queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
464 spin_unlock_irqrestore(&kbd_controller_lock, flags);
465 return result;
469 static inline int queue_empty(void)
471 return queue->head == queue->tail;
474 static int fasync_aux(int fd, struct file *filp, int on)
476 int retval;
478 //printk("fasync_aux\n");
479 retval = fasync_helper(fd, filp, on, &queue->fasync);
480 if (retval < 0)
481 return retval;
482 return 0;
487 * Random magic cookie for the aux device
489 #define AUX_DEV ((void *)queue)
491 static int release_aux(struct inode * inode, struct file * file)
493 fasync_aux(-1, file, 0);
494 aux_count--;
495 return 0;
498 static int open_aux(struct inode * inode, struct file * file)
500 if (aux_count++) {
501 return 0;
503 queue->head = queue->tail = 0; /* Flush input queue */
504 return 0;
508 * Put bytes from input queue to buffer.
511 static ssize_t read_aux(struct file * file, char * buffer,
512 size_t count, loff_t *ppos)
514 DECLARE_WAITQUEUE(wait, current);
515 ssize_t i = count;
516 unsigned char c;
518 if (queue_empty()) {
519 if (file->f_flags & O_NONBLOCK)
520 return -EAGAIN;
521 add_wait_queue(&queue->proc_list, &wait);
522 repeat:
523 set_current_state(TASK_INTERRUPTIBLE);
524 if (queue_empty() && !signal_pending(current)) {
525 schedule();
526 goto repeat;
528 current->state = TASK_RUNNING;
529 remove_wait_queue(&queue->proc_list, &wait);
531 while (i > 0 && !queue_empty()) {
532 c = get_from_queue();
533 put_user(c, buffer++);
534 i--;
536 if (count-i) {
537 struct inode *inode = file->f_dentry->d_inode;
538 inode->i_atime = current_fs_time(inode->i_sb);
539 return count-i;
541 if (signal_pending(current))
542 return -ERESTARTSYS;
543 return 0;
547 * Write to the aux device.
550 static ssize_t write_aux(struct file * file, const char * buffer,
551 size_t count, loff_t *ppos)
554 * The ITE boards this was tested on did not have the
555 * transmit wires connected.
557 return count;
560 static unsigned int aux_poll(struct file *file, poll_table * wait)
562 poll_wait(file, &queue->proc_list, wait);
563 if (!queue_empty())
564 return POLLIN | POLLRDNORM;
565 return 0;
568 struct file_operations psaux_fops = {
569 .read = read_aux,
570 .write = write_aux,
571 .poll = aux_poll,
572 .open = open_aux,
573 .release = release_aux,
574 .fasync = fasync_aux,
578 * Initialize driver.
580 static struct miscdevice psaux_mouse = {
581 PSMOUSE_MINOR, "psaux", &psaux_fops
584 static int __init psaux_init(void)
586 int retval;
588 retval = misc_register(&psaux_mouse);
589 if(retval < 0)
590 return retval;
592 queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
593 if (!queue) {
594 misc_deregister(&psaux_mouse);
595 return -ENOMEM;
598 memset(queue, 0, sizeof(*queue));
599 queue->head = queue->tail = 0;
600 init_waitqueue_head(&queue->proc_list);
602 return 0;
604 module_init(init_qtronix_990P_kbd);
605 #endif