Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EDTracker USB analog joystick is not detected (as a controller) #8443

Closed
SentineI opened this issue Feb 27, 2022 · 18 comments
Closed

EDTracker USB analog joystick is not detected (as a controller) #8443

SentineI opened this issue Feb 27, 2022 · 18 comments

Comments

@SentineI
Copy link

SentineI commented Feb 27, 2022

Your system information

  • Steam client version (build number or date): Jan 16 2022, at 17:34:49 (non-beta)
  • Steam client version (build number or date): Feb 22 2022, at 00:40:10 (beta)
  • Distribution (e.g. Ubuntu): Ubuntu 20.04 (5.13.0-30-generic # 33~20.04.1-Ubuntu SMP Mon Feb 7 14:25:10 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux)
  • Opted into Steam client beta?: Yes (was No)
  • Have you checked for system updates?: Yes

Please describe your issue in as much detail as possible:

The EDTracker USB analog joystick (*) is not detected as a controller by Steam, even though the "jstest-gtk" program sees it just fine, and Steam does detect a generic USB gamepad I have. (* EDTracker is actually a head tracker, but to a computer it just looks like a USB 3-axis analog joystick, and so should work with anything that supports a USB analog joystick.)

The "jstest-gtk" program sees it is connected & reports:

Arduino LLC EDTracker EDTracker2
Device: /dev/input/sr0
Axes: 3
Buttons: 0

EDIT: I got the above Device wrong, it actually says /dev/input/js0

As far as I can tell (see Additional Information below) Steam is not even trying to treat it as a potential joystick/controller.

Steps for reproducing this issue:

  1. Start the Steam client.
  2. Plug in EDTracker via USB.
  3. Go to Settings > Controller > General Controller Settings > it says "No Controllers Detected".

Additional Information

I checked "~/.steam/debian-installation/error.log", and nothing is reported when connecting the EDTracker (but I do see "Local Device Found" etc when connecting a generic USB gamepad).

I do have the "steam-devices" package installed:

# apt -qq list PACKAGE steam-devices
steam-devices/focal,focal,now 1:1.0.0.61-2ubuntu3 all [installed,automatic]

You can see that EDTracker is recognised as a "USB HID v1.01 Joystick" device:

# dmesg | less
[11156.461465] usb 1-8: new full-speed USB device number 15 using xhci_hcd
[11156.798366] usb 1-8: New USB device found, idVendor=2341, idProduct=8036, bcdDevice= 1.00
[11156.798375] usb 1-8: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[11156.798379] usb 1-8: Product: EDTracker EDTracker2
[11156.798382] usb 1-8: Manufacturer: Arduino LLC
[11156.824133] cdc_acm 1-8:1.0: ttyACM0: USB ACM device
[11156.830336] input: Arduino LLC EDTracker EDTracker2 as /devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.000C/input/input28
[11156.830497] hid-generic 0003:2341:8036.000C: input,hidraw4: USB HID v1.01 Joystick [Arduino LLC EDTracker EDTracker2] on usb-0000:02:00.0-8/input2

I'm hoping this might help:

# udevadm info -a -n /dev/input/js0 | less
  looking at device '/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.000C/input/input28/js0':
    KERNEL=="js0"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.000C/input/input28':
    KERNELS=="input28"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{inhibited}=="0"
    ATTRS{properties}=="0"
    ATTRS{name}=="Arduino LLC EDTracker EDTracker2"
    ATTRS{uniq}==""
    ATTRS{phys}=="usb-0000:02:00.0-8/input2"

  looking at parent device '/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.000C':
    KERNELS=="0003:2341:8036.000C"
    SUBSYSTEMS=="hid"
    DRIVERS=="hid-generic"
    ATTRS{country}=="00"
...

I have tried adding all sorts of udev rules to "/etc/udev/rules.d/60-local.rules" without any improvement (in rough order of increasing desperation):

KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", MODE="0660", TAG+="uaccess"
KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", GROUP="plugdev", OPTIONS+="static_node=uinput"
#KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", MODE="0660", OPTIONS+="static_node=uinput"
KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", RUN{program}+="/bin/sh -c 'udevadm test-builtin uaccess /sys/%p/../../hidraw/hidraw*'"

Of course I did run "udevadm control --reload" afterwards, and have verified it is actually being triggered when I connected the EDTracker.

I should mention that I'm assuming the controller needs to be recognised by Steam, before it will show-up in games running under Proton (e.g. Elite Dangerous).

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

It might be useful to use steam-runtime-input-monitor. This is a diagnostic tool that comes with the Steam Runtime.

Unplug the EDTracker, then run steam-runtime-input-monitor from a terminal as:

~/.steam/root/ubuntu12_32/steam-runtime/run.sh -- steam-runtime-input-monitor

You'll get lots of JSON describing your other input devices, which you can ignore, followed by {"all-for-now": true}.

Plug in your EDTracker, and you should see some more JSON appear. Press Ctrl+C to exit from the steam-runtime-input-monitor. Everything from {"all-for-now": true} down to the point where you pressed Ctrl+C will be a description of your EDTracker.

Device: /dev/input/sr0

This is unusual. What you would normally see, for a HID gamepad like a Playstation or Switch controller or a HID non-gamepad game controller like a flight stick or steering wheel, is three device nodes:

  • /dev/input/jsX, for some value of X, for the old high-level Linux "joystick" interface (for historical reasons all gaming input devices are referred to as "joysticks", even steering wheels and gamepads)
  • /dev/input/eventY, for some value of Y, for the newer high-level "evdev" interface
  • /dev/hidrawZ, for some value of Z, for the lower-level raw HID interface

Steam uses SDL, which I think only looks at /dev/input/eventY or /dev/hidrawZ, and I don't think it uses the old /dev/input/jsX interface at all.

Similarly, Proton only uses /dev/input/eventY and /dev/hidrawZ, and steam-runtime-input-monitor will only tell you about /dev/input/eventY and /dev/hidrawZ. The code in steam-runtime-input-monitor that does the detection is deliberately similar to what's in SDL and Wine.

I have tried adding all sorts of udev rules to "/etc/udev/rules.d/60-local.rules"

I would recommend removing these attempted workarounds before using steam-runtime-input-monitor. They shouldn't be necessary, because any evdev node that the kernel thinks is a joystick gets uaccess by default. After you know which device nodes don't have access but should, you can apply the rules you need and no others.

The thing you are probably missing is access to the raw HID device node, which normally comes from rules like this one (which happens to be for a PS5 gamepad):

# PS5 DualSense controller over USB hidraw
KERNEL=="hidraw*", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0ce6", MODE="0660", TAG+="uaccess"

Raw HID device nodes don't get uaccess by default, and setting this up is one of the important things that steam-devices does for supported controllers (Playstation, Switch, etc.).

steam-runtime-input-monitor would tell you whether you have access to the raw HID device node or not: the interface_flags for a device node will say readable and read-write if you have that access, or not if you don't.

I should mention that I'm assuming the controller needs to be recognised by Steam, before it will show-up in games running under Proton (e.g. Elite Dangerous).

Not necessarily! If you have asked Steam to remap controls via Generic Gamepad Configuration Support, then yes, Steam needs to recognise it; but if you are letting the game use the game controller directly, then all that should matter is whether Proton recognises it as a game controller and has sufficient permissions to do what it needs to do.

The controller-remapping features in Steam are mainly (only?) intended for gamepads that have the same general layout and functionality as an Xbox/Playstation/Switch controller, and I don't think they are generally useful for non-gamepad devices like flight sticks and steering wheels.

@SentineI
Copy link
Author

SentineI commented Feb 28, 2022

Device: /dev/input/sr0
This is unusual. What you would normally see, for a HID gamepad like a Playstation or Switch controller or a HID non-gamepad game controller like a flight stick or steering wheel, is three device nodes:

Sorry, I had to manually type that & somehow got it wrong. As you'd expect, it was actually:
Device: /dev/input/js0

You can see it correctly stated later where I copied & pasted: KERNEL=="js0"

I would recommend removing these attempted workarounds before using steam-runtime-input-monitor.

Done!

/dev/hidrawZ, for some value of Z, for the lower-level raw HID interface

The thing you are probably missing is access to the raw HID device node, which normally comes from rules like this one (which happens to be for a PS5 gamepad):

Raw HID device nodes don't get uaccess by default, and setting this up is one of the important things that steam-devices does for supported controllers (Playstation, Switch, etc.).

Thanks for your explanation. I didn't realise it would have a "/dev/hidrawZ" device (in addition to the one I mentioned). The "steam-devices" udev stuff makes more sense now (and also explains why my changes didn't help).

Plug in your EDTracker, and you should see some more JSON appear. Press Ctrl+C to exit from the steam-runtime-input-monitor. Everything from {"all-for-now": true} down to the point where you pressed Ctrl+C will be a description of your EDTracker.

Thanks, this is what I got:

{
  "added" : {
    "interface_flags" : [
      "raw-hid"
    ],
    "type_flags" : [
    ],
    "dev_node" : "/dev/hidraw4",
    "subsystem" : "hidraw",
    "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/hidraw/hidraw4",
    "bus_type" : "0x0003",
    "vendor_id" : "0x2341",
    "product_id" : "0x8036",
    "version" : "0x0100",
    "udev_properties" : [
      "ACTION=add",
      "DEVNAME=/dev/hidraw4",
      "DEVPATH=/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/hidraw/hidraw4",
      "MAJOR=507",
      "MINOR=4",
      "SEQNUM=4452",
      "SUBSYSTEM=hidraw",
      "USEC_INITIALIZED=797536286"
    ],
    "hid_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006",
      "name" : null,
      "bus_type" : "0x0003",
      "vendor_id" : "0x2341",
      "product_id" : "0x8036",
      "uniq" : null
    },
    "usb_device_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8",
      "vendor_id" : "0x2341",
      "product_id" : "0x8036",
      "version" : "0x0100",
      "manufacturer" : "Arduino LLC",
      "product" : "EDTracker EDTracker2",
      "serial" : null
    }
  }
}
{
  "added" : {
    "interface_flags" : [
      "event"
    ],
    "type_flags" : [
      "accelerometer"
    ],
    "dev_node" : "/dev/input/event21",
    "subsystem" : "input",
    "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/input/input22/event21",
    "bus_type" : "0x0003",
    "vendor_id" : "0x2341",
    "product_id" : "0x8036",
    "version" : "0x0101",
    "evdev" : {
      "types" : [
        "SYN",
        "ABS"
      ],
      "absolute_axes" : [
        "X",
        "Y",
        "Z"
      ],
      "relative_axes" : [
      ],
      "keys" : [
      ],
      "input_properties" : [
      ]
    },
    "udev_properties" : [
      "ACTION=add",
      "DEVLINKS=/dev/input/by-path/pci-0000:02:00.0-usb-0:8:1.2-event /dev/input/by-id/usb-Arduino_LLC_EDTracker_EDTracker2-event-if02",
      "DEVNAME=/dev/input/event21",
      "DEVPATH=/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/input/input22/event21",
      "ID_BUS=usb",
      "ID_INPUT=1",
      "ID_INPUT_ACCELEROMETER=1",
      "ID_MODEL=EDTracker_EDTracker2",
      "ID_MODEL_ENC=EDTracker\\x20EDTracker2",
      "ID_MODEL_ID=8036",
      "ID_PATH=pci-0000:02:00.0-usb-0:8:1.2",
      "ID_PATH_TAG=pci-0000_02_00_0-usb-0_8_1_2",
      "ID_REVISION=0100",
      "ID_SERIAL=Arduino_LLC_EDTracker_EDTracker2",
      "ID_TYPE=hid",
      "ID_USB_DRIVER=usbhid",
      "ID_USB_INTERFACES=:020200:0a0000:030000:",
      "ID_USB_INTERFACE_NUM=02",
      "ID_VENDOR=Arduino_LLC",
      "ID_VENDOR_ENC=Arduino\\x20LLC",
      "ID_VENDOR_ID=2341",
      "IIO_SENSOR_PROXY_TYPE=input-accel",
      "LIBINPUT_DEVICE_GROUP=3/2341/8036:usb-0000:02:00.0-8",
      "MAJOR=13",
      "MINOR=85",
      "SEQNUM=4450",
      "SUBSYSTEM=input",
      "SYSTEMD_WANTS=iio-sensor-proxy.service",
      "TAGS=:systemd:",
      "USEC_INITIALIZED=797614225"
    ],
    "hid_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006",
      "name" : null,
      "bus_type" : "0x0003",
      "vendor_id" : "0x2341",
      "product_id" : "0x8036",
      "uniq" : null
    },
    "input_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/input/input22",
      "name" : "Arduino LLC EDTracker EDTracker2",
      "bus_type" : "0x0003",
      "vendor_id" : "0x2341",
      "product_id" : "0x8036",
      "version" : "0x0101"
    },
    "usb_device_ancestor" : {
      "sys_path" : "/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8",
      "vendor_id" : "0x2341",
      "product_id" : "0x8036",
      "version" : "0x0100",
      "manufacturer" : "Arduino LLC",
      "product" : "EDTracker EDTracker2",
      "serial" : null
    }
  }
}

I didn't see anything there saying if it has suitable read/write access, but I think it doesn't?:

$ ll /dev/hidraw4
crw------- 1 root root 507, 4 Feb 28 17:40 /dev/hidraw4
$ ll /dev/input/event21
crw-rw---- 1 root input 13, 85 Feb 28 17:40 /dev/input/event21
$ ll /dev/input/js0
crw-rw-r-- 1 root input 13, 0 Feb 28 17:40 /dev/input/js0

I could make some guesses as what udev rules to add, but will wait to hear your recommendations on what I should try...

If you have asked Steam to remap controls ... then yes, Steam needs to recognise it; but if you are letting the game use the game controller directly, then all that should matter is whether Proton recognises it as a game controller and has sufficient permissions to do what it needs to do.

OK, although if Steam & Proton both require a "/dev/hidrawZ" device(??), then Steam seeing the controller must be a good start.

But I will also make sure to test whether a Proton game sees the EDTracker, even if Steam still doesn't.

@kisak-valve
Copy link
Member

Blind guess: KERNEL=="hidraw*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", MODE="0660", TAG+="uaccess"

@kisak-valve
Copy link
Member

ValveSoftware/Proton#5126 (comment) could be important here as well since the device has no buttons.

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

You said:

EDTracker is actually a head tracker, but to a computer it just looks like a USB 3-axis analog joystick, and so should work with anything that supports a USB analog joystick

but according to the steam-runtime-input-monitor, it is actually recognised as an accelerometer, which is not the same as a 3-axis joystick: the evdev interface expects games to distinguish between accelerometers and joysticks.

The older /dev/input/js* interface would report it as a joystick because it doesn't know any better, but the /dev/input/event* interface has enough information to distinguish between devices with axes and buttons (flight sticks, gamepads, etc.) and devices with only axes (accelerometers).

A more commonly-seen example is a Playstation controller (specifically, PS3 Sixaxis or newer), which is reported with two /dev/input/event* devices: the first one is the gamepad, with 6 analog axes (two sticks and two analog triggers) and a lot of buttons (D-pad, face buttons, etc.), and is reported as a "joystick", while the second one represents the motion controls, has 3 axes but no buttons, and is reported as an accelerometer.

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

Blind guess: KERNEL=="hidraw*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", MODE="0660", TAG+="uaccess"

That looks appropriate.

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

You'll probably also want a rule to give you access to the /dev/input/event* node, something like this (untested):

KERNEL=="input*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", MODE="0660", TAG+="uaccess"

This is because systemd/udev automatically puts uaccess on devices that it identifies as a "joystick" (flight sticks, steering wheels, gamepads), but it does not do the same for accelerometers, because there's no straightforward way to distinguish between an accelerometer in a gaming input device and an accelerometer in the computer itself.

@SentineI
Copy link
Author

SentineI commented Feb 28, 2022

Many thanks for the replies. Although I need to do more testing, I am very happy to report that the following udev rule allows a Proton 7.0-1 game to detect/use the EDTracker:
KERNEL=="hidraw*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", MODE="0660", TAG+="uaccess"

Steam still does NOT recognise it as a controller, but that's not a problem since I don't need to remap it (remapping wouldn't make much sense).

The above rule isn't ideal, because the Vendor/Product codes are a bit generic, and according to this just identify it as an Arduino Leonardo, which I think is just a generic microcrontroller. (Which isn't too surprising, since that's what the EDTracker basically was before it's firmware was flashed.)

However, I don't see any way to limit a "hidraw" udev rule to just the EDTracker, unless it's possible for it to match against part of it's "usb_device_ancestor"?

The following rule probably would work (I never tested it with Proton just Steam), but it seems even less desirable, if I understand correctly what it's doing:

KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", RUN{program}+="/bin/sh -c 'udevadm test-builtin uaccess /sys/%p/../../hidraw/hidraw*'"

I think it's giving uaccess to all hidraw devices, which doesn't sound very secure. So I'm not sure why Steam's official "steam-devices" package does something similar for "PowerA Wireless Controller for Nintendo Switch" devices.

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

Steam still does NOT recognise it as a controller, but that's not a problem since I don't need to remap it (remapping wouldn't make much sense).

This genuinely isn't a "controller" in the sense that Steam means, and neither are flight sticks or steering wheels, so I think this device is out-of-scope for Steam. The game controllers that Steam wants to deal with are specifically the ones that look like a gamepad (Xbox, Playstation, Switch and so on). Everything else should just be opened and used by the game as-is.

The above rule isn't ideal, because the Vendor/Product codes are a bit generic, and according to this just identify it as an Arduino Leonardo, which I think is just a generic microcrontroller. (Which isn't too surprising, since that's what the EDTracker basically was before it's firmware was flashed.)

I don't think there's necessarily any good solution for that. udev can only identify devices with the information that the kernel makes available to it, so if a consumer-facing product is using the USB ID of a generic microcontroller (because it's based on a generic microcontroller and hasn't swapped the USB ID to one that is more narrowly-scoped), then there isn't a whole lot we can do about that.

However, I don't see any way to limit a "hidraw" udev rule to just the EDTracker, unless it's possible for it to match against part of it's "usb_device_ancestor"?

You can use values in a udev rule that match against either the device itself, or exactly one ancestor (but you can't match against values from more than one ancestor in the same rule). See udev(7) for details, and use udevadm info -a -n /dev/hidraw4 to see what you would be able to match.

So you might be able to use:

  • KERNEL=="hidraw*" from the node itself
  • ATTRS{name}=="Arduino LLC EDTracker*" from the USB ancestor

to get a closer match?

I think it's giving uaccess to all hidraw devices, which doesn't sound very secure. So I'm not sure why Steam's official "steam-devices" package does something similar for "PowerA Wireless Controller for Nintendo Switch" devices.

It's entirely possible that that rule is wrong: its submitter probably only tested that it did give access to the Switch-clone controller, and probably didn't test that it didn't give access to other HID devices.

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

KERNEL=="input*", ATTRS{name}=="Arduino LLC EDTracker*", RUN{program}+="/bin/sh -c 'udevadm test-builtin uaccess /sys/%p/../../hidraw/hidraw*'"

I think it's giving uaccess to all hidraw devices, which doesn't sound very secure.

I think it's probably OK, because it's matching on the input (evdev) device node, which for your device is

/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/input/input22/event21

and then using %p to set the permissions on the device node in /dev that corresponds to this /sys path:

/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/input/input22/event21/../../hidraw/hidraw*

which after collapsing the ../.. ends up as

/sys/devices/pci0000:00/0000:00:01.3/0000:02:00.0/usb1/1-8/1-8:1.2/0003:2341:8036.0006/input/hidraw/hidraw*

or in other words, "every raw HID device belonging to the same USB device as this specific evdev node".

@SentineI
Copy link
Author

SentineI commented Feb 28, 2022

@smcv

use udevadm info -a -n /dev/hidraw4 to see what you would be able to match.

Thanks. Using that I was able to devise this improved rule, which should be specific to the EDTracker:

KERNEL=="hidraw*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", ATTRS{product}=="EDTracker*", MODE="0660", TAG+="uaccess"

I've tested this as working, and even rebooted to be doubly sure. It seems to work great with Elite Dangerous running under Proton 7.0-1.

I'm using a wildcard for the product name, as there might be other variations/versions ("EDTracker2" certainly suggests that).

@kisak-valve
I'm not sure if you would know, but is it possible for the above to be added to the official "steam-devices" package?

There were a lot of EDTracker users for Elite Dangerous a few years ago (see this mamoth 249 page forum thread from 2014 to 2018, never mind other & more recent threads), and it would be a shame if any of them trying to convert to Linux found their beloved EDTracker doesn't work. (I personally can't play Elite Dangerous without mine.)

Also, although the main website is now down, it seems it's still possible to buy a new EDTracker (which I hadn't realised myself, so I'm going to buy a backup one in case mine ever dies).

@kisak-valve
Copy link
Member

My understanding is that this device does not match the intent for Steam Input and the controller re-mapping it provides, so it's not a good match for the steam-devices udev set.

@smcv
Copy link
Contributor

smcv commented Feb 28, 2022

If you want this device to be supported by default, udev upstream (i.e. systemd) might be a better place to send udev rules (and indeed steam-devices has an issue open at the moment asking for some or all of its udev rules to be upstreamed into systemd).

@SentineI
Copy link
Author

SentineI commented Mar 3, 2022

It's a real shame to hear that Valve has zero interest in seeing non-gamepad controllers working on Linux. Hopefully that changes when/if Linux gaming becomes more popular.

@SentineI
Copy link
Author

SentineI commented Mar 3, 2022

I suspect this may be going off-topic and/or not the appropriate place, in which case I'm sorry, please delete this comment.
@smcv
Unfortunately I have no idea where gaming-related udev rules would be added to systemd - nor why even that would even make sense, when this seems to be something only needed by Wine & Proton. Hopefully someone will start collating gaming-related udev rules (I'm not that person).

@smcv
Copy link
Contributor

smcv commented Mar 8, 2022

I have no idea where gaming-related udev rules would be added to systemd - nor why even that would even make sense

systemd is the upstream project that maintains udev, and the udev "hwdb" which provides a centralized cross-distro repository of device quirks. udev rules for gaming input devices are not specific to Steam: any open-source flight simulator or driving game can potentially benefit from more direct access to gaming input devices, and so can upstream Wine (the version from your OS that is not part of Proton).

Over in https://github.com/ValveSoftware/steam-devices where Steam's udev rules for gamepads and VR devices are maintained, we've had a request to send them upstream to systemd, and I think for many of our rules, that would make sense. Having similar udev rules alongside those for non-gamepad devices like flight sticks and your headtracker would also make sense for the platform as a whole, just not really for Steam.

Please don't interpret this as thinking that non-gamepads are not something that should work on Linux. They should - but Steam shouldn't have to do anything Steam-specific for that to happen, because the right place to make changes is in lower layers. On Windows or macOS, there's no opportunity to change the lower layers unless you are Microsoft or Apple, so we get "the platform problem": if a higher layer like Steam doesn't like a decision made by a lower "platform" layer, the only option is to work around it. On Linux, it's possible to contribute changes to the lower layers directly, so it makes sense for changes to be targeted to happen in the place that will benefit the most people with the least ongoing maintenance work (which is why the Steam Deck and Proton have resulted in changes to several lower layers, including SDL and the Linux kernel).

The Steam Input mechanism that is part of the Steam client is intended to remap gamepad-style game controllers (Steam Controller, Xbox, Playstation, Switch, and generic PC gamepads) so that their input can be fed into older games that expect a keyboard/mouse and do not natively support a gamepad (for example Half-Life used to be in this category, although I think recent builds might have gained native gamepad support). Flight sticks, steering wheels and accelerometers are out-of-scope for this: they're not gamepads, and are not particularly useful for Steam to remap. If a game natively supports these controllers, it can open and use them as-is; if a game doesn't support these controllers, pretending they're a keyboard wouldn't work very well, because they're too different.

@smcv
Copy link
Contributor

smcv commented Mar 8, 2022

I've opened systemd/systemd#22681 to start the process of trying to get this into systemd, and mentioned your EDTracker there as one of the use-cases.

smcv added a commit to smcv/systemd that referenced this issue Mar 24, 2022
ID_INPUT_JOYSTICK refers to "joysticks", which for historical reasons is
the name given by the Linux kernel and udev to most game-oriented input
devices, including flight sticks, gamepads, steering wheels and so on
(but not accelerometers or gyroscopes that have axes but no buttons,
even if they are part of a gamepad with motion controls such as a
PS3/PS4/PS5 controller).

My intention is for ID_GAME_CONTROLLER to be a generalization of this,
applying to anything that a gamer would think of as a dedicated gaming
controller, for example:

* all "joysticks", including gamepads, steering wheels and so on
* the accelerometer that provides motion controls in a PS3/PS4/PS5
  controller, which is part of the same HID device but exposed as a
  separate evdev device node by the Linux kernel (see systemd#17691)
* the EDTracker, which is an Arduino-based accelerometer designed to
  be used for head tracking by Elite:Dangerous players (see
  ValveSoftware/steam-for-linux#8443)

However, ID_GAME_CONTROLLER should not include accelerometers used to
detect the orientation of a laptop/tablet, because those are not really a
gaming device (admittedly people have sometimes hooked up older Thinkpads'
HDAPS accelerometers to control games by tilting the laptop, but that
seems like something that's reasonable to have to configure for yourself).

I've named this without the INPUT_ prefix with the intention that it
can be applied to both evdev devices and hidraw devices (systemd#22681).

Signed-off-by: Simon McVittie <[email protected]>
@SentineI
Copy link
Author

SentineI commented Nov 10, 2024

In case anyone wants to get an EDTracker working with Linux these days & finds this bug report, the above UDev rule no-longer works. I had to add a second line to my /etc/udev/rules.d/60-local.rules file, so it now looks like:

KERNEL=="hidraw*", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", ATTRS{product}=="EDTracker*", MODE="0660", TAG+="uaccess"
SUBSYSTEM=="input", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="8036", ATTRS{product}=="EDTracker*", MODE="0660", ENV{ID_INPUT_JOYSTICK}="1"

This means that when I run steam-runtime-input-monitor, and then plug in the EDTracker, I see:

$ ~/.steam/root/ubuntu12_32/steam-runtime/run.sh -- steam-runtime-input-monitor
...
{"all-for-now": true}
{
  "added" : {
    "interface_flags" : [
      "raw-hid",
      "readable",
      "read-write"
    ],
    "type_flags" : [
    ],
    "dev_node" : "/dev/hidraw4",
    "subsystem" : "hidraw",
...
{
  "added" : {
    "interface_flags" : [
      "event",
      "readable",
      "read-write"
    ],
    "type_flags" : [
      "joystick",
      "accelerometer"
    ],
    "dev_node" : "/dev/input/event18",
    "subsystem" : "input",

i.e. The /dev/hidraw* device is marked as "readable" & "read-write" (as before), AND the /dev/input/event* device is marked as "readable" & "read-write", and "type_flags" says it's a "joystick".

While I was investigating this, I discovered it's possible to get OpenTrack to work with Steam games - and this helped me debug the issues quicker, as I could check whether or not OpenTrack saw it (as a USB joystick), without needing to fully start Elite Dangerous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants