aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2009-11-13 04:45:53 -0500
committerJiri Kosina <jkosina@suse.cz>2009-11-13 04:45:53 -0500
commit24985cf68612a5617d396b0b188cec807641cde1 (patch)
treeac0fcd5288312e8ecdad289258c07ae8ea8dca1c
parent5b915d9e6dc3d22fedde91dfef1cb1a8fa9a1870 (diff)
HID: support Logitech/3DConnexion SpaceTraveler and SpaceNavigator
These devices wrongly report their axes as relative instead of absolute. Fix this in up report descriptor of the device before it enters the parser. Reported-by: simon.windows@gmail.com Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/hid-lg.c13
3 files changed, 17 insertions, 0 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 6d5c84573b3a..30d85a1b414c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1324,6 +1324,8 @@ static const struct hid_device_id hid_blacklist[] = {
1324 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, 1324 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
1325 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, 1325 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
1326 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1326 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
1327 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
1328 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
1327 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, 1329 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
1328 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, 1330 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
1329 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, 1331 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 1d99c81ad171..2fd2aae332bc 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -305,6 +305,8 @@
305#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 305#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
306#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 306#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
307#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 307#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
308#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
309#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626
308#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 310#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
309#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 311#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
310#define USB_DEVICE_ID_DINOVO_MINI 0xc71f 312#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 0f870a3243ed..8e28f1dc40a6 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -33,6 +33,7 @@
33#define LG_NOGET 0x100 33#define LG_NOGET 0x100
34#define LG_FF 0x200 34#define LG_FF 0x200
35#define LG_FF2 0x400 35#define LG_FF2 0x400
36#define LG_RDESC_REL_ABS 0x800
36 37
37/* 38/*
38 * Certain Logitech keyboards send in report #3 keys which are far 39 * Certain Logitech keyboards send in report #3 keys which are far
@@ -51,6 +52,13 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
51 rdesc[84] = rdesc[89] = 0x4d; 52 rdesc[84] = rdesc[89] = 0x4d;
52 rdesc[85] = rdesc[90] = 0x10; 53 rdesc[85] = rdesc[90] = 0x10;
53 } 54 }
55 if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 &&
56 rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
57 rdesc[49] == 0x81 && rdesc[50] == 0x06) {
58 dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
59 "report descriptor\n");
60 rdesc[33] = rdesc[50] = 0x02;
61 }
54} 62}
55 63
56#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 64#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
@@ -303,8 +311,13 @@ static const struct hid_device_id lg_devices[] = {
303 .driver_data = LG_FF }, 311 .driver_data = LG_FF },
304 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), 312 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
305 .driver_data = LG_FF2 }, 313 .driver_data = LG_FF2 },
314 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
315 .driver_data = LG_RDESC_REL_ABS },
316 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
317 .driver_data = LG_RDESC_REL_ABS },
306 { } 318 { }
307}; 319};
320
308MODULE_DEVICE_TABLE(hid, lg_devices); 321MODULE_DEVICE_TABLE(hid, lg_devices);
309 322
310static struct hid_driver lg_driver = { 323static struct hid_driver lg_driver = {