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 
a5kkbd_key(unsigned int keycode,unsigned int up_flag)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 
a5kkbd_sendbyte(unsigned char val)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 
a5kkbd_reset(void)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 
a5kkbd_leds(unsigned char leds)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 
handle_rawcode(unsigned int keyval)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 
a5kkbd_rx(int irq,void * dev_id,struct pt_regs * regs)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 
a5kkbd_tx(int irq,void * dev_id,struct pt_regs * regs)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 
a5kkbd_setkeycode(unsigned int scancode,unsigned int keycode)422 static int a5kkbd_setkeycode(unsigned int scancode, unsigned int keycode)
423 {
424 	return -EINVAL;
425 }
426 
a5kkbd_getkeycode(unsigned int scancode)427 static int a5kkbd_getkeycode(unsigned int scancode)
428 {
429 	return -EINVAL;
430 }
431 
a5kkbd_translate(unsigned char scancode,unsigned char * keycode,char rawmode)432 static int a5kkbd_translate(unsigned char scancode, unsigned char *keycode, char rawmode)
433 {
434 	*keycode = scancode;
435 	return 1;
436 }
437 
a5kkbd_unexpected_up(unsigned char keycode)438 static char a5kkbd_unexpected_up(unsigned char keycode)
439 {
440 	return 0200;
441 }
442 
a5kkbd_rate(struct kbd_repeat * rep)443 static int a5kkbd_rate(struct kbd_repeat *rep)
444 {
445 	return -EINVAL;
446 }
447 
448 #ifdef CONFIG_KBDMOUSE
449 static struct busmouse a5kkbd_mouse = {
450 	6, "kbdmouse", NULL, NULL, NULL, 7
451 };
452 #endif
453 
454 struct kbd_ops_struct a5k_kbd_ops = {
455 	k_setkeycode:		a5kkbd_setkeycode,
456 	k_getkeycode:		a5kkbd_getkeycode,
457 	k_translate:		a5kkbd_translate,
458 	k_unexpected_up:	a5kkbd_unexpected_up,
459 	k_leds:			a5kkbd_leds,
460 	k_rate:			a5kkbd_rate,
461 #ifdef CONFIG_MAGIC_SYSRQ
462 	k_sysrq_xlate:		a5kkbd_sysrq_xlate,
463 	k_sysrq_key:		13,
464 #endif
465 };
466 
a5kkbd_init_hw(void)467 void __init a5kkbd_init_hw (void)
468 {
469 	if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0)
470 		panic("Could not allocate keyboard transmit IRQ!");
471 	(void)ioc_readb(IOC_KARTRX);
472 	if (request_irq (IRQ_KEYBOARDRX, a5kkbd_rx, 0, "keyboard", NULL) != 0)
473 		panic("Could not allocate keyboard receive IRQ!");
474 
475 	a5kkbd_sendbyte (HRST);	/* send HRST (expect HRST) */
476 
477 	/* wait 1s for keyboard to initialise */
478 	interruptible_sleep_on_timeout(&kbd_waitq, HZ);
479 
480 #ifdef CONFIG_KBDMOUSE
481 	mousedev = register_busmouse(&a5kkbd_mouse);
482 	if (mousedev < 0)
483 		printk(KERN_ERR "Unable to register mouse driver\n");
484 #endif
485 
486 	printk (KERN_INFO "Keyboard driver v%d.%02d. (", VERSION/100, VERSION%100);
487 	if (kbd_id != -1)
488 	      printk ("id=%d ", kbd_id);
489 	printk ("English)\n");
490 }
491