diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hiddev.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hiddev.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hiddev.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hiddev.c 2007-04-15
21:29:44.000000000 +0800
@@ -36,6 +36,11 @@
#include <linux/hiddev.h>
#include "usbhid.h"
+#define DRIVER_VERSION "v0.9.0"
+#define DRIVER_AUTHOR "Paul Stewart, Vojtech Pavlik"
+#define DRIVER_DESC "USB HIDDEV driver"
+#define DRIVER_LICENSE "GPL"
+
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define HIDDEV_MINOR_BASE 0
#define HIDDEV_MINORS 256
@@ -48,9 +53,11 @@
struct hiddev {
int exist;
int open;
+ int minor;
wait_queue_head_t wait;
struct hid_device *hid;
struct list_head list;
+ void *private;
};
struct hiddev_list {
@@ -159,7 +166,7 @@ hiddev_lookup_usage(struct hid_device *h
static void hiddev_send_event(struct hid_device *hid,
struct hiddev_usage_ref *uref)
{
- struct hiddev *hiddev = hid->hiddev;
+ struct hiddev *hiddev = hid->private;
struct hiddev_list *list;
list_for_each_entry(list, &hiddev->list, node) {
@@ -179,9 +186,10 @@ static void hiddev_send_event(struct hid
* This is where hid.c calls into hiddev to pass an event that occurred over
* the interrupt pipe
*/
-void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
+static int hiddev_hid_event(struct hid_field *field, struct hid_usage *usage,
+ __s32 value, int
interrupt)
{
+ struct hid_device *hid = field->report->device;
unsigned type = field->report_type;
struct hiddev_usage_ref uref;
@@ -196,6 +204,8 @@ void hiddev_hid_event(struct hid_device
uref.value = value;
hiddev_send_event(hid, &uref);
+ /* We always let HID core continue to dispatch this event here. */
+ return 1;
}
EXPORT_SYMBOL_GPL(hiddev_hid_event);
@@ -393,7 +403,7 @@ static int hiddev_ioctl(struct inode *in
struct hiddev_devinfo dinfo;
struct hid_report *report;
struct hid_field *field;
- struct usbhid_device *usbhid = hid->driver_data;
+ struct usbhid_device *usbhid = hid->tl_data;
void __user *user_arg = (void __user *)arg;
int i;
@@ -742,15 +752,15 @@ static struct usb_class_driver hiddev_cl
.minor_base = HIDDEV_MINOR_BASE,
};
-/*
- * This is where hid.c calls us to connect a hid device to the hiddev driver
- */
-int hiddev_connect(struct hid_device *hid)
+static int hiddev_connect(struct hid_device *hid)
{
struct hiddev *hiddev;
- struct usbhid_device *usbhid = hid->driver_data;
+ struct usbhid_device *usbhid = hid->tl_data;
int i;
int retval;
+
+ if (hid->bus != BUS_USB)
+ return -1;
for (i = 0; i < hid->maxcollection; i++)
if (hid->collection[i].type ==
@@ -776,8 +786,8 @@ int hiddev_connect(struct hid_device *hi
hiddev->hid = hid;
hiddev->exist = 1;
- hid->minor = usbhid->intf->minor;
- hid->hiddev = hiddev;
+ hiddev->minor = usbhid->intf->minor;
+ hid->private = hiddev;
hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
@@ -788,15 +798,17 @@ int hiddev_connect(struct hid_device *hi
* This is where hid.c calls us to disconnect a hiddev device from the
* corresponding hid device (usually because the usb device has disconnected)
*/
-static struct usb_class_driver hiddev_class;
-void hiddev_disconnect(struct hid_device *hid)
+static void hiddev_disconnect(struct hid_device *hid)
{
- struct hiddev *hiddev = hid->hiddev;
- struct usbhid_device *usbhid = hid->driver_data;
+ struct hiddev *hiddev = hid->private;
+ struct usbhid_device *usbhid = hid->tl_data;
+
+ if (hid->bus != BUS_USB)
+ return;
hiddev->exist = 0;
- hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
+ hiddev_table[hiddev->minor - HIDDEV_MINOR_BASE] = NULL;
usb_deregister_dev(usbhid->intf, &hiddev_class);
if (hiddev->open) {
@@ -807,41 +819,34 @@ void hiddev_disconnect(struct hid_device
}
}
-/* Currently this driver is a USB driver. It's not a conventional one in
- * the sense that it doesn't probe at the USB level. Instead it waits to
- * be connected by HID through the hiddev_connect / hiddev_disconnect
- * routines. The reason to register as a USB device is to gain part of the
- * minor number space from the USB major.
- *
- * In theory, should the HID code be generalized to more than one physical
- * medium (say, IEEE 1384), this driver will probably need to register its
- * own major number, and in doing so, no longer need to register with USB.
- * At that point the probe routine and hiddev_driver struct below will no
- * longer be useful.
- */
-
-
-/* We never attach in this manner, and rely on HID to connect us. This
- * is why there is no disconnect routine defined in the usb_driver either.
- */
-static int hiddev_usbd_probe(struct usb_interface *intf,
- const struct usb_device_id *hiddev_info)
-{
- return -ENODEV;
-}
-
+static struct hid_hook hiddev_hook = {
+ .hid_event = hiddev_hid_event,
+};
-static /* const */ struct usb_driver hiddev_driver = {
- .name = "hiddev",
- .probe = hiddev_usbd_probe,
+static struct hid_driver hid_hiddev_driver = {
+ .name = "hiddev",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .probe = hiddev_connect,
+ .remove = hiddev_disconnect,
+ .hook = &hiddev_hook,
};
int __init hiddev_init(void)
{
- return usb_register(&hiddev_driver);
+ set_hid_driver_sticky(&hid_hiddev_driver);
+ return hid_register_driver(&hid_hiddev_driver);
}
-void hiddev_exit(void)
+void __exit hiddev_exit(void)
{
- usb_deregister(&hiddev_driver);
+ hid_unregister_driver(&hid_hiddev_driver);
}
+
+module_init(hiddev_init);
+module_exit(hiddev_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-ff.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-ff.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-ff.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-ff.c 1970-01-01
08:00:00.000000000 +0800
@@ -1,90 +0,0 @@
-/*
- * $Id: hid-ff.c,v 1.2 2002/04/18 22:02:47 jdeneux Exp $
- *
- * Force feedback support for hid devices.
- * Not all hid devices use the same protocol. For example, some use PID,
- * other use their own proprietary procotol.
- *
- * Copyright (c) 2002-2004 Johann Deneux
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <[EMAIL PROTECTED]>
- */
-
-#include <linux/input.h>
-
-#undef DEBUG
-#include <linux/usb.h>
-
-#include <linux/hid.h>
-#include "usbhid.h"
-
-/*
- * This table contains pointers to initializers. To add support for new
- * devices, you need to add the USB vendor and product ids here.
- */
-struct hid_ff_initializer {
- u16 idVendor;
- u16 idProduct;
- int (*init)(struct hid_device*);
-};
-
-/*
- * We try pidff when no other driver is found because PID is the
- * standards compliant way of implementing force feedback in HID.
- * pidff_init() will quickly abort if the device doesn't appear to
- * be a PID device
- */
-static struct hid_ff_initializer inits[] = {
-#ifdef CONFIG_LOGITECH_FF
- { 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
- { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
- { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
- { 0x46d, 0xc294, hid_lgff_init }, /* Logitech Formula Force EX */
- { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
- { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
-#endif
-#ifdef CONFIG_PANTHERLORD_FF
- { 0x810, 0x0001, hid_plff_init },
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF
- { 0x44f, 0xb300, hid_tmff_init },
- { 0x44f, 0xb304, hid_tmff_init },
-#endif
-#ifdef CONFIG_ZEROPLUS_FF
- { 0xc12, 0x0005, hid_zpff_init },
- { 0xc12, 0x0030, hid_zpff_init },
-#endif
- { 0, 0, hid_pidff_init} /* Matches anything */
-};
-
-int hid_ff_init(struct hid_device* hid)
-{
- struct hid_ff_initializer *init;
- int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor);
- int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct);
-
- for (init = inits; init->idVendor; init++)
- if (init->idVendor == vendor && init->idProduct == product)
- break;
-
- return init->init(hid);
-}
-EXPORT_SYMBOL_GPL(hid_ff_init);
-
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-lgff.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-lgff.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-lgff.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-lgff.c 2007-04-15
21:29:54.000000000 +0800
@@ -29,9 +29,10 @@
#include <linux/input.h>
#include <linux/usb.h>
-#include <linux/hid.h>
#include "usbhid.h"
+#define DRIVER_VERSION "0.1.0"
+
struct dev_type {
u16 idVendor;
u16 idProduct;
@@ -99,7 +100,7 @@ static int hid_lgff_play(struct input_de
return 0;
}
-int hid_lgff_init(struct hid_device* hid)
+static int hid_lgff_init_device(struct hid_device* hid)
{
struct hid_input *hidinput = list_entry(hid->inputs.next, struct
hid_input, list);
struct list_head *report_list =
&hid->report_enum[HID_OUTPUT_REPORT].report_list;
@@ -148,3 +149,53 @@ int hid_lgff_init(struct hid_device* hid
return 0;
}
+
+static struct usb_device_id hid_lgff_ids[] = {
+ { USB_DEVICE(0x46d, 0xc211) }, /* Logitech Cordless rumble pad */
+ { USB_DEVICE(0x46d, 0xc219) }, /* Logitech Cordless rumble pad 2 */
+ { USB_DEVICE(0x46d, 0xc283) }, /* Logitech Wingman Force 3d */
+ { USB_DEVICE(0x46d, 0xc294) }, /* Logitech Formula Force EX */
+ { USB_DEVICE(0x46d, 0xc295) }, /* Logitech MOMO force wheel */
+ { USB_DEVICE(0x46d, 0xca03) }, /* Logitech MOMO force wheel */
+ {}
+};
+
+MODULE_DEVICE_TABLE (usb, hid_lgff_ids);
+
+static int hid_lgff_match(struct hid_driver *driver, struct hid_device *device)
+{
+ struct usbhid_device *usbhid;
+
+ usbhid = device->tl_data;
+ return (int)usb_match_id(usbhid->intf, hid_lgff_ids);
+}
+
+static int hid_lgff_probe(struct hid_device *device)
+{
+ if (hidinput_connect(device))
+ return -ENODEV;
+ return hid_lgff_init_device(device);
+}
+
+static struct hid_driver hid_lgff_driver = {
+ .name = "hid-lgff",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .match = hid_lgff_match,
+ .probe = hid_lgff_probe,
+};
+
+static int __init hid_lgff_init(void)
+{
+ return hid_register_driver(&hid_lgff_driver);
+}
+
+static void __exit hid_lgff_exit(void)
+{
+ hid_unregister_driver(&hid_lgff_driver);
+}
+
+module_init(hid_lgff_init);
+module_exit(hid_lgff_exit);
+MODULE_LICENSE("GPL");
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-pb.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-pb.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-pb.c 1970-01-01
08:00:00.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-pb.c 2007-04-15
21:30:02.000000000 +0800
@@ -0,0 +1,334 @@
+/*
+ * $Id: hid-input.c,v 1.2 2002/04/23 00:59:25 rdamazio Exp $
+ *
+ * Copyright (c) 2000-2001 Vojtech Pavlik
+ * Copyright (c) 2006-2007 Jiri Kosina
+ *
+ * iBook/PowerBook special keys support.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Should you need to contact me, the author, you can do so either by
+ * e-mail - mail your message to <[EMAIL PROTECTED]>, or by paper mail:
+ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+
+#include "usbhid.h"
+
+#define DRIVER_VERSION "0.1.0"
+
+static int hid_pb_fnmode = 1;
+module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644);
+MODULE_PARM_DESC(pb_fnmode,
+ "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 =
fkeysfirst)");
+
+#define USB_VENDOR_ID_APPLE 0x05ac
+#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
+#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
+#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
+#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
+#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
+#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
+#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
+#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
+#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
+#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
+#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
+#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
+#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
+#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
+#define USB_DEVICE_ID_APPLE_IR 0x8240
+
+#define USB_VENDOR_ID_CHERRY 0x046a
+#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
+
+struct hids_pb_data {
+ unsigned long pressed_fn[NBITS(KEY_MAX)];
+ unsigned long pressed_numlock[NBITS(KEY_MAX)];
+};
+
+static const struct pb_feature {
+ __u16 idProduct;
+ unsigned quirks;
+} pb_feature_list[] = {
+ { USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_IGNORE_MOUSE |
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+ { USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_IGNORE_MOUSE |
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+ { USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_IGNORE_MOUSE |
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+ { USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_IGNORE_MOUSE },
+ { USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_IGNORE_MOUSE },
+ { 0, 0 }
+};
+
+struct hidinput_key_translation {
+ u16 from;
+ u16 to;
+ u8 flags;
+};
+
+#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 struct hidinput_key_translation powerbook_iso_keyboard[] = {
+ { KEY_GRAVE, KEY_102ND },
+ { KEY_102ND, KEY_GRAVE },
+ { }
+};
+
+static 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++)
+ if (trans->from == from)
+ return trans;
+
+ return NULL;
+}
+
+static int hids_pb_hid_event(struct hid_field *field, struct hid_usage *usage,
+ __s32 value, int
interrupt)
+{
+ struct hidinput_key_translation *trans;
+ struct hid_input *hidinput = field->hidinput;
+ struct hid_device *hid = field->report->device;
+ struct hids_pb_data *pb_data = hid->driver->private;
+
+ if (!pb_data)
+ return -1;
+
+ if (usage->code == KEY_FN) {
+ if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON;
+ else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON;
+
+ input_event(hidinput->input, usage->type, usage->code, value);
+ return 0;
+ }
+
+ if (hid_pb_fnmode) {
+ int do_translate;
+
+ trans = find_translation(powerbook_fn_keys, usage->code);
+ if (trans) {
+ if (test_bit(usage->code, pb_data->pressed_fn))
+ do_translate = 1;
+ else if (trans->flags & POWERBOOK_FLAG_FKEY)
+ do_translate =
+ (hid_pb_fnmode == 2 && (hid->quirks &
HID_QUIRK_POWERBOOK_FN_ON)) ||
+ (hid_pb_fnmode == 1 && !(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,
pb_data->pressed_fn);
+ else
+ clear_bit(usage->code,
pb_data->pressed_fn);
+
+ input_event(hidinput->input, usage->type,
+ trans->to,
value);
+
+ return 0;
+ }
+ }
+
+ if (test_bit(usage->code, pb_data->pressed_numlock) ||
+ test_bit(LED_NUML, hidinput->input->led)) {
+ trans = find_translation(powerbook_numlock_keys,
usage->code);
+
+ if (trans) {
+ if (value)
+ set_bit(usage->code,
pb_data->pressed_numlock);
+ else
+ clear_bit(usage->code,
pb_data->pressed_numlock);
+
+ input_event(hidinput->input, usage->type,
trans->to, value);
+ }
+ return 0;
+ }
+ }
+
+ if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+ trans = find_translation(powerbook_iso_keyboard, usage->code);
+ if (trans) {
+ input_event(hidinput->input, usage->type, trans->to,
value);
+ return 0;
+ }
+ }
+
+ hidinput_hid_event(hid, field, usage, value);
+ return 0;
+}
+
+static void hidinput_pb_setup(struct input_dev *input)
+{
+ struct hidinput_key_translation *trans;
+
+ 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);
+
+ for (trans = powerbook_iso_keyboard; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+}
+
+static struct usb_device_id hids_pb_ids[] = {
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY)
},
+ { USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY)
},
+ {}
+};
+MODULE_DEVICE_TABLE (usb, hids_pb_ids);
+
+static int hid_pb_match(struct hid_driver *driver, struct hid_device *device)
+{
+ struct usbhid_device *usbhid;
+
+ if (!driver || !device)
+ return 0;
+ usbhid = device->tl_data;
+ return !!usb_match_id(usbhid->intf, hids_pb_ids);
+}
+
+static int hid_pb_probe(struct hid_device *dev)
+{
+ int i;
+ struct hid_driver *drv = dev->driver;
+
+ for (i=0; pb_feature_list[i].quirks; ++i) {
+ if (pb_feature_list[i].idProduct == dev->product)
+ dev->quirks = pb_feature_list[i].quirks;
+ }
+ drv->private = kzalloc(sizeof(struct hids_pb_data), GFP_KERNEL);
+ if (!drv->private)
+ return 0;
+ return hidinput_connect(dev);
+}
+
+static void hids_pb_setup_usage(struct hid_field *field, struct hid_usage
*usage)
+{
+ unsigned long *bit;
+ struct input_dev* input = field->hidinput->input;
+
+ if (0x003 != (usage->hid & HID_USAGE))
+ return;
+ usage->code = KEY_FN;
+ usage->type = EV_KEY;
+ bit = input->keybit;
+ clear_bit(KEY_FN, input->keybit);
+ hidinput_pb_setup(input);
+}
+
+static struct hid_hook hid_pb_hook = {
+ .hid_event = hids_pb_hid_event,
+ .setup_usage = hids_pb_setup_usage,
+};
+
+static struct hid_driver hids_pb_driver = {
+ .name = "hid-pb",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .match = hid_pb_match,
+ .probe = hid_pb_probe,
+ .hook = &hid_pb_hook,
+};
+
+static int __init hids_pb_init(void)
+{
+ return hid_register_driver(&hids_pb_driver);
+}
+
+static void __exit hids_pb_exit(void)
+{
+ hid_unregister_driver(&hids_pb_driver);
+}
+
+module_init(hids_pb_init);
+module_exit(hids_pb_exit);
+MODULE_LICENSE("GPL");
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-pidff.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-pidff.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-pidff.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-pidff.c 2007-04-15
21:30:14.000000000 +0800
@@ -27,10 +27,10 @@
#include <linux/input.h>
#include <linux/usb.h>
-#include <linux/hid.h>
-
#include "usbhid.h"
+#define DRIVER_VERSION "0.1.0"
+
#define PID_EFFECTS_MAX 64
/* Report usage table used to put reports into an array */
@@ -1236,7 +1236,7 @@ static int pidff_check_autocenter(struct
/*
* Check if the device is PID and initialize it
*/
-int hid_pidff_init(struct hid_device *hid)
+int hid_pidff_init_device(struct hid_device *hid)
{
struct pidff_device *pidff;
struct hid_input *hidinput = list_entry(hid->inputs.next,
@@ -1329,3 +1329,33 @@ int hid_pidff_init(struct hid_device *hi
kfree(pidff);
return error;
}
+
+static int hid_pidff_probe(struct hid_device *device)
+{
+ if (hidinput_connect(device))
+ return -ENODEV;
+ return hid_pidff_init_device(device);
+}
+
+static struct hid_driver hid_pidff_driver = {
+ .name = "hid-pidff",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .probe = hid_pidff_probe,
+};
+
+static int __init hid_pidff_init(void)
+{
+ set_hid_driver_sticky(&hid_pidff_driver);
+ return hid_register_driver(&hid_pidff_driver);
+}
+
+static void __exit hid_pidff_exit(void)
+{
+ hid_unregister_driver(&hid_pidff_driver);
+}
+
+module_init(hid_pidff_init);
+module_exit(hid_pidff_exit);
+MODULE_LICENSE("GPL");
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-plff.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-plff.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-plff.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-plff.c 2007-04-15
21:30:26.000000000 +0800
@@ -27,9 +27,10 @@
#include <linux/input.h>
#include <linux/usb.h>
-#include <linux/hid.h>
#include "usbhid.h"
+#define DRIVER_VERSION "0.1.0"
+
struct plff_device {
struct hid_report *report;
};
@@ -56,7 +57,7 @@ static int hid_plff_play(struct input_de
return 0;
}
-int hid_plff_init(struct hid_device *hid)
+int hid_plff_init_device(struct hid_device *hid)
{
struct plff_device *plff;
struct hid_report *report;
@@ -127,3 +128,48 @@ int hid_plff_init(struct hid_device *hid
return 0;
}
+
+static struct usb_device_id hid_plff_ids[] = {
+ { USB_DEVICE(0x810, 0x0001) },
+ {}
+};
+
+MODULE_DEVICE_TABLE (usb, hid_plff_ids);
+
+static int hid_plff_match(struct hid_driver *driver, struct hid_device *device)
+{
+ struct usbhid_device *usbhid;
+
+ usbhid = device->tl_data;
+ return (int)usb_match_id(usbhid->intf, hid_plff_ids);
+}
+
+static int hid_plff_probe(struct hid_device *device)
+{
+ if (hidinput_connect(device))
+ return -ENODEV;
+ return hid_plff_init_device(device);
+}
+
+static struct hid_driver hid_plff_driver = {
+ .name = "hid-plff",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .match = hid_plff_match,
+ .probe = hid_plff_probe,
+};
+
+static int __init hid_plff_init(void)
+{
+ return hid_register_driver(&hid_plff_driver);
+}
+
+static void __exit hid_plff_exit(void)
+{
+ hid_unregister_driver(&hid_plff_driver);
+}
+
+module_init(hid_plff_init);
+module_exit(hid_plff_exit);
+MODULE_LICENSE("GPL");
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-tmff.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-tmff.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-tmff.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-tmff.c 2007-04-15
21:30:35.000000000 +0800
@@ -32,9 +32,10 @@
#undef DEBUG
#include <linux/usb.h>
-#include <linux/hid.h>
#include "usbhid.h"
+#define DRIVER_VERSION "0.1.0"
+
/* Usages for thrustmaster devices I know about */
#define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb)
@@ -76,7 +77,7 @@ static int hid_tmff_play(struct input_de
return 0;
}
-int hid_tmff_init(struct hid_device *hid)
+int hid_tmff_init_device(struct hid_device *hid)
{
struct tmff_device *tmff;
struct list_head *pos;
@@ -145,3 +146,48 @@ int hid_tmff_init(struct hid_device *hid
return 0;
}
+
+static struct usb_device_id hid_tmff_ids[] = {
+ { USB_DEVICE(0x44f, 0xb304) },
+ {}
+};
+
+MODULE_DEVICE_TABLE (usb, hid_tmff_ids);
+
+static int hid_tmff_match(struct hid_driver *driver, struct hid_device *device)
+{
+ struct usbhid_device *usbhid;
+
+ usbhid = device->tl_data;
+ return (int)usb_match_id(usbhid->intf, hid_tmff_ids);
+}
+
+static int hid_tmff_probe(struct hid_device *device)
+{
+ if (hidinput_connect(device))
+ return -ENODEV;
+ return hid_tmff_init_device(device);
+}
+
+static struct hid_driver hid_tmff_driver = {
+ .name = "hid-tmff",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .match = hid_tmff_match,
+ .probe = hid_tmff_probe,
+};
+
+static int __init hid_tmff_init(void)
+{
+ return hid_register_driver(&hid_tmff_driver);
+}
+
+static void __exit hid_tmff_exit(void)
+{
+ hid_unregister_driver(&hid_tmff_driver);
+}
+
+module_init(hid_tmff_init);
+module_exit(hid_tmff_exit);
+MODULE_LICENSE("GPL");
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-zpff.c
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-zpff.c
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/hid-zpff.c 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/hid-zpff.c 2007-04-15
21:30:44.000000000 +0800
@@ -27,9 +27,10 @@
#include <linux/input.h>
#include <linux/usb.h>
-#include <linux/hid.h>
#include "usbhid.h"
+#define DRIVER_VERSION "0.1.0"
+
struct zpff_device {
struct hid_report *report;
};
@@ -62,7 +63,7 @@ static int hid_zpff_play(struct input_de
return 0;
}
-int hid_zpff_init(struct hid_device *hid)
+int hid_zpff_init_device(struct hid_device *hid)
{
struct zpff_device *zpff;
struct hid_report *report;
@@ -109,3 +110,50 @@ int hid_zpff_init(struct hid_device *hid
return 0;
}
+
+static struct usb_device_id hid_zpff_ids[] = {
+ { USB_DEVICE(0x46d, 0x0005) },
+ { USB_DEVICE(0xc12, 0x0030) },
+ {}
+};
+
+MODULE_DEVICE_TABLE (usb, hid_zpff_ids);
+
+static int hid_zpff_match(struct hid_driver *driver, struct hid_device *device)
+{
+ struct usbhid_device *usbhid;
+
+ usbhid = device->tl_data;
+ return (int)usb_match_id(usbhid->intf, hid_zpff_ids);
+}
+
+static int hid_zpff_probe(struct hid_device *device)
+{
+ if (hidinput_connect(device))
+ return -ENODEV;
+ return hid_zpff_init_device(device);
+}
+
+
+static struct hid_driver hid_zpff_driver = {
+ .name = "hid-zpff",
+ .version = DRIVER_VERSION,
+ .bus = BUS_USB,
+ .module = THIS_MODULE,
+ .match = hid_zpff_match,
+ .probe = hid_zpff_probe,
+};
+
+static int __init hid_zpff_init(void)
+{
+ return hid_register_driver(&hid_zpff_driver);
+}
+
+static void __exit hid_zpff_exit(void)
+{
+ hid_unregister_driver(&hid_zpff_driver);
+}
+
+module_init(hid_zpff_init);
+module_exit(hid_zpff_exit);
+MODULE_LICENSE("GPL");
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/Kconfig
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/Kconfig
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/Kconfig 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/Kconfig 2007-04-10
10:24:51.000000000 +0800
@@ -24,8 +24,8 @@ config USB_HID
comment "Input core support is needed for USB HID input layer or HIDBP support"
depends on USB_HID && INPUT=n
-config USB_HIDINPUT_POWERBOOK
- bool "Enable support for iBook/PowerBook special keys"
+config POWERBOOK
+ tristate "Enable support for iBook/PowerBook special keys"
default n
depends on USB_HID
help
@@ -34,29 +34,17 @@ config USB_HIDINPUT_POWERBOOK
If unsure, say N.
-config HID_FF
- bool "Force feedback support (EXPERIMENTAL)"
- depends on USB_HID && EXPERIMENTAL
- help
- Say Y here is you want force feedback support for a few HID devices.
- See below for a list of supported devices.
-
- See <file:Documentation/input/ff.txt> for a description of the force
- feedback API.
-
- If unsure, say N.
-
config HID_PID
- bool "PID device support"
- depends on HID_FF
+ tristate "PID device support"
+ depends on USB_HID
help
Say Y here if you have a PID-compliant device and wish to enable force
feedback for it. Microsoft Sidewinder Force Feedback 2 is one of such
devices.
config LOGITECH_FF
- bool "Logitech devices support"
- depends on HID_FF
+ tristate "Logitech devices support"
+ depends on USB_HID
select INPUT_FF_MEMLESS if USB_HID
help
Say Y here if you have one of these devices:
@@ -71,16 +59,16 @@ config LOGITECH_FF
force feedback.
config PANTHERLORD_FF
- bool "PantherLord USB/PS2 2in1 Adapter support"
- depends on HID_FF
+ tristate "PantherLord USB/PS2 2in1 Adapter support"
+ depends on USB_HID
select INPUT_FF_MEMLESS if USB_HID
help
Say Y here if you have a PantherLord USB/PS2 2in1 Adapter and want
to enable force feedback support for it.
config THRUSTMASTER_FF
- bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
- depends on HID_FF && EXPERIMENTAL
+ tristate "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
+ depends on USB_HID && EXPERIMENTAL
select INPUT_FF_MEMLESS if USB_HID
help
Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
@@ -89,15 +77,15 @@ config THRUSTMASTER_FF
force feedback.
config ZEROPLUS_FF
- bool "Zeroplus based game controller support"
- depends on HID_FF
+ tristate "Zeroplus based game controller support"
+ depends on USB_HID
select INPUT_FF_MEMLESS if USB_HID
help
Say Y here if you have a Zeroplus based game controller and want to
enable force feedback for it.
config USB_HIDDEV
- bool "/dev/hiddev raw HID device support"
+ tristate "/dev/hiddev raw HID device support"
depends on USB_HID
help
Say Y here if you want to support HID devices (from the USB
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/Makefile
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/Makefile
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/Makefile 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/Makefile 2007-04-17
09:23:33.000000000 +0800
@@ -6,29 +6,13 @@
usbhid-objs := hid-core.o
# Optional parts of multipart objects.
-
-ifeq ($(CONFIG_USB_HIDDEV),y)
- usbhid-objs += hiddev.o
-endif
-ifeq ($(CONFIG_HID_PID),y)
- usbhid-objs += hid-pidff.o
-endif
-ifeq ($(CONFIG_LOGITECH_FF),y)
- usbhid-objs += hid-lgff.o
-endif
-ifeq ($(CONFIG_PANTHERLORD_FF),y)
- usbhid-objs += hid-plff.o
-endif
-ifeq ($(CONFIG_THRUSTMASTER_FF),y)
- usbhid-objs += hid-tmff.o
-endif
-ifeq ($(CONFIG_ZEROPLUS_FF),y)
- usbhid-objs += hid-zpff.o
-endif
-ifeq ($(CONFIG_HID_FF),y)
- usbhid-objs += hid-ff.o
-endif
-
+obj-$(CONFIG_HID_PID) += hid-pidff.o
+obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o
+obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o
+obj-$(CONFIG_POWERBOOK) += hid-pb.o
+obj-$(CONFIG_LOGITECH_FF) += hid-lgff.o
+obj-$(CONFIG_PANTHERLORD_FF) += hid-plff.o
+obj-$(CONFIG_USB_HIDDEV) += hiddev.o
obj-$(CONFIG_USB_HID) += usbhid.o
obj-$(CONFIG_USB_KBD) += usbkbd.o
obj-$(CONFIG_USB_MOUSE) += usbmouse.o
diff -Naurp linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/usbhid.h
linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/usbhid.h
--- linux-2.6.21-rc6-mm1.orig/drivers/hid/usbhid/usbhid.h 2007-04-10
09:16:46.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/drivers/hid/usbhid/usbhid.h 2007-04-10
10:24:51.000000000 +0800
@@ -30,6 +30,9 @@
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/input.h>
+#include <linux/wait.h>
+#include <linux/hid.h>
+#include <linux/hid-debug.h>
/* API provided by hid-core.c for USB HID drivers */
int usbhid_wait_io(struct hid_device* hid);
@@ -77,6 +80,7 @@ struct usbhid_device {
unsigned long stop_retry; /* Time
to give up, in jiffies */
unsigned int retry_delay; /*
Delay length in ms */
struct work_struct reset_work; /* Task
context for resets */
+ wait_queue_head_t wait;
};
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel