hid-tmff2: add T500RS passive effects (spring, damper, friction, inertia) - #223
Draft
cazzoo wants to merge 4 commits into
Draft
hid-tmff2: add T500RS passive effects (spring, damper, friction, inertia)#223cazzoo wants to merge 4 commits into
cazzoo wants to merge 4 commits into
Conversation
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>
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. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…tia) Extend the T500RS driver with condition (passive) effects: spring, damper, friction, and inertia. Condition effects are the only family that occupy their own hardware slots: effect n gets slot n+1 with subtype channels derived from its logical id (param_sub = 0x0e + 0x1c*n, env_sub = 0x1c + 0x1c*n), so their 0x01/0x41 packets carry per-slot effect_ids and per-slot STOPs work. Each upload sends the 0x05 conditional packet twice (X axis on the parameter channel, Y axis on the envelope channel; the T500RS is a single-axis wheel). Spring/damper/friction strength is capped by the corresponding module parameters (PARAM_SPRING_LEVEL and friends, advertised via the core params); coefficients are scaled to the device 0-10 range with rounding, center by /20, deadband by /65 (divisor unconfirmed), and saturation from the Linux range. This completes the T500RS feature set; the cumulative tree now matches the full driver source of truth. Protocol reference updated: docs/T500RS_FFBEFFECTS.md gains the 0x05 condition section and condition rows in the slot/subtype and conversion sections. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
cazzoo
force-pushed
the
t500rs/passive-effects
branch
from
September 10, 2026 20:43
fe67a1e to
f4eed4e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on the periodic/ramp PR (T500RS stack, after #221).
Extends the T500RS driver with condition (passive) effects: spring, damper, friction, and inertia.
Condition effects are the only family that occupy their own hardware slots: effect n gets slot n+1 with subtype channels derived from its logical id (param_sub = 0x0e + 0x1cn, env_sub = 0x1c + 0x1cn), so their 0x01/0x41 packets carry per-slot effect_ids and per-slot STOPs work. Each upload sends the 0x05 conditional packet twice (X axis on the parameter channel, Y axis on the envelope channel; the T500RS is a single-axis wheel).
Spring/damper/friction strength is capped by the corresponding module params (PARAM_SPRING_LEVEL and friends, advertised via the core params); coefficients are scaled to the device 0-10 range with rounding, center by /20, deadband by /65 (divisor unconfirmed), and saturation from the Linux range.
This completes the T500RS feature set.
Protocol reference updated: docs/T500RS_FFBEFFECTS.md gains the 0x05 condition section and condition rows in the slot/subtype and conversion sections.