| /* |
| * arch/ppc/4xx_io/stb_kb.c |
| * |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file COPYING in the main directory of this archive for |
| * more details. |
| */ |
| #include <linux/config.h> |
| |
| #include <linux/spinlock.h> |
| #include <linux/sched.h> |
| #include <linux/interrupt.h> |
| #include <linux/tty.h> |
| #include <linux/mm.h> |
| #include <linux/signal.h> |
| #include <linux/init.h> |
| #include <linux/kbd_ll.h> |
| #include <linux/delay.h> |
| #include <linux/random.h> |
| #include <linux/poll.h> |
| #include <linux/miscdevice.h> |
| #include <linux/slab.h> |
| #include <linux/kbd_kern.h> |
| |
| /* the following are borrowed from pc_keyb.c, thanks to those involved! */ |
| /* |
| * 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 |
| |
| #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, 0, 0, 0 /* 0x78-0x7f */ |
| }; |
| |
| void __init rawirkbd_init_hw(void) { |
| |
| } |
| /* |
| int rawirkbd_setkeycode(unsigned int scancode, unsigned int keycode) |
| { |
| return -EINVAL; |
| } |
| |
| int rawirkbd_getkeycode(unsigned int scancode) |
| { |
| return -EINVAL; |
| } |
| */ |
| |
| int rawirkbd_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; |
| } |
| |
| int rawirkbd_getkeycode(unsigned int scancode) |
| { |
| return |
| (scancode < SC_LIM || scancode > 255) ? -EINVAL : |
| (scancode < 128) ? high_keys[scancode - SC_LIM] : |
| e0_keys[scancode - 128]; |
| } |
| |
| int rawirkbd_translate(unsigned char scancode, unsigned char *keycode, |
| char raw_mode) |
| { |
| static int prev_scancode = 0; |
| |
| /* 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; |
| } |
| |
| char rawirkbd_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; |
| } |
| |
| #include <asm/machdep.h> |
| |
| void redwood_irkb_init(void) |
| { |
| extern struct machdep_calls ppc_md; |
| |
| ppc_md.kbd_setkeycode = rawirkbd_setkeycode; |
| ppc_md.kbd_getkeycode = rawirkbd_getkeycode; |
| ppc_md.kbd_translate = rawirkbd_translate; |
| ppc_md.kbd_unexpected_up = rawirkbd_unexpected_up; |
| ppc_md.kbd_leds = NULL; /*rawirkbd_leds;*/ |
| ppc_md.kbd_init_hw = rawirkbd_init_hw; |
| } |
| |