make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / drivers / acorn / char / keyb_arc.c
1 /*
2  *  linux/drivers/acorn/char/keyb_arc.c
3  *
4  *  Copyright (C) 2000 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  Acorn keyboard driver for ARM Linux.
11  *
12  *  The Acorn keyboard appears to have a ***very*** buggy reset protocol -
13  *  every reset behaves differently.  We try to get round this by attempting
14  *  a few things...
15  */
16 #include <linux/config.h>
17 #include <linux/sched.h>
18 #include <linux/interrupt.h>
19 #include <linux/tty.h>
20 #include <linux/tty_flip.h>
21 #include <linux/mm.h>
22 #include <linux/slab.h>
23 #include <linux/ptrace.h>
24 #include <linux/signal.h>
25 #include <linux/timer.h>
26 #include <linux/random.h>
27 #include <linux/ctype.h>
28 #include <linux/init.h>
29 #include <linux/kbd_ll.h>
30 #include <linux/kbd_kern.h>
31 #include <linux/delay.h>
32
33 #include <asm/bitops.h>
34 #include <asm/keyboard.h>
35 #include <asm/irq.h>
36 #include <asm/hardware.h>
37 #include <asm/hardware/ioc.h>
38
39 #include "../../char/busmouse.h"
40
41 extern struct tasklet_struct keyboard_tasklet;
42 extern void kbd_reset_kdown(void);
43
44 #define VERSION 108
45
46 #define KBD_REPORT_ERR
47 #define KBD_REPORT_UNKN
48
49 #include <asm/io.h>
50 #include <asm/system.h>
51
52 static char kbd_txval[4];
53 static unsigned char kbd_txhead, kbd_txtail;
54 #define KBD_INCTXPTR(ptr) ((ptr) = ((ptr) + 1) & 3)
55 static int kbd_id = -1;
56 static DECLARE_WAIT_QUEUE_HEAD(kbd_waitq);
57 #ifdef CONFIG_KBDMOUSE
58 static int mousedev;
59 #endif
60
61 /*
62  * Protocol codes to send the keyboard.
63  */
64 #define HRST 0xff       /* reset keyboard */
65 #define RAK1 0xfe       /* reset response */
66 #define RAK2 0xfd       /* reset response */
67 #define BACK 0x3f       /* Ack for first keyboard pair */
68 #define SMAK 0x33       /* Last data byte ack (key scanning + mouse movement scanning) */
69 #define MACK 0x32       /* Last data byte ack (mouse movement scanning) */
70 #define SACK 0x31       /* Last data byte ack (key scanning) */
71 #define NACK 0x30       /* Last data byte ack (no scanning, mouse data) */
72 #define RQMP 0x22       /* Request mouse data */
73 #define PRST 0x21       /* nothing */
74 #define RQID 0x20       /* Request ID */
75
76 #define UP_FLAG 1
77
78 #ifdef CONFIG_MAGIC_SYSRQ
79 unsigned char a5kkbd_sysrq_xlate[] = 
80 {
81     27,    0,    0,    0,    0,    0,    0,    0,
82      0,    0,    0,    0,    0,    0,    0,    0,
83    '`',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
84    '8',  '9',  '0',  '-',  '=',  '£',  127,    0,
85      0,    0,    0,  '/',  '*',  '#',    9,  'q',
86    'w',  'e',  'r',  't',  'y',  'u',  'i',  'o',
87    'p',  '[',  ']', '\\',  22,    23,   25,  '7',
88    '8',  '9',  '-',    0,  'a',  's',  'd',  'f',
89    'g',  'h',  'j',  'k',  'l',  ';', '\'',   13,
90    '4',  '5',  '6',  '+',    0,    0,  'z',  'x',
91    'c',  'v',  'b',  'n',  'm',  ',',  '.',  '/',
92      0,    0,  '1',  '2',  '3',    0,    0,  ' ',
93      0,    0,    0,    0,    0,  '0',  '.',   10,
94      0,    0,    0,    0,    0,    0,    0,    0,
95      0,    0,    0,    0,    0,    0,    0,    0,
96      0,    0,    0,    0,    0,    0,    0,    0,
97 };
98 #endif
99
100 /*
101  * This array converts the scancode that we get from the keyboard to the
102  * real rows/columns on the A5000 keyboard.  This might be keyboard specific...
103  *
104  * It is these values that we use to maintain the key down array.  That way, we
105  * should pick up on the ghost key presses (which is what happens when you press
106  * three keys, and the keyboard thinks you have pressed four!)
107  *
108  * Row 8 (0x80+c) is actually a column with one key per row.  It is isolated from
109  * the other keys, and can't cause these problems (its used for shift, ctrl, alt etc).
110  *
111  * Illegal scancodes are denoted by an 0xff (in other words, we don't know about
112  * them, and can't process them for ghosts).  This does however, cause problems with
113  * autorepeat processing...
114  */
115 static unsigned char scancode_2_colrow[256] = {
116   0x01, 0x42, 0x32, 0x33, 0x43, 0x56, 0x5a, 0x6c, 0x7c, 0x5c, 0x5b, 0x6b, 0x7b, 0x84, 0x70, 0x60,
117   0x11, 0x51, 0x62, 0x63, 0x44, 0x54, 0x55, 0x45, 0x46, 0x4a, 0x3c, 0x4b, 0x59, 0x49, 0x69, 0x79,
118   0x83, 0x40, 0x30, 0x3b, 0x39, 0x38, 0x31, 0x61, 0x72, 0x73, 0x64, 0x74, 0x75, 0x65, 0x66, 0x6a,
119   0x1c, 0x2c, 0x7a, 0x36, 0x48, 0x68, 0x78, 0x20, 0x2b, 0x29, 0x28, 0x81, 0x71, 0x22, 0x23, 0x34,
120   0x24, 0x25, 0x35, 0x26, 0x3a, 0x0c, 0x2a, 0x76, 0x10, 0x1b, 0x19, 0x18, 0x82, 0xff, 0x21, 0x12,
121   0x13, 0x14, 0x04, 0x05, 0x15, 0x16, 0x1a, 0x0a, 0x85, 0x77, 0x00, 0x0b, 0x09, 0x02, 0x80, 0x03,
122   0x87, 0x86, 0x06, 0x17, 0x27, 0x07, 0x37, 0x08, 0xff,
123 };
124
125 #define BITS_PER_SHORT (8*sizeof(unsigned short))
126 static unsigned short ghost_down[128/BITS_PER_SHORT];
127
128 static void a5kkbd_key(unsigned int keycode, unsigned int up_flag)
129 {
130         unsigned int real_keycode;
131
132         if (keycode > 0x72) {
133 #ifdef KBD_REPORT_UNKN
134                 printk ("kbd: unknown scancode 0x%04x\n", keycode);
135 #endif
136                 return;
137         }
138         if (keycode >= 0x70) {
139 #ifdef CONFIG_KBDMOUSE
140                 if (mousedev >= 0)
141                         switch (keycode) {
142                         case 0x70: /* Left mouse button */
143                                 busmouse_add_buttons(mousedev, 4, up_flag ? 4 : 0);
144                                 break;
145
146                         case 0x71: /* Middle mouse button */
147                                 busmouse_add_buttons(mousedev, 2, up_flag ? 2 : 0);
148                                 break;
149
150                         case 0x72:/* Right mouse button */
151                                 busmouse_add_buttons(mousedev, 1, up_flag ? 1 : 0);
152                                 break;
153                         }
154 #endif
155                 return;
156         }
157
158         /*
159          * We have to work out if we accept this key press as a real key, or
160          * if it is a ghost.  IE. If you press three keys, the keyboard will think
161          * that you've pressed a fourth: (@ = key down, # = ghost)
162          *
163          *   0 1 2 3 4 5 6 7
164          *   | | | | | | | |
165          * 0-+-+-+-+-+-+-+-+-
166          *   | | | | | | | |
167          * 1-+-@-+-+-+-@-+-+-
168          *   | | | | | | | |
169          * 2-+-+-+-+-+-+-+-+-
170          *   | | | | | | | |
171          * 3-+-@-+-+-+-#-+-+-
172          *   | | | | | | | |
173          *
174          * This is what happens when you have a matrix keyboard...
175          */
176
177         real_keycode = scancode_2_colrow[keycode];
178
179         if ((real_keycode & 0x80) == 0) {
180                 int rr, kc = (real_keycode >> 4) & 7;
181                 int cc;
182                 unsigned short res, kdownkc;
183
184                 kdownkc = ghost_down[kc] | (1 << (real_keycode & 15));
185
186                 for (rr = 0; rr < 128/BITS_PER_SHORT; rr++)
187                         if (rr != kc && (res = ghost_down[rr] & kdownkc)) {
188                                 /*
189                                  * we have found a second row with at least one key pressed in the
190                                  * same column.
191                                  */
192                                 for (cc = 0; res; res >>= 1)
193                                         cc += (res & 1);
194                                 if (cc > 1)
195                                         return; /* ignore it */
196                         }
197                 if (up_flag)
198                         clear_bit (real_keycode, ghost_down);
199                 else
200                         set_bit (real_keycode, ghost_down);
201         }
202
203         handle_scancode(keycode, !up_flag);
204 }
205
206 static inline void a5kkbd_sendbyte(unsigned char val)
207 {
208         kbd_txval[kbd_txhead] = val;
209         KBD_INCTXPTR(kbd_txhead);
210         enable_irq(IRQ_KEYBOARDTX);
211 }
212
213 static inline void a5kkbd_reset(void)
214 {
215         int i;
216
217         for (i = 0; i < NR_SCANCODES/BITS_PER_SHORT; i++)
218                 ghost_down[i] = 0;
219
220         kbd_reset_kdown();
221 }
222
223 void a5kkbd_leds(unsigned char leds)
224 {
225         leds =  ((leds & (1<<VC_SCROLLOCK))?4:0) | ((leds & (1<<VC_NUMLOCK))?2:0) |
226                 ((leds & (1<<VC_CAPSLOCK))?1:0);
227         a5kkbd_sendbyte(leds);
228 }
229
230 /* Keyboard states:
231  *  0 initial reset condition, receive HRST, send RRAK1
232  *  1 Sent RAK1, wait for RAK1, send RRAK2
233  *  2 Sent RAK2, wait for RAK2, send SMAK or RQID
234  *  3 Sent RQID, expect KBID, send SMAK
235  *  4 Sent SMAK, wait for anything
236  *  5 Wait for second keyboard nibble for key pressed
237  *  6 Wait for second keyboard nibble for key released
238  *  7 Wait for second part of mouse data
239  *
240  * This function returns 1 when we successfully enter the IDLE state
241  * (and hence need to do some keyboard processing).
242  */
243 #define KBD_INITRST     0
244 #define KBD_RAK1        1
245 #define KBD_RAK2        2
246 #define KBD_ID          3
247 #define KBD_IDLE        4
248 #define KBD_KEYDOWN     5
249 #define KBD_KEYUP       6
250 #define KBD_MOUSE       7
251
252 static int handle_rawcode(unsigned int keyval)
253 {
254         static signed char kbd_mousedx = 0;
255                signed char kbd_mousedy;
256         static unsigned char kbd_state = KBD_INITRST;
257         static unsigned char kbd_keyhigh = 0;
258
259         if (keyval == HRST && kbd_state != KBD_INITRST && kbd_state != KBD_ID) {
260                 a5kkbd_sendbyte (HRST);
261                 a5kkbd_reset ();
262                 kbd_state = KBD_INITRST;
263         } else switch(kbd_state) {
264         case KBD_INITRST:                       /* hard reset - sent HRST */
265                 if (keyval == HRST) {
266                         a5kkbd_sendbyte (RAK1);
267                         kbd_state = KBD_RAK1;
268                 } else if (keyval == RAK1) {
269                         /* Some A5000 keyboards are very fussy and don't follow Acorn's
270                          * specs - this appears to fix them, but them it might stop
271                          * them from being initialised.
272                          *  fix by Philip Blundell
273                          */
274                         printk(KERN_DEBUG "keyboard sent early RAK1 -- ignored\n");
275                 } else
276                         goto kbd_wontreset;
277                 break;
278
279         case KBD_RAK1:                          /* sent RAK1 - expect RAK1 and send RAK2 */
280                 if (keyval == RAK1) {
281                         a5kkbd_sendbyte (RAK2);
282                         kbd_state = KBD_RAK2;
283                 } else
284                         goto kbd_wontreset;
285                 break;
286
287         case KBD_RAK2:                          /* Sent RAK2 - expect RAK2 and send either RQID or SMAK */
288                 if (keyval == RAK2) {
289                         if (kbd_id == -1) {
290                                 a5kkbd_sendbyte (NACK);
291                                 a5kkbd_sendbyte (RQID);
292                                 kbd_state = KBD_ID;
293                         } else {
294                                 a5kkbd_sendbyte (SMAK);
295                                 kbd_state = KBD_IDLE;
296                         }
297                 } else
298                         goto kbd_wontreset;
299                 break;
300
301         case KBD_ID:                            /* Sent RQID - expect KBID */
302                 if (keyval == HRST) {
303                         kbd_id = -2;
304                         a5kkbd_reset ();
305                         a5kkbd_sendbyte (HRST);
306                         kbd_state = KBD_INITRST;
307                         wake_up (&kbd_waitq);
308                 } else if ((keyval & 0xc0) == 0x80) {
309                         kbd_id = keyval & 0x3f;
310                         a5kkbd_sendbyte (SMAK);
311                         kbd_state = KBD_IDLE;
312                         wake_up (&kbd_waitq);
313                 }
314                 break;
315
316         case KBD_IDLE:                          /* Send SMAK, ready for any reply */
317                 switch (keyval & 0xf0) {
318                 default:        /* 0x00 - 0x7f */
319                         kbd_mousedx = keyval & 0x40 ? keyval|0x80 : keyval;
320                         kbd_state   = KBD_MOUSE;
321                         a5kkbd_sendbyte (BACK);
322                         break;
323
324                 case 0x80:
325                 case 0x90:
326                 case 0xa0:
327                 case 0xb0:
328                         if (kbd_id == -1)
329                                 kbd_id = keyval & 0x3f;
330                         break;
331
332                 case 0xc0:
333                         kbd_keyhigh = keyval;
334                         kbd_state   = KBD_KEYDOWN;
335                         a5kkbd_sendbyte (BACK);
336                         break;
337
338                 case 0xd0:
339                         kbd_keyhigh = keyval;
340                         kbd_state   = KBD_KEYUP;
341                         a5kkbd_sendbyte (BACK);
342                         break;
343
344                 case 0xe0:
345                 case 0xf0:
346                         goto kbd_error;
347                 }
348                 break;
349
350         case KBD_KEYDOWN:
351                 if ((keyval & 0xf0) != 0xc0)
352                         goto kbd_error;
353                 else {
354                         kbd_state = KBD_IDLE;
355                         a5kkbd_sendbyte (SMAK);
356                         if (((kbd_keyhigh ^ keyval) & 0xf0) == 0)
357                                 a5kkbd_key ((keyval & 0x0f) | ((kbd_keyhigh << 4) & 0xf0), 0);
358                 }
359                 break;
360
361         case KBD_KEYUP:
362                 if ((keyval & 0xf0) != 0xd0)
363                         goto kbd_error;
364                 else {
365                         kbd_state = KBD_IDLE;
366                         a5kkbd_sendbyte (SMAK);
367                         if (((kbd_keyhigh ^ keyval) & 0xf0) == 0)
368                                 a5kkbd_key ((keyval & 0x0f) | ((kbd_keyhigh << 4) & 0xf0), UP_FLAG);
369                 }
370                 break;
371
372         case KBD_MOUSE:
373                 if (keyval & 0x80)
374                         goto kbd_error;
375                 else {
376                         kbd_state = KBD_IDLE;
377                         a5kkbd_sendbyte (SMAK);
378                         kbd_mousedy = (char)(keyval & 0x40 ? keyval | 0x80 : keyval);
379 #ifdef CONFIG_KBDMOUSE
380                         if (mousedev >= 0)
381                                 busmouse_add_movement(mousedev, (int)kbd_mousedx, (int)kbd_mousedy);
382 #endif
383                 }
384         }
385         return kbd_state == KBD_IDLE ? 1 : 0;
386
387 kbd_wontreset:
388 #ifdef KBD_REPORT_ERR
389         printk ("kbd: keyboard won't reset (kbdstate %d, keyval %02X)\n",
390                 kbd_state, keyval);
391 #endif
392         mdelay(1);
393         ioc_readb(IOC_KARTRX);
394         a5kkbd_sendbyte (HRST);
395         kbd_state = KBD_INITRST;
396         return 0;
397
398 kbd_error:
399 #ifdef KBD_REPORT_ERR
400         printk ("kbd: keyboard out of sync - resetting\n");
401 #endif
402         a5kkbd_sendbyte (HRST);
403         kbd_state = KBD_INITRST;
404         return 0;
405 }
406
407 static void a5kkbd_rx(int irq, void *dev_id, struct pt_regs *regs)
408 {
409         kbd_pt_regs = regs;
410         if (handle_rawcode(ioc_readb(IOC_KARTRX)))
411                 tasklet_schedule(&keyboard_tasklet);
412 }
413
414 static void a5kkbd_tx(int irq, void *dev_id, struct pt_regs *regs)
415 {
416         ioc_writeb (kbd_txval[kbd_txtail], IOC_KARTTX);
417         KBD_INCTXPTR(kbd_txtail);
418         if (kbd_txtail == kbd_txhead)
419                 disable_irq(irq);
420 }
421
422 #ifdef CONFIG_KBDMOUSE
423 static struct busmouse a5kkbd_mouse = {
424         6, "kbdmouse", NULL, NULL, NULL, 7
425 };
426 #endif
427
428 void __init a5kkbd_init_hw (void)
429 {
430         if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0)
431                 panic("Could not allocate keyboard transmit IRQ!");
432         (void)ioc_readb(IOC_KARTRX);
433         if (request_irq (IRQ_KEYBOARDRX, a5kkbd_rx, 0, "keyboard", NULL) != 0)
434                 panic("Could not allocate keyboard receive IRQ!");
435
436         a5kkbd_sendbyte (HRST); /* send HRST (expect HRST) */
437
438         /* wait 1s for keyboard to initialise */
439         interruptible_sleep_on_timeout(&kbd_waitq, HZ);
440
441 #ifdef CONFIG_KBDMOUSE
442         mousedev = register_busmouse(&a5kkbd_mouse);
443         if (mousedev < 0)
444                 printk(KERN_ERR "Unable to register mouse driver\n");
445 #endif
446
447         printk (KERN_INFO "Keyboard driver v%d.%02d. (", VERSION/100, VERSION%100);
448         if (kbd_id != -1)
449               printk ("id=%d ", kbd_id);
450         printk ("English)\n");
451 }