Thrustmaster TS-PC Wheel Setup in Omarchy

How to get a Thrustmaster TS-PC (and TS-XW / T300-family) force-feedback wheel working on Omarchy using the hid-tmff2 kernel driver.

Overview

The stock kernel's hid_thrustmaster driver recognizes the wheel but provides no force feedback. The open-source hid-tmff2 driver (Kimplul/hid-tmff2) replaces it with full FFB support. TS-PC support is labelled experimental upstream, but works for FFB, range, gain and autocentering.

How it works

  1. The wheel enumerates as 044f:b65d ("Thrustmaster FFB Wheel").
  2. hid-tminit-new binds, sends the init sequence, and the wheel re-enumerates as 044f:b689 ("Thrustmaster TS-PC Racer").
  3. hid-tmff-new binds to the re-enumerated device and provides force feedback.

Requirements

  • Omarchy (Arch-based), with yay available.
  • The wheel's firmware must be v31 or newer — otherwise the driver will not work and the firmware must be updated from Windows with Thrustmaster's tools.

Install

1. Install dependencies

sudo pacman -S linux-headers dkms joyutils
  • linux-headers must match the running kernel exactly (same pacman -Q linux version).
  • joyutils provides jstest for verification.

2. Install the DKMS module from AUR

yay -S hid-tmff2-dkms-git

What the package does:

  • Installs DKMS sources to /usr/src/hid-tmff2-r<ver>/.
  • Installs a modprobe blacklist at /usr/lib/modprobe.d/hid-tmff2-dkms-git.conf that blacklists the stock hid_thrustmaster driver.
  • On install/upgrade, rmmods hid_thrustmaster.
  • Builds three modules: hid-tminit-new, usb-tminit-new, hid-tmff-new.

3. Install Oversteer (tuning GUI)

yay -S oversteer

Oversteer is used to set gain, range, and effects (spring/damper/friction).

Verify the wheel is bound

After a reboot (or replug), the wheel should appear as:

lsusb                                   # -> 044f:b689 Thrustmaster TS-PC Racer
lsmod | grep -E "tminit|tmff"           # -> hid_tmff_new, hid_tminit_new loaded
readlink /sys/bus/hid/devices/0003:044F:B689.*/driver   # -> .../drivers/tmff2
cat /sys/class/input/input*/capabilities/ff             # -> non-zero = FFB capable
jstest /dev/input/js0                   # -> 6 axes, 13 buttons

If nothing binds after a reboot, hid-tminit-new can be loaded manually:

sudo modprobe hid-tminit-new

Making Oversteer work with the TS-PC

1. Add the TS-PC to Oversteer's supported wheel list

Oversteer 0.8.3 does not know the TS-PC (044f:b689), so it shows a modal "No device available." dialog (which appears as a hang). Add the device ID:

sudo python3 -c "
p1='/usr/lib/python3.14/site-packages/oversteer/wheel_ids.py'
s=open(p1).read()
if 'TM_TS_PC' not in s:
    s=s.replace(\"TM_TSXW = '044f:b692'\", \"TM_TSXW = '044f:b692'\nTM_TS_PC = '044f:b689'\")
open(p1,'w').write(s)
p2='/usr/lib/python3.14/site-packages/oversteer/device_manager.py'
s=open(p2).read()
if 'TM_TS_PC' not in s:
    s=s.replace('wid.TM_TSXW: 1080,', 'wid.TM_TSXW: 1080,\n            wid.TM_TS_PC: 1080,')
open(p2,'w').write(s)
print('TS-PC added to oversteer')
"

The python3.14 path may differ if the system Python version changes.

2. Fix the udev permissions rule

The oversteer package ships /usr/lib/udev/rules.d/99-thrustmaster-wheel-perms.rules, but the packaged version is missing the TS-PC (b689) entry. Without it, the driver's sysfs attributes (range, gain, spring_level, damper_level, friction_level, alternate_modes) stay root-only and Oversteer shows a "you don't have the required permissions to change your wheel settings" dialog on every device selection.

Create /tmp/opencode/99-thrustmaster-wheel-perms.rules:

# Match kernel name of device, rather than ATTRS{idProduct} and ATTRS{idVendor}
# so we can access the range file and leds directory. Set rw access to these
# files for everyone.
# Avoid blanket matching all Thrustmaster devices, as that causes issues with mice,
# keyboards, and other non-wheel devices.

ACTION!="unbind", ACTION!="remove", SUBSYSTEM=="hid", ATTRS{idVendor}=="044f", GOTO="thrustmaster-rules"
GOTO="end"

LABEL="thrustmaster-rules"

DRIVER=="tmff2", GOTO="tmff-new"
DRIVER=="hid-tmff-new", GOTO="tmff-new"
DRIVER=="hid-t150", GOTO="t150"

GOTO="end"

LABEL="tmff-new"

# Thrustmaster T300RS Racing Wheel (USB)
ATTRS{idProduct}=="b66e", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level alternate_modes'"

# Thrustmaster Ferrari F1 Wheel Advanced T300 (USB)
ATTRS{idProduct}=="b66f", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level alternate_modes'"

# Thrustmaster T300RS GT Racing Wheel (USB)
ATTRS{idProduct}=="b66d", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level alternate_modes'"

# Thrustmaster T248 Racing Wheel (USB)
ATTRS{idProduct}=="b696", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level'"

# Thrustmaster TS-XW Racing Wheel (USB)
ATTRS{idProduct}=="b692", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level'"

# Thrustmaster TS-PC Racing Wheel (USB)
ATTRS{idProduct}=="b689", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level alternate_modes'"

# Thrustmaster T500RS Racing Wheel (USB)
ATTRS{idProduct}=="b65e", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level'"

# Thrustmaster TX 458 Italia
ATTRS{idProduct}=="b669", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain spring_level damper_level friction_level'"

GOTO="end"

LABEL="t150"

# Thrustmaster T150 Racing Wheel (USB)
ATTRS{idProduct}=="b677", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain autocenter'"

# Thrustmaster TMX Racing Wheel (USB)
ATTRS{idProduct}=="b67f", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain autocenter'"

LABEL="end"

Install it and re-trigger:

sudo install -m 0644 /tmp/opencode/99-thrustmaster-wheel-perms.rules /usr/lib/udev/rules.d/99-thrustmaster-wheel-perms.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=hid

The sysfs attributes should now be world-writable (-rw-rw-rw-):

ls -l /sys/devices/pci0000:00/0000:00:08.1/0000:2a:00.3/usb3/3-1/3-1:1.0/0003:044F:B689.*/{range,gain,spring_level,damper_level,friction_level,alternate_modes}

Usage

  • Launch oversteer to set gain, range (up to 1080°), spring/damper/friction.
  • Verify with jstest /dev/input/js0.

Troubleshooting

  • No FFB in games but buttons/axes work — add open_mode=0 to force the wheel to be opened immediately (increases idle power draw / fan spin): bash echo 'options hid-tmff-new open_mode=0' | sudo tee /etc/modprobe.d/hid-tmff-new.conf
  • FFB feels off / effects timing — tune the driver timer: bash echo 'options hid-tmff-new timer_msecs=2' | sudo tee /etc/modprobe.d/hid-tmff-new.conf
  • Games under Wine/Proton don't detect the wheel — some games need Thrustmaster's Windows driver files installed into the Wine prefix (see the repo's docs/DRIVER.md); the Linux driver is still required and the Windows driver itself does not work under Wine.
  • Wheel detected but nothing binds after boot — sudo modprobe hid-tminit-new, or confirm the DKMS module is built for the running kernel with dkms status.
  • Steam not seeing input — disable Steam Input for the wheel.

Caveats

  • TS-PC support is experimental in hid-tmff2 (contributed by @BDave95). Expect occasional inaccuracies vs. the Windows driver.
  • The oversteer AUR package is missing the TS-PC device ID and udev rule entry — both are fixed above, but will need re-applying after an oversteer upgrade.
  • DKMS auto-rebuilds the module on kernel updates (requires matching linux-headers).