The online racing simulator
I might have figured out the FF issue. In fallback mode the permissions for event10 - which is DFP on my box are:

crw-rw----+ 1 root root 13, 74 26.*kvě 23.45 event10

but in native mode it's:


crw------- 1 root root 13, 74 26.*kvě 23.45 event10

I'm honestly not sure what the "+" means, but if I force permissions to 777, I get FF working in VDrift, but not in LFS...
This sounds strange... I have the following rules setup for udev which seems to work fine in all cases (user has to be member of "games" group):
# Driving Force or fallback wheel for DFP/G25/G27...
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c294", SYMLINK+="input/DF"
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c294", MODE="0664", GROUP="games"
# MOMO Force
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c295", SYMLINK+="input/MF"
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c295", MODE="0664", GROUP="games"
# Driving Force Pro
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c298", SYMLINK+="input/DFP"
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c298", MODE="0664", GROUP="games"
# G25
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c299", SYMLINK+="input/G25"
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c299", MODE="0664", GROUP="games"
# Driving Force GT
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c29A", SYMLINK+="input/DFGT"
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c29A", MODE="0664", GROUP="games"
# G27
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c29B", SYMLINK+="input/G27"
KERNEL=="event[0-9]*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c29B", MODE="0664", GROUP="games"

This also gives me a correct symlink showing which wheel is connected/recognized

Maybe this helps?

Edit: This is how it looks with a DFP in native mode:


[michael@blackbox ~]$ ls -la /dev/input/
insgesamt 0
drwxr-xr-x 4 root root 320 27. Mai 00:12 .
drwxr-xr-x 16 root root 5740 27. Mai 00:12 ..
drwxr-xr-x 2 root root 220 27. Mai 00:12 by-id
drwxr-xr-x 2 root root 200 27. Mai 00:12 by-path
lrwxrwxrwx 1 root root 6 27. Mai 00:12 DFP -> event7
crw-r----- 1 root root 13, 64 26. Mai 17:16 event0
crw-r----- 1 root root 13, 65 26. Mai 17:16 event1
crw-r----- 1 root root 13, 66 26. Mai 17:16 event2
crw-r----- 1 root root 13, 67 26. Mai 17:16 event3
crw-r----- 1 root root 13, 68 26. Mai 17:16 event4
crw-r----- 1 root root 13, 69 26. Mai 17:16 event5
crw-r----- 1 root root 13, 70 26. Mai 17:16 event6
crw-rw-r--+ 1 root games 13, 71 27. Mai 00:12 event7
crw-rw-r--+ 1 root root 13, 0 27. Mai 00:12 js0
crw-r----- 1 root root 13, 63 26. Mai 17:16 mice
crw-r----- 1 root root 13, 32 26. Mai 17:16 mouse0

That's odd... I added the udev rules and my /dev/input looks like this

total 0
drwxr-xr-x 4 root root 420 27.*kvě 00.31 .
drwxr-xr-x 16 root root 6180 27.*kvě 00.31 ..
drwxr-xr-x 2 root root 120 27.*kvě 00.31 by-id
drwxr-xr-x 2 root root 200 27.*kvě 00.31 by-path
lrwxrwxrwx 1 root root 7 27.*kvě 00.31 DFP -> event10
crw-r----- 1 root root 13, 64 26.*kvě 22.48 event0
crw-r----- 1 root root 13, 65 26.*kvě 22.48 event1
crw-rw-r-- 1 root games 13, 74 27.*kvě 00.31 event10
crw-r----- 1 root root 13, 66 26.*kvě 22.48 event2
crw-r----- 1 root root 13, 67 26.*kvě 22.48 event3
crw-r----- 1 root root 13, 68 26.*kvě 22.48 event4
crw-r----- 1 root root 13, 69 26.*kvě 22.48 event5
crw-r----- 1 root root 13, 70 26.*kvě 22.48 event6
crw-r----- 1 root root 13, 71 26.*kvě 22.48 event7
crw-r----- 1 root root 13, 72 26.*kvě 22.48 event8
crw-r----- 1 root root 13, 73 26.*kvě 22.51 event9
crw-r--r-- 1 root root 13, 0 27.*kvě 00.31 js0
crw-r----- 1 root root 13, 63 26.*kvě 22.48 mice
crw-r----- 1 root root 13, 32 26.*kvě 22.48 mouse0
crw-r----- 1 root root 13, 33 26.*kvě 22.48 mouse1
crw-r----- 1 root root 13, 34 26.*kvě 22.51 mouse2

Games like VDrift that access the correct input handle directly work OK, but LFS doesn't, so it's most likely a WINE issue. I wonder what the "+" sign indicates. I get that "+" at js0 and event10 when my DFP is in fallback mode, switching to native mode makes it disappear...

Apart from a load of other info I get this in WINE debugging log:
"warn:dinput:joydev_enum_deviceA force feedback not supported"

EDIT: The trailing "+" indicates ACL rules being used. As long as the permissions are set correctly (they are, VDrift works OK), there's no need to be concerned about it.
It's not like I resolved the issue, but at least I think I know what the problem is.

When everything works OK my WINE output looks like this:

...
warn:dinput:find_joydevs Failed to open "/dev/input/event7": 13 Permission denied
warn:dinput:find_joydevs Failed to open "/dev/input/event8": 13 Permission denied
warn:dinput:find_joydevs Failed to open "/dev/input/event9": 13 Permission denied
trace:dinput:find_joydevs Found a joystick on /dev/input/event10: Logitech Logitech Driving Force ({9e573eda-7734-11d2-8d4a-23903fb6bdf7})
trace:dinput:find_joydevs ... with force feedback
trace:dinput:find_joydevs ... with axis 0: cur=512, min=0, max=1023, fuzz=3, flat=63
trace:dinput:find_joydevs ... with axis 1: cur=127, min=0, max=255, fuzz=0, flat=15
trace:dinput:find_joydevs ... with axis 16: cur=0, min=-1, max=1, fuzz=0, flat=0
trace:dinput:find_joydevs ... with axis 17: cur=0, min=-1, max=1, fuzz=0, flat=0
warn:dinput:find_joydevs Failed to open "/dev/input/event11": 2 No such file or directory
warn:dinput:find_joydevs Failed to open "/dev/input/event12": 2 No such file or directory
warn:dinput:find_joydevs Failed to open "/dev/input/event13": 2 No such file or directory
warn:dinput:find_joydevs Failed to open "/dev/input/event14": 2 No such file or directory
...

WINE reads the /dev/input/event* and checks for FF support. When I switch DFP to native mode, I get following:

...
warn:dinput:find_joydevs Failed to open "/dev/input/event7": 13 Permission denied
warn:dinput:find_joydevs Failed to open "/dev/input/event8": 13 Permission denied
warn:dinput:find_joydevs Failed to open "/dev/input/event9": 13 Permission denied

*** /dev/input/event10 is MISSING here, which suggests WINE opened it but didn't get data it needed from it ***

warn:dinput:find_joydevs Failed to open "/dev/input/event11": 2 No such file or directory
warn:dinput:find_joydevs Failed to open "/dev/input/event12": 2 No such file or directory
warn:dinput:find_joydevs Failed to open "/dev/input/event13": 2 No such file or directory
warn:dinput:find_joydevs Failed to open "/dev/input/event14": 2 No such file or directory

...

trace:dinput:IDirectInputAImpl_EnumDevices - checking device 3 ('Wine Linux joystick driver')
trace:dinput:find_joystick_devices Found a joystick on /dev/input/js0: Logitech Logitech Driving Force Pro
with 5 axes and 14 buttons
trace:dinput:joydev_enum_deviceA Enumerating the linux Joystick device: /dev/input/js0 (Logitech Logitech Driving Force Pro)

The /dev/input/js* doesn't have any FF interface, so if WINE cannot use event* for FF, it just won't work.
The question is why FF works in the fallback mode but not it the native mode for me...
So, to rule out/confirm the obvious: Does FF work in native mode without my patch?
I think I fixed the problem. I modified the descriptor a bit so apart from few minor tweaks it now reports the "spacer" as eight 1-bit fields instead of one 8-bit wide fake hat switch. I also changed the usage of the throttle field to axis Y instead of Z and that got the FF working in WINE. I suppose WINE expects that all joysticks have X and Y axes and that's how it's reported in Windows too.

The whole descriptor looks like this now:

static __u8 dfp_rdesc_fixed[] = {
0x05, 0x01, /* Usage Page (Desktop), */
0x09, 0x04, /* Usage (Joystik), */
0xA1, 0x01, /* Collection (Application), */
0xA1, 0x02, /* Collection (Logical), */
0x95, 0x01, /* Report Count (1), */
0x75, 0x0E, /* Report Size (14), */
0x14, /* Logical Minimum (0), */
0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
0x34, /* Physical Minimum (0), */
0x46, 0xFF, 0x3F, /* Physical Maximum (16383), */
0x09, 0x30, /* Usage (X), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x0E, /* Report Count (14), */
0x75, 0x01, /* Report Size (1), */
0x25, 0x01, /* Logical Maximum (1), */
0x45, 0x01, /* Physical Maximum (1), */
0x05, 0x09, /* Usage Page (Button), */
0x19, 0x01, /* Usage Minimum (01h), */
0x29, 0x0E, /* Usage Maximum (0Eh), */
0x81, 0x02, /* Input (Variable), */
0x05, 0x01, /* Usage Page (Desktop), */
0x95, 0x01, /* Report Count (1), */
0x75, 0x04, /* Report Size (4), */
0x25, 0x07, /* Logical Maximum (7), */
0x46, 0x3B, 0x01, /* Physical Maximum (315), */
0x65, 0x14, /* Unit (Degrees), */
0x09, 0x39, /* Usage (Hat Switch), */
0x81, 0x42, /* Input (Variable), */
0x75, 0x01, /* Report Size (1), */
0x95, 0x08, /* Report Count (8), */
0x65, 0x00, /* Unit, */
0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
0x25, 0x01, /* Logical Maximum (1), */
0x45, 0x01, /* Physical Maximum (1), */
0x09, 0x01, /* Usage (01h), */
0x81, 0x02, /* Input (Variable), */
0x05, 0x01, /* Usage Page (Desktop), */
0x95, 0x01, /* Report Count (1), */
0x75, 0x08, /* Report Size (8), */
0x14, /* Logical Minimum (0), */
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
0x34, /* Physical Minimum (0), */
0x46, 0xFF, 0x00, /* Physical Maximum (255), */
0x09, 0x31, /* Usage (Y), */
0x81, 0x02, /* Input (Variable), */
0x95, 0x01, /* Report Count (1), */
0x75, 0x08, /* Report Size (8), */
0x14, /* Logical Minimum (0), */
0x26, 0xFF, 0x00, /* Logical Maximum (255), */
0x34, /* Physical Minimum (0), */
0x46, 0xFF, 0x00, /* Physical Maximum (255), */
0x09, 0x35, /* Usage (Rz), */
0x81, 0x02, /* Input (Variable), */
0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
0x95, 0x01, /* Report Count (1), */
0x75, 0x08, /* Report Size (8), */
0x09, 0x00, /* Usage (00h), */
0x81, 0x02, /* Input (Variable), */
0xC0, /* End Collection, */
0xA1, 0x02, /* Collection (Logical), */
0x09, 0x02, /* Usage (02h), */
0x95, 0x07, /* Report Count (7), */
0x91, 0x02, /* Output (Variable), */
0xC0, /* End Collection, */
0xC0 /* End Collection */
};

I guess the most important work is done on this ground, great job!
Good find!
Last thing: Should we rename then the "Rz" to just "z"? So we have X,Y,Z axes instead of X,Y,Rz?

@Slim_one: Did you already submit the patch with the NOGET flag? If not, i can include it then with these changes as one patch. I think i will submit it as soon as the last question above is cleared...
IIRC Windows driver reports throttle as Y and brake as Rz, so as long as it works I guess we should stay consistent with the official behavior...
Quote from MikeB :Good find!
Last thing: Should we rename then the "Rz" to just "z"? So we have X,Y,Z axes instead of X,Y,Rz?

@Slim_one: Did you already submit the patch with the NOGET flag? If not, i can include it then with these changes as one patch. I think i will submit it as soon as the last question above is cleared...

no, i didn't.

btw, is the complete bytearray needed? Can't this be reduced to the changed values, like its done in function lg_report_fixup?
Quote from slim.one :no, i didn't.

btw, is the complete bytearray needed? Can't this be reduced to the changed values, like its done in function lg_report_fixup?

Not really - I know that this does not really fit with the other parts of the report_fixup, but as the new descriptor is much longer than the original one, patching it would be difficult.
I'll post it to linux-input and see whats their opinion. There are other hid-drivers which also do a complete replacement and have been accepted...
After some discussion on linux-input mailinglist here is a smaller patch (less comments and optimized descriptor)

@MadCatX: As my DFP buttons are broken could you please check this patch also to see if all buttons work? Then i will submit it again to linux-input...
Attached files
DFP_new.patch.txt - 4.7 KB - 328 views
Tried the updated patch and it seems to work fine. All buttons, axes, hat switch and FF are perfect, so I guess it's ready to challenge HID maintainers' high standards...
Quote from MadCatX :Tried the updated patch and it seems to work fine. All buttons, axes, hat switch and FF are perfect, so I guess it's ready to challenge HID maintainers' high standards...

Thanks I'll submit new patch tonight (if i don't have to stay too long at work )
Great... I'll see if I can push some updates for the LTWC. I'd like to rework the range setting function to get rid of the really convoluted "algorithm" it uses now.

It's also necessary to run "jscal" and calibrate the device every time the wheel is switched to the native mode. Unless it's done, there are pretty nasty deadzones on all axes and pedal axes are inverted. Do you observe this problem with G2x too? I'm thinking about calling "jscal" from within LTWC and set the corrections manually. Unless someone has a seriously borked wheel, I don't see a problem with using a "default" set of corrections. If it's needed for more devices than DFP, it might be a good idea to have an extra function for that...

EDIT: Patch1 incoming
Attached files
0001-Improved-get_range_cmd2-function.-Setting-range-from.patch.txt - 3.2 KB - 499 views
Okay, new patch submitted - *Crossing fingers* :-)

Quote from MadCatX :
It's also necessary to run "jscal" and calibrate the device every time the wheel is switched to the native mode. Unless it's done, there are pretty nasty deadzones on all axes and pedal axes are inverted. Do you observe this problem with G2x too? I'm thinking about calling "jscal" from within LTWC and set the corrections manually. Unless someone has a seriously borked wheel, I don't see a problem with using a "default" set of corrections. If it's needed for more devices than DFP, it might be a good idea to have an extra function for that...

This is an interesting question. Here i have a quite strange situation - Each axis is visible twice in LFS - One has a big deadzone, the other one behaves perfectly.

slightlymoved.png: shows that the upper axis already moved, while the lower one still sticks to zero.
quartermoved.png: The second axis starts moving and catches up with the first one a few degrees later.
allmostfullmoved.png: The upper axis is still not near the end, but the lower axis is "accelerated" somehow to already be close to maximum.

This happens with DFP and G25, both in native and restricted mode. I did not bother with this topic yet as i can always select the "upper" axes which show absolutely no deadzone.
Do you also have these double axes?

Quote from MadCatX :EDIT: Patch1 incoming

Applied and working fine Only thing is the case of rotation < 200 degrees is not handled. And the math still looks frightening There must be some simpler way to calculate the correct values
Attached images
slightlymoved.png
quartermoved.png
allmostfullmoved.png
I checked the axes problem and I get same results here - I just didn't notice before. It's a WINE issue which accepts gaming devices both as eventX and jsX. It however doesn't bother checking if jsX and eventX represent the same device. The jsX interface needs calibration, eventX works out of the box.

As for the range setting, I guess the 200 - 900 range algorithm is as simple as it can get accoring to my USBLyzer captures, not sure what to do with the <199 range, whatever strange maths is behind it, it eludes me
Quote from MadCatX :
As for the range setting, I guess the 200 - 900 range algorithm is as simple as it can get accoring to my USBLyzer captures, not sure what to do with the <199 range, whatever strange maths is behind it, it eludes me

I pushed a new version just now including your changes. Additionally some small refactoring and introduced per-wheel setting for minimum/maximum rotation range (DFP being set to min 200 now ).
And added report descriptors for both DFP and G25 just for reference...
I am still looking to find a way to reliable auto-detect the connected wheel. Current idea is to go for the usb device revision number.

Problem is that basically all usb device properties change between restricted and native mode, but it seems the revision stays the same (and is different at least between DFP and G25...)

DFP always reports revision "1106"
G25 always reports revision "1222"

@Slim_one: Could you check the revision your G27 is reporting in restricted and native mode?
Command would be:
udevadm info --query=all --name=/dev/input/<according event>

Please look for the line "E: ID_REVISION=<some number>".

If this turns out to be working we could soon get nice integration with udev, like slim_one suggested already: Udev knows adress and the revision of connected device, so with only one rule you could set any supported wheel to native mode automatically.
G27 uninitialized:
P: /devices/pci0000:00/0000:00:02.0/usb2/2-5/2-5:1.0/input/input11/event2
N: input/event2
S: input/by-id/usb-046d_G27_Racing_Wheel-event-joystick
S: input/by-path/pci-0000:00:02.0-usb-0:5:1.0-event-joystick
E: UDEV_LOG=3
E: DEVPATH=/devices/pci0000:00/0000:00:02.0/usb2/2-5/2-5:1.0/input/input11/event2
E: MAJOR=13
E: MINOR=66
E: DEVNAME=/dev/input/event2
E: SUBSYSTEM=input
E: ID_INPUT=1
E: ID_INPUT_JOYSTICK=1
E: ID_VENDOR=046d
E: ID_VENDOR_ENC=046d
E: ID_VENDOR_ID=046d
E: ID_MODEL=G27_Racing_Wheel
E: ID_MODEL_ENC=G27\x20Racing\x20Wheel
E: ID_MODEL_ID=c294
E: ID_REVISION=1238
E: ID_SERIAL=046d_G27_Racing_Wheel
E: ID_TYPE=hid
E: ID_BUS=usb
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usbhid
E: ID_PATH=pci-0000:00:02.0-usb-0:5:1.0
E: DEVLINKS=/dev/input/by-id/usb-046d_G27_Racing_Wheel-event-joystick /dev/input/by-path/pci-0000:00:02.0-usb-0:5:1.0-event-joystick
E: TAGS=:udev-acl:

and initialized:
P: /devices/pci0000:00/0000:00:02.0/usb2/2-5/2-5:1.0/input/input10/event2
N: input/event2
S: input/by-id/usb-046d_G27_Racing_Wheel-event-joystick
S: input/by-path/pci-0000:00:02.0-usb-0:5:1.0-event-joystick
S: input/G27event
E: UDEV_LOG=3
E: DEVPATH=/devices/pci0000:00/0000:00:02.0/usb2/2-5/2-5:1.0/input/input10/event2
E: MAJOR=13
E: MINOR=66
E: DEVNAME=/dev/input/event2
E: SUBSYSTEM=input
E: ID_INPUT=1
E: ID_INPUT_JOYSTICK=1
E: ID_VENDOR=046d
E: ID_VENDOR_ENC=046d
E: ID_VENDOR_ID=046d
E: ID_MODEL=G27_Racing_Wheel
E: ID_MODEL_ENC=G27\x20Racing\x20Wheel
E: ID_MODEL_ID=c29b
E: ID_REVISION=1238
E: ID_SERIAL=046d_G27_Racing_Wheel
E: ID_TYPE=hid
E: ID_BUS=usb
E: ID_USB_INTERFACES=:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=usbhid
E: ID_PATH=pci-0000:00:02.0-usb-0:5:1.0
E: DEVLINKS=/dev/input/by-id/usb-046d_G27_Racing_Wheel-event-joystick /dev/input/by-path/pci-0000:00:02.0-usb-0:5:1.0-event-joystick /dev/input/G27event
E: TAGS=:udev-acl:

Is there any chance for Logitech Formula EX?
Absolutely, if you have the device, can you help us with testing? At least its PID would be helpful.
Quote from wolfshark :Is there any chance for Logitech Formula EX?

as i understand it, Driving Force EX, Formula Force EX and Driving Force RX all have the same id as a normal Driving Force, but different revisions (DF EX has rev 2000, FF EX 2100 and DF RX 2200 according to the Logitech drivers .inf), so basically it should work right now out of the box - at least the kernel support has been included some major versions ago. I remember having the problem with no separate axis for gas/brakes with my old Formula Force GP, but FF should work fine.

Dumb question: Did you test it already? If yes, what works, what does not?
Probably the same issue with combined axes is existing there. I got now a Momo racing at hand - Same situation like with the DFP. The report descriptor needs to be updated to make the separate axes available to the system.

Problem i see here is that so many wheels are using the same IDs (some with different revision, some not, and also count in the various wheels in "fallback" mode) so i do not think we can just replac the report descriptor like we did for DFP. At least this should be tested then with ALL affected wheels.

PS: The patch for DFP is now accepted and will be part of linux 3.0

PPS: I'll be on vacation the next two weeks without internet
Yes i have the Formula Force EX
I have a box standard Mint 9
My wheel is working, but FF isn't, it has center spring and combined pedals.
Compiled ltwheelconf - --autocenter 0 is not working, so i tried --altautocenter on /dev/input/js0
Quote :set auto-center: Invalid argument

tried /dev/input/by-id/usb-Logitech_Logitech_Formula_Force_RX-event-joystick
- it seems to set something, but the wheel still has center spring.
Tried event0 but still nothing.

I will provide any info you want - just give me the commands.

Thre are some signs of force feedback in lfs - but it's very very buggy:
The wheel i constantly turned slightly left. When you turn left the wheel is light - when you turn right - it's heavy. When i drift i feel the reall FFB a bit but the center spring (which as i said is not really centered in game, but fine out of the game) is dominating.
which wine-version do you use? and which kernel? could you paste the output of 'wine --version' and 'uname -r', please?

LTWheelConf - Setup Logitech DFP/G25/G27 on linux
(269 posts, started )
FGED GREDG RDFGDR GSFDG