diff options
author | Frank Praznik <frank.praznik@oh.rr.com> | 2014-01-11 15:12:42 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-01-16 16:44:35 -0500 |
commit | 0bd88dd3dd5e73e5d43b8d1e7a96b841978df562 (patch) | |
tree | aeabfeb65996c7c400a240c6551edec58386d420 /drivers/hid | |
parent | 8cd5fcda24b48b162699730da7ead7329b27159e (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.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 39 |
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 | ||
644 | static 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 |
644 | static int sony_play_effect(struct input_dev *dev, void *data, | 668 | static 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 | }; |
792 | MODULE_DEVICE_TABLE(hid, sony_devices); | 825 | MODULE_DEVICE_TABLE(hid, sony_devices); |