* [PATCH 0/6] platform/x86/tuxedo: Fixes for TUXEDO NB04 driver
@ 2026-07-28 11:59 Aaron Erhardt
2026-07-28 11:59 ` [PATCH 1/6] platform/x86/tuxedo: Don't use device driver data Aaron Erhardt
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Aaron Erhardt @ 2026-07-28 11:59 UTC (permalink / raw)
To: wse, hansg, ilpo.jarvinen
Cc: Aaron Erhardt, linux-kernel, platform-driver-x86
This patch series contains several fixes for the TUXEDO NB04 driver.
Additional userspace tooling and a new WIP generic lamp array driver
being tested brought more attention to this driver, thus uncovering
some problems and potential for improvements.
Aaron Erhardt (6):
platform/x86/tuxedo: Don't use device driver data
platform/x86/tuxedo: Set HID report ID on success
platform/x86/tuxedo: Use intensity according to HID spec
platform/x86/tuxedo: Fix keyboard LED map ordering
platform/x86/tuxedo: Update and extend documentation
MAINTAINERS: Add Aaron Erhardt as maintainer of TUXEDO DRIVERS
MAINTAINERS | 1 +
drivers/platform/x86/tuxedo/nb04/wmi_ab.c | 122 ++++++++++++----------
2 files changed, 70 insertions(+), 53 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/6] platform/x86/tuxedo: Don't use device driver data
2026-07-28 11:59 [PATCH 0/6] platform/x86/tuxedo: Fixes for TUXEDO NB04 driver Aaron Erhardt
@ 2026-07-28 11:59 ` Aaron Erhardt
2026-07-28 11:59 ` [PATCH 2/6] platform/x86/tuxedo: Set HID report ID on success Aaron Erhardt
2026-07-28 11:59 ` [PATCH 3/6] platform/x86/tuxedo: Use intensity according to HID spec Aaron Erhardt
2 siblings, 0 replies; 5+ messages in thread
From: Aaron Erhardt @ 2026-07-28 11:59 UTC (permalink / raw)
To: wse, hansg, ilpo.jarvinen
Cc: Aaron Erhardt, linux-kernel, platform-driver-x86
The WMI driver for TUXEDO Sirius devices used to rely on the device
driver data through dev_set_drvdata even though it is only a virtual
low level HID driver. For this purpose, it is better to use the
driver_data of the hid_device struct to avoid interfering with high
level device drivers.
Signed-off-by: Aaron Erhardt <aer@tuxedocomputers.com>
---
drivers/platform/x86/tuxedo/nb04/wmi_ab.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
index 32d7756022c2..72205de72256 100644
--- a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
+++ b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
@@ -448,7 +448,7 @@ static int tux_ll_start(struct hid_device *hdev)
}
driver_data->next_lamp_id = 0;
- dev_set_drvdata(&hdev->dev, driver_data);
+ hdev->driver_data = driver_data;
return ret;
}
@@ -485,7 +485,7 @@ struct __packed lamp_array_attributes_report_t {
static int handle_lamp_array_attributes_report(struct hid_device *hdev,
struct lamp_array_attributes_report_t *rep)
{
- struct tux_hdev_driver_data_t *driver_data = dev_get_drvdata(&hdev->dev);
+ struct tux_hdev_driver_data_t *driver_data = hdev->driver_data;
rep->lamp_count = driver_data->lamp_count;
rep->bounding_box_width_in_micrometers = 368000;
@@ -510,7 +510,7 @@ struct __packed lamp_attributes_request_report_t {
static int handle_lamp_attributes_request_report(struct hid_device *hdev,
struct lamp_attributes_request_report_t *rep)
{
- struct tux_hdev_driver_data_t *driver_data = dev_get_drvdata(&hdev->dev);
+ struct tux_hdev_driver_data_t *driver_data = hdev->driver_data;
if (rep->lamp_id < driver_data->lamp_count)
driver_data->next_lamp_id = rep->lamp_id;
@@ -539,7 +539,7 @@ struct __packed lamp_attributes_response_report_t {
static int handle_lamp_attributes_response_report(struct hid_device *hdev,
struct lamp_attributes_response_report_t *rep)
{
- struct tux_hdev_driver_data_t *driver_data = dev_get_drvdata(&hdev->dev);
+ struct tux_hdev_driver_data_t *driver_data = hdev->driver_data;
u16 lamp_id = driver_data->next_lamp_id;
rep->lamp_id = lamp_id;
@@ -598,7 +598,7 @@ struct __packed lamp_multi_update_report_t {
static int handle_lamp_multi_update_report(struct hid_device *hdev,
struct lamp_multi_update_report_t *rep)
{
- struct tux_hdev_driver_data_t *driver_data = dev_get_drvdata(&hdev->dev);
+ struct tux_hdev_driver_data_t *driver_data = hdev->driver_data;
union tux_wmi_xx_496in_80out_in_t *next = &driver_data->next_kbl_set_multiple_keys_in;
struct tux_kbl_set_multiple_keys_in_rgb_config_t *rgb_configs_j;
struct wmi_device *wdev = to_wmi_device(hdev->dev.parent);
@@ -683,7 +683,7 @@ struct __packed lamp_range_update_report_t {
static int handle_lamp_range_update_report(struct hid_device *hdev,
struct lamp_range_update_report_t *rep)
{
- struct tux_hdev_driver_data_t *driver_data = dev_get_drvdata(&hdev->dev);
+ struct tux_hdev_driver_data_t *driver_data = hdev->driver_data;
struct lamp_multi_update_report_t lamp_multi_update_report = {
.report_id = LAMP_MULTI_UPDATE_REPORT_ID,
};
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/6] platform/x86/tuxedo: Set HID report ID on success
2026-07-28 11:59 [PATCH 0/6] platform/x86/tuxedo: Fixes for TUXEDO NB04 driver Aaron Erhardt
2026-07-28 11:59 ` [PATCH 1/6] platform/x86/tuxedo: Don't use device driver data Aaron Erhardt
@ 2026-07-28 11:59 ` Aaron Erhardt
2026-07-28 11:59 ` [PATCH 3/6] platform/x86/tuxedo: Use intensity according to HID spec Aaron Erhardt
2 siblings, 0 replies; 5+ messages in thread
From: Aaron Erhardt @ 2026-07-28 11:59 UTC (permalink / raw)
To: wse, hansg, ilpo.jarvinen
Cc: Aaron Erhardt, linux-kernel, platform-driver-x86
While not strictly necessary due to the synchronous handling of HID
requests, it is better to set the ID of the HID report before
returning the buffer. This also better complies with the HID spec and
avoids problems with userspace tools expecting a report ID.
Signed-off-by: Aaron Erhardt <aer@tuxedocomputers.com>
---
drivers/platform/x86/tuxedo/nb04/wmi_ab.c | 26 +++++++++++++++++------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
index 72205de72256..11babc7c7767 100644
--- a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
+++ b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
@@ -766,6 +766,8 @@ static int handle_lamp_array_control_report(struct hid_device *hdev __always_unu
static int tux_ll_raw_request(struct hid_device *hdev, u8 reportnum, u8 *buf,
size_t len, unsigned char rtype, int reqtype)
{
+ int ret = -EINVAL;
+
if (rtype != HID_FEATURE_REPORT)
return -EINVAL;
@@ -775,13 +777,15 @@ static int tux_ll_raw_request(struct hid_device *hdev, u8 reportnum, u8 *buf,
case LAMP_ARRAY_ATTRIBUTES_REPORT_ID:
if (len != sizeof(struct lamp_array_attributes_report_t))
return -EINVAL;
- return handle_lamp_array_attributes_report(hdev,
+ ret = handle_lamp_array_attributes_report(hdev,
(struct lamp_array_attributes_report_t *)buf);
+ break;
case LAMP_ATTRIBUTES_RESPONSE_REPORT_ID:
if (len != sizeof(struct lamp_attributes_response_report_t))
return -EINVAL;
- return handle_lamp_attributes_response_report(hdev,
+ ret = handle_lamp_attributes_response_report(hdev,
(struct lamp_attributes_response_report_t *)buf);
+ break;
}
break;
case HID_REQ_SET_REPORT:
@@ -789,28 +793,36 @@ static int tux_ll_raw_request(struct hid_device *hdev, u8 reportnum, u8 *buf,
case LAMP_ATTRIBUTES_REQUEST_REPORT_ID:
if (len != sizeof(struct lamp_attributes_request_report_t))
return -EINVAL;
- return handle_lamp_attributes_request_report(hdev,
+ ret = handle_lamp_attributes_request_report(hdev,
(struct lamp_attributes_request_report_t *)buf);
+ break;
case LAMP_MULTI_UPDATE_REPORT_ID:
if (len != sizeof(struct lamp_multi_update_report_t))
return -EINVAL;
- return handle_lamp_multi_update_report(hdev,
+ ret = handle_lamp_multi_update_report(hdev,
(struct lamp_multi_update_report_t *)buf);
+ break;
case LAMP_RANGE_UPDATE_REPORT_ID:
if (len != sizeof(struct lamp_range_update_report_t))
return -EINVAL;
- return handle_lamp_range_update_report(hdev,
+ ret = handle_lamp_range_update_report(hdev,
(struct lamp_range_update_report_t *)buf);
+ break;
case LAMP_ARRAY_CONTROL_REPORT_ID:
if (len != sizeof(struct lamp_array_control_report_t))
return -EINVAL;
- return handle_lamp_array_control_report(hdev,
+ ret = handle_lamp_array_control_report(hdev,
(struct lamp_array_control_report_t *)buf);
+ break;
}
break;
}
- return -EINVAL;
+ /* Set report number on success */
+ if (ret > 0)
+ buf[0] = reportnum;
+
+ return ret;
}
static const struct hid_ll_driver tux_ll_driver = {
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/6] platform/x86/tuxedo: Use intensity according to HID spec
2026-07-28 11:59 [PATCH 0/6] platform/x86/tuxedo: Fixes for TUXEDO NB04 driver Aaron Erhardt
2026-07-28 11:59 ` [PATCH 1/6] platform/x86/tuxedo: Don't use device driver data Aaron Erhardt
2026-07-28 11:59 ` [PATCH 2/6] platform/x86/tuxedo: Set HID report ID on success Aaron Erhardt
@ 2026-07-28 11:59 ` Aaron Erhardt
2026-08-24 15:13 ` Ilpo Järvinen
2 siblings, 1 reply; 5+ messages in thread
From: Aaron Erhardt @ 2026-07-28 11:59 UTC (permalink / raw)
To: wse, hansg, ilpo.jarvinen
Cc: Aaron Erhardt, linux-kernel, platform-driver-x86
For RGB LEDs, the HID spec offers an example that uses only two
intensity values for turning LEDs on and off. All other color values
are submitted through the color channels individually, thus avoiding
duplicated handling of brightness.
Signed-off-by: Aaron Erhardt <aer@tuxedocomputers.com>
---
drivers/platform/x86/tuxedo/nb04/wmi_ab.c | 25 ++++++++++++-----------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
index 11babc7c7767..8f1ffca0430d 100644
--- a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
+++ b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
@@ -553,7 +553,7 @@ static int handle_lamp_attributes_response_report(struct hid_device *hdev,
rep->red_level_count = 0xff;
rep->green_level_count = 0xff;
rep->blue_level_count = 0xff;
- rep->intensity_level_count = 0xff;
+ rep->intensity_level_count = 0x1;
rep->is_programmable = 1;
if (driver_data->kbl_map[lamp_id].code <= 0xe8) {
@@ -640,22 +640,23 @@ static int handle_lamp_multi_update_report(struct hid_device *hdev,
j + 1;
rgb_configs_j->key_id = key_id;
/*
- * While this driver respects update_channel.intensity
- * according to "HID Usage Tables v1.5" also on RGB
- * leds, the Microsoft MacroPad reference implementation
+ * This driver uses update_channel.intensity according to
+ * "Color Attributes Examples" in "HID Usage Tables v1.7".
+ * Only two intensity values are allowed for turning LEDs
+ * on or off, while color and brightness can be controlled
+ * through the RGB values. This is also identical to the
+ * Microsoft MacroPad reference implementation
* (https://github.com/microsoft/RP2040MacropadHidSample
- * 1d6c3ad) does not and ignores it. If it turns out
- * that Windows writes intensity = 0 for RGB leds
- * instead of intensity = 255, this driver should also
- * ignore the update_channel.intensity.
+ * 1d6c3ad).
*/
- intensity_i = rep->update_channels[i].intensity;
+ intensity_i = min(1, rep->update_channels[i].intensity);
red_i = rep->update_channels[i].red;
green_i = rep->update_channels[i].green;
blue_i = rep->update_channels[i].blue;
- rgb_configs_j->red = red_i * intensity_i / 0xff;
- rgb_configs_j->green = green_i * intensity_i / 0xff;
- rgb_configs_j->blue = blue_i * intensity_i / 0xff;
+
+ rgb_configs_j->red = red_i * intensity_i;
+ rgb_configs_j->green = green_i * intensity_i;
+ rgb_configs_j->blue = blue_i * intensity_i;
break;
}
--
2.43.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 3/6] platform/x86/tuxedo: Use intensity according to HID spec
2026-07-28 11:59 ` [PATCH 3/6] platform/x86/tuxedo: Use intensity according to HID spec Aaron Erhardt
@ 2026-08-24 15:13 ` Ilpo Järvinen
0 siblings, 0 replies; 5+ messages in thread
From: Ilpo Järvinen @ 2026-08-24 15:13 UTC (permalink / raw)
To: Aaron Erhardt; +Cc: wse, Hans de Goede, LKML, platform-driver-x86
On Tue, 28 Jul 2026, Aaron Erhardt wrote:
> For RGB LEDs, the HID spec offers an example that uses only two
> intensity values for turning LEDs on and off. All other color values
> are submitted through the color channels individually, thus avoiding
> duplicated handling of brightness.
Hi,
If you want to pursue this, please provide better justification. You
basically just rewrote the existing comment that told the current behavior
is intentionally written as it is --- without really explain why you want
to change it and what was problem with the current behavior.
> Signed-off-by: Aaron Erhardt <aer@tuxedocomputers.com>
> ---
> drivers/platform/x86/tuxedo/nb04/wmi_ab.c | 25 ++++++++++++-----------
> 1 file changed, 13 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
> index 11babc7c7767..8f1ffca0430d 100644
> --- a/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
> +++ b/drivers/platform/x86/tuxedo/nb04/wmi_ab.c
> @@ -553,7 +553,7 @@ static int handle_lamp_attributes_response_report(struct hid_device *hdev,
> rep->red_level_count = 0xff;
> rep->green_level_count = 0xff;
> rep->blue_level_count = 0xff;
> - rep->intensity_level_count = 0xff;
> + rep->intensity_level_count = 0x1;
> rep->is_programmable = 1;
>
> if (driver_data->kbl_map[lamp_id].code <= 0xe8) {
> @@ -640,22 +640,23 @@ static int handle_lamp_multi_update_report(struct hid_device *hdev,
> j + 1;
> rgb_configs_j->key_id = key_id;
> /*
> - * While this driver respects update_channel.intensity
> - * according to "HID Usage Tables v1.5" also on RGB
> - * leds, the Microsoft MacroPad reference implementation
> + * This driver uses update_channel.intensity according to
> + * "Color Attributes Examples" in "HID Usage Tables v1.7".
> + * Only two intensity values are allowed for turning LEDs
> + * on or off, while color and brightness can be controlled
> + * through the RGB values. This is also identical to the
> + * Microsoft MacroPad reference implementation
> * (https://github.com/microsoft/RP2040MacropadHidSample
> - * 1d6c3ad) does not and ignores it. If it turns out
> - * that Windows writes intensity = 0 for RGB leds
> - * instead of intensity = 255, this driver should also
> - * ignore the update_channel.intensity.
> + * 1d6c3ad).
> */
> - intensity_i = rep->update_channels[i].intensity;
> + intensity_i = min(1, rep->update_channels[i].intensity);
> red_i = rep->update_channels[i].red;
> green_i = rep->update_channels[i].green;
> blue_i = rep->update_channels[i].blue;
> - rgb_configs_j->red = red_i * intensity_i / 0xff;
> - rgb_configs_j->green = green_i * intensity_i / 0xff;
> - rgb_configs_j->blue = blue_i * intensity_i / 0xff;
> +
> + rgb_configs_j->red = red_i * intensity_i;
> + rgb_configs_j->green = green_i * intensity_i;
> + rgb_configs_j->blue = blue_i * intensity_i;
>
> break;
> }
>
--
i.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-24 15:13 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-28 11:59 [PATCH 0/6] platform/x86/tuxedo: Fixes for TUXEDO NB04 driver Aaron Erhardt
2026-07-28 11:59 ` [PATCH 1/6] platform/x86/tuxedo: Don't use device driver data Aaron Erhardt
2026-07-28 11:59 ` [PATCH 2/6] platform/x86/tuxedo: Set HID report ID on success Aaron Erhardt
2026-07-28 11:59 ` [PATCH 3/6] platform/x86/tuxedo: Use intensity according to HID spec Aaron Erhardt
2026-08-24 15:13 ` Ilpo Järvinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®