scarburato / hid-tminit

Linux driver to properly initialize some Thrustmaster Wheels
GNU General Public License v2.0
30 stars 8 forks source link

Status for T150/T150 pro support since kernel > 5.13 #17

Closed albfan closed 1 year ago

albfan commented 1 year ago

Checking kernel sources, since version 5.13 this seems to be integrated on kernel.

https://elixir.bootlin.com/linux/v5.13/source/drivers/hid/hid-thrustmaster.c https://patchwork.kernel.org/project/linux-input/patch/20210131090045.10636-1-dario.pagani.146@gmail.com/#24038275

Anyway something still is not working for T150 pro.

I check with this python script:

#!/usr/bin/python3
import usb.core

tm_wheel_infos = {
        0x0306: 0x0006, # T150RS
        0x0206: 0x0005, # T300RS
        0x0204: 0x0005, # T300 Ferrari Alcantara
        0x0002: 0x0002, # T500RS
        0x0407: 0x0001, # TMX
        }

def main():
    # Find the generic wheel
    dev = usb.core.find(idVendor = 0x44f, idProduct = 0xb677)
    if dev is None:
        raise ValueError('Device not found')

    # Fetch the model number (along with some other cruft we don't know the
    # meaning of)
    dev_info = dev.ctrl_transfer(0xc1, 73, 0, 0, 0x10)
    if not dev_info:
        raise ValueError('Device did not respond')

    # Calculate the equivalent values as the ones used as keys in
    # tm_wheel_infos
    model_num = dev_info[6] + dev_info[7]*256
    print("dev_info:", dev_info)
    print("dev_info[6]:", dev_info[6])
    print("dev_info[7]:", dev_info[7])
    print("model_num:", model_num)
    print("hex model_num:", hex(model_num))

if __name__ == '__main__':
    main()

and this is the output I get:

$ sudo ./print-model.py 
dev_info: array('B', [73, 0, 33, 0, 0, 0, 6, 3, 0, 0, 0, 0, 0, 0, 0, 0])
dev_info[6]: 6
dev_info[7]: 3
model_num: 774
hex model_num: 0x306

all looks correct, but still hid_thrustmaster do not change from 044f:b677 to 044f:b65e.

Is that usb product needed to run correctly your t150 driver?

Kimplul commented 1 year ago

Checking kernel sources, since version 5.13 this seems to be integrated on kernel.

A slightly older version, yes.

from 044f:b677 to 044f:b65e

Sorry, but is this what you mean? b65e is not an ID hid-tminit handles, and b677 seems to be the ID we would like to end up with. Have you checked which mode your wheel is in, PS3 or PS4?

albfan commented 1 year ago

Yes, I check t150 driver looks for that:

https://github.com/scarburato/t150_driver/blob/master/hid-t150/hid-t150.h#L4

I just review tmdrv again and code sent is different:

Here:

https://github.com/scarburato/hid-tminit/blob/master/hid-tminit.c#L73

https://github.com/scarburato/hid-tminit/blob/master/hid-tminit.c#L140

tmdrv:

https://gitlab.com/her0/tmdrv/-/blob/t150/tmdrv_devices/thrustmaster_t150.py#L5

So tmdrv sends:

0x41 83 0x0002 0x0000 0

while this sends:

0x41 83 0x0006 0x0000 0

and hid_thrustmaster sends

https://elixir.bootlin.com/linux/v5.13/source/drivers/hid/hid-thrustmaster.c#L66

0x41 83 0x0006 0x0000 0

maybe that 0x0002 instead of 0x0006 makes the difference.

Is there any documentation about this codes? what changes to use one code or the other? only difference I see is this product version b677, b65e

A slightly older version, yes.

Do that means hid_thrustmaster lacks some needed setup? in that case what is missing?

We recently remove this module from hid_t150 as not needed anymore (for kernel > 5.13)

https://github.com/scarburato/t150_driver/commit/165d0601e11576186c9416c40144927549ef804d

And all seems to work as expected.

Kimplul commented 1 year ago

Yes, I check t150 driver looks for that: [...]

Yes, the T150 USB product ID is b677, but in your initial comment you mention that you expect hid-tminit to initialize the wheel from b677 to b65e, which I don't fully understand. hid-tminit takes devices that show up as b65d and initializes them to whatever the actual device ID should be, in the T150's case b677, so seems like you've mixed up 'from' and 'to'. Just wanted to check if this was what you actually meant, or just a typo.

Secondly, b65e is not the same ID as b65d, and hid-tminit only accepts wheels with ID b65d. See

https://github.com/scarburato/hid-tminit/blob/9375f6c7d83af5dd6c8b8fe30351d0f36043b20a/hid-tminit.c#L385

Is b65e also a typo, or does the T150 Pro show up as b65e? Have you checked which mode the wheel is in, i.e. PS3 or PS4?

Do that means hid_thrustmaster lacks some needed setup? in that case what is missing?

Not setup per se, but at some point we realized that what the thought was a single wheel ID turned out to likely be a wheel ID and an attachment ID, see https://github.com/scarburato/hid-tminit/pull/9. Only the wheel ID is meaningful to us, at least currently, and in the older version an unknown attachment ID would be interpreted as an unknown wheel.

Not sure if that's what's going on with the T150 Pro, did you try temporarily installing this repository's version of the driver? You might also need to blacklist the in-kernel version, hid-thrustmaster.

albfan commented 1 year ago

Yes, at beginning I didn't know hid_thrustmaster was already there, so that's why I probably put some confusing product ids.

After clean mods:

$ sudo rmmod hid_thrustmaster
$ sudo rmmod hid_t150
$ cat /etc/modprobe.d/hid_thrustmaster.conf 
blacklist hid_thrustmaster
blacklist hid_t150
blacklist hid_tminit
install hid_tminit /bin/false
install hid_t150 /bin/false

this is vendor/product I see from lsusb:

$ lsusb -d 044f:
Bus 001 Device 019: ID 044f:b65d ThrustMaster, Inc. Thrustmaster FFB Wheel

If I run from this the tmdrv with t150 branch:

https://gitlab.com/her0/tmdrv/-/blob/t150/tmdrv_devices/thrustmaster_t150.py#L5

idProduct = [0xb65d, 0xb65e]
control = [
    {'step':1, 'request_type':0x41, 'request':83, 'value':0x0002, 'index':0x0000, 'data':b''},
]

Probably you already know, but tmdrv idProduct first element is the expected first id b65d and second is the changed one which is b65e

This is what I see after run that command

$ sudo ./tmdrv.py -d thrustmaster_t150
$ lsusb -d 044f:
Bus 001 Device 020: ID 044f:b65e ThrustMaster, Inc. TRS Racing Wheel

NOTE: I disable the jscal tmdrv applies by setting jscal=None

If I disconnect and connect again with hid_thrustmaster enabled:

$ cat /etc/modprobe.d/hid_thrustmaster.conf 
#blacklist hid_thrustmaster
blacklist hid_t150
blacklist hid_tminit
install hid_tminit /bin/false
install hid_t150 /bin/false

I see:

$ lsusb -d 044f:
Bus 001 Device 022: ID 044f:b677 ThrustMaster, Inc. T150 Racing Wheel

the expected b677

in jstest I don't see any difference, both b677 and b65e reports correctly wheel, buttons and pedals.

Just to confirm, I use 0x0006 in tmdrv and it changes to b677. Whatever this difference is, is it documented in any reverse engineering document for thrustmaster devices?

About need for hid_tminit, then is still needed for devices where you can change the wheel right?

albfan commented 1 year ago

I'm unsure if all this can be done just about support T150 (or T150 pro), but just to focus on goal for this issue):

I ask this because I guess the final step is to merge all this into upstream if possible. I want to collaborate on that if makes sense to merge

Kimplul commented 1 year ago

Just to confirm, I use 0x0006 in tmdrv and it changes to b677. Whatever this difference is, is it documented in any reverse engineering document for thrustmaster devices?

I'm not aware of any documentation wrt. b677 vs b65d. From the lsusb output you posted we can see that b65d is apparently some generic wheel, whereas b677 is a T150, and that's the ID the T150 driver expects, as you've pointed out.

If I had to guess, the b65d version wouldn't accept FFB commands. At some point I tried out what happens when you send an incorrect initialization to a wheel, in my case my T300, and I was able to get the T300 to show up in lsusb as a T150. The wheel's buttons and rotation was reported just fine, but the T150 FFB commands wouldn't work. I'm not sure, but I wouldn't be surprised if there's something similar going on here.

Is there any conflict from hid_thrustmaster if present at same time as hid_tminit (or just code is sent twice)

No, the kernel chooses one module and uses that one. The wheel is not initialized twice.

Can hid_tminit check if kernel is higger that 5.13 to stop managing what hid_thrustmaster already manage?

I suppose, but I would assume the easiest route is to just patch the upstream kernel. See https://github.com/scarburato/hid-tminit/issues/11

But just to be clear, does the T150 Pro work with the T150 driver when initialized to b677, force feedback and all?

albfan commented 1 year ago

But just to be clear, does the T150 Pro work with the T150 driver when initialized to b677, force feedback and all?

Yes it works fully using hid_thrustmaster and hid_t150. I get there could be people running kernel less than 5.13, probably typical situation when something needed at some point (hid_tminit) is not needed anymore as is covered upstream.

for hid_t150 we just remove the installation of hid_tminit:

https://github.com/scarburato/t150_driver/commit/165d0601e11576186c9416c40144927549ef804d

https://github.com/scarburato/hid-tminit/issues/11 is exactly the start of what I'm looking for, will try to collect patches missed and start a mail thread somewhere in kernel mailing list.

Lot to collect, but probably worth to try, let's see. I think we can continue there.

Kimplul commented 1 year ago

Here's the previously attempted patch, in case you need it: https://www.spinics.net/lists/linux-input/msg78586.html

albfan commented 1 year ago

Ok, got it now.