From 65f87975a1a19c4880c57872991961128d190fc3 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sat, 24 Jan 2026 15:33:36 +0800 Subject: [PATCH] linux: Parse HID_FIRMWARE_VERSION from uevent for release_number Parse the HID_FIRMWARE_VERSION uevent property to populate release_number for all HID devices. This provides device version information for I2C, Bluetooth, SPI, and virtual HID devices. For USB devices, the existing bcdDevice lookup from sysfs still takes precedence, maintaining backward compatibility. The HID_FIRMWARE_VERSION property is being added to the Linux kernel (patch series submitted to linux-input@vger.kernel.org). On kernels without this property, release_number will remain 0 for non-USB devices, preserving existing behavior. Signed-off-by: Daniel Schaefer --- linux/hid.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/linux/hid.c b/linux/hid.c index a4dc26f4..3afe91c2 100644 --- a/linux/hid.c +++ b/linux/hid.c @@ -571,7 +571,8 @@ static int get_hid_report_descriptor_from_hidraw(hid_device *dev, struct hidraw_ */ static int parse_uevent_info(const char *uevent, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id, - char **serial_number_utf8, char **product_name_utf8) + char **serial_number_utf8, char **product_name_utf8, + unsigned short *version) { char tmp[1024]; @@ -622,6 +623,9 @@ static int parse_uevent_info(const char *uevent, unsigned *bus_type, /* The caller has to free the serial number */ *serial_number_utf8 = strdup(value); found_serial = 1; + } else if (strcmp(key, "HID_FIRMWARE_VERSION") == 0) { + /* Device version from kernel */ + *version = (unsigned short)strtol(value, NULL, 16); } next_line: @@ -648,6 +652,7 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device char *serial_number_utf8 = NULL; char *product_name_utf8 = NULL; unsigned bus_type; + unsigned short hid_version = 0; int result; struct hidraw_report_descriptor report_desc; @@ -670,7 +675,8 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device &dev_vid, &dev_pid, &serial_number_utf8, - &product_name_utf8); + &product_name_utf8, + &hid_version); if (!result) { /* parse_uevent_info() failed for at least one field. */ @@ -709,7 +715,7 @@ static struct hid_device_info * create_device_info_for_device(struct udev_device cur_dev->serial_number = utf8_to_wchar_t(serial_number_utf8); /* Release Number */ - cur_dev->release_number = 0x0; + cur_dev->release_number = hid_version; /* Interface Number */ cur_dev->interface_number = -1;