1 |
1275 |
phoenix |
/*
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
456 |
|
|
void kbd_reset_setup(void)
|
457 |
|
|
{
|
458 |
|
|
}
|
459 |
|
|
|
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 |
|
|
|