aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorAntonio Ospite <ospite@studenti.unina.it>2011-02-20 12:26:45 -0500
committerJiri Kosina <jkosina@suse.cz>2011-02-21 07:48:50 -0500
commit5710fabf315efcd53c54ad4ecc6158f2964745e3 (patch)
tree303776801d76cd4e2534247f4422be80c8ca4975 /drivers/hid
parent177900e8c9ab28cdf097314fe7dd3877774df97d (diff)
HID: hid-sony.c: Fix sending Output reports to the Sixaxis
The Sixaxis does not want the report_id as part of the data packet in Output reports, so we have to discard buf[0] when sending the actual control message. Add also some documentation about that and about why hdev->hid_output_raw_report needs to be overridden. Signed-off-by: Antonio Ospite <ospite@studenti.unina.it> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-sony.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 68d7b36e31e4..93819a08121a 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -46,6 +46,16 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
46 return rdesc; 46 return rdesc;
47} 47}
48 48
49/*
50 * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
51 * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
52 * so we need to override that forcing HID Output Reports on the Control EP.
53 *
54 * There is also another issue about HID Output Reports via USB, the Sixaxis
55 * does not want the report_id as part of the data packet, so we have to
56 * discard buf[0] when sending the actual control message, even for numbered
57 * reports, humpf!
58 */
49static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 59static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
50 size_t count, unsigned char report_type) 60 size_t count, unsigned char report_type)
51{ 61{
@@ -55,6 +65,12 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
55 int report_id = buf[0]; 65 int report_id = buf[0];
56 int ret; 66 int ret;
57 67
68 if (report_type == HID_OUTPUT_REPORT) {
69 /* Don't send the Report ID */
70 buf++;
71 count--;
72 }
73
58 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 74 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
59 HID_REQ_SET_REPORT, 75 HID_REQ_SET_REPORT,
60 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 76 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
@@ -62,6 +78,10 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
62 interface->desc.bInterfaceNumber, buf, count, 78 interface->desc.bInterfaceNumber, buf, count,
63 USB_CTRL_SET_TIMEOUT); 79 USB_CTRL_SET_TIMEOUT);
64 80
81 /* Count also the Report ID, in case of an Output report. */
82 if (ret > 0 && report_type == HID_OUTPUT_REPORT)
83 ret++;
84
65 return ret; 85 return ret;
66} 86}
67 87