Skip to content

Commit bbf9927

Browse files
Rosalie241Jiri Kosina
authored andcommitted
HID: sony: add support for Rock Band 4 PS4 and PS5 guitars
This commit adds support for the PDP RiffMaster and the CRKD Gibson SG in both their PS4 and PS5 modes. These devices aren't mapped correctly without these changes, they also lack support for their whammy and tilt functionality which this patch adds support for by binding them to the left and right triggers. Signed-off-by: Rosalie Wanders <rosalie@mailbox.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 79b95d7 commit bbf9927

3 files changed

Lines changed: 127 additions & 4 deletions

File tree

drivers/hid/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ config HID_SIGMAMICRO
10841084
- Rapoo V500
10851085

10861086
config HID_SONY
1087-
tristate "Sony PS2/3/4 accessories"
1087+
tristate "Sony PS2/3/4/5 accessories"
10881088
depends on USB_HID
10891089
depends on NEW_LEDS
10901090
depends on LEDS_CLASS
@@ -1094,12 +1094,12 @@ config HID_SONY
10941094
Support for
10951095

10961096
* Sony PS3 6-axis controllers
1097-
* Sony PS4 DualShock 4 controllers
10981097
* Buzz controllers
10991098
* Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
11001099
* Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)
11011100
* Guitar Hero Live PS3, Wii U and PS4 guitar dongles
11021101
* Guitar Hero PS3 and PC guitar dongles
1102+
* Rock Band 4 PS4 and PS5 guitars
11031103

11041104
config SONY_FF
11051105
bool "Sony PS2/3/4 accessories force feedback support"

drivers/hid/hid-ids.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,10 @@
364364
#define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801
365365
#define USB_DEVICE_ID_CREATIVE_SB0540 0x3100
366366

367+
#define USB_VENDOR_ID_CRKD 0x3651
368+
#define USB_DEVICE_ID_CRKD_PS4_GIBSON_SG 0x1500
369+
#define USB_DEVICE_ID_CRKD_PS5_GIBSON_SG 0x1600
370+
367371
#define USB_VENDOR_ID_CVTOUCH 0x1ff7
368372
#define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013
369373

@@ -1150,6 +1154,10 @@
11501154
#define USB_VENDOR_ID_POWERCOM 0x0d9f
11511155
#define USB_DEVICE_ID_POWERCOM_UPS 0x0002
11521156

1157+
#define USB_VENDOR_ID_PDP 0x0e6F
1158+
#define USB_DEVICE_ID_PDP_PS4_RIFFMASTER 0x024a
1159+
#define USB_DEVICE_ID_PDP_PS5_RIFFMASTER 0x0249
1160+
11531161
#define USB_VENDOR_ID_PRODIGE 0x05af
11541162
#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
11551163

drivers/hid/hid-sony.c

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* Copyright (c) 2020-2021 Pascal Giard <pascal.giard@etsmtl.ca>
1515
* Copyright (c) 2020 Sanjay Govind <sanjay.govind9@gmail.com>
1616
* Copyright (c) 2021 Daniel Nguyen <daniel.nguyen.1@ens.etsmtl.ca>
17+
* Copyright (c) 2026 Rosalie Wanders <rosalie@mailbox.org>
1718
*/
1819

1920
/*
@@ -61,6 +62,8 @@
6162
#define GH_GUITAR_CONTROLLER BIT(14)
6263
#define GHL_GUITAR_PS3WIIU BIT(15)
6364
#define GHL_GUITAR_PS4 BIT(16)
65+
#define RB4_GUITAR_PS4 BIT(17)
66+
#define RB4_GUITAR_PS5 BIT(18)
6467

6568
#define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)
6669
#define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT)
@@ -418,6 +421,27 @@ static const unsigned int sixaxis_keymap[] = {
418421
[0x11] = BTN_MODE, /* PS */
419422
};
420423

424+
static const unsigned int rb4_absmap[] = {
425+
[0x30] = ABS_X,
426+
[0x31] = ABS_Y,
427+
};
428+
429+
static const unsigned int rb4_keymap[] = {
430+
[0x1] = BTN_WEST, /* Square */
431+
[0x2] = BTN_SOUTH, /* Cross */
432+
[0x3] = BTN_EAST, /* Circle */
433+
[0x4] = BTN_NORTH, /* Triangle */
434+
[0x5] = BTN_TL, /* L1 */
435+
[0x6] = BTN_TR, /* R1 */
436+
[0x7] = BTN_TL2, /* L2 */
437+
[0x8] = BTN_TR2, /* R2 */
438+
[0x9] = BTN_SELECT, /* Share */
439+
[0xa] = BTN_START, /* Options */
440+
[0xb] = BTN_THUMBL, /* L3 */
441+
[0xc] = BTN_THUMBR, /* R3 */
442+
[0xd] = BTN_MODE, /* PS */
443+
};
444+
421445
static enum power_supply_property sony_battery_props[] = {
422446
POWER_SUPPLY_PROP_PRESENT,
423447
POWER_SUPPLY_PROP_CAPACITY,
@@ -484,6 +508,7 @@ struct sony_sc {
484508
spinlock_t lock;
485509
struct list_head list_node;
486510
struct hid_device *hdev;
511+
struct input_dev *input_dev;
487512
struct input_dev *touchpad;
488513
struct input_dev *sensor_dev;
489514
struct led_classdev *leds[MAX_LEDS];
@@ -584,7 +609,7 @@ static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev,
584609
return 0;
585610
}
586611

587-
static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi,
612+
static int gh_guitar_mapping(struct hid_device *hdev, struct hid_input *hi,
588613
struct hid_field *field, struct hid_usage *usage,
589614
unsigned long **bit, int *max)
590615
{
@@ -599,6 +624,38 @@ static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi,
599624
return 0;
600625
}
601626

627+
static int rb4_guitar_mapping(struct hid_device *hdev, struct hid_input *hi,
628+
struct hid_field *field, struct hid_usage *usage,
629+
unsigned long **bit, int *max)
630+
631+
{
632+
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) {
633+
unsigned int key = usage->hid & HID_USAGE;
634+
635+
if (key >= ARRAY_SIZE(rb4_keymap))
636+
return 0;
637+
638+
key = rb4_keymap[key];
639+
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
640+
return 1;
641+
} else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) {
642+
unsigned int abs = usage->hid & HID_USAGE;
643+
644+
/* Let the HID parser deal with the HAT. */
645+
if (usage->hid == HID_GD_HATSWITCH)
646+
return 0;
647+
648+
if (abs >= ARRAY_SIZE(rb4_absmap))
649+
return 0;
650+
651+
abs = rb4_absmap[abs];
652+
hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs);
653+
return 1;
654+
}
655+
656+
return 0;
657+
}
658+
602659
static const u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc,
603660
unsigned int *rsize)
604661
{
@@ -915,6 +972,40 @@ static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size)
915972
input_sync(sc->touchpad);
916973
}
917974

975+
static void rb4_ps4_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size)
976+
{
977+
/*
978+
* Rock Band 4 PS4 guitars have whammy and
979+
* tilt functionality, they're located at
980+
* byte 44 and 45 respectively.
981+
*
982+
* We will map these values to the triggers
983+
* because the guitars don't have anything
984+
* mapped there.
985+
*/
986+
input_report_abs(sc->input_dev, ABS_Z, rd[44]);
987+
input_report_abs(sc->input_dev, ABS_RZ, rd[45]);
988+
989+
input_sync(sc->input_dev);
990+
}
991+
992+
static void rb4_ps5_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size)
993+
{
994+
/*
995+
* Rock Band 4 PS5 guitars have whammy and
996+
* tilt functionality, they're located at
997+
* byte 41 and 42 respectively.
998+
*
999+
* We will map these values to the triggers
1000+
* because the guitars don't have anything
1001+
* mapped there.
1002+
*/
1003+
input_report_abs(sc->input_dev, ABS_Z, rd[41]);
1004+
input_report_abs(sc->input_dev, ABS_RZ, rd[42]);
1005+
1006+
input_sync(sc->input_dev);
1007+
}
1008+
9181009
static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
9191010
u8 *rd, int size)
9201011
{
@@ -950,6 +1041,12 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
9501041
} else if ((sc->quirks & NSG_MRXU_REMOTE) && rd[0] == 0x02) {
9511042
nsg_mrxu_parse_report(sc, rd, size);
9521043
return 1;
1044+
} else if ((sc->quirks & RB4_GUITAR_PS4) && rd[0] == 0x01 && size == 64) {
1045+
rb4_ps4_guitar_parse_report(sc, rd, size);
1046+
return 1;
1047+
} else if ((sc->quirks & RB4_GUITAR_PS5) && rd[0] == 0x01 && size == 64) {
1048+
rb4_ps5_guitar_parse_report(sc, rd, size);
1049+
return 1;
9531050
}
9541051

9551052
if (sc->defer_initialization) {
@@ -999,7 +1096,13 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi,
9991096
return sixaxis_mapping(hdev, hi, field, usage, bit, max);
10001097

10011098
if (sc->quirks & GH_GUITAR_CONTROLLER)
1002-
return guitar_mapping(hdev, hi, field, usage, bit, max);
1099+
return gh_guitar_mapping(hdev, hi, field, usage, bit, max);
1100+
1101+
if (sc->quirks & RB4_GUITAR_PS4)
1102+
return rb4_guitar_mapping(hdev, hi, field, usage, bit, max);
1103+
1104+
if (sc->quirks & RB4_GUITAR_PS5)
1105+
return rb4_guitar_mapping(hdev, hi, field, usage, bit, max);
10031106

10041107
/* Let hid-core decide for the others */
10051108
return 0;
@@ -2016,6 +2119,8 @@ static int sony_input_configured(struct hid_device *hdev,
20162119

20172120
} else if (sc->quirks & MOTION_CONTROLLER) {
20182121
sony_init_output_report(sc, motion_send_output_report);
2122+
} else if (sc->quirks & (RB4_GUITAR_PS4 | RB4_GUITAR_PS5)) {
2123+
sc->input_dev = hidinput->input;
20192124
}
20202125

20212126
if (sc->quirks & SONY_LED_SUPPORT) {
@@ -2271,6 +2376,16 @@ static const struct hid_device_id sony_devices[] = {
22712376
/* Guitar Hero Live PS4 guitar dongles */
22722377
{ HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE),
22732378
.driver_data = GHL_GUITAR_PS4 | GH_GUITAR_CONTROLLER },
2379+
/* Rock Band 4 PS4 guitars */
2380+
{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER),
2381+
.driver_data = RB4_GUITAR_PS4 },
2382+
{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG),
2383+
.driver_data = RB4_GUITAR_PS4 },
2384+
/* Rock Band 4 PS5 guitars */
2385+
{ HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS5_RIFFMASTER),
2386+
.driver_data = RB4_GUITAR_PS5 },
2387+
{ HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG),
2388+
.driver_data = RB4_GUITAR_PS5 },
22742389
{ }
22752390
};
22762391
MODULE_DEVICE_TABLE(hid, sony_devices);

0 commit comments

Comments
 (0)