| #include <linux/kd.h> | |
| //#include <linux/kbd_ll.h> | |
| #include <linux/kbd_kern.h> | |
| /* | |
| * Translation of escaped scancodes to keycodes. | |
| * This is now user-settable. | |
| * The keycodes 1-88,96-111,119 are fairly standard, and | |
| * should probably not be changed - changing might confuse X. | |
| * X also interprets scancode 0x5d (KEY_Begin). | |
| * | |
| * For 1-88 keycode equals scancode. | |
| */ | |
| #define E0_KPENTER 96 | |
| #define E0_RCTRL 97 | |
| #define E0_KPSLASH 98 | |
| #define E0_PRSCR 99 | |
| #define E0_RALT 100 | |
| #define E0_BREAK 101 /* (control-pause) */ | |
| #define E0_HOME 102 | |
| #define E0_UP 103 | |
| #define E0_PGUP 104 | |
| #define E0_LEFT 105 | |
| #define E0_RIGHT 106 | |
| #define E0_END 107 | |
| #define E0_DOWN 108 | |
| #define E0_PGDN 109 | |
| #define E0_INS 110 | |
| #define E0_DEL 111 | |
| /* for USB 106 keyboard */ | |
| #define E0_YEN 124 | |
| #define E0_BACKSLASH 89 | |
| #define E1_PAUSE 119 | |
| /* | |
| * The keycodes below are randomly located in 89-95,112-118,120-127. | |
| * They could be thrown away (and all occurrences below replaced by 0), | |
| * but that would force many users to use the `setkeycodes' utility, where | |
| * they needed not before. It does not matter that there are duplicates, as | |
| * long as no duplication occurs for any single keyboard. | |
| */ | |
| #define SC_LIM 89 | |
| #define FOCUS_PF1 85 /* actual code! */ | |
| #define FOCUS_PF2 89 | |
| #define FOCUS_PF3 90 | |
| #define FOCUS_PF4 91 | |
| #define FOCUS_PF5 92 | |
| #define FOCUS_PF6 93 | |
| #define FOCUS_PF7 94 | |
| #define FOCUS_PF8 95 | |
| #define FOCUS_PF9 120 | |
| #define FOCUS_PF10 121 | |
| #define FOCUS_PF11 122 | |
| #define FOCUS_PF12 123 | |
| #define JAP_86 124 | |
| /* tfj@olivia.ping.dk: | |
| * The four keys are located over the numeric keypad, and are | |
| * labelled A1-A4. It's an rc930 keyboard, from | |
| * Regnecentralen/RC International, Now ICL. | |
| * Scancodes: 59, 5a, 5b, 5c. | |
| */ | |
| #define RGN1 124 | |
| #define RGN2 125 | |
| #define RGN3 126 | |
| #define RGN4 127 | |
| static unsigned char high_keys[128 - SC_LIM] = { | |
| RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */ | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ | |
| 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */ | |
| 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */ | |
| FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */ | |
| FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */ | |
| }; | |
| /* BTC */ | |
| #define E0_MACRO 112 | |
| /* LK450 */ | |
| #define E0_F13 113 | |
| #define E0_F14 114 | |
| #define E0_HELP 115 | |
| #define E0_DO 116 | |
| #define E0_F17 117 | |
| #define E0_KPMINPLUS 118 | |
| /* | |
| * My OmniKey generates e0 4c for the "OMNI" key and the | |
| * right alt key does nada. [kkoller@nyx10.cs.du.edu] | |
| */ | |
| #define E0_OK 124 | |
| /* | |
| * New microsoft keyboard is rumoured to have | |
| * e0 5b (left window button), e0 5c (right window button), | |
| * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] | |
| * [or: Windows_L, Windows_R, TaskMan] | |
| */ | |
| #define E0_MSLW 125 | |
| #define E0_MSRW 126 | |
| #define E0_MSTM 127 | |
| static unsigned char e0_keys[128] = { | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */ | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */ | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */ | |
| 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */ | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */ | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */ | |
| 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */ | |
| E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */ | |
| E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */ | |
| E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END, /* 0x48-0x4f */ | |
| E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */ | |
| 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */ | |
| 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */ | |
| 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */ | |
| //0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */ | |
| 0, 0, 0, 0, 0, E0_BACKSLASH, 0, 0, /* 0x70-0x77 */ | |
| 0, 0, 0, E0_YEN, 0, 0, 0, 0 /* 0x78-0x7f */ | |
| }; | |
| static int gen_setkeycode(unsigned int scancode, unsigned int keycode) | |
| { | |
| if (scancode < SC_LIM || scancode > 255 || keycode > 127) | |
| return -EINVAL; | |
| if (scancode < 128) | |
| high_keys[scancode - SC_LIM] = keycode; | |
| else | |
| e0_keys[scancode - 128] = keycode; | |
| return 0; | |
| } | |
| static int gen_getkeycode(unsigned int scancode) | |
| { | |
| return | |
| (scancode < SC_LIM || scancode > 255) ? -EINVAL : | |
| (scancode < | |
| 128) ? high_keys[scancode - SC_LIM] : e0_keys[scancode - 128]; | |
| } | |
| static int | |
| gen_translate(unsigned char scancode, unsigned char *keycode, char raw_mode) | |
| { | |
| static int prev_scancode; | |
| /* special prefix scancodes.. */ | |
| if (scancode == 0xe0 || scancode == 0xe1) { | |
| prev_scancode = scancode; | |
| return 0; | |
| } | |
| /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */ | |
| if (scancode == 0x00 || scancode == 0xff) { | |
| prev_scancode = 0; | |
| return 0; | |
| } | |
| scancode &= 0x7f; | |
| if (prev_scancode) { | |
| /* | |
| * usually it will be 0xe0, but a Pause key generates | |
| * e1 1d 45 e1 9d c5 when pressed, and nothing when released | |
| */ | |
| if (prev_scancode != 0xe0) { | |
| if (prev_scancode == 0xe1 && scancode == 0x1d) { | |
| prev_scancode = 0x100; | |
| return 0; | |
| } | |
| else if (prev_scancode == 0x100 | |
| && scancode == 0x45) { | |
| *keycode = E1_PAUSE; | |
| prev_scancode = 0; | |
| } else { | |
| #ifdef KBD_REPORT_UNKN | |
| if (!raw_mode) | |
| printk(KERN_INFO | |
| "keyboard: unknown e1 escape sequence\n"); | |
| #endif | |
| prev_scancode = 0; | |
| return 0; | |
| } | |
| } else { | |
| prev_scancode = 0; | |
| /* | |
| * The keyboard maintains its own internal caps lock and | |
| * num lock statuses. In caps lock mode E0 AA precedes make | |
| * code and E0 2A follows break code. In num lock mode, | |
| * E0 2A precedes make code and E0 AA follows break code. | |
| * We do our own book-keeping, so we will just ignore these. | |
| */ | |
| /* | |
| * For my keyboard there is no caps lock mode, but there are | |
| * both Shift-L and Shift-R modes. The former mode generates | |
| * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs. | |
| * So, we should also ignore the latter. - aeb@cwi.nl | |
| */ | |
| if (scancode == 0x2a || scancode == 0x36) | |
| return 0; | |
| if (e0_keys[scancode]) | |
| *keycode = e0_keys[scancode]; | |
| else { | |
| #ifdef KBD_REPORT_UNKN | |
| if (!raw_mode) | |
| printk(KERN_INFO | |
| "keyboard: unknown scancode e0 %02x\n", | |
| scancode); | |
| #endif | |
| return 0; | |
| } | |
| } | |
| } else if (scancode >= SC_LIM) { | |
| /* This happens with the FOCUS 9000 keyboard | |
| Its keys PF1..PF12 are reported to generate | |
| 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f | |
| Moreover, unless repeated, they do not generate | |
| key-down events, so we have to zero up_flag below */ | |
| /* Also, Japanese 86/106 keyboards are reported to | |
| generate 0x73 and 0x7d for \ - and \ | respectively. */ | |
| /* Also, some Brazilian keyboard is reported to produce | |
| 0x73 and 0x7e for \ ? and KP-dot, respectively. */ | |
| *keycode = high_keys[scancode - SC_LIM]; | |
| if (!*keycode) { | |
| if (!raw_mode) { | |
| #ifdef KBD_REPORT_UNKN | |
| printk(KERN_INFO | |
| "keyboard: unrecognized scancode (%02x)" | |
| " - ignored\n", scancode); | |
| #endif | |
| } | |
| return 0; | |
| } | |
| } else | |
| *keycode = scancode; | |
| return 1; | |
| } | |
| static char gen_unexpected_up(unsigned char keycode) | |
| { | |
| /* unexpected, but this can happen: maybe this was a key release for a | |
| FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */ | |
| if (keycode >= SC_LIM || keycode == 85) | |
| return 0; | |
| else | |
| return 0200; | |
| } | |
| /* | |
| * These are the default mappings | |
| */ | |
| int (*k_setkeycode)(unsigned int, unsigned int) = gen_setkeycode; | |
| int (*k_getkeycode)(unsigned int) = gen_getkeycode; | |
| int (*k_translate)(unsigned char, unsigned char *, char) = gen_translate; | |
| char (*k_unexpected_up)(unsigned char) = gen_unexpected_up; | |
| void (*k_leds)(unsigned char); | |
| /* Simple translation table for the SysRq keys */ | |
| #ifdef CONFIG_MAGIC_SYSRQ | |
| static unsigned char gen_sysrq_xlate[128] = | |
| "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ | |
| "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ | |
| "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ | |
| "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ | |
| "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ | |
| "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ | |
| "\r\000/"; /* 0x60 - 0x6f */ | |
| unsigned char *k_sysrq_xlate = gen_sysrq_xlate; | |
| int k_sysrq_key = 0x54; | |
| #endif |