Skip to content

hid-tmff2: add T500RS periodic and ramp effects - #222

Draft
cazzoo wants to merge 3 commits into
Kimplul:masterfrom
cazzoo:t500rs/periodic-ramp
Draft

hid-tmff2: add T500RS periodic and ramp effects#222
cazzoo wants to merge 3 commits into
Kimplul:masterfrom
cazzoo:t500rs/periodic-ramp

Conversation

@cazzoo

@cazzoo cazzoo commented Sep 10, 2026

Copy link
Copy Markdown

Stacked on #221 (T500RS constant force).

Extends the T500RS driver with periodic (sine, square, triangle, saw) and ramp effects.

The firmware has no periodic waveform engine, so these effects are synthesized host-side: the first periodic/ramp upload declares slot 0 as a sine (0x22) MAIN with the constant-force channels, and a software synthesis engine computes the waveform, applies attack/fade envelopes in software, sums in any playing constant force, and streams the combined signed level as 0x04 0x0e packets from a delayed workqueue. Per-slot periodic parameter declarations (0x04 with code != 0x0e) are known to wedge the firmware and are never sent.

Periodic parameters (magnitude/offset/phase/period, ramp levels) never travel the wire; FF_PERIODIC advertising also re-enables FF_RUMBLE via the parent framework.

Protocol reference updated: docs/T500RS_FFBEFFECTS.md gains the 0x04 level-stream section; condition effects are still unsupported at this stage.

cazzoo and others added 2 commits September 10, 2026 22:41
The input core invokes the FF gain and autocenter callbacks from
event context, which may run with IRQs disabled, and the sysfs gain
store calls them from process context. Model drivers issue blocking
HID output in these callbacks, which is illegal in atomic context
and races the effect worker on shared transfer buffers.

Route both through the existing effect workqueue instead: mark the
request pending in the device entry and apply it in the worker,
serialized with effect processing.

Gain follows the master x game model (as lg4ff): the sysfs gain
parameter acts as the master gain, the value written through the
input API is the game gain, and the worker sends their product to
the wheel via tmff2_scale_gain(). Both sources only mark the gain
pending; the worker recomputes the product from the live values on
each flush, so a sysfs change takes effect immediately without
having to replay the last in-game request.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add a T500RS driver on top of the core hid-tmff2 framework:

- HID-mode init sequence (0x42 sync, slot STOP sweep, 0x40 autocenter
  teardown, 0x43 gain default); the b65d bootloader -> b65e mode switch
  is handled by hid-tminit.
- Constant force effects only at this stage: hardware slot 0 with fixed
  subtypes (param 0x0e / env 0x1c), 0x03 level updates, mandatory
  zero-envelope 0x02, and a software expiry timer sending per-slot 0x41
  STOPs (the wheel never auto-stops on its own).
- Gain and range via the core parameters; autocentering routed through
  the core workqueue (T500RS callbacks do blocking HID I/O and must not
  run from atomic context).
- Protocol reference: docs/T500RS_FFBEFFECTS.md (constant force
  sections). The shared docs/FFBEFFECTS.md is renamed to
  docs/T300RS_FFBEFFECTS.md since it documents the T300RS protocol.
- udev rule for the SteamDeck variant.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@cazzoo
cazzoo force-pushed the t500rs/periodic-ramp branch from 7a70fb6 to faa85e5 Compare September 10, 2026 20:43
Extend the T500RS driver with periodic (sine, square, triangle, saw) and
ramp effects.

The firmware has no periodic waveform engine, so these effects are
synthesized host-side: the first periodic/ramp upload declares slot 0 as
a sine (0x22) MAIN with the constant-force channels, and a software
synthesis engine computes the waveform, applies attack/fade envelopes in
software, sums in any playing constant force, and streams the combined
signed level as 0x04 0x0e packets from a delayed workqueue. Per-slot
periodic parameter declarations (0x04 with code != 0x0e) are known to
wedge the firmware and are never sent.

Periodic parameters (magnitude/offset/phase/period, ramp levels) never
travel the wire; FF_PERIODIC advertising also re-enables FF_RUMBLE via
the parent framework.

Protocol reference updated: docs/T500RS_FFBEFFECTS.md gains the 0x04
level-stream section; condition effects are still unsupported at this
stage.
@cazzoo
cazzoo force-pushed the t500rs/periodic-ramp branch from faa85e5 to 13b9833 Compare September 10, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant