Yes. The kernel creates a regular joystick device node for it, such as /dev/input/js1.
Yes, but read on ...
Yes and no. Each of the controllers has its own individual serial number, and both usb and input subsystem make this number available. The number isn't made part of the joystick identifier as returned by the JSIOCGNAME ioctl() function, though. The kernel only returns the generic product name »Leo Bodnar BU0836A Interface« for all attached BU0836A devices. There's no way to distinguish different BU0836 devices by their joystick name.
A simple kernel patch fixes the problem (tested under 2.6.33). It adds iSerial to the device name, so that each BU0836A appears under an individual name, e.g. »Leo Bodnar BU0836A Interface A10345«. This is done for all HID devices (USB mice, keyboards, ...), which hasn't led to any problems here. Most HID devices probably don't set iSerial anyway, so there's no change for them. And even those that do don't seem to care about their »name« at all.
--- a/drivers/hid/usbhid/hid-core.c 2010-03-04 02:49:38.676850618 +0100
+++ b/drivers/hid/usbhid/hid-core.c 2010-03-04 03:03:43.269006052 +0100
@@ -1131,6 +1131,12 @@
strlcat(hid->name, dev->product, sizeof(hid->name));
}
+ if (dev->serial) {
+ if (hid->name[0])
+ strlcat(hid->name, " ", sizeof(hid->name));
+ strlcat(hid->name, dev->serial, sizeof(hid->name));
+ }
+
if (!strlen(hid->name))
snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
le16_to_cpu(dev->descriptor.idVendor),
Yes, but so far there wasn't much interest. The reasoning was something like (paraphrased): »The joystick interface sucks anyway. Just use another interface.« Of course, this is of no help if you are forced to use the joystick interface, for which one reason might be that it's the only interface supporting calibration.
In one of the next answers you find a link to a bu0836 configuration program. This also contains a preload library that modifies the kernel's answer to requests for joystick names. Just set LD_PRELOAD to library js_serial_preload.so before you run the joystick using application:
$ LD_PRELOAD=/usr/local/lib/js_serial_preload.so fgfs --aircraft=bo105 --airport=lowi
This simple library monitors all ioctl() function calls and catches JSIOCGNAME requests, whose answer it replaces by a name including the serial number. This name is retrieved from the associated events device. The preload library relies on proper joystick symlinks being set under /dev/input/by-id/, so if it yields an error message, check out the next question.
Normally, the system creates symbolic links (»symlinks«) under /dev/input/by-id/ for every joystick, one ending with -joystick and linking to the joystick device, and one ending with -event-joystick and linking to the event device. Ideally, the same happens with BU0836 controllers, as shown in the green lines in this example:
$ ls -l /dev/input/by-id/|grep BU0836|cut -d' ' -f8- usb-Leo_Bodnar_BU0836A_Interface_A12300-joystick -> ../js1 usb-Leo_Bodnar_BU0836A_Interface_A12300-event-joystick -> ../event5 usb-Leo_Bodnar_BU0836A_Interface_A12301-event-if00 -> ../event6
In some cases you might just get one single symlink ending with -event-if00, as shown in the red line. This is not the kernel's fault, but caused by udev's joystick detection heuristics. udev (by way of its helper program /lib/udev/input_id) only treats input devices as joysticks, if they provide an absolute x-axis, y-axis, and at least one of trigger button, a-button or 1-button. But you don't have to bother hardware-configuring your BU0836 like that, and can just give udev a little lesson instead: create a file /etc/udev/rules.d/00-local.rules containing this line:
SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Leo Bodnar", ATTRS{product}=="BU0836*", ENV{ID_INPUT_JOYSTICK}:="1"
This will tell udev that all BU0836 devices are in fact joysticks, no matter which axes and buttons they have. Change the manufacturer and product strings accordingly if you use a custom device. The following command will tell you more about which properties are available to identify device /dev/input/js1:
$ /sbin/udevadm info -q all --attribute-walk -n /dev/input/js1
The applications »BU0836 configuration.exe« and »BU0836_encoders.exe« for Microsoft® Windows® don't yet work under Wine. This is due to Wine not fully supporting generic USB-devices. There is a Free implementation of Bodnar's tools for Linux/Unix available here: http://gitorious.org/bu0836/ (man-page). The following image shows its status screen:
$ lsusb -s2:2 -v
Bus 002 Device 002: ID 16c0:05ba VOTI
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x16c0 VOTI
idProduct 0x05ba
bcdDevice 1.22
iManufacturer 1 Leo Bodnar
iProduct 2 BU0836A Interface
iSerial 3 A10345
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 103
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 4
Device Status: 0x0000
(Bus Powered)
For a device with two axes activated, it looks something like the following, whereby the first number is an offset, followed by the actual code and an interpretation. Note, how offsets 14 to 24 simply replace 09 by 15 as a placeholder for unused axes. That way the record length remains the same no matter how many axes are used. Also note that offset 97 says that the device expects 17 bytes control input. This is one address offset byte and 16 data bytes.
0: 05 01 Usage Page 'Generic Desktop Controls' 2: 09 04 Usage 'Joystick' 4: a1 01 Collection 'Application (mouse, keyboard)' 6: 09 01 Usage 'Pointer' 8: a1 00 Collection 'Physical (group of axes)' 10: 09 30 Usage 'X' 12: 09 31 Usage 'Y' 14: 15 32 Logical Minimum = 50 16: 15 33 Logical Minimum = 51 18: 15 34 Logical Minimum = 52 20: 15 35 Logical Minimum = 53 22: 15 37 Logical Minimum = 55 24: 15 36 Logical Minimum = 54 26: 15 00 Logical Minimum = 0 28: 26 ff 0f Logical Maximum = 4095 31: 75 10 Report Size = 16 33: 95 02 Report Count = 2 35: 81 02 Input data *var abs lin pref-state null-pos bit-field 37: c0 End Collection 38: 05 09 Usage Page 'Button' 40: 19 01 Usage Minimum = 1 42: 29 20 Usage Maximum = 32 44: 15 00 Logical Minimum = 0 46: 25 01 Logical Maximum = 1 48: 75 01 Report Size = 1 50: 95 20 Report Count = 32 52: 81 02 Input data *var abs lin pref-state null-pos bit-field 54: 05 01 Usage Page 'Generic Desktop Controls' 56: 09 39 Usage 'Hat switch' 58: 25 07 Logical Maximum = 7 60: 35 00 Physical Minimum = 0 62: 46 3b 01 Physical Maximum = 315 65: 55 00 Unit Exponent = 0 67: 65 44 Unit = System(English-Rotation) Length(Degrees) 69: 75 04 Report Size = 4 71: 95 01 Report Count = 1 73: 81 42 Input data *var abs lin pref-state null-pos bit-field 75: 65 00 Unit = None 77: 95 01 Report Count = 1 79: 75 04 Report Size = 4 81: 81 03 Input *const *var abs lin pref-state null-pos bit-field 83: a1 02 Collection 'Logical (interrelated data)' 85: 06 00 ff Usage Page 'Vendor-defined' 88: 09 01 Usage 1 90: 15 00 Logical Minimum = 0 92: 26 ff 00 Logical Maximum = 255 95: 75 08 Report Size = 8 97: 95 11 Report Count = 17 99: b1 02 Feature data *var abs lin pref-state null-pos non-vol bit-field 101: c0 End Collection 102: c0 End Collection
Each USB/HID request for a feature report returns 17 bytes of data (one line in the data block below), of which the first byte is an address offset for the following 16 bytes, which are a segment of the controller's EEPROM. The reports come in order, but don't necessarily start with report 00. After report f0 follows another 00 report and the sequence repeats. All in all this makes 256 data bytes.
00 03 0a 00 00 00 00 00 00 00 00 00 00 01 00 00 00 10 00 00 00 00 00 00 00 00 00 00 06 00 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 04 60 00 00 00 00 00 00 88 77 04 00 00 00 00 00 90 c3 f5 03 3b 03 c0 82 28 00 72 0c 00 03 82 11 00 a0 3f 00 0f 00 a0 00 70 fc 09 03 00 00 00 00 00 00 b0 00 00 00 00 0f 00 00 00 00 00 00 00 00 00 00 00 c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Some of the EEPROM addresses and their meaning are listed below. Note that the zoom factor is an 8-bit number, not just a boolean.
Offset Type Meaning 0b uint8_t bitmap for axis inversion 0c uint8_t axis autodiscovery: 0 = off, 1 = on 0d uint8_t bitmap for axis shut-off: 1 = force off (only if autodiscovery is off) 0e-15 uint8_t[8] zoom values (0 = "Normal", 198 = "Zoom") 16 uint16_t bit0 of the rotary encoder bitmap (Network Endian) 18 uint16_t bit1 of the rotary encoder bitmap (Network Endian) bit0 and bit1 together describe the encoder type for each of the 16 button pairs: 0 = "OFF", 1 = "1:1", 2 = "1:2", 3 = "1:4" 1a uint8_t pulse width; range 1–11 (multiplicated with 8 gives width in ms, so 8 to 88 ms, default: 6, that is 48 ms)
Writing to the EEPROM is done by sending a feature report of two bytes length. The first byte is the address offset, and the second the data byte to write.
VOTI (Van Ooijen Technische Informatica) owns vendor id 0x16c0 and sold the right to use product ids 0x05b4–0x05bd and 0x2774–0x27d7 to Leo Bodnar.