From: Michael Hanselmann <linux-kernel@hansmi.ch>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linux-kernel@killerfox.forkbomb.ch, dtor_core@ameritech.net,
linux-kernel@vger.kernel.org, linuxppc-dev@ozlabs.org,
Vojtech Pavlik <vojtech@suse.cz>,
linux-input@atrey.karlin.mff.cuni.cz
Subject: Re: [PATCH/RFC?] usb/input: Add support for fn key on Apple PowerBooks
Date: Wed, 11 Jan 2006 22:46:07 +0100 [thread overview]
Message-ID: <20060111214607.GG6617@hansmi.ch> (raw)
In-Reply-To: <1137015006.5138.18.camel@localhost.localdomain>
On Thu, Jan 12, 2006 at 08:30:06AM +1100, Benjamin Herrenschmidt wrote:
> I personally think one parameter is plenty enough (on/off) . Michael,
> can you send Dimitri the latest version of that patch please ?
Here it is, CC to Dmitry.
This patch implements support for the fn key on PowerBooks using USB
based keyboards.
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
Acked-by: Rene Nussbaumer <linux-kernel@killerfox.forkbomb.ch>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/Kconfig linux-2.6.15-rc7/drivers/usb/input/Kconfig
--- linux-2.6.15-rc7.orig/drivers/usb/input/Kconfig 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/Kconfig 2006-01-02 20:26:21.000000000 +0100
@@ -37,6 +37,16 @@ config USB_HIDINPUT
If unsure, say Y.
+config USB_HIDINPUT_POWERBOOK
+ bool "Enable support for iBook/PowerBook special keys"
+ default n
+ depends on USB_HIDINPUT
+ help
+ Say Y here if you want support for the special keys (Fn, Numlock) on
+ Apple iBooks and PowerBooks.
+
+ If unsure, say N.
+
config HID_FF
bool "Force feedback support (EXPERIMENTAL)"
depends on USB_HIDINPUT && EXPERIMENTAL
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/hid-core.c linux-2.6.15-rc7/drivers/usb/input/hid-core.c
--- linux-2.6.15-rc7.orig/drivers/usb/input/hid-core.c 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/hid-core.c 2006-01-02 13:52:59.000000000 +0100
@@ -1580,6 +1580,14 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
+
{ 0, 0 }
};
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/hid-input.c linux-2.6.15-rc7/drivers/usb/input/hid-input.c
--- linux-2.6.15-rc7.orig/drivers/usb/input/hid-input.c 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/hid-input.c 2006-01-03 20:21:00.000000000 +0100
@@ -63,6 +63,71 @@ static struct {
__s32 y;
} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
+struct hidinput_key_translation {
+ u16 from;
+ u16 to;
+ u8 flags;
+};
+
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+
+#define POWERBOOK_FLAG_FKEY 0x01
+
+static struct hidinput_key_translation powerbook_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY },
+ { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY },
+ { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY },
+ { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY },
+ { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY },
+ { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY },
+ { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY },
+ { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY },
+ { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static struct hidinput_key_translation powerbook_numlock_keys[] = {
+ { KEY_J, KEY_KP1 },
+ { KEY_K, KEY_KP2 },
+ { KEY_L, KEY_KP3 },
+ { KEY_U, KEY_KP4 },
+ { KEY_I, KEY_KP5 },
+ { KEY_O, KEY_KP6 },
+ { KEY_7, KEY_KP7 },
+ { KEY_8, KEY_KP8 },
+ { KEY_9, KEY_KP9 },
+ { KEY_M, KEY_KP0 },
+ { KEY_DOT, KEY_KPDOT },
+ { KEY_SLASH, KEY_KPPLUS },
+ { KEY_SEMICOLON, KEY_KPMINUS },
+ { KEY_P, KEY_KPASTERISK },
+ { KEY_MINUS, KEY_KPEQUAL },
+ { KEY_0, KEY_KPSLASH },
+ { KEY_F6, KEY_NUMLOCK },
+ { KEY_KPENTER, KEY_KPENTER },
+ { KEY_BACKSPACE, KEY_BACKSPACE },
+ { }
+};
+
+static int usbhid_pb_fkeyslast;
+module_param_named(pb_fkeyslast, usbhid_pb_fkeyslast, bool, 0644);
+MODULE_PARM_DESC(usbhid_pb_fkeyslast, "Use F keys only while pressing fn on PowerBooks");
+
+static int usbhid_pb_disablefnkeys;
+module_param_named(pb_disablefnkeys, usbhid_pb_disablefnkeys, bool, 0644);
+MODULE_PARM_DESC(usbhid_pb_disablefnkeys, "Disable fn special keys on PowerBooks");
+
+static int usbhid_pb_disablekeypad;
+module_param_named(pb_disablekeypad, usbhid_pb_disablekeypad, bool, 0644);
+MODULE_PARM_DESC(usbhid_pb_disablekeypad, "Disable keypad keys on PowerBooks");
+#endif
+
#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0)
#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
@@ -73,6 +138,85 @@ static struct {
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)
+static inline struct hidinput_key_translation *find_translation(
+ struct hidinput_key_translation *table, u16 from)
+{
+ struct hidinput_key_translation *trans;
+
+ /* Look for the translation */
+ for(trans = table; trans->from && (trans->from != from); trans++);
+
+ return (trans->from?trans:NULL);
+}
+
+static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
+ struct hid_usage *usage, __s32 value)
+{
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+ struct hidinput_key_translation *trans;
+
+ if (usage->code == KEY_FN) {
+ if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON;
+ else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON;
+
+ input_event(input, usage->type, usage->code, value);
+
+ return 1;
+ }
+
+ if (!usbhid_pb_disablefnkeys) {
+ trans = find_translation(powerbook_fn_keys, usage->code);
+
+ if (trans) {
+ int do_translate;
+
+ if (test_bit(usage->code, hid->pb_fn))
+ do_translate = 1;
+ else if (trans->flags & POWERBOOK_FLAG_FKEY)
+ do_translate =
+ (!usbhid_pb_fkeyslast && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
+ ( usbhid_pb_fkeyslast && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
+ else
+ do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON);
+
+ if (do_translate) {
+ if (value)
+ set_bit(usage->code, hid->pb_fn);
+ else
+ clear_bit(usage->code, hid->pb_fn);
+
+ input_event(input, usage->type, trans->to, value);
+
+ return 1;
+ }
+ }
+ }
+
+ if (!usbhid_pb_disablekeypad) {
+ int try_translate =
+ test_bit(usage->code, hid->pb_numlock)?1:
+ test_bit(LED_NUML, input->led);
+
+ if (try_translate) {
+ trans = find_translation(powerbook_numlock_keys, usage->code);
+
+ if (trans) {
+ if (value)
+ set_bit(usage->code, hid->pb_numlock);
+ else
+ clear_bit(usage->code, hid->pb_numlock);
+
+ input_event(input, usage->type, trans->to, value);
+ }
+
+ return 1;
+ }
+ }
+#endif
+
+ return 0;
+}
+
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
@@ -325,7 +469,27 @@ static void hidinput_configure_usage(str
set_bit(EV_REP, input->evbit);
switch(usage->hid & HID_USAGE) {
- case 0x003: map_key_clear(KEY_FN); break;
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+ /* The fn key on Apple PowerBooks */
+ case 0x0003: {
+ struct hidinput_key_translation *trans;
+
+ map_key_clear(KEY_FN);
+
+ set_bit(KEY_FN, input->keybit);
+ set_bit(KEY_NUMLOCK, input->keybit);
+
+ /* Enable all needed keys */
+ for(trans = powerbook_fn_keys; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+
+ for(trans = powerbook_numlock_keys; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+
+ goto ignore;
+ }
+#endif
+
default: goto ignore;
}
break;
@@ -482,6 +646,11 @@ void hidinput_hid_event(struct hid_devic
return;
}
+ if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) &&
+ hidinput_pb_event(hid, input, usage, value)) {
+ return;
+ }
+
if (usage->hat_min < usage->hat_max || usage->hat_dir) {
int hat_dir = usage->hat_dir;
if (!hat_dir)
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/hid.h linux-2.6.15-rc7/drivers/usb/input/hid.h
--- linux-2.6.15-rc7.orig/drivers/usb/input/hid.h 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/hid.h 2006-01-03 00:45:13.000000000 +0100
@@ -246,6 +246,8 @@ struct hid_item {
#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400
+#define HID_QUIRK_POWERBOOK_HAS_FN 0x00000800
+#define HID_QUIRK_POWERBOOK_FN_ON 0x00001000
/*
* This is the global environment of the parser. This information is
@@ -431,6 +433,14 @@ struct hid_device { /* device repo
void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */
int (*ff_event)(struct hid_device *hid, struct input_dev *input,
unsigned int type, unsigned int code, int value);
+
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+ /* We do this here because it's only relevant for the
+ * USB devices, not for all input_dev's.
+ */
+ unsigned long pb_fn[NBITS(KEY_MAX)];
+ unsigned long pb_numlock[NBITS(KEY_MAX)];
+#endif
};
#define HID_GLOBAL_STACK_SIZE 4
WARNING: multiple messages have this Message-ID (diff)
From: Michael Hanselmann <linux-kernel@hansmi.ch>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: dtor_core@ameritech.net, linux-kernel@vger.kernel.org,
linux-input@atrey.karlin.mff.cuni.cz, linuxppc-dev@ozlabs.org,
linux-kernel@killerfox.forkbomb.ch,
Vojtech Pavlik <vojtech@suse.cz>
Subject: Re: [PATCH/RFC?] usb/input: Add support for fn key on Apple PowerBooks
Date: Wed, 11 Jan 2006 22:46:07 +0100 [thread overview]
Message-ID: <20060111214607.GG6617@hansmi.ch> (raw)
In-Reply-To: <1137015006.5138.18.camel@localhost.localdomain>
On Thu, Jan 12, 2006 at 08:30:06AM +1100, Benjamin Herrenschmidt wrote:
> I personally think one parameter is plenty enough (on/off) . Michael,
> can you send Dimitri the latest version of that patch please ?
Here it is, CC to Dmitry.
This patch implements support for the fn key on PowerBooks using USB
based keyboards.
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
Acked-by: Rene Nussbaumer <linux-kernel@killerfox.forkbomb.ch>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/Kconfig linux-2.6.15-rc7/drivers/usb/input/Kconfig
--- linux-2.6.15-rc7.orig/drivers/usb/input/Kconfig 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/Kconfig 2006-01-02 20:26:21.000000000 +0100
@@ -37,6 +37,16 @@ config USB_HIDINPUT
If unsure, say Y.
+config USB_HIDINPUT_POWERBOOK
+ bool "Enable support for iBook/PowerBook special keys"
+ default n
+ depends on USB_HIDINPUT
+ help
+ Say Y here if you want support for the special keys (Fn, Numlock) on
+ Apple iBooks and PowerBooks.
+
+ If unsure, say N.
+
config HID_FF
bool "Force feedback support (EXPERIMENTAL)"
depends on USB_HIDINPUT && EXPERIMENTAL
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/hid-core.c linux-2.6.15-rc7/drivers/usb/input/hid-core.c
--- linux-2.6.15-rc7.orig/drivers/usb/input/hid-core.c 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/hid-core.c 2006-01-02 13:52:59.000000000 +0100
@@ -1580,6 +1580,14 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
{ USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
+ { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
+
{ 0, 0 }
};
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/hid-input.c linux-2.6.15-rc7/drivers/usb/input/hid-input.c
--- linux-2.6.15-rc7.orig/drivers/usb/input/hid-input.c 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/hid-input.c 2006-01-03 20:21:00.000000000 +0100
@@ -63,6 +63,71 @@ static struct {
__s32 y;
} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
+struct hidinput_key_translation {
+ u16 from;
+ u16 to;
+ u8 flags;
+};
+
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+
+#define POWERBOOK_FLAG_FKEY 0x01
+
+static struct hidinput_key_translation powerbook_fn_keys[] = {
+ { KEY_BACKSPACE, KEY_DELETE },
+ { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY },
+ { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY },
+ { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY },
+ { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY },
+ { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY },
+ { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY },
+ { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY },
+ { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY },
+ { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY },
+ { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY },
+ { KEY_UP, KEY_PAGEUP },
+ { KEY_DOWN, KEY_PAGEDOWN },
+ { KEY_LEFT, KEY_HOME },
+ { KEY_RIGHT, KEY_END },
+ { }
+};
+
+static struct hidinput_key_translation powerbook_numlock_keys[] = {
+ { KEY_J, KEY_KP1 },
+ { KEY_K, KEY_KP2 },
+ { KEY_L, KEY_KP3 },
+ { KEY_U, KEY_KP4 },
+ { KEY_I, KEY_KP5 },
+ { KEY_O, KEY_KP6 },
+ { KEY_7, KEY_KP7 },
+ { KEY_8, KEY_KP8 },
+ { KEY_9, KEY_KP9 },
+ { KEY_M, KEY_KP0 },
+ { KEY_DOT, KEY_KPDOT },
+ { KEY_SLASH, KEY_KPPLUS },
+ { KEY_SEMICOLON, KEY_KPMINUS },
+ { KEY_P, KEY_KPASTERISK },
+ { KEY_MINUS, KEY_KPEQUAL },
+ { KEY_0, KEY_KPSLASH },
+ { KEY_F6, KEY_NUMLOCK },
+ { KEY_KPENTER, KEY_KPENTER },
+ { KEY_BACKSPACE, KEY_BACKSPACE },
+ { }
+};
+
+static int usbhid_pb_fkeyslast;
+module_param_named(pb_fkeyslast, usbhid_pb_fkeyslast, bool, 0644);
+MODULE_PARM_DESC(usbhid_pb_fkeyslast, "Use F keys only while pressing fn on PowerBooks");
+
+static int usbhid_pb_disablefnkeys;
+module_param_named(pb_disablefnkeys, usbhid_pb_disablefnkeys, bool, 0644);
+MODULE_PARM_DESC(usbhid_pb_disablefnkeys, "Disable fn special keys on PowerBooks");
+
+static int usbhid_pb_disablekeypad;
+module_param_named(pb_disablekeypad, usbhid_pb_disablekeypad, bool, 0644);
+MODULE_PARM_DESC(usbhid_pb_disablekeypad, "Disable keypad keys on PowerBooks");
+#endif
+
#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0)
#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
@@ -73,6 +138,85 @@ static struct {
#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)
+static inline struct hidinput_key_translation *find_translation(
+ struct hidinput_key_translation *table, u16 from)
+{
+ struct hidinput_key_translation *trans;
+
+ /* Look for the translation */
+ for(trans = table; trans->from && (trans->from != from); trans++);
+
+ return (trans->from?trans:NULL);
+}
+
+static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
+ struct hid_usage *usage, __s32 value)
+{
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+ struct hidinput_key_translation *trans;
+
+ if (usage->code == KEY_FN) {
+ if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON;
+ else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON;
+
+ input_event(input, usage->type, usage->code, value);
+
+ return 1;
+ }
+
+ if (!usbhid_pb_disablefnkeys) {
+ trans = find_translation(powerbook_fn_keys, usage->code);
+
+ if (trans) {
+ int do_translate;
+
+ if (test_bit(usage->code, hid->pb_fn))
+ do_translate = 1;
+ else if (trans->flags & POWERBOOK_FLAG_FKEY)
+ do_translate =
+ (!usbhid_pb_fkeyslast && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) ||
+ ( usbhid_pb_fkeyslast && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON));
+ else
+ do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON);
+
+ if (do_translate) {
+ if (value)
+ set_bit(usage->code, hid->pb_fn);
+ else
+ clear_bit(usage->code, hid->pb_fn);
+
+ input_event(input, usage->type, trans->to, value);
+
+ return 1;
+ }
+ }
+ }
+
+ if (!usbhid_pb_disablekeypad) {
+ int try_translate =
+ test_bit(usage->code, hid->pb_numlock)?1:
+ test_bit(LED_NUML, input->led);
+
+ if (try_translate) {
+ trans = find_translation(powerbook_numlock_keys, usage->code);
+
+ if (trans) {
+ if (value)
+ set_bit(usage->code, hid->pb_numlock);
+ else
+ clear_bit(usage->code, hid->pb_numlock);
+
+ input_event(input, usage->type, trans->to, value);
+ }
+
+ return 1;
+ }
+ }
+#endif
+
+ return 0;
+}
+
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
@@ -325,7 +469,27 @@ static void hidinput_configure_usage(str
set_bit(EV_REP, input->evbit);
switch(usage->hid & HID_USAGE) {
- case 0x003: map_key_clear(KEY_FN); break;
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+ /* The fn key on Apple PowerBooks */
+ case 0x0003: {
+ struct hidinput_key_translation *trans;
+
+ map_key_clear(KEY_FN);
+
+ set_bit(KEY_FN, input->keybit);
+ set_bit(KEY_NUMLOCK, input->keybit);
+
+ /* Enable all needed keys */
+ for(trans = powerbook_fn_keys; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+
+ for(trans = powerbook_numlock_keys; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+
+ goto ignore;
+ }
+#endif
+
default: goto ignore;
}
break;
@@ -482,6 +646,11 @@ void hidinput_hid_event(struct hid_devic
return;
}
+ if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) &&
+ hidinput_pb_event(hid, input, usage, value)) {
+ return;
+ }
+
if (usage->hat_min < usage->hat_max || usage->hat_dir) {
int hat_dir = usage->hat_dir;
if (!hat_dir)
diff -rNup linux-2.6.15-rc7.orig/drivers/usb/input/hid.h linux-2.6.15-rc7/drivers/usb/input/hid.h
--- linux-2.6.15-rc7.orig/drivers/usb/input/hid.h 2006-01-01 00:41:15.000000000 +0100
+++ linux-2.6.15-rc7/drivers/usb/input/hid.h 2006-01-03 00:45:13.000000000 +0100
@@ -246,6 +246,8 @@ struct hid_item {
#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400
+#define HID_QUIRK_POWERBOOK_HAS_FN 0x00000800
+#define HID_QUIRK_POWERBOOK_FN_ON 0x00001000
/*
* This is the global environment of the parser. This information is
@@ -431,6 +433,14 @@ struct hid_device { /* device repo
void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */
int (*ff_event)(struct hid_device *hid, struct input_dev *input,
unsigned int type, unsigned int code, int value);
+
+#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
+ /* We do this here because it's only relevant for the
+ * USB devices, not for all input_dev's.
+ */
+ unsigned long pb_fn[NBITS(KEY_MAX)];
+ unsigned long pb_numlock[NBITS(KEY_MAX)];
+#endif
};
#define HID_GLOBAL_STACK_SIZE 4
next prev parent reply other threads:[~2006-01-11 21:46 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-12-25 21:20 [PATCH/RFC?] usb/input: Add support for fn key on Apple PowerBooks Michael Hanselmann
2005-12-25 21:20 ` Michael Hanselmann
2005-12-25 21:57 ` Benjamin Herrenschmidt
2005-12-25 21:57 ` Benjamin Herrenschmidt
2005-12-26 4:04 ` Dmitry Torokhov
2005-12-26 4:04 ` Dmitry Torokhov
2005-12-26 5:46 ` Benjamin Herrenschmidt
2005-12-26 5:46 ` Benjamin Herrenschmidt
2006-01-11 21:07 ` Dmitry Torokhov
2006-01-11 21:07 ` Dmitry Torokhov
2006-01-11 21:20 ` Michael Hanselmann
2006-01-11 21:20 ` Michael Hanselmann
2006-01-11 21:34 ` Benjamin Herrenschmidt
2006-01-11 21:34 ` Benjamin Herrenschmidt
2006-01-11 21:38 ` Michael Hanselmann
2006-01-11 21:38 ` Michael Hanselmann
2006-01-11 21:41 ` Benjamin Herrenschmidt
2006-01-11 21:41 ` Benjamin Herrenschmidt
2006-01-11 21:43 ` Michael Hanselmann
2006-01-11 21:43 ` Michael Hanselmann
2006-01-11 21:47 ` Vojtech Pavlik
2006-01-11 21:47 ` Vojtech Pavlik
2006-01-11 21:50 ` Michael Hanselmann
2006-01-11 21:50 ` Michael Hanselmann
2006-01-11 21:54 ` Benjamin Herrenschmidt
2006-01-11 21:54 ` Benjamin Herrenschmidt
2006-01-11 21:30 ` Benjamin Herrenschmidt
2006-01-11 21:30 ` Benjamin Herrenschmidt
2006-01-11 21:45 ` Vojtech Pavlik
2006-01-11 21:45 ` Vojtech Pavlik
2006-01-11 21:46 ` Michael Hanselmann [this message]
2006-01-11 21:46 ` Michael Hanselmann
2006-01-11 23:26 ` Michael Hanselmann
2006-01-11 23:26 ` Michael Hanselmann
2006-01-11 23:41 ` Benjamin Herrenschmidt
2006-01-11 23:41 ` Benjamin Herrenschmidt
2006-01-12 0:08 ` Michael Hanselmann
2006-01-12 0:08 ` Michael Hanselmann
2006-01-13 4:12 ` Dmitry Torokhov
2006-01-13 4:12 ` Dmitry Torokhov
2006-01-13 6:53 ` Michael Hanselmann
2006-01-13 6:53 ` Michael Hanselmann
2006-01-13 7:47 ` Vojtech Pavlik
2006-01-13 7:47 ` Vojtech Pavlik
2006-01-13 22:02 ` Michael Hanselmann
2006-01-13 22:02 ` Michael Hanselmann
2006-01-14 4:58 ` Dmitry Torokhov
2006-01-14 4:58 ` Dmitry Torokhov
2006-01-14 10:41 ` Vojtech Pavlik
2006-01-14 10:41 ` Vojtech Pavlik
2006-01-14 10:57 ` Michael Hanselmann
2006-01-14 10:57 ` Michael Hanselmann
2006-01-13 21:55 ` Benjamin Herrenschmidt
2006-01-13 21:55 ` Benjamin Herrenschmidt
2006-01-13 21:57 ` Benjamin Herrenschmidt
2006-01-13 21:57 ` Benjamin Herrenschmidt
2006-01-13 22:05 ` Dmitry Torokhov
2006-01-13 22:05 ` Dmitry Torokhov
2006-01-13 22:08 ` Dmitry Torokhov
2006-01-13 22:08 ` Dmitry Torokhov
2006-01-13 22:14 ` Benjamin Herrenschmidt
2006-01-13 22:14 ` Benjamin Herrenschmidt
2006-01-13 22:25 ` Dmitry Torokhov
2006-01-13 22:25 ` Dmitry Torokhov
2006-01-12 9:07 ` Vojtech Pavlik
2006-01-12 9:07 ` Vojtech Pavlik
2006-01-12 23:39 ` Michael Hanselmann
2006-01-12 23:39 ` Michael Hanselmann
2006-01-13 1:53 ` Benjamin Herrenschmidt
2006-01-13 1:53 ` Benjamin Herrenschmidt
2005-12-31 23:51 ` Michael Hanselmann
2005-12-31 23:51 ` Michael Hanselmann
2006-01-01 1:33 ` Michael Hanselmann
2006-01-01 1:33 ` Michael Hanselmann
2006-01-01 2:56 ` Benjamin Herrenschmidt
2006-01-01 2:56 ` Benjamin Herrenschmidt
2006-01-01 3:03 ` Michael Hanselmann
2006-01-01 3:03 ` Michael Hanselmann
2006-01-01 6:09 ` Benjamin Herrenschmidt
2006-01-01 6:09 ` Benjamin Herrenschmidt
2006-01-02 22:46 ` Michael Hanselmann
2006-01-02 22:46 ` Michael Hanselmann
2006-01-03 2:29 ` Ben Collins
2006-01-03 2:29 ` Ben Collins
2006-01-03 19:14 ` Michael Hanselmann
2006-01-03 19:14 ` Michael Hanselmann
2006-01-03 19:18 ` Ben Collins
2006-01-03 19:18 ` Ben Collins
2006-01-03 19:25 ` Michael Hanselmann
2006-01-03 19:25 ` Michael Hanselmann
2006-01-02 12:06 ` Stelian Pop
2006-01-02 12:06 ` Stelian Pop
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060111214607.GG6617@hansmi.ch \
--to=linux-kernel@hansmi.ch \
--cc=benh@kernel.crashing.org \
--cc=dtor_core@ameritech.net \
--cc=linux-input@atrey.karlin.mff.cuni.cz \
--cc=linux-kernel@killerfox.forkbomb.ch \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@ozlabs.org \
--cc=vojtech@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.