From: Rosalie Wanders Date: Sat, 7 Mar 2026 09:48:25 +0000 (+0100) Subject: HID: sony: add battery status support for Rock Band 4 PS5 guitars X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e4bdeaef035135957d2a833c16117e6f6f16260e;p=thirdparty%2Fkernel%2Flinux.git HID: sony: add battery status support for Rock Band 4 PS5 guitars This commit adds battery status support for Rock Band 4 PS5 guitars. The data is reported in the same way as the dualsense in hid-playstation except it's located at byte 30. Signed-off-by: Rosalie Wanders Signed-off-by: Jiri Kosina --- diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index e37e19c017af6..83e82a0a3327a 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -76,7 +76,8 @@ NAVIGATION_CONTROLLER_BT) #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ MOTION_CONTROLLER | NAVIGATION_CONTROLLER) -#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER) +#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER |\ + RB4_GUITAR_PS5) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | MOTION_CONTROLLER) #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) #define NSG_MRXU_REMOTE (NSG_MR5U_REMOTE_BT | NSG_MR7U_REMOTE_BT) @@ -1087,6 +1088,12 @@ static void rb4_ps4_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size) static void rb4_ps5_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size) { + u8 charging_status; + u8 battery_data; + u8 battery_capacity; + u8 battery_status; + unsigned long flags; + /* * Rock Band 4 PS5 guitars have whammy and * tilt functionality, they're located at @@ -1099,6 +1106,37 @@ static void rb4_ps5_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size) input_report_abs(sc->input_dev, ABS_Z, rd[41]); input_report_abs(sc->input_dev, ABS_RZ, rd[42]); + /* + * Rock Band 4 PS5 guitars also report the + * battery status and level at byte 30. + */ + charging_status = (rd[30] >> 4) & 0x0F; + battery_data = rd[30] & 0x0F; + + switch (charging_status) { + case 0x0: + battery_capacity = min(battery_data * 10 + 5, 100); + battery_status = POWER_SUPPLY_STATUS_DISCHARGING; + break; + case 0x1: + battery_capacity = min(battery_data * 10 + 5, 100); + battery_status = POWER_SUPPLY_STATUS_CHARGING; + break; + case 0x2: + battery_capacity = 100; + battery_status = POWER_SUPPLY_STATUS_FULL; + break; + default: + battery_capacity = 0; + battery_status = POWER_SUPPLY_STATUS_UNKNOWN; + break; + } + + spin_lock_irqsave(&sc->lock, flags); + sc->battery_capacity = battery_capacity; + sc->battery_status = battery_status; + spin_unlock_irqrestore(&sc->lock, flags); + input_sync(sc->input_dev); }