Johannes Berg wrote: > update: kernel patch against 2.6.11.5 to make the fn key work.
I don't know whether anyone would find this useful but I took Johannes patch and have started to provide the 'fn' key within the hid code so that it acts as a modifier, rather than maps to right control. Attached is a patch against the 2.6.11 kernel (I'm using Gentoo so I'm hoping it'll work generally) that, when you press the 'fn' key, maps the Fx keys to their standard codes and maps the cursor keys to home, end, page up and page down. It uses the 'hid_fn' lookup table (that I've added) for this and so changing or adding to these mappings should be a case of altering that table only. I will point out that I'm certainly no kernel hacker (by a long shot!) but this patch means that I can use pbbuttonsd without having to change the standard setup. If someone can help point me to where I can store the state of the 'fn' key and why I have to use set_bit before calling input_event for these keys, I'd appreciate it. Matt
diff -Naur linux-2.6.11-gentoo-r4/drivers/usb/input/hid-core.c linux-2.6.11-gentoo-r4-patched/drivers/usb/input/hid-core.c --- linux-2.6.11-gentoo-r4/drivers/usb/input/hid-core.c 2005-04-02 09:04:52.000000000 +0000 +++ linux-2.6.11-gentoo-r4-patched/drivers/usb/input/hid-core.c 2005-04-02 09:11:45.000000000 +0000 @@ -1494,6 +1494,11 @@ #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 +#define USB_VENDOR_ID_APPLE 0x05AC +#define USB_DEVICE_ID_POWERBOOK_KB_US 0x020E +#define USB_DEVICE_ID_POWERBOOK_KB_UK 0x020F + + static struct hid_blacklist { __u16 idVendor; __u16 idProduct; @@ -1586,6 +1591,9 @@ { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_POWERBOOK_KB_US, HID_QUIRK_POWERBOOK_FN_BUTTON }, + { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_POWERBOOK_KB_UK, HID_QUIRK_POWERBOOK_FN_BUTTON }, + { 0, 0 } }; diff -Naur linux-2.6.11-gentoo-r4/drivers/usb/input/hid-input.c linux-2.6.11-gentoo-r4-patched/drivers/usb/input/hid-input.c --- linux-2.6.11-gentoo-r4/drivers/usb/input/hid-input.c 2005-04-02 09:04:52.000000000 +0000 +++ linux-2.6.11-gentoo-r4-patched/drivers/usb/input/hid-input.c 2005-04-02 09:12:50.000000000 +0000 @@ -39,22 +39,46 @@ #define unk KEY_UNKNOWN static unsigned char hid_keyboard[256] = { - 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, - 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, - 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, - 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, - 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, - 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, - 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, - 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, - 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk + 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, /* 0- 15 */ + 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, /* 16- 31 */ + 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, /* 32- 47 */ + 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, /* 48- 63 */ + 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, /* 64- 79 */ + 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, /* 80- 95 */ + 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, /* 96-111 */ + 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, /* 112-127 */ + 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, /* 128-143 */ + 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 144-159 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 160-175 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 176-191 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 192-207 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 208-223 */ + 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, /* 224-239 */ + 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk /* 240-255 */ +}; + +/* + * The stuff that follows is related to the powerbook 'fn' key quirk, maintaining the + * state of the key and a mapping for the various other keys that are affected by it. + */ +static unsigned int fn_state = 0; /* TODO: Move this input a device specific container, for different devices */ +static unsigned char hid_fn[256] = { + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 0- 15 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 16- 31 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 32- 47 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,224,225,113,114,115, /* 48- 63 */ + unk,unk,228,229,230,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 64- 79 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 80- 95 */ + unk,unk,unk,unk,unk,unk,unk,104,unk,102,107,unk,109,unk,unk,unk, /* 96-111 */ /* pageup, home, end, pagedown */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 112-127 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 128-143 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 144-159 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 160-175 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 176-191 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 192-207 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 208-223 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, /* 224-239 */ + unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk /* 240-255 */ }; static struct { @@ -409,6 +432,25 @@ if (!usage->type) return; + /* + * If the keyboard has the powerbook 'fn' key quirk then we need to check what's going on. + * If it's the 'fn' key that has caused the event then we need to store its state. If it's + * a normal key, and the 'fn' key has it's state set to on, then we need to map the key that + * was just pressed into a new key. + */ + if (hid->quirks & HID_QUIRK_POWERBOOK_FN_BUTTON) { + if ((usage->type == EV_ABS) && (usage->code == 40)) { + fn_state = value; + + /* Just in case, don't swallow the event! */ + } else if ((usage->type == EV_KEY) && fn_state) { + set_bit(hid_fn[ usage->code ], input->keybit); /* Q: Why do I have to do this? */ + input_event(input, EV_KEY, hid_fn[ usage->code ], value); + clear_bit(hid_fn[ usage->code ], input->keybit); /* Q: Hmm, probably shouldn't */ + return; + } + } + if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; diff -Naur linux-2.6.11-gentoo-r4/drivers/usb/input/hid.h linux-2.6.11-gentoo-r4-patched/drivers/usb/input/hid.h --- linux-2.6.11-gentoo-r4/drivers/usb/input/hid.h 2005-04-02 09:04:52.000000000 +0000 +++ linux-2.6.11-gentoo-r4-patched/drivers/usb/input/hid.h 2005-03-24 12:38:36.000000000 +0000 @@ -242,6 +242,7 @@ #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 +#define HID_QUIRK_POWERBOOK_FN_BUTTON 0x400 /* * This is the global environment of the parser. This information is