summaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-sony.c
diff options
context:
space:
mode:
authorRoderick Colenbrander <roderick.colenbrander@sony.com>2016-10-07 15:39:37 -0400
committerJiri Kosina <jkosina@suse.cz>2016-10-10 04:43:25 -0400
commite7ef53adbf47734e90f9fd6e2a7a57df6f1fbc6b (patch)
treeef43b09a1a865cb71687245d35ac51ee34cd3aef /drivers/hid/hid-sony.c
parent49b9ca6c6c361a19d223ff84bd0ff871c01b528a (diff)
HID: sony: Send ds4 output reports on output end-point
Add a CRC value to each output report. This removes the need for the 'no output reports on interrupt end-point' quirk. Signed-off-by: Roderick Colenbrander <roderick.colenbrander@sony.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-sony.c')
-rw-r--r--drivers/hid/hid-sony.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 34988ce9434a..24f7d1937264 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1895,7 +1895,7 @@ static void dualshock4_send_output_report(struct sony_sc *sc)
1895 } else { 1895 } else {
1896 memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE); 1896 memset(buf, 0, DS4_OUTPUT_REPORT_0x11_SIZE);
1897 buf[0] = 0x11; 1897 buf[0] = 0x11;
1898 buf[1] = 0x80; 1898 buf[1] = 0xC0; /* HID + CRC */
1899 buf[3] = 0x0F; 1899 buf[3] = 0x0F;
1900 offset = 6; 1900 offset = 6;
1901 } 1901 }
@@ -1922,9 +1922,16 @@ static void dualshock4_send_output_report(struct sony_sc *sc)
1922 1922
1923 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) 1923 if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
1924 hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE); 1924 hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x05_SIZE);
1925 else 1925 else {
1926 hid_hw_raw_request(hdev, 0x11, buf, DS4_OUTPUT_REPORT_0x11_SIZE, 1926 /* CRC generation */
1927 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 1927 u8 bthdr = 0xA2;
1928 u32 crc;
1929
1930 crc = crc32_le(0xFFFFFFFF, &bthdr, 1);
1931 crc = ~crc32_le(crc, buf, DS4_OUTPUT_REPORT_0x11_SIZE-4);
1932 put_unaligned_le32(crc, &buf[74]);
1933 hid_hw_output_report(hdev, buf, DS4_OUTPUT_REPORT_0x11_SIZE);
1934 }
1928} 1935}
1929 1936
1930static void motion_send_output_report(struct sony_sc *sc) 1937static void motion_send_output_report(struct sony_sc *sc)
@@ -2378,11 +2385,6 @@ static int sony_input_configured(struct hid_device *hdev,
2378 sony_init_output_report(sc, sixaxis_send_output_report); 2385 sony_init_output_report(sc, sixaxis_send_output_report);
2379 } else if (sc->quirks & DUALSHOCK4_CONTROLLER) { 2386 } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
2380 if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) { 2387 if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
2381 /*
2382 * The DualShock 4 wants output reports sent on the ctrl
2383 * endpoint when connected via Bluetooth.
2384 */
2385 hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
2386 ret = dualshock4_set_operational_bt(hdev); 2388 ret = dualshock4_set_operational_bt(hdev);
2387 if (ret < 0) { 2389 if (ret < 0) {
2388 hid_err(hdev, "failed to set the Dualshock 4 operational mode\n"); 2390 hid_err(hdev, "failed to set the Dualshock 4 operational mode\n");