diff options
| -rw-r--r-- | drivers/hid/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 8 | ||||
| -rw-r--r-- | drivers/hid/hid-sony.c | 119 |
3 files changed, 127 insertions, 4 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 920a64b66b25..932e4110bb38 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1084,7 +1084,7 @@ config HID_SIGMAMICRO - Rapoo V500 config HID_SONY - tristate "Sony PS2/3/4 accessories" + tristate "Sony PS2/3/4/5 accessories" depends on USB_HID depends on NEW_LEDS depends on LEDS_CLASS @@ -1094,12 +1094,12 @@ config HID_SONY Support for * Sony PS3 6-axis controllers - * Sony PS4 DualShock 4 controllers * Buzz controllers * Sony PS3 Blue-ray Disk Remote Control (Bluetooth) * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth) * Guitar Hero Live PS3, Wii U and PS4 guitar dongles * Guitar Hero PS3 and PC guitar dongles + * Rock Band 4 PS4 and PS5 guitars config SONY_FF bool "Sony PS2/3/4 accessories force feedback support" diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9c2bf584d9f6..ae4b37bb7020 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -364,6 +364,10 @@ #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 #define USB_DEVICE_ID_CREATIVE_SB0540 0x3100 +#define USB_VENDOR_ID_CRKD 0x3651 +#define USB_DEVICE_ID_CRKD_PS4_GIBSON_SG 0x1500 +#define USB_DEVICE_ID_CRKD_PS5_GIBSON_SG 0x1600 + #define USB_VENDOR_ID_CVTOUCH 0x1ff7 #define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013 @@ -1150,6 +1154,10 @@ #define USB_VENDOR_ID_POWERCOM 0x0d9f #define USB_DEVICE_ID_POWERCOM_UPS 0x0002 +#define USB_VENDOR_ID_PDP 0x0e6F +#define USB_DEVICE_ID_PDP_PS4_RIFFMASTER 0x024a +#define USB_DEVICE_ID_PDP_PS5_RIFFMASTER 0x0249 + #define USB_VENDOR_ID_PRODIGE 0x05af #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index b966e4044238..e2f17a99fa42 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -14,6 +14,7 @@ * Copyright (c) 2020-2021 Pascal Giard <pascal.giard@etsmtl.ca> * Copyright (c) 2020 Sanjay Govind <sanjay.govind9@gmail.com> * Copyright (c) 2021 Daniel Nguyen <daniel.nguyen.1@ens.etsmtl.ca> + * Copyright (c) 2026 Rosalie Wanders <rosalie@mailbox.org> */ /* @@ -61,6 +62,8 @@ #define GH_GUITAR_CONTROLLER BIT(14) #define GHL_GUITAR_PS3WIIU BIT(15) #define GHL_GUITAR_PS4 BIT(16) +#define RB4_GUITAR_PS4 BIT(17) +#define RB4_GUITAR_PS5 BIT(18) #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) @@ -418,6 +421,27 @@ static const unsigned int sixaxis_keymap[] = { [0x11] = BTN_MODE, /* PS */ }; +static const unsigned int rb4_absmap[] = { + [0x30] = ABS_X, + [0x31] = ABS_Y, +}; + +static const unsigned int rb4_keymap[] = { + [0x1] = BTN_WEST, /* Square */ + [0x2] = BTN_SOUTH, /* Cross */ + [0x3] = BTN_EAST, /* Circle */ + [0x4] = BTN_NORTH, /* Triangle */ + [0x5] = BTN_TL, /* L1 */ + [0x6] = BTN_TR, /* R1 */ + [0x7] = BTN_TL2, /* L2 */ + [0x8] = BTN_TR2, /* R2 */ + [0x9] = BTN_SELECT, /* Share */ + [0xa] = BTN_START, /* Options */ + [0xb] = BTN_THUMBL, /* L3 */ + [0xc] = BTN_THUMBR, /* R3 */ + [0xd] = BTN_MODE, /* PS */ +}; + static enum power_supply_property sony_battery_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_CAPACITY, @@ -484,6 +508,7 @@ struct sony_sc { spinlock_t lock; struct list_head list_node; struct hid_device *hdev; + struct input_dev *input_dev; struct input_dev *touchpad; struct input_dev *sensor_dev; struct led_classdev *leds[MAX_LEDS]; @@ -584,7 +609,7 @@ static int ghl_init_urb(struct sony_sc *sc, struct usb_device *usbdev, return 0; } -static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi, +static int gh_guitar_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { @@ -599,6 +624,38 @@ static int guitar_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static int rb4_guitar_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) + +{ + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { + unsigned int key = usage->hid & HID_USAGE; + + if (key >= ARRAY_SIZE(rb4_keymap)) + return 0; + + key = rb4_keymap[key]; + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); + return 1; + } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { + unsigned int abs = usage->hid & HID_USAGE; + + /* Let the HID parser deal with the HAT. */ + if (usage->hid == HID_GD_HATSWITCH) + return 0; + + if (abs >= ARRAY_SIZE(rb4_absmap)) + return 0; + + abs = rb4_absmap[abs]; + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs); + return 1; + } + + return 0; +} + static const u8 *motion_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *rsize) { @@ -915,6 +972,40 @@ static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size) input_sync(sc->touchpad); } +static void rb4_ps4_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size) +{ + /* + * Rock Band 4 PS4 guitars have whammy and + * tilt functionality, they're located at + * byte 44 and 45 respectively. + * + * We will map these values to the triggers + * because the guitars don't have anything + * mapped there. + */ + input_report_abs(sc->input_dev, ABS_Z, rd[44]); + input_report_abs(sc->input_dev, ABS_RZ, rd[45]); + + input_sync(sc->input_dev); +} + +static void rb4_ps5_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size) +{ + /* + * Rock Band 4 PS5 guitars have whammy and + * tilt functionality, they're located at + * byte 41 and 42 respectively. + * + * We will map these values to the triggers + * because the guitars don't have anything + * mapped there. + */ + input_report_abs(sc->input_dev, ABS_Z, rd[41]); + input_report_abs(sc->input_dev, ABS_RZ, rd[42]); + + input_sync(sc->input_dev); +} + static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *rd, int size) { @@ -950,6 +1041,12 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, } else if ((sc->quirks & NSG_MRXU_REMOTE) && rd[0] == 0x02) { nsg_mrxu_parse_report(sc, rd, size); return 1; + } else if ((sc->quirks & RB4_GUITAR_PS4) && rd[0] == 0x01 && size == 64) { + rb4_ps4_guitar_parse_report(sc, rd, size); + return 1; + } else if ((sc->quirks & RB4_GUITAR_PS5) && rd[0] == 0x01 && size == 64) { + rb4_ps5_guitar_parse_report(sc, rd, size); + return 1; } if (sc->defer_initialization) { @@ -999,7 +1096,13 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, return sixaxis_mapping(hdev, hi, field, usage, bit, max); if (sc->quirks & GH_GUITAR_CONTROLLER) - return guitar_mapping(hdev, hi, field, usage, bit, max); + return gh_guitar_mapping(hdev, hi, field, usage, bit, max); + + if (sc->quirks & RB4_GUITAR_PS4) + return rb4_guitar_mapping(hdev, hi, field, usage, bit, max); + + if (sc->quirks & RB4_GUITAR_PS5) + return rb4_guitar_mapping(hdev, hi, field, usage, bit, max); /* Let hid-core decide for the others */ return 0; @@ -2016,6 +2119,8 @@ static int sony_input_configured(struct hid_device *hdev, } else if (sc->quirks & MOTION_CONTROLLER) { sony_init_output_report(sc, motion_send_output_report); + } else if (sc->quirks & (RB4_GUITAR_PS4 | RB4_GUITAR_PS5)) { + sc->input_dev = hidinput->input; } if (sc->quirks & SONY_LED_SUPPORT) { @@ -2271,6 +2376,16 @@ static const struct hid_device_id sony_devices[] = { /* Guitar Hero Live PS4 guitar dongles */ { HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE), .driver_data = GHL_GUITAR_PS4 | GH_GUITAR_CONTROLLER }, + /* Rock Band 4 PS4 guitars */ + { HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER), + .driver_data = RB4_GUITAR_PS4 }, + { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG), + .driver_data = RB4_GUITAR_PS4 }, + /* Rock Band 4 PS5 guitars */ + { HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS5_RIFFMASTER), + .driver_data = RB4_GUITAR_PS5 }, + { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG), + .driver_data = RB4_GUITAR_PS5 }, { } }; MODULE_DEVICE_TABLE(hid, sony_devices); |
