Commit cc6e0bbb authored by Jiri Kosina's avatar Jiri Kosina

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: default avatarStefan Hundhammer <sh@suse.de>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent eb991089
...@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = { ...@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { 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) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
......
...@@ -350,6 +350,7 @@ ...@@ -350,6 +350,7 @@
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
#define USB_VENDOR_ID_SONY 0x054c #define USB_VENDOR_ID_SONY 0x054c
#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
* Copyright (c) 1999 Andreas Gal * Copyright (c) 1999 Andreas Gal
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc * 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) 2007 Paul Walmsley
* Copyright (c) 2008 Jiri Slaby * Copyright (c) 2008 Jiri Slaby
* Copyright (c) 2006-2008 Jiri Kosina
*/ */
/* /*
...@@ -23,6 +23,26 @@ ...@@ -23,6 +23,26 @@
#include "hid-ids.h" #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 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
* to "operational". Without this, the ps3 controller will not report any * to "operational". Without this, the ps3 controller will not report any
...@@ -56,6 +76,17 @@ static int sony_set_operational(struct hid_device *hdev) ...@@ -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) static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
{ {
int ret; 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); ret = hid_parse(hdev);
if (ret) { if (ret) {
...@@ -78,11 +109,20 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) ...@@ -78,11 +109,20 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
err_stop: err_stop:
hid_hw_stop(hdev); hid_hw_stop(hdev);
err_free: err_free:
kfree(sc);
return ret; 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[] = { 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_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); MODULE_DEVICE_TABLE(hid, sony_devices);
...@@ -91,6 +131,8 @@ static struct hid_driver sony_driver = { ...@@ -91,6 +131,8 @@ static struct hid_driver sony_driver = {
.name = "sony", .name = "sony",
.id_table = sony_devices, .id_table = sony_devices,
.probe = sony_probe, .probe = sony_probe,
.remove = sony_remove,
.report_fixup = sony_report_fixup,
}; };
static int sony_init(void) static int sony_init(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment