diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-16 22:04:48 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-16 22:04:48 +0100 |
commit | 78f902ccc597d6ce3e8d1477d70f2d79e960ba7a (patch) | |
tree | c6ceab663de16501d1dda1c1596fe2dacaaef8e3 /drivers/hid/hid-sony.c | |
parent | 9ee670fd87b7d69c8633b94c42aadcbbcb96f28e (diff) | |
parent | 8b1fae4e4200388b64dd88065639413cb3f1051c (diff) |
Merge commit 'v2.6.28-rc8' into x86/doc
Diffstat (limited to 'drivers/hid/hid-sony.c')
-rw-r--r-- | drivers/hid/hid-sony.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 3af8095a7de..86e563b8d64 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -4,9 +4,9 @@ * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc - * Copyright (c) 2006-2007 Jiri Kosina * Copyright (c) 2007 Paul Walmsley * Copyright (c) 2008 Jiri Slaby + * Copyright (c) 2006-2008 Jiri Kosina */ /* @@ -23,6 +23,26 @@ #include "hid-ids.h" +#define VAIO_RDESC_CONSTANT 0x0001 + +struct sony_sc { + unsigned long quirks; +}; + +/* Sony Vaio VGX has wrongly mouse pointer declared as constant */ +static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int rsize) +{ + struct sony_sc *sc = hid_get_drvdata(hdev); + + if ((sc->quirks & VAIO_RDESC_CONSTANT) && + rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { + dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " + "descriptor\n"); + rdesc[55] = 0x06; + } +} + /* * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller * to "operational". Without this, the ps3 controller will not report any @@ -56,6 +76,17 @@ static int sony_set_operational(struct hid_device *hdev) static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; + unsigned long quirks = id->driver_data; + struct sony_sc *sc; + + sc = kzalloc(sizeof(*sc), GFP_KERNEL); + if (sc == NULL) { + dev_err(&hdev->dev, "can't alloc apple descriptor\n"); + return -ENOMEM; + } + + sc->quirks = quirks; + hid_set_drvdata(hdev, sc); ret = hid_parse(hdev); if (ret) { @@ -78,11 +109,20 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) err_stop: hid_hw_stop(hdev); err_free: + kfree(sc); return ret; } +static void sony_remove(struct hid_device *hdev) +{ + hid_hw_stop(hdev); + kfree(hid_get_drvdata(hdev)); +} + static const struct hid_device_id sony_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), + .driver_data = VAIO_RDESC_CONSTANT }, { } }; MODULE_DEVICE_TABLE(hid, sony_devices); @@ -91,6 +131,8 @@ static struct hid_driver sony_driver = { .name = "sony", .id_table = sony_devices, .probe = sony_probe, + .remove = sony_remove, + .report_fixup = sony_report_fixup, }; static int sony_init(void) |