1 /*
2 * linux/drivers/char/hp_keyb.c
3 * helper-functions for the keyboard/psaux driver for HP-PARISC workstations
4 *
5 * based on pc_keyb.c by Geert Uytterhoeven & Martin Mares
6 *
7 * 2000/10/26 Debacker Xavier <debackex@esiee.fr>
8 * Marteau Thomas <marteaut@esiee.fr>
9 * Djoudi Malek <djoudim@esiee.fr>
10 * - fixed some keysym defines
11 *
12 * 2001/04/28 Debacker Xavier <debackex@esiee.fr>
13 * - scancode translation rewritten in handle_at_scancode()
14 */
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/kbd_ll.h>
29 #include <linux/init.h>
30
31 #include <asm/bitops.h>
32 #include <asm/irq.h>
33 #include <asm/hardware.h>
34 #include <asm/io.h>
35 #include <asm/system.h>
36
37 #define KBD_REPORT_ERR
38 #define KBD_REPORT_UNKN
39
40 #define KBD_ESCAPEE0 0xe0 /* in */
41 #define KBD_ESCAPEE1 0xe1 /* in */
42
43 #define ESCE0(x) (0xe000|(x))
44 #define ESCE1(x) (0xe100|(x))
45
46 #define KBD_BAT 0xaa /* in */
47 #define KBD_SETLEDS 0xed /* out */
48 #define KBD_ECHO 0xee /* in/out */
49 #define KBD_BREAK 0xf0 /* in */
50 #define KBD_TYPRATEDLY 0xf3 /* out */
51 #define KBD_SCANENABLE 0xf4 /* out */
52 #define KBD_DEFDISABLE 0xf5 /* out */
53 #define KBD_DEFAULT 0xf6 /* out */
54 #define KBD_ACK 0xfa /* in */
55 #define KBD_DIAGFAIL 0xfd /* in */
56 #define KBD_RESEND 0xfe /* in/out */
57 #define KBD_RESET 0xff /* out */
58
59 #define CODE_BREAK 1
60 #define CODE_ESCAPEE0 2
61 #define CODE_ESCAPEE1 4
62 #define CODE_ESCAPE12 8
63
64 #define K_NONE 0x7f
65 #define K_ESC 0x01
66 #define K_F1 0x3b
67 #define K_F2 0x3c
68 #define K_F3 0x3d
69 #define K_F4 0x3e
70 #define K_F5 0x3f
71 #define K_F6 0x40
72 #define K_F7 0x41
73 #define K_F8 0x42
74 #define K_F9 0x43
75 #define K_F10 0x44
76 #define K_F11 0x57
77 #define K_F12 0x58
78 #define K_PRNT 0x54
79 #define K_SCRL 0x46
80 #define K_BRK 0x77
81 #define K_AGR 0x29
82 #define K_1 0x02
83 #define K_2 0x03
84 #define K_3 0x04
85 #define K_4 0x05
86 #define K_5 0x06
87 #define K_6 0x07
88 #define K_7 0x08
89 #define K_8 0x09
90 #define K_9 0x0a
91 #define K_0 0x0b
92 #define K_MINS 0x0c
93 #define K_EQLS 0x0d
94 #define K_BKSP 0x0e
95 #define K_INS 0x6e
96 #define K_HOME 0x66
97 #define K_PGUP 0x68
98 #define K_NUML 0x45
99 #define KP_SLH 0x62
100 #define KP_STR 0x37
101 #define KP_MNS 0x4a
102 #define K_TAB 0x0f
103 #define K_Q 0x10
104 #define K_W 0x11
105 #define K_E 0x12
106 #define K_R 0x13
107 #define K_T 0x14
108 #define K_Y 0x15
109 #define K_U 0x16
110 #define K_I 0x17
111 #define K_O 0x18
112 #define K_P 0x19
113 #define K_LSBK 0x1a
114 #define K_RSBK 0x1b
115 #define K_ENTR 0x1c
116 #define K_DEL 111
117 #define K_END 0x6b
118 #define K_PGDN 0x6d
119 #define KP_7 0x47
120 #define KP_8 0x48
121 #define KP_9 0x49
122 #define KP_PLS 0x4e
123 #define K_CAPS 0x3a
124 #define K_A 0x1e
125 #define K_S 0x1f
126 #define K_D 0x20
127 #define K_F 0x21
128 #define K_G 0x22
129 #define K_H 0x23
130 #define K_J 0x24
131 #define K_K 0x25
132 #define K_L 0x26
133 #define K_SEMI 0x27
134 #define K_SQOT 0x28
135 #define K_HASH K_NONE
136 #define KP_4 0x4b
137 #define KP_5 0x4c
138 #define KP_6 0x4d
139 #define K_LSFT 0x2a
140 #define K_BSLH 0x2b
141 #define K_Z 0x2c
142 #define K_X 0x2d
143 #define K_C 0x2e
144 #define K_V 0x2f
145 #define K_B 0x30
146 #define K_N 0x31
147 #define K_M 0x32
148 #define K_COMA 0x33
149 #define K_DOT 0x34
150 #define K_FSLH 0x35
151 #define K_RSFT 0x36
152 #define K_UP 0x67
153 #define KP_1 0x4f
154 #define KP_2 0x50
155 #define KP_3 0x51
156 #define KP_ENT 0x60
157 #define K_LCTL 0x1d
158 #define K_LALT 0x38
159 #define K_SPCE 0x39
160 #define K_RALT 0x64
161 #define K_RCTL 0x61
162 #define K_LEFT 0x69
163 #define K_DOWN 0x6c
164 #define K_RGHT 0x6a
165 #define KP_0 0x52
166 #define KP_DOT 0x53
167
168 static unsigned char keycode_translate[256] =
169 {
170 /* 00 */ K_NONE, K_F9 , K_NONE, K_F5 , K_F3 , K_F1 , K_F2 , K_F12 ,
171 /* 08 */ K_NONE, K_F10 , K_F8 , K_F6 , K_F4 , K_TAB , K_AGR , K_NONE,
172 /* 10 */ K_NONE, K_LALT, K_LSFT, K_NONE, K_LCTL, K_Q , K_1 , K_NONE,
173 /* 18 */ K_NONE, K_NONE, K_Z , K_S , K_A , K_W , K_2 , K_NONE,
174 /* 20 */ K_NONE, K_C , K_X , K_D , K_E , K_4 , K_3 , K_NONE,
175 /* 28 */ K_NONE, K_SPCE, K_V , K_F , K_T , K_R , K_5 , K_NONE,
176 /* 30 */ K_NONE, K_N , K_B , K_H , K_G , K_Y , K_6 , K_NONE,
177 /* 38 */ K_NONE, K_NONE, K_M , K_J , K_U , K_7 , K_8 , K_NONE,
178 /* 40 */ K_NONE, K_COMA, K_K , K_I , K_O , K_0 , K_9 , K_NONE,
179 /* 48 */ K_PGUP, K_DOT , K_FSLH, K_L , K_SEMI, K_P , K_MINS, K_NONE,
180 /* 50 */ K_NONE, K_NONE, K_SQOT, K_NONE, K_LSBK, K_EQLS, K_NONE, K_NONE,
181 /* 58 */ K_CAPS, K_RSFT, K_ENTR, K_RSBK, K_NONE, K_BSLH, K_NONE, K_NONE,
182 /* 60 */ K_NONE, K_HASH, K_NONE, K_NONE, K_NONE, K_NONE, K_BKSP, K_NONE,
183 /* 68 */ K_NONE, KP_1 , K_NONE, KP_4 , KP_7 , K_NONE, K_NONE, K_NONE,
184 /* 70 */ KP_0 , KP_DOT, KP_2 , KP_5 , KP_6 , KP_8 , K_ESC , K_NUML,
185 /* 78 */ K_F11 , KP_PLS, KP_3 , KP_MNS, KP_STR, KP_9 , K_SCRL, K_PRNT,
186 /* 80 */ K_NONE, K_NONE, K_NONE, K_F7 , K_NONE, K_NONE, K_NONE, K_NONE,
187 /* 88 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
188 /* 90 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
189 /* 98 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
190 /* a0 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
191 /* a8 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
192 /* b0 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
193 /* b8 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
194 /* c0 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
195 /* c8 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
196 /* d0 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
197 /* d8 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
198 /* e0 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
199 /* e8 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
200 /* f0 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE,
201 /* f8 */ K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, KBD_RESEND, K_NONE
202 };
203
204 /* ----- the following code stolen from pc_keyb.c */
205
206
207 #ifdef CONFIG_MAGIC_SYSRQ
208 unsigned char hp_ps2kbd_sysrq_xlate[128] =
209 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
210 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
211 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
212 "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
213 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
214 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
215 "\r\000/"; /* 0x60 - 0x6f */
216 #endif
217
218 /*
219 * Translation of escaped scancodes to keycodes.
220 * This is now user-settable.
221 * The keycodes 1-88,96-111,119 are fairly standard, and
222 * should probably not be changed - changing might confuse X.
223 * X also interprets scancode 0x5d (KEY_Begin).
224 *
225 * For 1-88 keycode equals scancode.
226 */
227
228 #define E0_KPENTER 96
229 #define E0_RCTRL 97
230 #define E0_KPSLASH 98
231 #define E0_PRSCR 99
232 #define E0_RALT 100
233 #define E0_BREAK 101 /* (control-pause) */
234 #define E0_HOME 102
235 #define E0_UP 103
236 #define E0_PGUP 104
237 #define E0_LEFT 105
238 #define E0_RIGHT 106
239 #define E0_END 107
240 #define E0_DOWN 108
241 #define E0_PGDN 109
242 #define E0_INS 110
243 #define E0_DEL 111
244
245 #define E1_PAUSE 119
246
247 /*
248 * The keycodes below are randomly located in 89-95,112-118,120-127.
249 * They could be thrown away (and all occurrences below replaced by 0),
250 * but that would force many users to use the `setkeycodes' utility, where
251 * they needed not before. It does not matter that there are duplicates, as
252 * long as no duplication occurs for any single keyboard.
253 */
254 #define SC_LIM 89 /* 0x59 == 89 */
255
256 #define FOCUS_PF1 85 /* actual code! */
257 #define FOCUS_PF2 89
258 #define FOCUS_PF3 90
259 #define FOCUS_PF4 91
260 #define FOCUS_PF5 92
261 #define FOCUS_PF6 93
262 #define FOCUS_PF7 94
263 #define FOCUS_PF8 95
264 #define FOCUS_PF9 120
265 #define FOCUS_PF10 121
266 #define FOCUS_PF11 122
267 #define FOCUS_PF12 123
268
269 #define JAP_86 124
270
271 /* On one Compaq UK keyboard, at least, bar/backslash generates scancode
272 * 0x7f. 0x7f generated on some .de and .no keyboards also.
273 */
274 #define UK_86 86
275
276 /* tfj@olivia.ping.dk:
277 * The four keys are located over the numeric keypad, and are
278 * labelled A1-A4. It's an rc930 keyboard, from
279 * Regnecentralen/RC International, Now ICL.
280 * Scancodes: 59, 5a, 5b, 5c.
281 */
282 #define RGN1 124
283 #define RGN2 125
284 #define RGN3 126
285 #define RGN4 127
286
287 static unsigned char high_keys[128 - SC_LIM] = {
288 RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
289 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
290 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
291 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
292 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
293 FOCUS_PF8, JAP_86, FOCUS_PF10, UK_86 /* 0x7c-0x7f */
294 };
295
296 /* BTC */
297 #define E0_MACRO 112
298 /* LK450 */
299 #define E0_F13 113
300 #define E0_F14 114
301 #define E0_HELP 115
302 #define E0_DO 116
303 #define E0_F17 117
304 #define E0_KPMINPLUS 118
305 /*
306 * My OmniKey generates e0 4c for the "OMNI" key and the
307 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
308 */
309 #define E0_OK 124
310 /*
311 * New microsoft keyboard is rumoured to have
312 * e0 5b (left window button), e0 5c (right window button),
313 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
314 * [or: Windows_L, Windows_R, TaskMan]
315 */
316 #define E0_MSLW 125
317 #define E0_MSRW 126
318 #define E0_MSTM 127
319
320 static unsigned char e0_keys[128] = {
321 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
322 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
323 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
324 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
325 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
326 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
327 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
328 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
329 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
330 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
331 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
332 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
333 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
334 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
335 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
336 0, 0, 0, 0, 0, 0, 0, E0_MSLW /* 0x78-0x7f */
337 };
338
pckbd_setkeycode(unsigned int scancode,unsigned int keycode)339 int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
340 {
341 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
342 return -EINVAL;
343 if (scancode < 128)
344 high_keys[scancode - SC_LIM] = keycode;
345 else
346 e0_keys[scancode - 128] = keycode;
347 return 0;
348 }
349
pckbd_getkeycode(unsigned int scancode)350 int pckbd_getkeycode(unsigned int scancode)
351 {
352 return
353 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
354 (scancode < 128) ? high_keys[scancode - SC_LIM] :
355 e0_keys[scancode - 128];
356 }
357
pckbd_translate(unsigned char scancode,unsigned char * keycode,char raw_mode)358 int pckbd_translate(unsigned char scancode, unsigned char *keycode,
359 char raw_mode)
360 {
361 static int prev_scancode;
362
363 /* special prefix scancodes.. */
364 if (scancode == 0xe0 || scancode == 0xe1) {
365 prev_scancode = scancode;
366 return 0;
367 }
368
369 /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
370 if (scancode == 0x00 || scancode == 0xff) {
371 prev_scancode = 0;
372 return 0;
373 }
374 scancode &= 0x7f;
375
376 if (prev_scancode) {
377 /*
378 * usually it will be 0xe0, but a Pause key generates
379 * e1 1d 45 e1 9d c5 when pressed, and nothing when released
380 */
381 if (prev_scancode != 0xe0) {
382 if (prev_scancode == 0xe1 && scancode == 0x1d) {
383 prev_scancode = 0x100;
384 return 0;
385 } else if (prev_scancode == 0x100 && scancode == 0x45) {
386 *keycode = E1_PAUSE;
387 prev_scancode = 0;
388 } else {
389 #ifdef KBD_REPORT_UNKN
390 if (!raw_mode)
391 printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
392 #endif
393 prev_scancode = 0;
394 return 0;
395 }
396 } else {
397 prev_scancode = 0;
398 /*
399 * The keyboard maintains its own internal caps lock and
400 * num lock statuses. In caps lock mode E0 AA precedes make
401 * code and E0 2A follows break code. In num lock mode,
402 * E0 2A precedes make code and E0 AA follows break code.
403 * We do our own book-keeping, so we will just ignore these.
404 */
405 /*
406 * For my keyboard there is no caps lock mode, but there are
407 * both Shift-L and Shift-R modes. The former mode generates
408 * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
409 * So, we should also ignore the latter. - aeb@cwi.nl
410 */
411 if (scancode == 0x2a || scancode == 0x36)
412 return 0;
413
414 if (e0_keys[scancode])
415 *keycode = e0_keys[scancode];
416 else {
417 #ifdef KBD_REPORT_UNKN
418 if (!raw_mode)
419 printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
420 scancode);
421 #endif
422 return 0;
423 }
424 }
425 } else if (scancode >= SC_LIM) {
426 /* This happens with the FOCUS 9000 keyboard
427 Its keys PF1..PF12 are reported to generate
428 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
429 Moreover, unless repeated, they do not generate
430 key-down events, so we have to zero up_flag below */
431 /* Also, Japanese 86/106 keyboards are reported to
432 generate 0x73 and 0x7d for \ - and \ | respectively. */
433 /* Also, some Brazilian keyboard is reported to produce
434 0x73 and 0x7e for \ ? and KP-dot, respectively. */
435
436 *keycode = high_keys[scancode - SC_LIM];
437
438 if (!*keycode) {
439 if (!raw_mode) {
440 #ifdef KBD_REPORT_UNKN
441 printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
442 " - ignored\n", scancode);
443 #endif
444 }
445 return 0;
446 }
447 } else
448 *keycode = scancode;
449
450 return 1;
451 }
452
453 /* ----- end of stolen part ------ */
454
455
kbd_reset_setup(void)456 void kbd_reset_setup(void)
457 {
458 }
459
handle_at_scancode(int keyval)460 void handle_at_scancode(int keyval)
461 {
462 static int brk;
463 static int esc0;
464 static int esc1;
465 int scancode = 0;
466
467 switch (keyval) {
468 case KBD_BREAK :
469 /* sets the "release_key" bit when a key is
470 released. HP keyboard send f0 followed by
471 the keycode while AT keyboard send the keycode
472 with this bit set. */
473 brk = 0x80;
474 return;
475 case KBD_ESCAPEE0 :
476 /* 2chars sequence, commonly used to differenciate
477 the two ALT keys and the two ENTER keys and so
478 on... */
479 esc0 = 2; /* e0-xx are 2 chars */
480 scancode = keyval;
481 break;
482 case KBD_ESCAPEE1 :
483 /* 3chars sequence, only used by the Pause key. */
484 esc1 = 3; /* e1-xx-xx are 3 chars */
485 scancode = keyval;
486 break;
487 #if 0
488 case KBD_RESEND :
489 /* dunno what to do when it happens. RFC */
490 printk(KERN_INFO "keyboard: KBD_RESEND received.\n");
491 return;
492 #endif
493 case 0x14 :
494 /* translate e1-14-77-e1-f0-14-f0-77 to
495 e1-1d-45-e1-9d-c5 (the Pause key) */
496 if (esc1==2) scancode = brk | 0x1d;
497 break;
498 case 0x77 :
499 if (esc1==1) scancode = brk | 0x45;
500 break;
501 case 0x12 :
502 /* an extended key is e0-12-e0-xx e0-f0-xx-e0-f0-12
503 on HP, while it is e0-2a-e0-xx e0-(xx|80)-f0-aa
504 on AT. */
505 if (esc0==1) scancode = brk | 0x2a;
506 break;
507 }
508
509
510 /* translates HP scancodes to AT scancodes */
511 if (!scancode) scancode = brk | keycode_translate[keyval];
512
513
514 if (!scancode) printk(KERN_INFO "keyboard: unexpected key code %02x\n",keyval);
515
516 /* now behave like an AT keyboard */
517 handle_scancode(scancode,!(scancode&0x80));
518
519 if (esc0) esc0--;
520 if (esc1) esc1--;
521
522 /* release key bit must be unset for the next key */
523 brk = 0;
524 }
525
526