diff --git a/6.9/misc/0001-trigger-rumble.patch b/6.9/misc/0001-trigger-rumble.patch new file mode 100644 index 00000000..b0e4fd71 --- /dev/null +++ b/6.9/misc/0001-trigger-rumble.patch @@ -0,0 +1,165 @@ +From 648d4f032006095ded8b047c533f594f009b1180 Mon Sep 17 00:00:00 2001 +From: Daniel Bomar +Date: Thu, 20 Jun 2024 15:26:54 +0200 +Subject: [PATCH] input: Implement an API for trigger rumble motors + +This patchset extends the force feedback API to allow userspace to control +the force feedback motors underneath the triggers in some gamepads. + +Patches 3 and 4 of this patchset implement this API in the xpad and +hid-microsoft drivers for the Xbox One controller over USB and bluetooth +respectively. + +--- + drivers/hid/hid-microsoft.c | 14 ++++++++++++-- + drivers/input/ff-memless.c | 8 +++++++- + drivers/input/joystick/xpad.c | 8 ++++++-- + include/uapi/linux/input.h | 4 ++++ + 4 files changed, 29 insertions(+), 5 deletions(-) + +diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c +index 9345e2bfd56e..2020e897be4c 100644 +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -32,6 +32,8 @@ struct ms_data { + unsigned long quirks; + struct hid_device *hdev; + struct work_struct ff_worker; ++ __u8 trigger_left; ++ __u8 trigger_right; + __u8 strong; + __u8 weak; + void *output_report_dmabuf; +@@ -40,9 +42,13 @@ struct ms_data { + #define XB1S_FF_REPORT 3 + #define ENABLE_WEAK BIT(0) + #define ENABLE_STRONG BIT(1) ++#define ENABLE_RIGHT BIT(2) ++#define ENABLE_LEFT BIT(3) + + enum { +- MAGNITUDE_STRONG = 2, ++ MAGNITUDE_LEFT, ++ MAGNITUDE_RIGHT, ++ MAGNITUDE_STRONG, + MAGNITUDE_WEAK, + MAGNITUDE_NUM + }; +@@ -288,7 +294,7 @@ static void ms_ff_worker(struct work_struct *work) + memset(r, 0, sizeof(*r)); + + r->report_id = XB1S_FF_REPORT; +- r->enable = ENABLE_WEAK | ENABLE_STRONG; ++ r->enable = ENABLE_WEAK | ENABLE_STRONG | ENABLE_RIGHT | ENABLE_LEFT; + /* + * Specifying maximum duration and maximum loop count should + * cover maximum duration of a single effect, which is 65536 +@@ -296,6 +302,8 @@ static void ms_ff_worker(struct work_struct *work) + */ + r->duration_10ms = U8_MAX; + r->loop_count = U8_MAX; ++ r->magnitude[MAGNITUDE_LEFT] = ms->trigger_left; ++ r->magnitude[MAGNITUDE_RIGHT] = ms->trigger_right; + r->magnitude[MAGNITUDE_STRONG] = ms->strong; /* left actuator */ + r->magnitude[MAGNITUDE_WEAK] = ms->weak; /* right actuator */ + +@@ -316,6 +324,8 @@ static int ms_play_effect(struct input_dev *dev, void *data, + /* + * Magnitude is 0..100 so scale the 16-bit input here + */ ++ ms->trigger_left = ((u32) effect->u.rumble.trigger_left * 100) / U16_MAX; ++ ms->trigger_right = ((u32) effect->u.rumble.trigger_right * 100) / U16_MAX; + ms->strong = ((u32) effect->u.rumble.strong_magnitude * 100) / U16_MAX; + ms->weak = ((u32) effect->u.rumble.weak_magnitude * 100) / U16_MAX; + +diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c +index c321cdabd214..6b7f916e2b14 100644 +--- a/drivers/input/ff-memless.c ++++ b/drivers/input/ff-memless.c +@@ -242,7 +242,7 @@ static void ml_combine_effects(struct ff_effect *effect, + int gain) + { + struct ff_effect *new = state->effect; +- unsigned int strong, weak, i; ++ unsigned int strong, weak, trigger_left, trigger_right, i; + int x, y; + s16 level; + +@@ -268,6 +268,8 @@ static void ml_combine_effects(struct ff_effect *effect, + case FF_RUMBLE: + strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff; + weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff; ++ trigger_left = (u32)new->u.rumble.trigger_left * gain / 0xffff; ++ trigger_right = (u32)new->u.rumble.trigger_right * gain / 0xffff; + + if (effect->u.rumble.strong_magnitude + strong) + effect->direction = ml_calculate_direction( +@@ -286,6 +288,10 @@ static void ml_combine_effects(struct ff_effect *effect, + 0xffffU); + effect->u.rumble.weak_magnitude = + min(weak + effect->u.rumble.weak_magnitude, 0xffffU); ++ effect->u.rumble.trigger_left = ++ min(trigger_left + effect->u.rumble.trigger_left, 0xffffU); ++ effect->u.rumble.trigger_right = ++ min(trigger_right + effect->u.rumble.trigger_right, 0xffffU); + break; + + case FF_PERIODIC: +diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c +index 6fadaddb2b90..4cba9b42f61d 100644 +--- a/drivers/input/joystick/xpad.c ++++ b/drivers/input/joystick/xpad.c +@@ -1483,6 +1483,8 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect + struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_FF_IDX]; + __u16 strong; + __u16 weak; ++ __u16 trigger_left; ++ __u16 trigger_right; + int retval; + unsigned long flags; + +@@ -1491,6 +1493,8 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect + + strong = effect->u.rumble.strong_magnitude; + weak = effect->u.rumble.weak_magnitude; ++ trigger_left = effect->u.rumble.trigger_left; ++ trigger_right = effect->u.rumble.trigger_right; + + spin_lock_irqsave(&xpad->odata_lock, flags); + +@@ -1543,8 +1547,8 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect + packet->data[3] = GIP_PL_LEN(9); + packet->data[4] = 0x00; + packet->data[5] = GIP_MOTOR_ALL; +- packet->data[6] = 0x00; /* left trigger */ +- packet->data[7] = 0x00; /* right trigger */ ++ packet->data[6] = trigger_left / 512; /* left trigger */ ++ packet->data[7] = trigger_right / 512; /* right trigger */ + packet->data[8] = strong / 512; /* left actuator */ + packet->data[9] = weak / 512; /* right actuator */ + packet->data[10] = 0xFF; /* on period */ +diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h +index 2557eb7b0561..9f35b97720e3 100644 +--- a/include/uapi/linux/input.h ++++ b/include/uapi/linux/input.h +@@ -419,6 +419,8 @@ struct ff_periodic_effect { + * struct ff_rumble_effect - defines parameters of a periodic force-feedback effect + * @strong_magnitude: magnitude of the heavy motor + * @weak_magnitude: magnitude of the light one ++ * @trigger_left: magnitude of the motor behind the left trigger ++ * @trigger_right: magnitude of the motor behind the right trigger + * + * Some rumble pads have two motors of different weight. Strong_magnitude + * represents the magnitude of the vibration generated by the heavy one. +@@ -426,6 +428,8 @@ struct ff_periodic_effect { + struct ff_rumble_effect { + __u16 strong_magnitude; + __u16 weak_magnitude; ++ __u16 trigger_left; ++ __u16 trigger_right; + }; + + /** +-- +2.45.2 +