aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-sony.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2008-10-23 06:58:38 -0400
committerJiri Kosina <jkosina@suse.cz>2008-10-23 06:58:38 -0400
commitcc6e0bbb47f02fd36cd55b3189c0c79079096ab8 (patch)
tree9c2e60517a4d00607f505b09e67b1966420b0c4a /drivers/hid/hid-sony.c
parenteb9910894d7857c273e049b297fd6251e5ecc43e (diff)
HID: Add support for Sony Vaio VGX-TP1E
The Sony Vaio VGX-TP1E multimedia PC has a wireless keyboard with a touchpad. The mouse pointer is wrongly declared as constant non-data variable, which make HID code to completely ignore all the "Pointer" usages. Fix the report descriptor before it enters the parser to contain touchpad pointer description that is correctly parsable (declaring data rather than constant). Reported-by: Stefan Hundhammer <sh@suse.de> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-sony.c')
-rw-r--r--drivers/hid/hid-sony.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 3af8095a7de1..86e563b8d644 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -4,9 +4,9 @@
4 * Copyright (c) 1999 Andreas Gal 4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc 6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley 7 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby 8 * Copyright (c) 2008 Jiri Slaby
9 * Copyright (c) 2006-2008 Jiri Kosina
10 */ 10 */
11 11
12/* 12/*
@@ -23,6 +23,26 @@
23 23
24#include "hid-ids.h" 24#include "hid-ids.h"
25 25
26#define VAIO_RDESC_CONSTANT 0x0001
27
28struct sony_sc {
29 unsigned long quirks;
30};
31
32/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
33static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
34 unsigned int rsize)
35{
36 struct sony_sc *sc = hid_get_drvdata(hdev);
37
38 if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
39 rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
40 dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report "
41 "descriptor\n");
42 rdesc[55] = 0x06;
43 }
44}
45
26/* 46/*
27 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller 47 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
28 * to "operational". Without this, the ps3 controller will not report any 48 * to "operational". Without this, the ps3 controller will not report any
@@ -56,6 +76,17 @@ static int sony_set_operational(struct hid_device *hdev)
56static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 76static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
57{ 77{
58 int ret; 78 int ret;
79 unsigned long quirks = id->driver_data;
80 struct sony_sc *sc;
81
82 sc = kzalloc(sizeof(*sc), GFP_KERNEL);
83 if (sc == NULL) {
84 dev_err(&hdev->dev, "can't alloc apple descriptor\n");
85 return -ENOMEM;
86 }
87
88 sc->quirks = quirks;
89 hid_set_drvdata(hdev, sc);
59 90
60 ret = hid_parse(hdev); 91 ret = hid_parse(hdev);
61 if (ret) { 92 if (ret) {
@@ -78,11 +109,20 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
78err_stop: 109err_stop:
79 hid_hw_stop(hdev); 110 hid_hw_stop(hdev);
80err_free: 111err_free:
112 kfree(sc);
81 return ret; 113 return ret;
82} 114}
83 115
116static void sony_remove(struct hid_device *hdev)
117{
118 hid_hw_stop(hdev);
119 kfree(hid_get_drvdata(hdev));
120}
121
84static const struct hid_device_id sony_devices[] = { 122static const struct hid_device_id sony_devices[] = {
85 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 123 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
124 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
125 .driver_data = VAIO_RDESC_CONSTANT },
86 { } 126 { }
87}; 127};
88MODULE_DEVICE_TABLE(hid, sony_devices); 128MODULE_DEVICE_TABLE(hid, sony_devices);
@@ -91,6 +131,8 @@ static struct hid_driver sony_driver = {
91 .name = "sony", 131 .name = "sony",
92 .id_table = sony_devices, 132 .id_table = sony_devices,
93 .probe = sony_probe, 133 .probe = sony_probe,
134 .remove = sony_remove,
135 .report_fixup = sony_report_fixup,
94}; 136};
95 137
96static int sony_init(void) 138static int sony_init(void)