Skip to content

Commit

Permalink
HID: sony: Add force-feedback support for the Dualshock 4
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Frank Praznik authored and Jiri Kosina committed Jan 16, 2014
1 parent 8cd5fcd commit 0bd88dd
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
2 changes: 2 additions & 0 deletions drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1831,6 +1831,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) },
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@
#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
#define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000
Expand Down
39 changes: 36 additions & 3 deletions drivers/hid/hid-sony.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define SIXAXIS_CONTROLLER_BT BIT(2)
#define BUZZ_CONTROLLER BIT(3)
#define PS3REMOTE BIT(4)
#define DUALSHOCK4_CONTROLLER BIT(5)

#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER)

Expand Down Expand Up @@ -630,7 +631,7 @@ static void sony_state_worker(struct work_struct *work)
};

#ifdef CONFIG_SONY_FF
buf[3] = sc->right;
buf[3] = sc->right ? 1 : 0;
buf[5] = sc->left;
#endif

Expand All @@ -640,6 +641,29 @@ static void sony_state_worker(struct work_struct *work)
HID_OUTPUT_REPORT);
}

static void dualshock4_state_worker(struct work_struct *work)
{
struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
unsigned char buf[] = {
0x05,
0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
};

#ifdef CONFIG_SONY_FF
buf[4] = sc->right;
buf[5] = sc->left;
#endif

sc->hdev->hid_output_raw_report(sc->hdev, buf, sizeof(buf),
HID_OUTPUT_REPORT);
}

#ifdef CONFIG_SONY_FF
static int sony_play_effect(struct input_dev *dev, void *data,
struct ff_effect *effect)
Expand All @@ -651,7 +675,7 @@ static int sony_play_effect(struct input_dev *dev, void *data,
return 0;

sc->left = effect->u.rumble.strong_magnitude / 256;
sc->right = effect->u.rumble.weak_magnitude ? 1 : 0;
sc->right = effect->u.rumble.weak_magnitude / 256;

schedule_work(&sc->state_worker);
return 0;
Expand Down Expand Up @@ -728,8 +752,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
}
else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
ret = sixaxis_set_operational_bt(hdev);
else
else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
ret = 0;
INIT_WORK(&sc->state_worker, dualshock4_state_worker);
} else {
ret = 0;
}

if (ret < 0)
goto err_stop;
Expand Down Expand Up @@ -787,6 +815,11 @@ static const struct hid_device_id sony_devices[] = {
/* Logitech Harmony Adapter for PS3 */
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3),
.driver_data = PS3REMOTE },
/* Sony Dualshock 4 controllers for PS4 */
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
.driver_data = DUALSHOCK4_CONTROLLER },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
.driver_data = DUALSHOCK4_CONTROLLER },
{ }
};
MODULE_DEVICE_TABLE(hid, sony_devices);
Expand Down

0 comments on commit 0bd88dd

Please sign in to comment.