aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorFrank Praznik <frank.praznik@oh.rr.com>2014-01-11 15:12:42 -0500
committerJiri Kosina <jkosina@suse.cz>2014-01-16 16:44:35 -0500
commit0bd88dd3dd5e73e5d43b8d1e7a96b841978df562 (patch)
treeaeabfeb65996c7c400a240c6551edec58386d420 /drivers/hid
parent8cd5fcda24b48b162699730da7ead7329b27159e (diff)
HID: sony: Add force-feedback support for the Dualshock 4
Adds the Dualshock 4 to the HID device list and enables force-feedback. Adds a Dualshock 4 specific worker function since the Dualshock 4 needs a different report than the Sixaxis. The right motor in the Dualshock 4 is variable so the full rumble value is now passed to the worker function and clamped there if necessary. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-sony.c39
3 files changed, 39 insertions, 3 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 957d35ba84bc..70cc4682044a 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1831,6 +1831,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
1831 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1831 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1832 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, 1832 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
1833 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1833 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1834 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
1835 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
1834 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1836 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
1835 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, 1837 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
1836 { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, 1838 { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 60336f06874c..ce24459284e3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -766,6 +766,7 @@
766#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374 766#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
767#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 767#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
768#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 768#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
769#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
769#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f 770#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
770#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002 771#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
771#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000 772#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index f57ab5e2832f..8020d10ce703 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -38,6 +38,7 @@
38#define SIXAXIS_CONTROLLER_BT BIT(2) 38#define SIXAXIS_CONTROLLER_BT BIT(2)
39#define BUZZ_CONTROLLER BIT(3) 39#define BUZZ_CONTROLLER BIT(3)
40#define PS3REMOTE BIT(4) 40#define PS3REMOTE BIT(4)
41#define DUALSHOCK4_CONTROLLER BIT(5)
41 42
42#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER) 43#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER)
43 44
@@ -630,7 +631,7 @@ static void sony_state_worker(struct work_struct *work)
630 }; 631 };
631 632
632#ifdef CONFIG_SONY_FF 633#ifdef CONFIG_SONY_FF
633 buf[3] = sc->right; 634 buf[3] = sc->right ? 1 : 0;
634 buf[5] = sc->left; 635 buf[5] = sc->left;
635#endif 636#endif
636 637
@@ -640,6 +641,29 @@ static void sony_state_worker(struct work_struct *work)
640 HID_OUTPUT_REPORT); 641 HID_OUTPUT_REPORT);
641} 642}
642 643
644static void dualshock4_state_worker(struct work_struct *work)
645{
646 struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
647 unsigned char buf[] = {
648 0x05,
649 0x03, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00,
656 };
657
658#ifdef CONFIG_SONY_FF
659 buf[4] = sc->right;
660 buf[5] = sc->left;
661#endif
662
663 sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
664 HID_OUTPUT_REPORT);
665}
666
643#ifdef CONFIG_SONY_FF 667#ifdef CONFIG_SONY_FF
644static int sony_play_effect(struct input_dev *dev, void *data, 668static int sony_play_effect(struct input_dev *dev, void *data,
645 struct ff_effect *effect) 669 struct ff_effect *effect)
@@ -651,7 +675,7 @@ static int sony_play_effect(struct input_dev *dev, void *data,
651 return 0; 675 return 0;
652 676
653 sc->left = effect->u.rumble.strong_magnitude / 256; 677 sc->left = effect->u.rumble.strong_magnitude / 256;
654 sc->right = effect->u.rumble.weak_magnitude ? 1 : 0; 678 sc->right = effect->u.rumble.weak_magnitude / 256;
655 679
656 schedule_work(&sc->state_worker); 680 schedule_work(&sc->state_worker);
657 return 0; 681 return 0;
@@ -728,8 +752,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
728 } 752 }
729 else if (sc->quirks & SIXAXIS_CONTROLLER_BT) 753 else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
730 ret = sixaxis_set_operational_bt(hdev); 754 ret = sixaxis_set_operational_bt(hdev);
731 else 755 else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
732 ret = 0; 756 ret = 0;
757 INIT_WORK(&sc->state_worker, dualshock4_state_worker);
758 } else {
759 ret = 0;
760 }
733 761
734 if (ret < 0) 762 if (ret < 0)
735 goto err_stop; 763 goto err_stop;
@@ -787,6 +815,11 @@ static const struct hid_device_id sony_devices[] = {
787 /* Logitech Harmony Adapter for PS3 */ 815 /* Logitech Harmony Adapter for PS3 */
788 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3), 816 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
789 .driver_data = PS3REMOTE }, 817 .driver_data = PS3REMOTE },
818 /* Sony Dualshock 4 controllers for PS4 */
819 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
820 .driver_data = DUALSHOCK4_CONTROLLER },
821 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
822 .driver_data = DUALSHOCK4_CONTROLLER },
790 { } 823 { }
791}; 824};
792MODULE_DEVICE_TABLE(hid, sony_devices); 825MODULE_DEVICE_TABLE(hid, sony_devices);