cleanup
[linux-2.4.21-pre4.git] / drivers / char / q40_keyb.c
1 /*
2  * linux/drivers/char/q40_keyb.c
3  *
4  */
5
6 #include <linux/config.h>
7
8 #include <linux/spinlock.h>
9 #include <linux/sched.h>
10 #include <linux/interrupt.h>
11 #include <linux/tty.h>
12 #include <linux/mm.h>
13 #include <linux/keyboard.h>
14 #include <linux/signal.h>
15 #include <linux/ioport.h>
16 #include <linux/init.h>
17 #include <linux/kbd_ll.h>
18 #include <linux/kbd_kern.h>
19 #include <linux/delay.h>
20 #include <linux/sysrq.h>
21 #include <linux/random.h>
22 #include <linux/poll.h>
23 #include <linux/miscdevice.h>
24 #include <linux/slab.h>
25
26 #include <asm/keyboard.h>
27 #include <asm/bitops.h>
28 #include <asm/io.h>
29 #include <asm/uaccess.h>
30 #include <asm/q40_master.h>
31 #include <asm/irq.h>
32 #include <asm/q40ints.h>
33
34
35 /* Simple translation table for the SysRq keys */
36
37 #define SYSRQ_KEY 0x54
38
39 #ifdef CONFIG_MAGIC_SYSRQ
40 unsigned char q40kbd_sysrq_xlate[128] =
41         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
42         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
43         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
44         "bnm,./\000*\000 \000\201\202\203\204\205"      /* 0x30 - 0x3f */
45         "\206\207\210\211\212\000\000789-456+1"         /* 0x40 - 0x4f */
46         "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
47         "\r\000/";                                      /* 0x60 - 0x6f */
48 #endif
49
50 /* Q40 uses AT scancodes - no way to change it. so we have to translate ..*/
51 /* 0x00 means not a valid entry or no conversion known                    */
52
53 unsigned static char q40cl[256] =
54 {/* 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   a,   b,   c,   d,   e,   f, */
55  0x00,0x43,0x00,0x3f,0x3d,0x3b,0x3c,0x58,0x00,0x44,0x42,0x40,0x3e,0x0f,0x29,0x00,     /* 0x00 - 0x0f */
56  0x00,0x38,0x2a,0x00,0x1d,0x10,0x02,0x00,0x00,0x00,0x2c,0x1f,0x1e,0x11,0x03,0x00,     /* 0x10 - 0x1f */
57  0x00,0x2e,0x2d,0x20,0x12,0x05,0x04,0x00,0x21,0x39,0x2f,0x21,0x14,0x13,0x06,0x00,     /* 0x20 - 0x2f  'f' is at 0x2b, what is 0x28 ???*/
58  0x00,0x31,0x30,0x23,0x22,0x15,0x07,0x00,0x24,0x00,0x32,0x24,0x16,0x08,0x09,0x00,     /* 0x30 - 0x3f */
59  0x00,0x33,0x25,0x17,0x18,0x0b,0x0a,0x00,0x00,0x34,0x35,0x26,0x27,0x19,0x0c,0x00,     /* 0x40 - 0x4f */
60  0x00,0x00,0x28,0x00,0x1a,0x0d,0x00,0x00,0x3a,0x36,0x1c,0x1b,0x00,0x2b,0x00,0x00,     /* 0x50 - 0x5f*/
61  0x00,0x56,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x4f,0x00,0x4b,0x47,0x00,0x00,0x00,     /* 0x60 - 0x6f */
62  0x52,0x53,0x50,0x4c,0x4d,0x48,0x01,0x45,0x57,0x4e,0x51,0x4a,0x37,0x49,0x46,0x00,     /* 0x70 - 0x7f */
63  0x00,0x00,0x00,0x41,0x37,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x80 - 0x8f  0x84/0x37 is SySrq*/
64  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x90 - 0x9f */
65  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xa0 - 0xaf */
66  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xb0 - 0xbf */
67  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xc0 - 0xcf */
68  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xd0 - 0xdf */
69  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xe0 - 0xef */
70  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xf0 - 0xff */
71 };
72
73 /* another table, AT 0xe0 codes to PC 0xe0 codes, 
74    0xff special entry for SysRq - DROPPED right now  */
75 static unsigned char q40ecl[]=
76 {/* 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   a,   b,   c,   d,   e,   f, */
77  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x00 - 0x0f*/
78  0x00,0x38,0x2a,0x00,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x10 - 0x1f */
79  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x20 - 0x2f*/
80  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x30 - 0x3f*/
81  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x00,0x00,     /* 0x40 - 0x4f*/
82  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x1c,0x00,0x00,0x00,0x00,0x00,     /* 0x50 - 0x5f*/
83  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x00,0x4b,0x47,0x00,0x00,0x00,     /* 0x60 - 0x6f*/
84  0x52,0x53,0x50,0x00,0x4d,0x48,0x00,0x00,0x00,0x00,0x51,0x00,0x00,0x49,0x00,0x00,     /* 0x70 - 0x7f*/
85  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x80 - 0x8f*/
86  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0x90 - 0x9f*/
87  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xa0 - 0xaf*/
88  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xb0 - 0xbf*/
89  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xc0 - 0xcf*/
90  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xd0 - 0xdf*/
91  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,     /* 0xe0 - 0xef*/
92  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00      /* 0xf0 - 0xff*/
93 };
94
95
96 static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
97
98
99 /*
100  * Translation of escaped scancodes to keycodes.
101  * This is now user-settable.
102  * The keycodes 1-88,96-111,119 are fairly standard, and
103  * should probably not be changed - changing might confuse X.
104  * X also interprets scancode 0x5d (KEY_Begin).
105  *
106  * For 1-88 keycode equals scancode.
107  */
108
109 #define E0_KPENTER 96
110 #define E0_RCTRL   97
111 #define E0_KPSLASH 98
112 #define E0_PRSCR   99
113 #define E0_RALT    100
114 #define E0_BREAK   101  /* (control-pause) */
115 #define E0_HOME    102
116 #define E0_UP      103
117 #define E0_PGUP    104
118 #define E0_LEFT    105
119 #define E0_RIGHT   106
120 #define E0_END     107
121 #define E0_DOWN    108
122 #define E0_PGDN    109
123 #define E0_INS     110
124 #define E0_DEL     111
125
126 #define E1_PAUSE   119
127
128 /*
129  * The keycodes below are randomly located in 89-95,112-118,120-127.
130  * They could be thrown away (and all occurrences below replaced by 0),
131  * but that would force many users to use the `setkeycodes' utility, where
132  * they needed not before. It does not matter that there are duplicates, as
133  * long as no duplication occurs for any single keyboard.
134  */
135 #define SC_LIM 89
136
137 #define FOCUS_PF1 85           /* actual code! */
138 #define FOCUS_PF2 89
139 #define FOCUS_PF3 90
140 #define FOCUS_PF4 91
141 #define FOCUS_PF5 92
142 #define FOCUS_PF6 93
143 #define FOCUS_PF7 94
144 #define FOCUS_PF8 95
145 #define FOCUS_PF9 120
146 #define FOCUS_PF10 121
147 #define FOCUS_PF11 122
148 #define FOCUS_PF12 123
149
150 #define JAP_86     124
151 /* tfj@olivia.ping.dk:
152  * The four keys are located over the numeric keypad, and are
153  * labelled A1-A4. It's an rc930 keyboard, from
154  * Regnecentralen/RC International, Now ICL.
155  * Scancodes: 59, 5a, 5b, 5c.
156  */
157 #define RGN1 124
158 #define RGN2 125
159 #define RGN3 126
160 #define RGN4 127
161
162 static unsigned char high_keys[128 - SC_LIM] = {
163   RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
164   0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
165   0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
166   0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
167   FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
168   FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
169 };
170
171 /* BTC */
172 #define E0_MACRO   112
173 /* LK450 */
174 #define E0_F13     113
175 #define E0_F14     114
176 #define E0_HELP    115
177 #define E0_DO      116
178 #define E0_F17     117
179 #define E0_KPMINPLUS 118
180 /*
181  * My OmniKey generates e0 4c for  the "OMNI" key and the
182  * right alt key does nada. [kkoller@nyx10.cs.du.edu]
183  */
184 #define E0_OK   124
185 /*
186  * New microsoft keyboard is rumoured to have
187  * e0 5b (left window button), e0 5c (right window button),
188  * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
189  * [or: Windows_L, Windows_R, TaskMan]
190  */
191 #define E0_MSLW 125
192 #define E0_MSRW 126
193 #define E0_MSTM 127
194
195 /* this can be changed using setkeys : */
196 static unsigned char e0_keys[128] = {
197   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x00-0x07 */
198   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x08-0x0f */
199   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x10-0x17 */
200   0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,             /* 0x18-0x1f */
201   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x20-0x27 */
202   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x28-0x2f */
203   0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,             /* 0x30-0x37 */
204   E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,       /* 0x38-0x3f */
205   E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,       /* 0x40-0x47 */
206   E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
207   E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,       /* 0x50-0x57 */
208   0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,           /* 0x58-0x5f */
209   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x60-0x67 */
210   0, 0, 0, 0, 0, 0, 0, E0_MACRO,                      /* 0x68-0x6f */
211   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x70-0x77 */
212   0, 0, 0, 0, 0, 0, 0, 0                              /* 0x78-0x7f */
213 };
214
215
216 int q40kbd_setkeycode(unsigned int scancode, unsigned int keycode)
217 {
218         if (scancode < SC_LIM || scancode > 255 || keycode > 127)
219           return -EINVAL;
220         if (scancode < 128)
221           high_keys[scancode - SC_LIM] = keycode;
222         else
223           e0_keys[scancode - 128] = keycode;
224         return 0;
225 }
226
227 int q40kbd_getkeycode(unsigned int scancode)
228 {
229         return
230           (scancode < SC_LIM || scancode > 255) ? -EINVAL :
231           (scancode < 128) ? high_keys[scancode - SC_LIM] :
232             e0_keys[scancode - 128];
233 }
234
235
236 #define disable_keyboard()      
237 #define enable_keyboard()       
238
239
240
241
242 int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
243                     char raw_mode)
244 {
245         static int prev_scancode;
246
247         /* special prefix scancodes.. */
248         if (scancode == 0xe0 || scancode == 0xe1) {
249                 prev_scancode = scancode;
250                 return 0;
251         }
252
253         /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
254         if (scancode == 0x00 || scancode == 0xff) {
255                 prev_scancode = 0;
256                 return 0;
257         }
258
259         scancode &= 0x7f;
260
261         if (prev_scancode) {
262           /*
263            * usually it will be 0xe0, but a Pause key generates
264            * e1 1d 45 e1 9d c5 when pressed, and nothing when released
265            */
266           if (prev_scancode != 0xe0) {
267               if (prev_scancode == 0xe1 && scancode == 0x1d) {
268                   prev_scancode = 0x100;
269                   return 0;
270               } else if (prev_scancode == 0x100 && scancode == 0x45) {
271                   *keycode = E1_PAUSE;
272                   prev_scancode = 0;
273               } else {
274 #ifdef KBD_REPORT_UNKN
275                   if (!raw_mode)
276                     printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
277 #endif
278                   prev_scancode = 0;
279                   return 0;
280               }
281           } else {
282               prev_scancode = 0;
283               /*
284                *  The keyboard maintains its own internal caps lock and
285                *  num lock statuses. In caps lock mode E0 AA precedes make
286                *  code and E0 2A follows break code. In num lock mode,
287                *  E0 2A precedes make code and E0 AA follows break code.
288                *  We do our own book-keeping, so we will just ignore these.
289                */
290               /*
291                *  For my keyboard there is no caps lock mode, but there are
292                *  both Shift-L and Shift-R modes. The former mode generates
293                *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
294                *  So, we should also ignore the latter. - aeb@cwi.nl
295                */
296               if (scancode == 0x2a || scancode == 0x36)
297                 return 0;
298
299               if (e0_keys[scancode])
300                 *keycode = e0_keys[scancode];
301               else {
302 #ifdef KBD_REPORT_UNKN
303                   if (!raw_mode)
304                     printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
305                            scancode);
306 #endif
307                   return 0;
308               }
309           }
310         } else if (scancode >= SC_LIM) {
311             /* This happens with the FOCUS 9000 keyboard
312                Its keys PF1..PF12 are reported to generate
313                55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
314                Moreover, unless repeated, they do not generate
315                key-down events, so we have to zero up_flag below */
316             /* Also, Japanese 86/106 keyboards are reported to
317                generate 0x73 and 0x7d for \ - and \ | respectively. */
318             /* Also, some Brazilian keyboard is reported to produce
319                0x73 and 0x7e for \ ? and KP-dot, respectively. */
320
321           *keycode = high_keys[scancode - SC_LIM];
322
323           if (!*keycode) {
324               if (!raw_mode) {
325 #ifdef KBD_REPORT_UNKN
326                   printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
327                          " - ignored\n", scancode);
328 #endif
329               }
330               return 0;
331           }
332         } else
333           *keycode = scancode;
334         return 1;
335 }
336
337 char q40kbd_unexpected_up(unsigned char keycode)
338 {
339         /* unexpected, but this can happen: maybe this was a key release for a
340            FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
341         if (keycode >= SC_LIM || keycode == 85)
342             return 0;
343         else
344             return 0200;
345 }
346
347 static int keyup=0;
348 static int qprev=0;
349
350 static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
351 {
352         unsigned char status;
353
354         spin_lock(&kbd_controller_lock);
355         kbd_pt_regs = regs;
356
357         status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
358         if (status ) 
359           {
360             unsigned char scancode,qcode;
361             
362             qcode = master_inb(KEYCODE_REG);
363             
364             if (qcode != 0xf0)
365               {
366                 if (qcode == 0xe0)
367                   {
368                     qprev=0xe0;
369                     handle_scancode(qprev , 1);
370                     goto exit;
371                   }
372                 
373                 scancode=qprev ? q40ecl[qcode] : q40cl[qcode];
374 #if 0
375 /* next line is last resort to hanlde some oddities */
376                 if (qprev && !scancode) scancode=q40cl[qcode];
377 #endif
378                 qprev=0;
379                 if (!scancode)
380                   {
381                     printk("unknown scancode %x\n",qcode);
382                     goto exit;
383                   }
384                 if (scancode==0xff)  /* SySrq */
385                   scancode=SYSRQ_KEY;
386
387                 handle_scancode(scancode, ! keyup );
388                 keyup=0;
389                 tasklet_schedule(&keyboard_tasklet);
390               }
391             else
392               keyup=1;
393           }
394 exit:
395         spin_unlock(&kbd_controller_lock);
396         master_outb(-1,KEYBOARD_UNLOCK_REG); /* keyb ints reenabled herewith */
397 }
398
399
400 #define KBD_NO_DATA     (-1)    /* No data */
401 #define KBD_BAD_DATA    (-2)    /* Parity or other error */
402
403 static int __init kbd_read_input(void)
404 {
405         int retval = KBD_NO_DATA;
406         unsigned char status;
407
408         status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
409         if (status) {
410                 unsigned char data = master_inb(KEYCODE_REG);
411
412                 retval = data;
413                 master_outb(-1,KEYBOARD_UNLOCK_REG);
414         }
415         return retval;
416 }
417
418
419 static void __init kbd_clear_input(void)
420 {
421         int maxread = 100;      /* Random number */
422
423         do {
424                 if (kbd_read_input() == KBD_NO_DATA)
425                         break;
426         } while (--maxread);
427 }
428
429
430 int __init q40kbd_init_hw(void)
431 {
432
433         /* Flush any pending input. */
434         kbd_clear_input();
435
436         /* Ok, finally allocate the IRQ, and off we go.. */
437         request_irq(Q40_IRQ_KEYBOARD, keyboard_interrupt, 0, "keyboard", NULL);
438         master_outb(-1,KEYBOARD_UNLOCK_REG);
439         master_outb(1,KEY_IRQ_ENABLE_REG);
440
441         return 0;
442 }
443