diff options
author | Geoff Levand <geoffrey.levand@am.sony.com> | 2007-01-15 23:11:52 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-07 18:44:36 -0500 |
commit | 4a1a4d8b87389e35c3af04c0d0a95f6a0391b964 (patch) | |
tree | aa68e0259f38d2342d7c7719a324d917fd29fc1e | |
parent | ad75a41085d80c8ce5e885962c15779935f8267e (diff) |
USB: ps3 controller hid quirk
Add the USB HID quirk HID_QUIRK_SONY_PS3_CONTROLLER. This sends an
HID_REQ_GET_REPORT to the the PS3 controller to put the device into
'operational mode'.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/input/hid-core.c | 35 | ||||
-rw-r--r-- | include/linux/hid.h | 1 |
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index e07a30490726..84983d1b7164 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -768,6 +768,9 @@ void usbhid_init_reports(struct hid_device *hid) | |||
768 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 | 768 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 |
769 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 | 769 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 |
770 | 770 | ||
771 | #define USB_VENDOR_ID_SONY 0x054c | ||
772 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | ||
773 | |||
771 | /* | 774 | /* |
772 | * Alphabetically sorted blacklist by quirk type. | 775 | * Alphabetically sorted blacklist by quirk type. |
773 | */ | 776 | */ |
@@ -949,6 +952,8 @@ static const struct hid_blacklist { | |||
949 | 952 | ||
950 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 953 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
951 | 954 | ||
955 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, | ||
956 | |||
952 | { 0, 0 } | 957 | { 0, 0 } |
953 | }; | 958 | }; |
954 | 959 | ||
@@ -1013,6 +1018,32 @@ static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) | |||
1013 | } | 1018 | } |
1014 | } | 1019 | } |
1015 | 1020 | ||
1021 | /* | ||
1022 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | ||
1023 | * to "operational". Without this, the ps3 controller will not report any | ||
1024 | * events. | ||
1025 | */ | ||
1026 | static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) | ||
1027 | { | ||
1028 | int result; | ||
1029 | char *buf = kmalloc(18, GFP_KERNEL); | ||
1030 | |||
1031 | if (!buf) | ||
1032 | return; | ||
1033 | |||
1034 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
1035 | HID_REQ_GET_REPORT, | ||
1036 | USB_DIR_IN | USB_TYPE_CLASS | | ||
1037 | USB_RECIP_INTERFACE, | ||
1038 | (3 << 8) | 0xf2, ifnum, buf, 17, | ||
1039 | USB_CTRL_GET_TIMEOUT); | ||
1040 | |||
1041 | if (result < 0) | ||
1042 | err("%s failed: %d\n", __func__, result); | ||
1043 | |||
1044 | kfree(buf); | ||
1045 | } | ||
1046 | |||
1016 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) | 1047 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) |
1017 | { | 1048 | { |
1018 | struct usb_host_interface *interface = intf->cur_altsetting; | 1049 | struct usb_host_interface *interface = intf->cur_altsetting; |
@@ -1303,6 +1334,10 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1303 | if ((hid->claimed & HID_CLAIMED_INPUT)) | 1334 | if ((hid->claimed & HID_CLAIMED_INPUT)) |
1304 | hid_ff_init(hid); | 1335 | hid_ff_init(hid); |
1305 | 1336 | ||
1337 | if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) | ||
1338 | hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), | ||
1339 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
1340 | |||
1306 | printk(KERN_INFO); | 1341 | printk(KERN_INFO); |
1307 | 1342 | ||
1308 | if (hid->claimed & HID_CLAIMED_INPUT) | 1343 | if (hid->claimed & HID_CLAIMED_INPUT) |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 93173fe45634..d26b08f461f2 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -266,6 +266,7 @@ struct hid_item { | |||
266 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 | 266 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 |
267 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 | 267 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00020000 |
268 | #define HID_QUIRK_IGNORE_MOUSE 0x00040000 | 268 | #define HID_QUIRK_IGNORE_MOUSE 0x00040000 |
269 | #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00080000 | ||
269 | 270 | ||
270 | /* | 271 | /* |
271 | * This is the global environment of the parser. This information is | 272 | * This is the global environment of the parser. This information is |