[PATCH] solaris emulation: incorrect tty locking
[linux-2.6] / drivers / char / qtronix.c
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
37 /* 
38  * NOTE:  
39  *
40  *      This driver has only been tested with the Consumer IR
41  *      port of the ITE 8172 system controller.
42  *
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.
48  *      
49  */
50
51 #ifdef CONFIG_QTRONIX_KEYBOARD
52
53 #include <linux/module.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kernel.h>
57
58 #include <asm/it8172/it8172.h>
59 #include <asm/it8172/it8172_int.h>
60 #include <asm/it8172/it8172_cir.h>
61
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>
78
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>
84
85 #define leading1 0
86 #define leading2 0xF
87
88 #define KBD_CIR_PORT 0
89 #define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */
90
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 */
95
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);
101
102 static struct aux_queue *queue; /* Mouse data buffer. */
103 static int aux_count = 0;
104
105 /*
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.
110  */
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 */
120
121 };
122
123 void __init init_qtronix_990P_kbd(void)
124 {
125         int retval;
126
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;
131         }
132
133         /* 
134          * revisit
135          * this should be programmable, somehow by the, by the user.
136          */
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);
145
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);
149
150         if (retval) {
151                 printk("unable to allocate cir %d irq %d\n", 
152                                 cir->port, IT8172_CIR0_IRQ);
153         }
154 #ifdef CONFIG_PSMOUSE
155         psaux_init();
156 #endif
157 }
158
159 static inline unsigned char BitReverse(unsigned short key)
160 {
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;
171
172 }
173
174
175 static inline u_int8_t UpperByte(u_int8_t data)
176 {
177         return (data >> 4);
178 }
179
180
181 static inline u_int8_t LowerByte(u_int8_t data)
182 {
183         return (data & 0xF);
184 }
185
186
187 int CheckSumOk(u_int8_t byte1, u_int8_t byte2, 
188                 u_int8_t byte3, u_int8_t byte4, u_int8_t byte5)
189 {
190         u_int8_t CheckSum;
191
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;
197 }
198
199
200 static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs)
201 {
202         struct cir_port *cir;
203         int j;
204         unsigned char int_status;
205
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;
211         }
212
213         while (cir_get_rx_count(cir)) {
214
215                 cir_data[data_index] = cir_read_data(cir);
216
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;
223                         }
224                 }
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;
231                         }
232                 }
233
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]);
240                         }
241 #endif
242                         data_index = 0;
243                         handle_data(cir_data);
244                         return;
245                 }
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]);
252                         }
253 #endif
254                         data_index = 0;
255                         clear_fifo(cir);
256                         return;
257                 }
258                 data_index++;
259         }
260 }
261
262
263 #define NUM_KBD_BYTES 5
264 static int handle_data(unsigned char *p_data)
265 {
266         u_int32_t bit_bucket;
267         u_int32_t i, j;
268         u_int32_t got_bits, next_byte;
269         int down = 0;
270
271         /* Reorganize the bit stream */
272         for (i=0; i<16; i++)
273                 p_data[i] = BitReverse(~p_data[i]);
274
275         /* 
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.
281          */
282         bit_bucket = p_data[1] << 12;
283         got_bits = 4;
284         next_byte = 2;
285
286         /* 
287          * Process four bits at a time
288          */
289         for (i=0; i<NUM_KBD_BYTES; i++) {
290
291                 kbdbytes[i]=0;
292
293                 for (j=0; j<8; j++) /* 8 bits per byte */
294                 {
295                         if (got_bits < 4) {
296                                 bit_bucket |= (p_data[next_byte++] << (8 - got_bits));
297                                 got_bits += 8;
298                         }
299
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;
305                         }
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;
311                         }
312                         else {
313                                 /* bad serial stream */
314                                 return 1;
315                         }
316
317                         if (next_byte > 16) {
318                                 //printk("error: too many bytes\n");
319                                 return 1;
320                         }
321                 }
322         }
323
324
325         if (!CheckSumOk(kbdbytes[0], kbdbytes[1], 
326                                 kbdbytes[2], kbdbytes[3], kbdbytes[4])) {
327                 //printk("checksum failed\n");
328                 return 1;
329         }
330
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]);
336         }
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);
346         }
347         return 0;
348 }
349
350
351 DEFINE_SPINLOCK(kbd_controller_lock);
352 static unsigned char handle_kbd_event(void);
353
354
355 int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
356 {
357         printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode);
358         return 0;
359 }
360
361 int kbd_getkeycode(unsigned int scancode)
362 {
363         return scancode;
364 }
365
366
367 int kbd_translate(unsigned char scancode, unsigned char *keycode,
368                     char raw_mode)
369 {
370         static int prev_scancode = 0;
371
372         if (scancode == 0x00 || scancode == 0xff) {
373                 prev_scancode = 0;
374                 return 0;
375         }
376
377         /* todo */
378         if (!prev_scancode && scancode == 160) { /* Fn key down */
379                 //printk("Fn key down\n");
380                 prev_scancode = 160;
381                 return 0;
382         }
383         else if (prev_scancode && scancode == 160) { /* Fn key up */
384                 //printk("Fn key up\n");
385                 prev_scancode = 0;
386                 return 0;
387         }
388
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);
394                 }
395                 else
396                         return 0;
397         } 
398         else if (scancode <= 127) {
399                 *keycode = scancode;
400         }
401         else
402                 return 0;
403
404
405         return 1;
406 }
407
408 char kbd_unexpected_up(unsigned char keycode)
409 {
410         //printk("kbd_unexpected_up\n");
411         return 0;
412 }
413
414 static unsigned char kbd_exists = 1;
415
416 static inline void handle_keyboard_event(unsigned char scancode, int down)
417 {
418         kbd_exists = 1;
419         handle_scancode(scancode, down);
420         tasklet_schedule(&keyboard_tasklet);
421 }       
422
423
424 void kbd_leds(unsigned char leds)
425 {
426 }
427
428 /* dummy */
429 void kbd_init_hw(void)
430 {
431 }
432
433
434
435 static inline void handle_mouse_event(unsigned char scancode)
436 {
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;
441         }
442
443         if (aux_count) {
444                 int head = queue->head;
445
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);
452                 }
453         }
454 }
455
456 static unsigned char get_from_queue(void)
457 {
458         unsigned char result;
459         unsigned long flags;
460
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;
466 }
467
468
469 static inline int queue_empty(void)
470 {
471         return queue->head == queue->tail;
472 }
473
474 static int fasync_aux(int fd, struct file *filp, int on)
475 {
476         int retval;
477
478         //printk("fasync_aux\n");
479         retval = fasync_helper(fd, filp, on, &queue->fasync);
480         if (retval < 0)
481                 return retval;
482         return 0;
483 }
484
485
486 /*
487  * Random magic cookie for the aux device
488  */
489 #define AUX_DEV ((void *)queue)
490
491 static int release_aux(struct inode * inode, struct file * file)
492 {
493         fasync_aux(-1, file, 0);
494         aux_count--;
495         return 0;
496 }
497
498 static int open_aux(struct inode * inode, struct file * file)
499 {
500         if (aux_count++) {
501                 return 0;
502         }
503         queue->head = queue->tail = 0;          /* Flush input queue */
504         return 0;
505 }
506
507 /*
508  * Put bytes from input queue to buffer.
509  */
510
511 static ssize_t read_aux(struct file * file, char * buffer,
512                         size_t count, loff_t *ppos)
513 {
514         DECLARE_WAITQUEUE(wait, current);
515         ssize_t i = count;
516         unsigned char c;
517
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;
527                 }
528                 current->state = TASK_RUNNING;
529                 remove_wait_queue(&queue->proc_list, &wait);
530         }
531         while (i > 0 && !queue_empty()) {
532                 c = get_from_queue();
533                 put_user(c, buffer++);
534                 i--;
535         }
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;
540         }
541         if (signal_pending(current))
542                 return -ERESTARTSYS;
543         return 0;
544 }
545
546 /*
547  * Write to the aux device.
548  */
549
550 static ssize_t write_aux(struct file * file, const char * buffer,
551                          size_t count, loff_t *ppos)
552 {
553         /*
554          * The ITE boards this was tested on did not have the
555          * transmit wires connected.
556          */
557         return count;
558 }
559
560 static unsigned int aux_poll(struct file *file, poll_table * wait)
561 {
562         poll_wait(file, &queue->proc_list, wait);
563         if (!queue_empty())
564                 return POLLIN | POLLRDNORM;
565         return 0;
566 }
567
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,
575 };
576
577 /*
578  * Initialize driver.
579  */
580 static struct miscdevice psaux_mouse = {
581         PSMOUSE_MINOR, "psaux", &psaux_fops
582 };
583
584 static int __init psaux_init(void)
585 {
586         int retval;
587
588         retval = misc_register(&psaux_mouse);
589         if(retval < 0)
590                 return retval;
591
592         queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
593         if (!queue) {
594                 misc_deregister(&psaux_mouse);
595                 return -ENOMEM;
596         }
597                 
598         memset(queue, 0, sizeof(*queue));
599         queue->head = queue->tail = 0;
600         init_waitqueue_head(&queue->proc_list);
601
602         return 0;
603 }
604 module_init(init_qtronix_990P_kbd);
605 #endif