Hello there, while using the Formos Infrared Receiver (147a:e016), I've noticed, that it won't stop blinking and doesn't register any presses. This issue appears to have been present since 2019, according to a thread on a German VDR forum. And appears to be a regression, as according to that thread it used to work with their software (yavdr-0.6.2, which appears to based on kernel 3.13.0). I've tried this on 5.16-rc2 (mainline on an X86 machine) and with 6.6.62+rpt-rpi-v8 from the latest Raspberry Pi OS. I've analyzed a PCAP dump from a Windows 7 machine to see where the initialization differs and noticed, that an undocumented byte 0xF4 is being sent, after DEVICE_RESUME and G_REVISION (which are both sent in one packet). By unbinding the driver, manually sending 0xF4 to the device and rebinding the driver, I'm able to workaround this issue. The blinking is gone and keypresses are now received. (Except for the OK key). No further testing has been done. I'm willing to provide PCAP traces, if of interest. I've attached the userspace C program for the workaround (which requires libusb-1.0 to build). Greetings, Patrick
#include <sys/ioctl.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <linux/usbdevice_fs.h> #include <libusb-1.0/libusb.h> int main(int argc, char *argv[]) { (void)argc; (void)argv; int result; libusb_device_handle *hDevice = NULL; uint8_t data[64] = {0}; int bytesRead = 0; result = libusb_init(NULL); if (result < 0) { printf("libusb initialization failed:\n"); } libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); hDevice = libusb_open_device_with_vid_pid(NULL, 0x147a, 0xe016); result = hDevice ? 0 : -EIO; if (result < 0) { printf("failed to open device:\n error: %s \n", strerror(errno)); // file return 1; } // Unregister kernel driver result = libusb_kernel_driver_active(hDevice, 0); if (result == 1) { result = libusb_detach_kernel_driver(hDevice, 0); if (result < 0) { printf("failed to detach kernel driver: %s, errno: %s\n", libusb_error_name(result), strerror(errno)); } } int err = libusb_claim_interface(hDevice, 0); if (err) { printf("Error: %s, errno: %s\n", libusb_error_name(err), strerror(errno)); return 1; } data[0] = 0xf4; result = libusb_bulk_transfer(hDevice, LIBUSB_ENDPOINT_OUT | 0x01, data, 1, &bytesRead, 0); sleep(1); result = libusb_release_interface(hDevice, 0); if (result < 0) { printf("failed to release interface: %s, errno: %s\n", libusb_error_name(result), strerror(errno)); } // reattach kernel driver result = libusb_attach_kernel_driver(hDevice, 0); if (result < 0) { printf("failed to attach kernel driver: %s, errno: %s\n", libusb_error_name(result), strerror(errno)); } libusb_close(hDevice); libusb_exit(NULL); printf("Workaround applied successfully\n"); }