From: Vojtech Pavlik I have two patches I'd like to get tested by a wider audience before sending them to Linus for the 2.6 tree. The first one fixes an issue in current 2.6-test with AT keyboard repeat rate setting, the second one makes setkeycodes/getkeycodes work the same as 2.4, so that people can keep their setups. It also fixes japanese and korean key handling. drivers/char/keyboard.c | 35 ++++--- drivers/input/keyboard/atkbd.c | 191 +++++++++++++++++++++-------------------- include/linux/keyboard.h | 3 3 files changed, 124 insertions(+), 105 deletions(-) diff -puN drivers/char/keyboard.c~atkbd-24-compatibility drivers/char/keyboard.c --- 25/drivers/char/keyboard.c~atkbd-24-compatibility 2003-11-10 15:45:05.000000000 -0800 +++ 25-akpm/drivers/char/keyboard.c 2003-11-10 15:45:05.000000000 -0800 @@ -941,16 +941,16 @@ static unsigned short x86_keycodes[256] 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 43, 85, 86, 87, 88,115,119,120,121,375,123, 90, - 284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339, - 367,288,302,304,350, 92,334,512,116,377,109,111,373,347,348,349, - 360, 93, 94, 95, 98,376,100,101,321,316,354,286,289,102,351,355, + 80, 81, 82, 83, 84, 93, 86, 87, 88, 94, 95, 85,259,375,260, 90, + 284,285,309,311,312, 91,327,328,329,331,333,335,336,337,338,339, + 367,288,302,304,350, 89,334,326,116,377,109,111,126,347,348,349, + 360,261,262,263,298,376,100,101,321,316,373,286,289,102,351,355, 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, - 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,270,114, - 118,117,125,374,379,115,112,125,121,123,264,265,266,267,268,269, - 271,273,276,277,278,282,283,295,296,297,299,300,301,293,303,307, - 308,310,313,314,315,317,318,319,320,357,322,323,324,325,326,330, - 332,340,365,342,343,344,345,346,356,113,341,368,369,370,371,372 }; + 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114, + 264,117,271,374,379,115,125,273,121,123, 92,265,266,267,268,269, + 120,119,118,277,278,282,283,295,296,297,299,300,301,293,303,307, + 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, + 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; #ifdef CONFIG_MAC_EMUMOUSEBTN extern int mac_hid_mouse_emulate_buttons(int, int, int); @@ -972,11 +972,18 @@ static int emulate_raw(struct vc_data *v if (keycode > 255 || !x86_keycodes[keycode]) return -1; - if (keycode == KEY_PAUSE) { - put_queue(vc, 0xe1); - put_queue(vc, 0x1d | up_flag); - put_queue(vc, 0x45 | up_flag); - return 0; + switch (keycode) { + case KEY_PAUSE: + put_queue(vc, 0xe1); + put_queue(vc, 0x1d | up_flag); + put_queue(vc, 0x45 | up_flag); + return 0; + case KEY_LANG1: + if (!up_flag) put_queue(vc, 0xf1); + return 0; + case KEY_LANG2: + if (!up_flag) put_queue(vc, 0xf2); + return 0; } if (keycode == KEY_SYSRQ && sysrq_alt) { diff -puN drivers/input/keyboard/atkbd.c~atkbd-24-compatibility drivers/input/keyboard/atkbd.c --- 25/drivers/input/keyboard/atkbd.c~atkbd-24-compatibility 2003-11-10 15:45:05.000000000 -0800 +++ 25-akpm/drivers/input/keyboard/atkbd.c 2003-11-10 15:45:05.000000000 -0800 @@ -48,33 +48,30 @@ static int atkbd_softrepeat; */ static unsigned char atkbd_set2_keycode[512] = { - 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41, 85, - 0, 56, 42,182, 29, 16, 2, 89, 0, 0, 44, 31, 30, 17, 3, 90, - 0, 46, 45, 32, 18, 5, 4, 91, 90, 57, 47, 33, 20, 19, 6, 0, - 91, 49, 48, 35, 34, 21, 7, 0, 0, 0, 50, 36, 22, 8, 9, 0, + + 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117, + 0, 56, 42,182, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0, + 0, 46, 45, 32, 18, 5, 4,186, 0, 57, 47, 33, 20, 19, 6, 85, + 0, 49, 48, 35, 34, 21, 7, 89, 0, 0, 50, 36, 22, 8, 9, 90, 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, - 122, 89, 40,120, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 0, - 85, 86, 90, 91, 92, 93, 14, 94, 95, 79,183, 75, 71,121, 0,123, + 0,181, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0,194, + 0, 86,193,192,184, 0, 14,185, 0, 79,182, 75, 71,124, 0, 0, 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99, - 0, 0, 0, 65, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, - 0, 0, 92, 90, 85, 0,137, 0, 0, 0, 0, 91, 89,144,115, 0, - 217,100,255, 0, 97,165,164, 0,156, 0, 0,140,115, 0, 0,125, - 173,114, 0,113,152,163,151,126,128,166, 0,140, 0,147, 0,127, - 159,167,115,160,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, - 157, 0,114,166,168, 0, 0,213,155, 0, 98,113, 0,163, 0,138, - 226, 0, 0, 0, 0, 0,153,140, 0,255, 96, 0, 0, 0,143, 0, - 133, 0,116, 0,143, 0,174,133, 0,107, 0,105,102, 0, 0,112, - 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119 + 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, + 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, + 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, + 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, + 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, + 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0, + + 0, 0, 0, 65, 99, }; static unsigned char atkbd_set3_keycode[512] = { + 0, 0, 0, 0, 0, 0, 0, 59, 1,138,128,129,130, 15, 41, 60, 131, 29, 42, 86, 58, 16, 2, 61,133, 56, 44, 31, 30, 17, 3, 62, 134, 46, 45, 32, 18, 5, 4, 63,135, 57, 47, 33, 20, 19, 6, 64, @@ -83,25 +80,21 @@ static unsigned char atkbd_set3_keycode[ 113,114, 40, 84, 26, 13, 87, 99, 97, 54, 28, 27, 43, 84, 88, 70, 108,105,119,103,111,107, 14,110, 0, 79,106, 75, 71,109,102,104, 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55, 85, + 89, 90, 91, 92, 74,185,184,182, 0, 0, 0,125,126,127,112, 0, 0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168, - 148,149,147,140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255 + 148,149,147,140 }; static unsigned char atkbd_unxlate_table[128] = { - 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, - 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, - 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, - 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3, - 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105, - 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63, - 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, - 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 + 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, + 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, + 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, + 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3, + 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105, + 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63, + 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, + 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 }; #define ATKBD_CMD_SETLEDS 0x10ed @@ -125,6 +118,9 @@ static unsigned char atkbd_unxlate_table #define ATKBD_RET_EMULX 0x80 #define ATKBD_RET_EMUL1 0xe1 #define ATKBD_RET_RELEASE 0xf0 +#define ATKBD_RET_HANGUEL 0xf1 +#define ATKBD_RET_HANJA 0xf2 +#define ATKBD_RET_ERR 0xff #define ATKBD_KEY_UNKNOWN 0 #define ATKBD_KEY_NULL 255 @@ -156,6 +152,17 @@ struct atkbd { unsigned long time; }; +static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int code, int value) +{ + input_regs(dev, regs); + if (value == 3) { + input_report_key(dev, code, 1); + input_report_key(dev, code, 0); + } else + input_event(dev, EV_KEY, code, value); + input_sync(dev); +} + /* * atkbd_interrupt(). Here takes place processing of data received from * the keyboard into events. @@ -184,47 +191,37 @@ static irqreturn_t atkbd_interrupt(struc atkbd->resend = 0; #endif - switch (code) { - case ATKBD_RET_ACK: - atkbd->ack = 1; - goto out; - case ATKBD_RET_NAK: - atkbd->ack = -1; - goto out; - } - - if (atkbd->translated) do { - - if (atkbd->emul != 1) { - if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) - break; - if (code == ATKBD_RET_BAT) { - if (!atkbd->bat_xl) - break; - atkbd->bat_xl = 0; - } - if (code == (ATKBD_RET_BAT & 0x7f)) - atkbd->bat_xl = 1; - } - - if (code < 0x80) { - code = atkbd_unxlate_table[code]; - break; + if (!atkbd->ack) + switch (code) { + case ATKBD_RET_ACK: + atkbd->ack = 1; + goto out; + case ATKBD_RET_NAK: + atkbd->ack = -1; + goto out; } - if (atkbd->cmdcnt) - break; - - code = atkbd_unxlate_table[code & 0x7f]; - atkbd->release = 1; - - } while (0); - if (atkbd->cmdcnt) { atkbd->cmdbuf[--atkbd->cmdcnt] = code; goto out; } + if (atkbd->translated) { + + if (atkbd->emul || + !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 || + code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA || + code == ATKBD_RET_ERR || + (code == ATKBD_RET_BAT && !atkbd->bat_xl))) { + atkbd->release = code >> 7; + code &= 0x7f; + } + + if (!atkbd->emul && + (code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) + atkbd->bat_xl = !atkbd->release; + } + switch (code) { case ATKBD_RET_BAT: serio_rescan(atkbd->serio); @@ -238,22 +235,33 @@ static irqreturn_t atkbd_interrupt(struc case ATKBD_RET_RELEASE: atkbd->release = 1; goto out; + case ATKBD_RET_HANGUEL: + atkbd_report_key(&atkbd->dev, regs, KEY_LANG1, 3); + goto out; + case ATKBD_RET_HANJA: + atkbd_report_key(&atkbd->dev, regs, KEY_LANG2, 3); + goto out; + case ATKBD_RET_ERR: + printk(KERN_WARNING "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); + goto out; } + if (atkbd->set != 3) + code = (code & 0x7f) | ((code & 0x80) << 1); if (atkbd->emul) { if (--atkbd->emul) goto out; - code |= 0x100; + code |= (atkbd->set != 3) ? 0x80 : 0x100; } switch (atkbd->keycode[code]) { case ATKBD_KEY_NULL: break; case ATKBD_KEY_UNKNOWN: - printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x, data %#x, on %s).\n", + printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", atkbd->release ? "released" : "pressed", atkbd->translated ? "translated" : "raw", - atkbd->set, code, data, serio->phys); + atkbd->set, code, serio->phys); break; default: value = atkbd->release ? 0 : @@ -273,9 +281,7 @@ static irqreturn_t atkbd_interrupt(struc break; } - input_regs(&atkbd->dev, regs); - input_event(&atkbd->dev, EV_KEY, atkbd->keycode[code], value); - input_sync(&atkbd->dev); + atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value); } atkbd->release = 0; @@ -369,10 +375,11 @@ static int atkbd_command(struct atkbd *a static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct atkbd *atkbd = dev->private; - struct { int p; u8 v; } period[] = - { {30, 0x00}, {25, 0x02}, {20, 0x04}, {15, 0x08}, {10, 0x0c}, {7, 0x10}, {5, 0x14}, {0, 0x14} }; - struct { int d; u8 v; } delay[] = - { {1000, 0x60}, {750, 0x40}, {500, 0x20}, {250, 0x00}, {0, 0x00} }; + const short period[32] = + { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, + 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 }; + const short delay[4] = + { 250, 500, 750, 1000 }; char param[2]; int i, j; @@ -406,11 +413,11 @@ static int atkbd_event(struct input_dev if (atkbd_softrepeat) return 0; i = j = 0; - while (period[i].p > dev->rep[REP_PERIOD]) i++; - while (delay[j].d > dev->rep[REP_DELAY]) j++; - dev->rep[REP_PERIOD] = period[i].p; - dev->rep[REP_DELAY] = delay[j].d; - param[0] = period[i].v | delay[j].v; + while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++; + while (j < 4 && delay[j] < dev->rep[REP_DELAY]) j++; + dev->rep[REP_PERIOD] = period[i]; + dev->rep[REP_DELAY] = delay[j]; + param[0] = i | (j << 5); atkbd_command(atkbd, param, ATKBD_CMD_SETREP); return 0; @@ -624,6 +631,7 @@ static void atkbd_connect(struct serio * atkbd->dev.rep[REP_PERIOD] = 33; } + atkbd->ack = 1; atkbd->serio = serio; init_input_dev(&atkbd->dev); @@ -668,16 +676,22 @@ static void atkbd_connect(struct serio * sprintf(atkbd->phys, "%s/input0", serio->phys); - if (atkbd->set == 3) - memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode)); - else + if (atkbd->translated) { + for (i = 0; i < 128; i++) { + atkbd->keycode[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]]; + atkbd->keycode[i | 0x80] = atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80]; + } + } else if (atkbd->set == 2) { memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode)); + } else { + memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode)); + } atkbd->dev.name = atkbd->name; atkbd->dev.phys = atkbd->phys; atkbd->dev.id.bustype = BUS_I8042; atkbd->dev.id.vendor = 0x0001; - atkbd->dev.id.product = atkbd->set; + atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set; atkbd->dev.id.version = atkbd->id; for (i = 0; i < 512; i++) @@ -689,7 +703,6 @@ static void atkbd_connect(struct serio * printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys); } - static struct serio_dev atkbd_dev = { .interrupt = atkbd_interrupt, .connect = atkbd_connect, diff -puN include/linux/keyboard.h~atkbd-24-compatibility include/linux/keyboard.h --- 25/include/linux/keyboard.h~atkbd-24-compatibility 2003-11-10 15:45:05.000000000 -0800 +++ 25-akpm/include/linux/keyboard.h 2003-11-10 15:45:05.000000000 -0800 @@ -2,7 +2,6 @@ #define __LINUX_KEYBOARD_H #include -#include #define KG_SHIFT 0 #define KG_CTRL 2 @@ -17,7 +16,7 @@ #define NR_SHIFT 9 -#define NR_KEYS (KEY_MAX+1) +#define NR_KEYS 255 #define MAX_NR_KEYMAPS 256 /* This means 128Kb if all keymaps are allocated. Only the superuser may increase the number of keymaps beyond MAX_NR_OF_USER_KEYMAPS. */ _