2 * linux/drivers/char/q40_keyb.c
6 #include <linux/config.h>
8 #include <linux/spinlock.h>
9 #include <linux/sched.h>
10 #include <linux/interrupt.h>
11 #include <linux/tty.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>
26 #include <asm/keyboard.h>
27 #include <asm/bitops.h>
29 #include <asm/uaccess.h>
30 #include <asm/q40_master.h>
32 #include <asm/q40ints.h>
35 /* Simple translation table for the SysRq keys */
37 #define SYSRQ_KEY 0x54
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 */
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 */
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 */
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*/
96 static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
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).
106 * For 1-88 keycode equals scancode.
109 #define E0_KPENTER 96
111 #define E0_KPSLASH 98
114 #define E0_BREAK 101 /* (control-pause) */
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.
137 #define FOCUS_PF1 85 /* actual code! */
145 #define FOCUS_PF9 120
146 #define FOCUS_PF10 121
147 #define FOCUS_PF11 122
148 #define FOCUS_PF12 123
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.
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 */
179 #define E0_KPMINPLUS 118
181 * My OmniKey generates e0 4c for the "OMNI" key and the
182 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
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]
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 */
216 int q40kbd_setkeycode(unsigned int scancode, unsigned int keycode)
218 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
221 high_keys[scancode - SC_LIM] = keycode;
223 e0_keys[scancode - 128] = keycode;
227 int q40kbd_getkeycode(unsigned int scancode)
230 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
231 (scancode < 128) ? high_keys[scancode - SC_LIM] :
232 e0_keys[scancode - 128];
236 #define disable_keyboard()
237 #define enable_keyboard()
242 int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
245 static int prev_scancode;
247 /* special prefix scancodes.. */
248 if (scancode == 0xe0 || scancode == 0xe1) {
249 prev_scancode = scancode;
253 /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
254 if (scancode == 0x00 || scancode == 0xff) {
263 * usually it will be 0xe0, but a Pause key generates
264 * e1 1d 45 e1 9d c5 when pressed, and nothing when released
266 if (prev_scancode != 0xe0) {
267 if (prev_scancode == 0xe1 && scancode == 0x1d) {
268 prev_scancode = 0x100;
270 } else if (prev_scancode == 0x100 && scancode == 0x45) {
274 #ifdef KBD_REPORT_UNKN
276 printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
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.
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
296 if (scancode == 0x2a || scancode == 0x36)
299 if (e0_keys[scancode])
300 *keycode = e0_keys[scancode];
302 #ifdef KBD_REPORT_UNKN
304 printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
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. */
321 *keycode = high_keys[scancode - SC_LIM];
325 #ifdef KBD_REPORT_UNKN
326 printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
327 " - ignored\n", scancode);
337 char q40kbd_unexpected_up(unsigned char keycode)
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)
350 static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
352 unsigned char status;
354 spin_lock(&kbd_controller_lock);
357 status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
360 unsigned char scancode,qcode;
362 qcode = master_inb(KEYCODE_REG);
369 handle_scancode(qprev , 1);
373 scancode=qprev ? q40ecl[qcode] : q40cl[qcode];
375 /* next line is last resort to hanlde some oddities */
376 if (qprev && !scancode) scancode=q40cl[qcode];
381 printk("unknown scancode %x\n",qcode);
384 if (scancode==0xff) /* SySrq */
387 handle_scancode(scancode, ! keyup );
389 tasklet_schedule(&keyboard_tasklet);
395 spin_unlock(&kbd_controller_lock);
396 master_outb(-1,KEYBOARD_UNLOCK_REG); /* keyb ints reenabled herewith */
400 #define KBD_NO_DATA (-1) /* No data */
401 #define KBD_BAD_DATA (-2) /* Parity or other error */
403 static int __init kbd_read_input(void)
405 int retval = KBD_NO_DATA;
406 unsigned char status;
408 status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
410 unsigned char data = master_inb(KEYCODE_REG);
413 master_outb(-1,KEYBOARD_UNLOCK_REG);
419 static void __init kbd_clear_input(void)
421 int maxread = 100; /* Random number */
424 if (kbd_read_input() == KBD_NO_DATA)
430 int __init q40kbd_init_hw(void)
433 /* Flush any pending input. */
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);