aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2007-01-15 23:11:52 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:36 -0500
commit4a1a4d8b87389e35c3af04c0d0a95f6a0391b964 (patch)
treeaa68e0259f38d2342d7c7719a324d917fd29fc1e /drivers/usb
parentad75a41085d80c8ce5e885962c15779935f8267e (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>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/input/hid-core.c35
1 files changed, 35 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 */
1026static 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
1016static struct hid_device *usb_hid_configure(struct usb_interface *intf) 1047static 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)