From: Vicki Pfau <vi@endrift.com>
To: Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <bentiss@kernel.org>,
linux-input@vger.kernel.org
Cc: Vicki Pfau <vi@endrift.com>,
Yousef Alhouseen <alhouseenyousef@gmail.com>
Subject: [PATCH v3 05/10] HID: steam: Coalesce rumble packets
Date: Thu, 9 Jul 2026 19:00:40 -0700 [thread overview]
Message-ID: <20260710020048.2337655-6-vi@endrift.com> (raw)
In-Reply-To: <20260710020048.2337655-1-vi@endrift.com>
The Steam Deck resets the haptic pattern every time it receives a rumble
packet, leading to weird discontinuities or sometimes cutting out entirely.
Instead of overloading the interface, Steam interally rate-limits sending
these packets, so we should too.
Signed-off-by: Vicki Pfau <vi@endrift.com>
---
drivers/hid/hid-steam.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 6029c055a6cf..553748813901 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -343,6 +343,7 @@ struct steam_device {
bool did_mode_switch;
bool gamepad_mode;
struct work_struct rumble_work;
+ struct delayed_work coalesce_rumble_work;
u16 rumble_left;
u16 rumble_right;
unsigned int sensor_timestamp_us;
@@ -603,10 +604,24 @@ static void steam_haptic_rumble_cb(struct work_struct *work)
{
struct steam_device *steam = container_of(work, struct steam_device,
rumble_work);
+
steam_haptic_rumble(steam, 0, steam->rumble_left,
steam->rumble_right, 2, 0);
}
+static void steam_coalesce_rumble_cb(struct work_struct *work)
+{
+ struct steam_device *steam = container_of(to_delayed_work(work),
+ struct steam_device,
+ coalesce_rumble_work);
+
+ steam_haptic_rumble(steam, 0, steam->rumble_left,
+ steam->rumble_right, 2, 0);
+
+ if (steam->rumble_left || steam->rumble_right)
+ schedule_delayed_work(&steam->coalesce_rumble_work, HZ / 20);
+}
+
#ifdef CONFIG_STEAM_FF
static int steam_play_effect(struct input_dev *dev, void *data,
struct ff_effect *effect)
@@ -616,6 +631,14 @@ static int steam_play_effect(struct input_dev *dev, void *data,
steam->rumble_left = effect->u.rumble.strong_magnitude;
steam->rumble_right = effect->u.rumble.weak_magnitude;
+ /*
+ * The interface gets somewhat overloaded when too many rumble
+ * packets are sent in a row, so Steam throttles it to 20 Hz
+ */
+ if (delayed_work_pending(&steam->coalesce_rumble_work))
+ return 0;
+
+ schedule_delayed_work(&steam->coalesce_rumble_work, HZ / 20);
return schedule_work(&steam->rumble_work);
}
#endif
@@ -1360,6 +1383,7 @@ static int steam_probe(struct hid_device *hdev,
INIT_DELAYED_WORK(&steam->mode_switch, steam_mode_switch_cb);
INIT_LIST_HEAD(&steam->list);
INIT_WORK(&steam->rumble_work, steam_haptic_rumble_cb);
+ INIT_DELAYED_WORK(&steam->coalesce_rumble_work, steam_coalesce_rumble_cb);
steam->sensor_timestamp_us = 0;
if (steam->quirks & STEAM_QUIRK_DECK)
steam->sensor_update_rate_us = 4000;
@@ -1426,6 +1450,7 @@ static int steam_probe(struct hid_device *hdev,
cancel_work_sync(&steam->work_connect);
cancel_delayed_work_sync(&steam->mode_switch);
cancel_work_sync(&steam->rumble_work);
+ cancel_delayed_work_sync(&steam->coalesce_rumble_work);
cancel_work_sync(&steam->unregister_work);
return ret;
@@ -1444,6 +1469,7 @@ static void steam_remove(struct hid_device *hdev)
cancel_delayed_work_sync(&steam->mode_switch);
cancel_work_sync(&steam->work_connect);
cancel_work_sync(&steam->rumble_work);
+ cancel_delayed_work_sync(&steam->coalesce_rumble_work);
cancel_work_sync(&steam->unregister_work);
steam->client_hdev = NULL;
steam->client_opened = 0;
--
2.54.0
next prev parent reply other threads:[~2026-07-10 2:02 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 2:00 [PATCH v3 00/10] HID: steam: General cleanup and improvements Vicki Pfau
2026-07-10 2:00 ` [PATCH v3 01/10] HID: steam: Update documentation Vicki Pfau
2026-07-10 2:00 ` [PATCH v3 02/10] HID: steam: Refactor and clean up report parsing Vicki Pfau
2026-07-10 2:14 ` sashiko-bot
2026-07-10 2:00 ` [PATCH v3 03/10] HID: steam: Rename some constants that got renamed upstream Vicki Pfau
2026-07-10 2:00 ` [PATCH v3 04/10] HID: steam: Add support for sensor events on the Steam Controller (2015) Vicki Pfau
2026-07-10 2:19 ` sashiko-bot
2026-07-10 2:00 ` Vicki Pfau [this message]
2026-07-10 2:19 ` [PATCH v3 05/10] HID: steam: Coalesce rumble packets sashiko-bot
2026-07-10 2:00 ` [PATCH v3 06/10] HID: steam: Fully unregister controller when hidraw is opened Vicki Pfau
2026-07-10 2:17 ` sashiko-bot
2026-07-10 2:00 ` [PATCH v3 07/10] HID: steam: Rearrange teardown sequences Vicki Pfau
2026-07-10 2:18 ` sashiko-bot
2026-07-10 2:00 ` [PATCH v3 08/10] HID: steam: Improve logging and other cleanup Vicki Pfau
2026-07-10 2:17 ` sashiko-bot
2026-07-10 2:00 ` [PATCH v3 09/10] HID: steam: Reject short reads Vicki Pfau
2026-07-10 2:27 ` sashiko-bot
2026-07-10 2:00 ` [PATCH v3 10/10] HID: steam: Retry send/recv reports if stale Vicki Pfau
2026-07-10 2:31 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260710020048.2337655-6-vi@endrift.com \
--to=vi@endrift.com \
--cc=alhouseenyousef@gmail.com \
--cc=bentiss@kernel.org \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.