* [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature
@ 2026-04-21 20:01 Werner Sembach
2026-04-21 20:01 ` [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits Werner Sembach
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Werner Sembach @ 2026-04-21 20:01 UTC (permalink / raw)
To: W_Armin, hansg, ilpo.jarvinen
Cc: platform-driver-x86, linux-kernel, Werner Sembach
Hi,
This series is based on another not yet accepted series
https://lore.kernel.org/all/20260417050912.5582-1-W_Armin@gmx.de/
RFC because of that, because the third patch is not yet tested, and because
I have a question regarding the 3rd patch:
Should I abstract the call to wmi_evaluate_method away in a wrapper
function in uniwill-wmi somehow, or is it ok to have it straight in the
uniwill-laptop code like that? It is quite self contained.
Best regards,
Werner
Werner Sembach (3):
platform/x86: uniwill-laptop: Make super key init lineup with other
inits
platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
platform/x86: uniwill-laptop: Offer support to activate local dimming
drivers/platform/x86/uniwill/uniwill-acpi.c | 195 ++++++++++++++++++--
1 file changed, 182 insertions(+), 13 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits
2026-04-21 20:01 [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Werner Sembach
@ 2026-04-21 20:01 ` Werner Sembach
2026-04-22 9:33 ` Ilpo Järvinen
2026-04-22 11:11 ` Armin Wolf
2026-04-21 20:01 ` [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19) Werner Sembach
` (2 subsequent siblings)
3 siblings, 2 replies; 15+ messages in thread
From: Werner Sembach @ 2026-04-21 20:01 UTC (permalink / raw)
To: W_Armin, hansg, ilpo.jarvinen
Cc: platform-driver-x86, linux-kernel, Werner Sembach
The super key init, while being trivial, was the only one not in its own
method and before the EC init.
Make an own method and move it after EC init and probe call to make it
consistent with other initialization steps.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
---
drivers/platform/x86/uniwill/uniwill-acpi.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
index 766bc1ee192d2..7d1fdbacc6871 100644
--- a/drivers/platform/x86/uniwill/uniwill-acpi.c
+++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
@@ -768,6 +768,14 @@ static ssize_t super_key_enable_show(struct device *dev, struct device_attribute
static DEVICE_ATTR_RW(super_key_enable);
+static int super_key_enable_init(struct uniwill_data *data)
+{
+ if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
+ return 0;
+
+ return devm_mutex_init(&data->dev, &data->super_key_lock);
+}
+
static int uniwill_write_touchpad_toggle_enable(struct uniwill_data *data, bool status)
{
unsigned int value;
@@ -1869,10 +1877,6 @@ static int uniwill_probe(struct platform_device *pdev)
data->regmap = regmap;
- ret = devm_mutex_init(&pdev->dev, &data->super_key_lock);
- if (ret < 0)
- return ret;
-
ret = uniwill_ec_init(data);
if (ret < 0)
return ret;
@@ -1890,6 +1894,10 @@ static int uniwill_probe(struct platform_device *pdev)
return ret;
}
+ ret = super_key_enable_init(data);
+ if (ret < 0)
+ return ret;
+
ret = uniwill_battery_init(data);
if (ret < 0)
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
2026-04-21 20:01 [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Werner Sembach
2026-04-21 20:01 ` [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits Werner Sembach
@ 2026-04-21 20:01 ` Werner Sembach
2026-04-22 9:34 ` Ilpo Järvinen
2026-04-22 11:17 ` Armin Wolf
2026-04-21 20:01 ` [RFC PATCH 3/3] platform/x86: uniwill-laptop: Offer support to activate local dimming Werner Sembach
2026-04-22 11:28 ` [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Armin Wolf
3 siblings, 2 replies; 15+ messages in thread
From: Werner Sembach @ 2026-04-21 20:01 UTC (permalink / raw)
To: W_Armin, hansg, ilpo.jarvinen
Cc: platform-driver-x86, linux-kernel, Werner Sembach
The XMG Fusion (L19) also has a lightbar but with a different max
brightness value of 36 instead of 200.
This patch adds a new feature flag for the driver to correctly handle this
case and applies it to the mentioned device.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
---
drivers/platform/x86/uniwill/uniwill-acpi.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
index 7d1fdbacc6871..62d56cc67e2e8 100644
--- a/drivers/platform/x86/uniwill/uniwill-acpi.c
+++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
@@ -318,7 +318,6 @@
#define FAN_TABLE_LENGTH 16
#define LED_CHANNELS 3
-#define LED_MAX_BRIGHTNESS 200
#define UNIWILL_FEATURE_FN_LOCK BIT(0)
#define UNIWILL_FEATURE_SUPER_KEY BIT(1)
@@ -344,6 +343,7 @@ struct uniwill_data {
acpi_handle handle;
struct regmap *regmap;
unsigned int features;
+ u8 lightbar_max_brightness;
struct acpi_battery_hook hook;
struct mutex battery_lock; /* Protects the list of currently registered batteries */
union {
@@ -376,6 +376,7 @@ struct uniwill_battery_entry {
struct uniwill_device_descriptor {
unsigned int features;
+ u8 lightbar_max_brightness;
/* Executed during driver probing */
int (*probe)(struct uniwill_data *data);
};
@@ -1340,7 +1341,7 @@ static int uniwill_led_brightness_set(struct led_classdev *led_cdev, enum led_br
for (int i = 0; i < LED_CHANNELS; i++) {
/* Prevent the brightness values from overflowing */
- value = min(LED_MAX_BRIGHTNESS, data->led_mc_subled_info[i].brightness);
+ value = min(data->lightbar_max_brightness, data->led_mc_subled_info[i].brightness);
ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
if (ret < 0)
return ret;
@@ -1376,12 +1377,14 @@ static int uniwill_led_init(struct uniwill_data *data)
LED_COLOR_ID_GREEN,
LED_COLOR_ID_BLUE,
};
- unsigned int value;
+ unsigned int value, max_brightness;
int ret;
if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
return 0;
+ max_brightness = data->lightbar_max_brightness;
+
ret = devm_mutex_init(data->dev, &data->led_lock);
if (ret < 0)
return ret;
@@ -1409,14 +1412,14 @@ static int uniwill_led_init(struct uniwill_data *data)
return ret;
data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI;
- data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS;
+ data->led_mc_cdev.led_cdev.max_brightness = max_brightness;
data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT;
data->led_mc_cdev.led_cdev.brightness_set_blocking = uniwill_led_brightness_set;
if (value & LIGHTBAR_S0_OFF)
data->led_mc_cdev.led_cdev.brightness = 0;
else
- data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS;
+ data->led_mc_cdev.led_cdev.brightness = max_brightness;
for (int i = 0; i < LED_CHANNELS; i++) {
data->led_mc_subled_info[i].color_index = color_indices[i];
@@ -1429,7 +1432,7 @@ static int uniwill_led_init(struct uniwill_data *data)
* Make sure that the initial intensity value is not greater than
* the maximum brightness.
*/
- value = min(LED_MAX_BRIGHTNESS, value);
+ value = min(max_brightness, value);
ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
if (ret < 0)
return ret;
@@ -1882,6 +1885,7 @@ static int uniwill_probe(struct platform_device *pdev)
return ret;
data->features = device_descriptor.features;
+ data->lightbar_max_brightness = device_descriptor.lightbar_max_brightness;
/*
* Some devices might need to perform some device-specific initialization steps
@@ -2130,11 +2134,13 @@ static struct platform_driver uniwill_driver = {
static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor __initdata = {
.features = UNIWILL_FEATURE_SUPER_KEY |
+ UNIWILL_FEATURE_LIGHTBAR |
UNIWILL_FEATURE_BATTERY_CHARGE_LIMIT |
UNIWILL_FEATURE_CPU_TEMP |
UNIWILL_FEATURE_GPU_TEMP |
UNIWILL_FEATURE_PRIMARY_FAN |
UNIWILL_FEATURE_SECONDARY_FAN,
+ .lightbar_max_brightness = 36,
};
static struct uniwill_device_descriptor lapac71h_descriptor __initdata = {
@@ -2158,6 +2164,7 @@ static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = {
UNIWILL_FEATURE_GPU_TEMP |
UNIWILL_FEATURE_PRIMARY_FAN |
UNIWILL_FEATURE_SECONDARY_FAN,
+ .lightbar_max_brightness = 200,
};
/*
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [RFC PATCH 3/3] platform/x86: uniwill-laptop: Offer support to activate local dimming
2026-04-21 20:01 [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Werner Sembach
2026-04-21 20:01 ` [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits Werner Sembach
2026-04-21 20:01 ` [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19) Werner Sembach
@ 2026-04-21 20:01 ` Werner Sembach
2026-04-21 22:03 ` Armin Wolf
2026-04-22 11:28 ` [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Armin Wolf
3 siblings, 1 reply; 15+ messages in thread
From: Werner Sembach @ 2026-04-21 20:01 UTC (permalink / raw)
To: W_Armin, hansg, ilpo.jarvinen
Cc: platform-driver-x86, linux-kernel, Werner Sembach
This patch adds a sysfs variable local_dimming to supported devices.
Setting it to true enables local dimming for the internal notebook display.
Currently only TUXEDO Stellaris 16 Gen7 Intel/AMD with mLED displays are
supported.
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
---
drivers/platform/x86/uniwill/uniwill-acpi.c | 162 +++++++++++++++++++-
1 file changed, 158 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
index 62d56cc67e2e8..909d8608a2f80 100644
--- a/drivers/platform/x86/uniwill/uniwill-acpi.c
+++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
@@ -275,6 +275,9 @@
#define EC_ADDR_USB_C_POWER_PRIORITY 0x07CC
#define USB_C_POWER_PRIORITY BIT(7)
+#define EC_ADDR_LOCAL_DIMMING_SUPPORT 0x0D4F
+#define LOCAL_DIMMING_SUPPORT BIT(0)
+
/* Same bits as EC_ADDR_LIGHTBAR_AC_CTRL except LIGHTBAR_S3_OFF */
#define EC_ADDR_LIGHTBAR_BAT_CTRL 0x07E2
@@ -296,6 +299,14 @@
#define EC_ADDR_GPU_FAN_SPEED_TABLE 0x0F50
+#define WMI_GUID_BC "ABBC0F6F-8EA1-11D1-00A0-C90629100000"
+#define WMI_DEFAULT_INSTANCE 0x00
+#define WMI_DEFAULT_METHOD 0x04
+
+#define WMI_FUNC_SET_FEATURE 0x00000500
+#define WMI_FEATURE_LOCAL_DIMMING_OFF 0x0d
+#define WMI_FEATURE_LOCAL_DIMMING_ON 0x0e
+
/*
* Those two registers technically allow for manual fan control,
* but are unstable on some models and are likely not meant to
@@ -332,6 +343,7 @@
#define UNIWILL_FEATURE_SECONDARY_FAN BIT(9)
#define UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL BIT(10)
#define UNIWILL_FEATURE_USB_C_POWER_PRIORITY BIT(11)
+#define UNIWILL_FEATURE_LOCAL_DIMMING BIT(12)
enum usb_c_power_priority_options {
USB_C_POWER_PRIORITY_CHARGING = 0,
@@ -367,6 +379,8 @@ struct uniwill_data {
struct notifier_block nb;
struct mutex usb_c_power_priority_lock; /* Protects dependent bit write and state safe */
enum usb_c_power_priority_options last_usb_c_power_priority_option;
+ struct mutex local_dimming_lock; /* Protects call to local dimming wmi method */
+ bool last_local_dimming_option;
};
struct uniwill_battery_entry {
@@ -774,7 +788,7 @@ static int super_key_enable_init(struct uniwill_data *data)
if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
return 0;
- return devm_mutex_init(&data->dev, &data->super_key_lock);
+ return devm_mutex_init(data->dev, &data->super_key_lock);
}
static int uniwill_write_touchpad_toggle_enable(struct uniwill_data *data, bool status)
@@ -1086,6 +1100,87 @@ static int usb_c_power_priority_init(struct uniwill_data *data)
return 0;
}
+struct __packed uniwill_wmi_input {
+ u8 args[4];
+ u32 function;
+ /* Prevent accidential out of bounds access by the ACPI code */
+ u32 reserved[8];
+};
+
+static int set_local_dimming(bool enable)
+{
+ struct __packed uniwill_wmi_input wmi_input;
+ struct acpi_buffer wmi_buf = { (acpi_size) sizeof(wmi_input), &wmi_input };
+ acpi_status status;
+
+ wmi_input.function = WMI_FUNC_SET_FEATURE;
+ wmi_input.args[0] = enable ? WMI_FEATURE_LOCAL_DIMMING_ON : WMI_FEATURE_LOCAL_DIMMING_OFF;
+
+ status = wmi_evaluate_method(WMI_GUID_BC, WMI_DEFAULT_INSTANCE, WMI_DEFAULT_METHOD,
+ &wmi_buf, &wmi_buf);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+}
+
+static ssize_t local_dimming_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct uniwill_data *data = dev_get_drvdata(dev);
+ bool enable;
+ int ret;
+
+ ret = kstrtobool(buf, &enable);
+ if (ret < 0)
+ return ret;
+
+ guard(mutex)(&data->local_dimming_lock);
+
+ ret = set_local_dimming(enable);
+ if (ret)
+ return ret;
+
+ data->last_local_dimming_option = enable;
+
+ return count;
+}
+
+static ssize_t local_dimming_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct uniwill_data *data = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%d\n", data->last_local_dimming_option);
+}
+
+static DEVICE_ATTR_RW(local_dimming);
+
+static int local_dimming_restore(struct uniwill_data *data)
+{
+ guard(mutex)(&data->local_dimming_lock);
+
+ return set_local_dimming(data->last_local_dimming_option);
+}
+
+static int local_dimming_init(struct uniwill_data *data)
+{
+ int ret;
+
+ if (!uniwill_device_supports(data, UNIWILL_FEATURE_LOCAL_DIMMING))
+ return 0;
+
+ ret = devm_mutex_init(data->dev, &data->local_dimming_lock);
+ if (ret < 0)
+ return ret;
+
+ data->last_local_dimming_option = 0;
+
+ return local_dimming_restore(data);
+}
+
static struct attribute *uniwill_attrs[] = {
/* Keyboard-related */
&dev_attr_fn_lock.attr,
@@ -1097,6 +1192,7 @@ static struct attribute *uniwill_attrs[] = {
/* Power-management-related */
&dev_attr_ctgp_offset.attr,
&dev_attr_usb_c_power_priority.attr,
+ &dev_attr_local_dimming.attr,
NULL
};
@@ -1136,6 +1232,11 @@ static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *a
return attr->mode;
}
+ if (attr == &dev_attr_local_dimming.attr) {
+ if (uniwill_device_supports(data, UNIWILL_FEATURE_LOCAL_DIMMING))
+ return attr->mode;
+ }
+
return 0;
}
@@ -1922,6 +2023,10 @@ static int uniwill_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ ret = local_dimming_init(data);
+ if (ret < 0)
+ return ret;
+
return uniwill_input_init(data);
}
@@ -2075,6 +2180,14 @@ static int uniwill_resume_usb_c_power_priority(struct uniwill_data *data)
return usb_c_power_priority_restore(data);
}
+static int uniwill_resume_local_dimming(struct uniwill_data *data)
+{
+ if (!uniwill_device_supports(data, UNIWILL_FEATURE_LOCAL_DIMMING))
+ return 0;
+
+ return local_dimming_restore(data);
+}
+
static int uniwill_resume(struct device *dev)
{
struct uniwill_data *data = dev_get_drvdata(dev);
@@ -2106,7 +2219,11 @@ static int uniwill_resume(struct device *dev)
if (ret < 0)
return ret;
- return uniwill_resume_usb_c_power_priority(data);
+ ret = uniwill_resume_usb_c_power_priority(data);
+ if (ret < 0)
+ return ret;
+
+ return uniwill_resume_local_dimming(data);
}
static DEFINE_SIMPLE_DEV_PM_OPS(uniwill_pm_ops, uniwill_suspend, uniwill_resume);
@@ -2222,6 +2339,17 @@ static struct uniwill_device_descriptor tux_featureset_3_nvidia_descriptor __ini
UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL,
};
+static struct uniwill_device_descriptor tux_featureset_3_nvidia_mled_descriptor __initdata = {
+ .features = UNIWILL_FEATURE_FN_LOCK |
+ UNIWILL_FEATURE_SUPER_KEY |
+ UNIWILL_FEATURE_CPU_TEMP |
+ UNIWILL_FEATURE_GPU_TEMP |
+ UNIWILL_FEATURE_PRIMARY_FAN |
+ UNIWILL_FEATURE_SECONDARY_FAN |
+ UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL |
+ UNIWILL_FEATURE_LOCAL_DIMMING,
+};
+
static int phxtxx1_probe(struct uniwill_data *data)
{
unsigned int value;
@@ -2272,6 +2400,32 @@ static struct uniwill_device_descriptor phxarx1_phxaqf1_descriptor __initdata =
.probe = phxarx1_phxaqf1_probe,
};
+static int x6fr5xxy_probe(struct uniwill_data *data)
+{
+ unsigned int value;
+ int ret;
+
+ ret = regmap_read(data->regmap, EC_ADDR_LOCAL_DIMMING_SUPPORT, &value);
+ if (ret < 0)
+ return ret;
+
+ if (value != 0xff && value & LOCAL_DIMMING_SUPPORT)
+ data->features |= UNIWILL_FEATURE_LOCAL_DIMMING;
+
+ return 0;
+};
+
+static struct uniwill_device_descriptor x6fr5xxy_descriptor __initdata = {
+ .features = UNIWILL_FEATURE_FN_LOCK |
+ UNIWILL_FEATURE_SUPER_KEY |
+ UNIWILL_FEATURE_CPU_TEMP |
+ UNIWILL_FEATURE_GPU_TEMP |
+ UNIWILL_FEATURE_PRIMARY_FAN |
+ UNIWILL_FEATURE_SECONDARY_FAN |
+ UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL,
+ .probe = x6fr5xxy_probe,
+};
+
static struct uniwill_device_descriptor pf5pu1g_descriptor __initdata = {
.features = UNIWILL_FEATURE_FN_LOCK |
UNIWILL_FEATURE_SUPER_KEY |
@@ -2662,7 +2816,7 @@ static const struct dmi_system_id uniwill_dmi_table[] __initconst = {
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6FR5xxY"),
},
- .driver_data = &tux_featureset_3_nvidia_descriptor,
+ .driver_data = &x6fr5xxy_descriptor,
},
{
.ident = "TUXEDO Stellaris 16 Gen7 Intel",
@@ -2678,7 +2832,7 @@ static const struct dmi_system_id uniwill_dmi_table[] __initconst = {
DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY_mLED"),
},
- .driver_data = &tux_featureset_3_nvidia_descriptor,
+ .driver_data = &tux_featureset_3_nvidia_mled_descriptor,
},
{
.ident = "TUXEDO Book BA15 Gen10 AMD",
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 3/3] platform/x86: uniwill-laptop: Offer support to activate local dimming
2026-04-21 20:01 ` [RFC PATCH 3/3] platform/x86: uniwill-laptop: Offer support to activate local dimming Werner Sembach
@ 2026-04-21 22:03 ` Armin Wolf
0 siblings, 0 replies; 15+ messages in thread
From: Armin Wolf @ 2026-04-21 22:03 UTC (permalink / raw)
To: Werner Sembach, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 21.04.26 um 22:01 schrieb Werner Sembach:
> This patch adds a sysfs variable local_dimming to supported devices.
> Setting it to true enables local dimming for the internal notebook display.
>
> Currently only TUXEDO Stellaris 16 Gen7 Intel/AMD with mLED displays are
> supported.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
> drivers/platform/x86/uniwill/uniwill-acpi.c | 162 +++++++++++++++++++-
> 1 file changed, 158 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
> index 62d56cc67e2e8..909d8608a2f80 100644
> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
> @@ -275,6 +275,9 @@
> #define EC_ADDR_USB_C_POWER_PRIORITY 0x07CC
> #define USB_C_POWER_PRIORITY BIT(7)
>
> +#define EC_ADDR_LOCAL_DIMMING_SUPPORT 0x0D4F
> +#define LOCAL_DIMMING_SUPPORT BIT(0)
> +
> /* Same bits as EC_ADDR_LIGHTBAR_AC_CTRL except LIGHTBAR_S3_OFF */
> #define EC_ADDR_LIGHTBAR_BAT_CTRL 0x07E2
>
> @@ -296,6 +299,14 @@
>
> #define EC_ADDR_GPU_FAN_SPEED_TABLE 0x0F50
>
> +#define WMI_GUID_BC "ABBC0F6F-8EA1-11D1-00A0-C90629100000"
> +#define WMI_DEFAULT_INSTANCE 0x00
> +#define WMI_DEFAULT_METHOD 0x04
> +
> +#define WMI_FUNC_SET_FEATURE 0x00000500
> +#define WMI_FEATURE_LOCAL_DIMMING_OFF 0x0d
> +#define WMI_FEATURE_LOCAL_DIMMING_ON 0x0e
> +
> /*
> * Those two registers technically allow for manual fan control,
> * but are unstable on some models and are likely not meant to
> @@ -332,6 +343,7 @@
> #define UNIWILL_FEATURE_SECONDARY_FAN BIT(9)
> #define UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL BIT(10)
> #define UNIWILL_FEATURE_USB_C_POWER_PRIORITY BIT(11)
> +#define UNIWILL_FEATURE_LOCAL_DIMMING BIT(12)
>
> enum usb_c_power_priority_options {
> USB_C_POWER_PRIORITY_CHARGING = 0,
> @@ -367,6 +379,8 @@ struct uniwill_data {
> struct notifier_block nb;
> struct mutex usb_c_power_priority_lock; /* Protects dependent bit write and state safe */
> enum usb_c_power_priority_options last_usb_c_power_priority_option;
> + struct mutex local_dimming_lock; /* Protects call to local dimming wmi method */
> + bool last_local_dimming_option;
> };
>
> struct uniwill_battery_entry {
> @@ -774,7 +788,7 @@ static int super_key_enable_init(struct uniwill_data *data)
> if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
> return 0;
>
> - return devm_mutex_init(&data->dev, &data->super_key_lock);
> + return devm_mutex_init(data->dev, &data->super_key_lock);
> }
>
> static int uniwill_write_touchpad_toggle_enable(struct uniwill_data *data, bool status)
> @@ -1086,6 +1100,87 @@ static int usb_c_power_priority_init(struct uniwill_data *data)
> return 0;
> }
>
> +struct __packed uniwill_wmi_input {
> + u8 args[4];
> + u32 function;
> + /* Prevent accidential out of bounds access by the ACPI code */
> + u32 reserved[8];
> +};
> +
> +static int set_local_dimming(bool enable)
> +{
> + struct __packed uniwill_wmi_input wmi_input;
> + struct acpi_buffer wmi_buf = { (acpi_size) sizeof(wmi_input), &wmi_input };
> + acpi_status status;
> +
> + wmi_input.function = WMI_FUNC_SET_FEATURE;
> + wmi_input.args[0] = enable ? WMI_FEATURE_LOCAL_DIMMING_ON : WMI_FEATURE_LOCAL_DIMMING_OFF;
> +
> + status = wmi_evaluate_method(WMI_GUID_BC, WMI_DEFAULT_INSTANCE, WMI_DEFAULT_METHOD,
> + &wmi_buf, &wmi_buf);
NAK, this API is deprecated and should not be used. Instead we should register a WMI driver during module
initialization that uses wmidev_invoke_method().
Can you share with me the ACPI tables of a device that supports this feature?
Thanks,
Armin Wolf
> + if (ACPI_FAILURE(status))
> + return -EIO;
> +
> + return 0;
> +}
> +
> +static ssize_t local_dimming_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct uniwill_data *data = dev_get_drvdata(dev);
> + bool enable;
> + int ret;
> +
> + ret = kstrtobool(buf, &enable);
> + if (ret < 0)
> + return ret;
> +
> + guard(mutex)(&data->local_dimming_lock);
> +
> + ret = set_local_dimming(enable);
> + if (ret)
> + return ret;
> +
> + data->last_local_dimming_option = enable;
> +
> + return count;
> +}
> +
> +static ssize_t local_dimming_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct uniwill_data *data = dev_get_drvdata(dev);
> +
> + return sysfs_emit(buf, "%d\n", data->last_local_dimming_option);
> +}
> +
> +static DEVICE_ATTR_RW(local_dimming);
> +
> +static int local_dimming_restore(struct uniwill_data *data)
> +{
> + guard(mutex)(&data->local_dimming_lock);
> +
> + return set_local_dimming(data->last_local_dimming_option);
> +}
> +
> +static int local_dimming_init(struct uniwill_data *data)
> +{
> + int ret;
> +
> + if (!uniwill_device_supports(data, UNIWILL_FEATURE_LOCAL_DIMMING))
> + return 0;
> +
> + ret = devm_mutex_init(data->dev, &data->local_dimming_lock);
> + if (ret < 0)
> + return ret;
> +
> + data->last_local_dimming_option = 0;
> +
> + return local_dimming_restore(data);
> +}
> +
> static struct attribute *uniwill_attrs[] = {
> /* Keyboard-related */
> &dev_attr_fn_lock.attr,
> @@ -1097,6 +1192,7 @@ static struct attribute *uniwill_attrs[] = {
> /* Power-management-related */
> &dev_attr_ctgp_offset.attr,
> &dev_attr_usb_c_power_priority.attr,
> + &dev_attr_local_dimming.attr,
> NULL
> };
>
> @@ -1136,6 +1232,11 @@ static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *a
> return attr->mode;
> }
>
> + if (attr == &dev_attr_local_dimming.attr) {
> + if (uniwill_device_supports(data, UNIWILL_FEATURE_LOCAL_DIMMING))
> + return attr->mode;
> + }
> +
> return 0;
> }
>
> @@ -1922,6 +2023,10 @@ static int uniwill_probe(struct platform_device *pdev)
> if (ret < 0)
> return ret;
>
> + ret = local_dimming_init(data);
> + if (ret < 0)
> + return ret;
> +
> return uniwill_input_init(data);
> }
>
> @@ -2075,6 +2180,14 @@ static int uniwill_resume_usb_c_power_priority(struct uniwill_data *data)
> return usb_c_power_priority_restore(data);
> }
>
> +static int uniwill_resume_local_dimming(struct uniwill_data *data)
> +{
> + if (!uniwill_device_supports(data, UNIWILL_FEATURE_LOCAL_DIMMING))
> + return 0;
> +
> + return local_dimming_restore(data);
> +}
> +
> static int uniwill_resume(struct device *dev)
> {
> struct uniwill_data *data = dev_get_drvdata(dev);
> @@ -2106,7 +2219,11 @@ static int uniwill_resume(struct device *dev)
> if (ret < 0)
> return ret;
>
> - return uniwill_resume_usb_c_power_priority(data);
> + ret = uniwill_resume_usb_c_power_priority(data);
> + if (ret < 0)
> + return ret;
> +
> + return uniwill_resume_local_dimming(data);
> }
>
> static DEFINE_SIMPLE_DEV_PM_OPS(uniwill_pm_ops, uniwill_suspend, uniwill_resume);
> @@ -2222,6 +2339,17 @@ static struct uniwill_device_descriptor tux_featureset_3_nvidia_descriptor __ini
> UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL,
> };
>
> +static struct uniwill_device_descriptor tux_featureset_3_nvidia_mled_descriptor __initdata = {
> + .features = UNIWILL_FEATURE_FN_LOCK |
> + UNIWILL_FEATURE_SUPER_KEY |
> + UNIWILL_FEATURE_CPU_TEMP |
> + UNIWILL_FEATURE_GPU_TEMP |
> + UNIWILL_FEATURE_PRIMARY_FAN |
> + UNIWILL_FEATURE_SECONDARY_FAN |
> + UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL |
> + UNIWILL_FEATURE_LOCAL_DIMMING,
> +};
> +
> static int phxtxx1_probe(struct uniwill_data *data)
> {
> unsigned int value;
> @@ -2272,6 +2400,32 @@ static struct uniwill_device_descriptor phxarx1_phxaqf1_descriptor __initdata =
> .probe = phxarx1_phxaqf1_probe,
> };
>
> +static int x6fr5xxy_probe(struct uniwill_data *data)
> +{
> + unsigned int value;
> + int ret;
> +
> + ret = regmap_read(data->regmap, EC_ADDR_LOCAL_DIMMING_SUPPORT, &value);
> + if (ret < 0)
> + return ret;
> +
> + if (value != 0xff && value & LOCAL_DIMMING_SUPPORT)
> + data->features |= UNIWILL_FEATURE_LOCAL_DIMMING;
> +
> + return 0;
> +};
> +
> +static struct uniwill_device_descriptor x6fr5xxy_descriptor __initdata = {
> + .features = UNIWILL_FEATURE_FN_LOCK |
> + UNIWILL_FEATURE_SUPER_KEY |
> + UNIWILL_FEATURE_CPU_TEMP |
> + UNIWILL_FEATURE_GPU_TEMP |
> + UNIWILL_FEATURE_PRIMARY_FAN |
> + UNIWILL_FEATURE_SECONDARY_FAN |
> + UNIWILL_FEATURE_NVIDIA_CTGP_CONTROL,
> + .probe = x6fr5xxy_probe,
> +};
> +
> static struct uniwill_device_descriptor pf5pu1g_descriptor __initdata = {
> .features = UNIWILL_FEATURE_FN_LOCK |
> UNIWILL_FEATURE_SUPER_KEY |
> @@ -2662,7 +2816,7 @@ static const struct dmi_system_id uniwill_dmi_table[] __initconst = {
> DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
> DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6FR5xxY"),
> },
> - .driver_data = &tux_featureset_3_nvidia_descriptor,
> + .driver_data = &x6fr5xxy_descriptor,
> },
> {
> .ident = "TUXEDO Stellaris 16 Gen7 Intel",
> @@ -2678,7 +2832,7 @@ static const struct dmi_system_id uniwill_dmi_table[] __initconst = {
> DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
> DMI_EXACT_MATCH(DMI_BOARD_NAME, "X6AR5xxY_mLED"),
> },
> - .driver_data = &tux_featureset_3_nvidia_descriptor,
> + .driver_data = &tux_featureset_3_nvidia_mled_descriptor,
> },
> {
> .ident = "TUXEDO Book BA15 Gen10 AMD",
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits
2026-04-21 20:01 ` [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits Werner Sembach
@ 2026-04-22 9:33 ` Ilpo Järvinen
2026-04-22 11:11 ` Armin Wolf
1 sibling, 0 replies; 15+ messages in thread
From: Ilpo Järvinen @ 2026-04-22 9:33 UTC (permalink / raw)
To: Werner Sembach; +Cc: W_Armin, Hans de Goede, platform-driver-x86, LKML
[-- Attachment #1: Type: text/plain, Size: 1891 bytes --]
On Tue, 21 Apr 2026, Werner Sembach wrote:
> The super key init, while being trivial, was the only one not in its own
> method and before the EC init.
>
> Make an own method and move it after EC init and probe call to make it
> consistent with other initialization steps.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
> drivers/platform/x86/uniwill/uniwill-acpi.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
> index 766bc1ee192d2..7d1fdbacc6871 100644
> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
> @@ -768,6 +768,14 @@ static ssize_t super_key_enable_show(struct device *dev, struct device_attribute
>
> static DEVICE_ATTR_RW(super_key_enable);
>
> +static int super_key_enable_init(struct uniwill_data *data)
> +{
> + if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
> + return 0;
> +
> + return devm_mutex_init(&data->dev, &data->super_key_lock);
> +}
> +
> static int uniwill_write_touchpad_toggle_enable(struct uniwill_data *data, bool status)
> {
> unsigned int value;
> @@ -1869,10 +1877,6 @@ static int uniwill_probe(struct platform_device *pdev)
>
> data->regmap = regmap;
>
> - ret = devm_mutex_init(&pdev->dev, &data->super_key_lock);
> - if (ret < 0)
> - return ret;
> -
> ret = uniwill_ec_init(data);
> if (ret < 0)
> return ret;
> @@ -1890,6 +1894,10 @@ static int uniwill_probe(struct platform_device *pdev)
> return ret;
> }
>
> + ret = super_key_enable_init(data);
> + if (ret < 0)
> + return ret;
> +
> ret = uniwill_battery_init(data);
> if (ret < 0)
> return ret;
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
2026-04-21 20:01 ` [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19) Werner Sembach
@ 2026-04-22 9:34 ` Ilpo Järvinen
2026-04-22 11:17 ` Armin Wolf
1 sibling, 0 replies; 15+ messages in thread
From: Ilpo Järvinen @ 2026-04-22 9:34 UTC (permalink / raw)
To: Werner Sembach; +Cc: W_Armin, Hans de Goede, platform-driver-x86, LKML
[-- Attachment #1: Type: text/plain, Size: 4944 bytes --]
On Tue, 21 Apr 2026, Werner Sembach wrote:
> The XMG Fusion (L19) also has a lightbar but with a different max
> brightness value of 36 instead of 200.
>
> This patch adds a new feature flag for the driver to correctly handle this
> case and applies it to the mentioned device.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
> drivers/platform/x86/uniwill/uniwill-acpi.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
> index 7d1fdbacc6871..62d56cc67e2e8 100644
> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
> @@ -318,7 +318,6 @@
> #define FAN_TABLE_LENGTH 16
>
> #define LED_CHANNELS 3
> -#define LED_MAX_BRIGHTNESS 200
>
> #define UNIWILL_FEATURE_FN_LOCK BIT(0)
> #define UNIWILL_FEATURE_SUPER_KEY BIT(1)
> @@ -344,6 +343,7 @@ struct uniwill_data {
> acpi_handle handle;
> struct regmap *regmap;
> unsigned int features;
> + u8 lightbar_max_brightness;
> struct acpi_battery_hook hook;
> struct mutex battery_lock; /* Protects the list of currently registered batteries */
> union {
> @@ -376,6 +376,7 @@ struct uniwill_battery_entry {
>
> struct uniwill_device_descriptor {
> unsigned int features;
> + u8 lightbar_max_brightness;
> /* Executed during driver probing */
> int (*probe)(struct uniwill_data *data);
> };
> @@ -1340,7 +1341,7 @@ static int uniwill_led_brightness_set(struct led_classdev *led_cdev, enum led_br
>
> for (int i = 0; i < LED_CHANNELS; i++) {
> /* Prevent the brightness values from overflowing */
> - value = min(LED_MAX_BRIGHTNESS, data->led_mc_subled_info[i].brightness);
> + value = min(data->lightbar_max_brightness, data->led_mc_subled_info[i].brightness);
> ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
> if (ret < 0)
> return ret;
> @@ -1376,12 +1377,14 @@ static int uniwill_led_init(struct uniwill_data *data)
> LED_COLOR_ID_GREEN,
> LED_COLOR_ID_BLUE,
> };
> - unsigned int value;
> + unsigned int value, max_brightness;
> int ret;
>
> if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
> return 0;
>
> + max_brightness = data->lightbar_max_brightness;
> +
> ret = devm_mutex_init(data->dev, &data->led_lock);
> if (ret < 0)
> return ret;
> @@ -1409,14 +1412,14 @@ static int uniwill_led_init(struct uniwill_data *data)
> return ret;
>
> data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI;
> - data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS;
> + data->led_mc_cdev.led_cdev.max_brightness = max_brightness;
> data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT;
> data->led_mc_cdev.led_cdev.brightness_set_blocking = uniwill_led_brightness_set;
>
> if (value & LIGHTBAR_S0_OFF)
> data->led_mc_cdev.led_cdev.brightness = 0;
> else
> - data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS;
> + data->led_mc_cdev.led_cdev.brightness = max_brightness;
>
> for (int i = 0; i < LED_CHANNELS; i++) {
> data->led_mc_subled_info[i].color_index = color_indices[i];
> @@ -1429,7 +1432,7 @@ static int uniwill_led_init(struct uniwill_data *data)
> * Make sure that the initial intensity value is not greater than
> * the maximum brightness.
> */
> - value = min(LED_MAX_BRIGHTNESS, value);
> + value = min(max_brightness, value);
> ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
> if (ret < 0)
> return ret;
> @@ -1882,6 +1885,7 @@ static int uniwill_probe(struct platform_device *pdev)
> return ret;
>
> data->features = device_descriptor.features;
> + data->lightbar_max_brightness = device_descriptor.lightbar_max_brightness;
>
> /*
> * Some devices might need to perform some device-specific initialization steps
> @@ -2130,11 +2134,13 @@ static struct platform_driver uniwill_driver = {
>
> static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor __initdata = {
> .features = UNIWILL_FEATURE_SUPER_KEY |
> + UNIWILL_FEATURE_LIGHTBAR |
> UNIWILL_FEATURE_BATTERY_CHARGE_LIMIT |
> UNIWILL_FEATURE_CPU_TEMP |
> UNIWILL_FEATURE_GPU_TEMP |
> UNIWILL_FEATURE_PRIMARY_FAN |
> UNIWILL_FEATURE_SECONDARY_FAN,
> + .lightbar_max_brightness = 36,
> };
>
> static struct uniwill_device_descriptor lapac71h_descriptor __initdata = {
> @@ -2158,6 +2164,7 @@ static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = {
> UNIWILL_FEATURE_GPU_TEMP |
> UNIWILL_FEATURE_PRIMARY_FAN |
> UNIWILL_FEATURE_SECONDARY_FAN,
> + .lightbar_max_brightness = 200,
> };
>
> /*
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits
2026-04-21 20:01 ` [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits Werner Sembach
2026-04-22 9:33 ` Ilpo Järvinen
@ 2026-04-22 11:11 ` Armin Wolf
1 sibling, 0 replies; 15+ messages in thread
From: Armin Wolf @ 2026-04-22 11:11 UTC (permalink / raw)
To: Werner Sembach, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 21.04.26 um 22:01 schrieb Werner Sembach:
> The super key init, while being trivial, was the only one not in its own
> method and before the EC init.
>
> Make an own method and move it after EC init and probe call to make it
> consistent with other initialization steps.
>
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
> drivers/platform/x86/uniwill/uniwill-acpi.c | 16 ++++++++++++----
> 1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
> index 766bc1ee192d2..7d1fdbacc6871 100644
> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
> @@ -768,6 +768,14 @@ static ssize_t super_key_enable_show(struct device *dev, struct device_attribute
>
> static DEVICE_ATTR_RW(super_key_enable);
>
> +static int super_key_enable_init(struct uniwill_data *data)
> +{
> + if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY))
> + return 0;
> +
> + return devm_mutex_init(&data->dev, &data->super_key_lock);
> +}
> +
> static int uniwill_write_touchpad_toggle_enable(struct uniwill_data *data, bool status)
> {
> unsigned int value;
> @@ -1869,10 +1877,6 @@ static int uniwill_probe(struct platform_device *pdev)
>
> data->regmap = regmap;
>
> - ret = devm_mutex_init(&pdev->dev, &data->super_key_lock);
> - if (ret < 0)
> - return ret;
> -
> ret = uniwill_ec_init(data);
> if (ret < 0)
> return ret;
> @@ -1890,6 +1894,10 @@ static int uniwill_probe(struct platform_device *pdev)
> return ret;
> }
>
> + ret = super_key_enable_init(data);
> + if (ret < 0)
> + return ret;
> +
> ret = uniwill_battery_init(data);
> if (ret < 0)
> return ret;
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
2026-04-21 20:01 ` [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19) Werner Sembach
2026-04-22 9:34 ` Ilpo Järvinen
@ 2026-04-22 11:17 ` Armin Wolf
2026-04-22 11:29 ` Armin Wolf
2026-04-22 13:13 ` Werner Sembach
1 sibling, 2 replies; 15+ messages in thread
From: Armin Wolf @ 2026-04-22 11:17 UTC (permalink / raw)
To: Werner Sembach, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 21.04.26 um 22:01 schrieb Werner Sembach:
> The XMG Fusion (L19) also has a lightbar but with a different max
> brightness value of 36 instead of 200.
>
> This patch adds a new feature flag for the driver to correctly handle this
> case and applies it to the mentioned device.
>
> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
> ---
> drivers/platform/x86/uniwill/uniwill-acpi.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c
> index 7d1fdbacc6871..62d56cc67e2e8 100644
> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
> @@ -318,7 +318,6 @@
> #define FAN_TABLE_LENGTH 16
>
> #define LED_CHANNELS 3
> -#define LED_MAX_BRIGHTNESS 200
>
> #define UNIWILL_FEATURE_FN_LOCK BIT(0)
> #define UNIWILL_FEATURE_SUPER_KEY BIT(1)
> @@ -344,6 +343,7 @@ struct uniwill_data {
> acpi_handle handle;
> struct regmap *regmap;
> unsigned int features;
> + u8 lightbar_max_brightness;
> struct acpi_battery_hook hook;
> struct mutex battery_lock; /* Protects the list of currently registered batteries */
> union {
> @@ -376,6 +376,7 @@ struct uniwill_battery_entry {
>
> struct uniwill_device_descriptor {
> unsigned int features;
> + u8 lightbar_max_brightness;
> /* Executed during driver probing */
> int (*probe)(struct uniwill_data *data);
> };
> @@ -1340,7 +1341,7 @@ static int uniwill_led_brightness_set(struct led_classdev *led_cdev, enum led_br
>
> for (int i = 0; i < LED_CHANNELS; i++) {
> /* Prevent the brightness values from overflowing */
> - value = min(LED_MAX_BRIGHTNESS, data->led_mc_subled_info[i].brightness);
> + value = min(data->lightbar_max_brightness, data->led_mc_subled_info[i].brightness);
> ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
> if (ret < 0)
> return ret;
> @@ -1376,12 +1377,14 @@ static int uniwill_led_init(struct uniwill_data *data)
> LED_COLOR_ID_GREEN,
> LED_COLOR_ID_BLUE,
> };
> - unsigned int value;
> + unsigned int value, max_brightness;
> int ret;
>
> if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
> return 0;
>
> + max_brightness = data->lightbar_max_brightness;
Please drop the max_brightness variable and assign
led_cdev.max_brightness and led_cdev.brightness directly.
> +
> ret = devm_mutex_init(data->dev, &data->led_lock);
> if (ret < 0)
> return ret;
> @@ -1409,14 +1412,14 @@ static int uniwill_led_init(struct uniwill_data *data)
> return ret;
>
> data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI;
> - data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS;
> + data->led_mc_cdev.led_cdev.max_brightness = max_brightness;
> data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT;
> data->led_mc_cdev.led_cdev.brightness_set_blocking = uniwill_led_brightness_set;
>
> if (value & LIGHTBAR_S0_OFF)
> data->led_mc_cdev.led_cdev.brightness = 0;
> else
> - data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS;
> + data->led_mc_cdev.led_cdev.brightness = max_brightness;
>
> for (int i = 0; i < LED_CHANNELS; i++) {
> data->led_mc_subled_info[i].color_index = color_indices[i];
> @@ -1429,7 +1432,7 @@ static int uniwill_led_init(struct uniwill_data *data)
> * Make sure that the initial intensity value is not greater than
> * the maximum brightness.
> */
> - value = min(LED_MAX_BRIGHTNESS, value);
> + value = min(max_brightness, value);
> ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i], value);
> if (ret < 0)
> return ret;
> @@ -1882,6 +1885,7 @@ static int uniwill_probe(struct platform_device *pdev)
> return ret;
>
> data->features = device_descriptor.features;
> + data->lightbar_max_brightness = device_descriptor.lightbar_max_brightness;
>
> /*
> * Some devices might need to perform some device-specific initialization steps
> @@ -2130,11 +2134,13 @@ static struct platform_driver uniwill_driver = {
>
> static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor __initdata = {
> .features = UNIWILL_FEATURE_SUPER_KEY |
> + UNIWILL_FEATURE_LIGHTBAR |
> UNIWILL_FEATURE_BATTERY_CHARGE_LIMIT |
> UNIWILL_FEATURE_CPU_TEMP |
> UNIWILL_FEATURE_GPU_TEMP |
> UNIWILL_FEATURE_PRIMARY_FAN |
> UNIWILL_FEATURE_SECONDARY_FAN,
> + .lightbar_max_brightness = 36,
> };
>
> static struct uniwill_device_descriptor lapac71h_descriptor __initdata = {
> @@ -2158,6 +2164,7 @@ static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = {
> UNIWILL_FEATURE_GPU_TEMP |
> UNIWILL_FEATURE_PRIMARY_FAN |
> UNIWILL_FEATURE_SECONDARY_FAN,
> + .lightbar_max_brightness = 200,
Please also set lightbar_max_brightness to 200 during module
initialization when the "force" parameter is set.
I suggest you rebase this series on top of the "platform/x86:
uniwill-laptop: Charging-related improvements" series to avoid merge
conflicts.
Thanks,
Armin Wolf
> };
>
> /*
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature
2026-04-21 20:01 [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Werner Sembach
` (2 preceding siblings ...)
2026-04-21 20:01 ` [RFC PATCH 3/3] platform/x86: uniwill-laptop: Offer support to activate local dimming Werner Sembach
@ 2026-04-22 11:28 ` Armin Wolf
2026-04-22 15:30 ` Werner Sembach
3 siblings, 1 reply; 15+ messages in thread
From: Armin Wolf @ 2026-04-22 11:28 UTC (permalink / raw)
To: Werner Sembach, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 21.04.26 um 22:01 schrieb Werner Sembach:
> Hi,
>
> This series is based on another not yet accepted series
> https://lore.kernel.org/all/20260417050912.5582-1-W_Armin@gmx.de/
>
> RFC because of that, because the third patch is not yet tested, and because
> I have a question regarding the 3rd patch:
>
> Should I abstract the call to wmi_evaluate_method away in a wrapper
> function in uniwill-wmi somehow, or is it ok to have it straight in the
> uniwill-laptop code like that? It is quite self contained.
>
> Best regards,
>
> Werner
Hi,
i prefer having the code for this WMI interface inside a separate file.
I think we have to first rename uniwill-wmi* to uniwill-wmi-event*, then
the new code can live in uniwill-wmi.c
However we also need some synchronization mechanism between uniwill-acpi
and the new uniwill-wmi because some code path need to check EC
registers before enabling support for local dimming. I suggest that you
use the component framework for that. Basically the new WMI driver
registers a component during probing, while the EC acts as a component
master _if_ local dimming support is present. When the component and the
component master match a sysfs attribute is registered to allow
userspace application to control this feature.
Thanks,
Armin Wolf
>
> Werner Sembach (3):
> platform/x86: uniwill-laptop: Make super key init lineup with other
> inits
> platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
> platform/x86: uniwill-laptop: Offer support to activate local dimming
>
> drivers/platform/x86/uniwill/uniwill-acpi.c | 195 ++++++++++++++++++--
> 1 file changed, 182 insertions(+), 13 deletions(-)
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
2026-04-22 11:17 ` Armin Wolf
@ 2026-04-22 11:29 ` Armin Wolf
2026-04-22 13:13 ` Werner Sembach
1 sibling, 0 replies; 15+ messages in thread
From: Armin Wolf @ 2026-04-22 11:29 UTC (permalink / raw)
To: Werner Sembach, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 22.04.26 um 13:17 schrieb Armin Wolf:
> Am 21.04.26 um 22:01 schrieb Werner Sembach:
>> The XMG Fusion (L19) also has a lightbar but with a different max
>> brightness value of 36 instead of 200.
>>
>> This patch adds a new feature flag for the driver to correctly handle
>> this
>> case and applies it to the mentioned device.
>>
>> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
>> ---
>> drivers/platform/x86/uniwill/uniwill-acpi.c | 19 +++++++++++++------
>> 1 file changed, 13 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/
>> platform/x86/uniwill/uniwill-acpi.c
>> index 7d1fdbacc6871..62d56cc67e2e8 100644
>> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
>> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
>> @@ -318,7 +318,6 @@
>> #define FAN_TABLE_LENGTH 16
>> #define LED_CHANNELS 3
>> -#define LED_MAX_BRIGHTNESS 200
>> #define UNIWILL_FEATURE_FN_LOCK BIT(0)
>> #define UNIWILL_FEATURE_SUPER_KEY BIT(1)
>> @@ -344,6 +343,7 @@ struct uniwill_data {
>> acpi_handle handle;
>> struct regmap *regmap;
>> unsigned int features;
>> + u8 lightbar_max_brightness;
>> struct acpi_battery_hook hook;
>> struct mutex battery_lock; /* Protects the list of currently
>> registered batteries */
>> union {
>> @@ -376,6 +376,7 @@ struct uniwill_battery_entry {
>> struct uniwill_device_descriptor {
>> unsigned int features;
>> + u8 lightbar_max_brightness;
>> /* Executed during driver probing */
>> int (*probe)(struct uniwill_data *data);
>> };
>> @@ -1340,7 +1341,7 @@ static int uniwill_led_brightness_set(struct
>> led_classdev *led_cdev, enum led_br
>> for (int i = 0; i < LED_CHANNELS; i++) {
>> /* Prevent the brightness values from overflowing */
>> - value = min(LED_MAX_BRIGHTNESS, data-
>> >led_mc_subled_info[i].brightness);
>> + value = min(data->lightbar_max_brightness, data-
>> >led_mc_subled_info[i].brightness);
>> ret = regmap_write(data->regmap,
>> uniwill_led_channel_to_ac_reg[i], value);
>> if (ret < 0)
>> return ret;
>> @@ -1376,12 +1377,14 @@ static int uniwill_led_init(struct
>> uniwill_data *data)
>> LED_COLOR_ID_GREEN,
>> LED_COLOR_ID_BLUE,
>> };
>> - unsigned int value;
>> + unsigned int value, max_brightness;
>> int ret;
>> if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
>> return 0;
>> + max_brightness = data->lightbar_max_brightness;
>
> Please drop the max_brightness variable and assign
> led_cdev.max_brightness and led_cdev.brightness directly.
>
>> +
>> ret = devm_mutex_init(data->dev, &data->led_lock);
>> if (ret < 0)
>> return ret;
>> @@ -1409,14 +1412,14 @@ static int uniwill_led_init(struct
>> uniwill_data *data)
>> return ret;
>> data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI;
>> - data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS;
>> + data->led_mc_cdev.led_cdev.max_brightness = max_brightness;
>> data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT;
>> data->led_mc_cdev.led_cdev.brightness_set_blocking =
>> uniwill_led_brightness_set;
>> if (value & LIGHTBAR_S0_OFF)
>> data->led_mc_cdev.led_cdev.brightness = 0;
>> else
>> - data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS;
>> + data->led_mc_cdev.led_cdev.brightness = max_brightness;
>> for (int i = 0; i < LED_CHANNELS; i++) {
>> data->led_mc_subled_info[i].color_index = color_indices[i];
>> @@ -1429,7 +1432,7 @@ static int uniwill_led_init(struct uniwill_data
>> *data)
>> * Make sure that the initial intensity value is not greater
>> than
>> * the maximum brightness.
>> */
>> - value = min(LED_MAX_BRIGHTNESS, value);
>> + value = min(max_brightness, value);
>> ret = regmap_write(data->regmap,
>> uniwill_led_channel_to_ac_reg[i], value);
>> if (ret < 0)
>> return ret;
>> @@ -1882,6 +1885,7 @@ static int uniwill_probe(struct platform_device
>> *pdev)
>> return ret;
>> data->features = device_descriptor.features;
>> + data->lightbar_max_brightness =
>> device_descriptor.lightbar_max_brightness;
>> /*
>> * Some devices might need to perform some device-specific
>> initialization steps
>> @@ -2130,11 +2134,13 @@ static struct platform_driver uniwill_driver = {
>> static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor
>> __initdata = {
>> .features = UNIWILL_FEATURE_SUPER_KEY |
>> + UNIWILL_FEATURE_LIGHTBAR |
>> UNIWILL_FEATURE_BATTERY_CHARGE_LIMIT |
>> UNIWILL_FEATURE_CPU_TEMP |
>> UNIWILL_FEATURE_GPU_TEMP |
>> UNIWILL_FEATURE_PRIMARY_FAN |
>> UNIWILL_FEATURE_SECONDARY_FAN,
>> + .lightbar_max_brightness = 36,
>> };
>> static struct uniwill_device_descriptor lapac71h_descriptor
>> __initdata = {
>> @@ -2158,6 +2164,7 @@ static struct uniwill_device_descriptor
>> lapkc71f_descriptor __initdata = {
>> UNIWILL_FEATURE_GPU_TEMP |
>> UNIWILL_FEATURE_PRIMARY_FAN |
>> UNIWILL_FEATURE_SECONDARY_FAN,
>> + .lightbar_max_brightness = 200,
>
> Please also set lightbar_max_brightness to 200 during module
> initialization when the "force" parameter is set.
>
> I suggest you rebase this series on top of the "platform/x86: uniwill-
> laptop: Charging-related improvements" series to avoid merge conflicts.
Forget about the rebase part, the series is already based on this series xd.
Thanks,
Armin Wolf
>
> Thanks,
> Armin Wolf
>
>> };
>> /*
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
2026-04-22 11:17 ` Armin Wolf
2026-04-22 11:29 ` Armin Wolf
@ 2026-04-22 13:13 ` Werner Sembach
1 sibling, 0 replies; 15+ messages in thread
From: Werner Sembach @ 2026-04-22 13:13 UTC (permalink / raw)
To: Armin Wolf, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Hi Armin,
Am 22.04.26 um 13:17 schrieb Armin Wolf:
> Am 21.04.26 um 22:01 schrieb Werner Sembach:
>> The XMG Fusion (L19) also has a lightbar but with a different max
>> brightness value of 36 instead of 200.
>>
>> This patch adds a new feature flag for the driver to correctly handle this
>> case and applies it to the mentioned device.
>>
>> Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
>> ---
>> drivers/platform/x86/uniwill/uniwill-acpi.c | 19 +++++++++++++------
>> 1 file changed, 13 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c
>> b/drivers/platform/x86/uniwill/uniwill-acpi.c
>> index 7d1fdbacc6871..62d56cc67e2e8 100644
>> --- a/drivers/platform/x86/uniwill/uniwill-acpi.c
>> +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c
>> @@ -318,7 +318,6 @@
>> #define FAN_TABLE_LENGTH 16
>> #define LED_CHANNELS 3
>> -#define LED_MAX_BRIGHTNESS 200
>> #define UNIWILL_FEATURE_FN_LOCK BIT(0)
>> #define UNIWILL_FEATURE_SUPER_KEY BIT(1)
>> @@ -344,6 +343,7 @@ struct uniwill_data {
>> acpi_handle handle;
>> struct regmap *regmap;
>> unsigned int features;
>> + u8 lightbar_max_brightness;
>> struct acpi_battery_hook hook;
>> struct mutex battery_lock; /* Protects the list of currently
>> registered batteries */
>> union {
>> @@ -376,6 +376,7 @@ struct uniwill_battery_entry {
>> struct uniwill_device_descriptor {
>> unsigned int features;
>> + u8 lightbar_max_brightness;
>> /* Executed during driver probing */
>> int (*probe)(struct uniwill_data *data);
>> };
>> @@ -1340,7 +1341,7 @@ static int uniwill_led_brightness_set(struct
>> led_classdev *led_cdev, enum led_br
>> for (int i = 0; i < LED_CHANNELS; i++) {
>> /* Prevent the brightness values from overflowing */
>> - value = min(LED_MAX_BRIGHTNESS,
>> data->led_mc_subled_info[i].brightness);
>> + value = min(data->lightbar_max_brightness,
>> data->led_mc_subled_info[i].brightness);
>> ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i],
>> value);
>> if (ret < 0)
>> return ret;
>> @@ -1376,12 +1377,14 @@ static int uniwill_led_init(struct uniwill_data *data)
>> LED_COLOR_ID_GREEN,
>> LED_COLOR_ID_BLUE,
>> };
>> - unsigned int value;
>> + unsigned int value, max_brightness;
>> int ret;
>> if (!uniwill_device_supports(data, UNIWILL_FEATURE_LIGHTBAR))
>> return 0;
>> + max_brightness = data->lightbar_max_brightness;
>
> Please drop the max_brightness variable and assign led_cdev.max_brightness and
> led_cdev.brightness directly.
ok
>
>> +
>> ret = devm_mutex_init(data->dev, &data->led_lock);
>> if (ret < 0)
>> return ret;
>> @@ -1409,14 +1412,14 @@ static int uniwill_led_init(struct uniwill_data *data)
>> return ret;
>> data->led_mc_cdev.led_cdev.color = LED_COLOR_ID_MULTI;
>> - data->led_mc_cdev.led_cdev.max_brightness = LED_MAX_BRIGHTNESS;
>> + data->led_mc_cdev.led_cdev.max_brightness = max_brightness;
>> data->led_mc_cdev.led_cdev.flags = LED_REJECT_NAME_CONFLICT;
>> data->led_mc_cdev.led_cdev.brightness_set_blocking =
>> uniwill_led_brightness_set;
>> if (value & LIGHTBAR_S0_OFF)
>> data->led_mc_cdev.led_cdev.brightness = 0;
>> else
>> - data->led_mc_cdev.led_cdev.brightness = LED_MAX_BRIGHTNESS;
>> + data->led_mc_cdev.led_cdev.brightness = max_brightness;
>> for (int i = 0; i < LED_CHANNELS; i++) {
>> data->led_mc_subled_info[i].color_index = color_indices[i];
>> @@ -1429,7 +1432,7 @@ static int uniwill_led_init(struct uniwill_data *data)
>> * Make sure that the initial intensity value is not greater than
>> * the maximum brightness.
>> */
>> - value = min(LED_MAX_BRIGHTNESS, value);
>> + value = min(max_brightness, value);
>> ret = regmap_write(data->regmap, uniwill_led_channel_to_ac_reg[i],
>> value);
>> if (ret < 0)
>> return ret;
>> @@ -1882,6 +1885,7 @@ static int uniwill_probe(struct platform_device *pdev)
>> return ret;
>> data->features = device_descriptor.features;
>> + data->lightbar_max_brightness = device_descriptor.lightbar_max_brightness;
>> /*
>> * Some devices might need to perform some device-specific
>> initialization steps
>> @@ -2130,11 +2134,13 @@ static struct platform_driver uniwill_driver = {
>> static struct uniwill_device_descriptor lapqc71a_lapqc71b_descriptor
>> __initdata = {
>> .features = UNIWILL_FEATURE_SUPER_KEY |
>> + UNIWILL_FEATURE_LIGHTBAR |
>> UNIWILL_FEATURE_BATTERY_CHARGE_LIMIT |
>> UNIWILL_FEATURE_CPU_TEMP |
>> UNIWILL_FEATURE_GPU_TEMP |
>> UNIWILL_FEATURE_PRIMARY_FAN |
>> UNIWILL_FEATURE_SECONDARY_FAN,
>> + .lightbar_max_brightness = 36,
>> };
>> static struct uniwill_device_descriptor lapac71h_descriptor __initdata = {
>> @@ -2158,6 +2164,7 @@ static struct uniwill_device_descriptor
>> lapkc71f_descriptor __initdata = {
>> UNIWILL_FEATURE_GPU_TEMP |
>> UNIWILL_FEATURE_PRIMARY_FAN |
>> UNIWILL_FEATURE_SECONDARY_FAN,
>> + .lightbar_max_brightness = 200,
>
> Please also set lightbar_max_brightness to 200 during module initialization
> when the "force" parameter is set.
Ok
Best regards,
Werner
>
> I suggest you rebase this series on top of the "platform/x86: uniwill-laptop:
> Charging-related improvements" series to avoid merge conflicts.
>
> Thanks,
> Armin Wolf
>
>> };
>> /*
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature
2026-04-22 11:28 ` [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Armin Wolf
@ 2026-04-22 15:30 ` Werner Sembach
2026-04-22 16:12 ` Armin Wolf
0 siblings, 1 reply; 15+ messages in thread
From: Werner Sembach @ 2026-04-22 15:30 UTC (permalink / raw)
To: Armin Wolf, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 22.04.26 um 13:28 schrieb Armin Wolf:
> Am 21.04.26 um 22:01 schrieb Werner Sembach:
>> Hi,
>>
>> This series is based on another not yet accepted series
>> https://lore.kernel.org/all/20260417050912.5582-1-W_Armin@gmx.de/
>>
>> RFC because of that, because the third patch is not yet tested, and because
>> I have a question regarding the 3rd patch:
>>
>> Should I abstract the call to wmi_evaluate_method away in a wrapper
>> function in uniwill-wmi somehow, or is it ok to have it straight in the
>> uniwill-laptop code like that? It is quite self contained.
>>
>> Best regards,
>>
>> Werner
>
> Hi,
>
> i prefer having the code for this WMI interface inside a separate file. I
> think we have to first rename uniwill-wmi* to uniwill-wmi-event*, then the new
> code can live in uniwill-wmi.c
>
> However we also need some synchronization mechanism between uniwill-acpi and
> the new uniwill-wmi because some code path need to check EC registers before
> enabling support for local dimming. I suggest that you use the component
> framework for that. Basically the new WMI driver registers a component during
> probing, while the EC acts as a component master _if_ local dimming support is
> present. When the component and the component master match a sysfs attribute
> is registered to allow userspace application to control this feature.
Calling the old uniwill-wmi uniwill-wmi-event and the new driver uniwill-wmi
from here on:
I haven't yet worked with the component framework, but i wonder: since the same
manual register call structure that we already have for uniwill-wmi-event will
be also required for uniwill-wmi, can't this call not also be used to exchange
callbacks like for uniwill-wmi-event and the notifier block? just the other way
around with uniwill-acpi receiving a callback instead of providing one.
ofc these callbacks must be guarded in some way to not accidentally call
uninitialized code, if uniwill-wmi fails to init or probe
>
> Thanks,
> Armin Wolf
>
>>
>> Werner Sembach (3):
>> platform/x86: uniwill-laptop: Make super key init lineup with other
>> inits
>> platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
>> platform/x86: uniwill-laptop: Offer support to activate local dimming
>>
>> drivers/platform/x86/uniwill/uniwill-acpi.c | 195 ++++++++++++++++++--
>> 1 file changed, 182 insertions(+), 13 deletions(-)
>>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature
2026-04-22 15:30 ` Werner Sembach
@ 2026-04-22 16:12 ` Armin Wolf
2026-04-24 12:28 ` Werner Sembach
0 siblings, 1 reply; 15+ messages in thread
From: Armin Wolf @ 2026-04-22 16:12 UTC (permalink / raw)
To: Werner Sembach, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 22.04.26 um 17:30 schrieb Werner Sembach:
>
> Am 22.04.26 um 13:28 schrieb Armin Wolf:
>> Am 21.04.26 um 22:01 schrieb Werner Sembach:
>>> Hi,
>>>
>>> This series is based on another not yet accepted series
>>> https://lore.kernel.org/all/20260417050912.5582-1-W_Armin@gmx.de/
>>>
>>> RFC because of that, because the third patch is not yet tested, and
>>> because
>>> I have a question regarding the 3rd patch:
>>>
>>> Should I abstract the call to wmi_evaluate_method away in a wrapper
>>> function in uniwill-wmi somehow, or is it ok to have it straight in the
>>> uniwill-laptop code like that? It is quite self contained.
>>>
>>> Best regards,
>>>
>>> Werner
>>
>> Hi,
>>
>> i prefer having the code for this WMI interface inside a separate
>> file. I think we have to first rename uniwill-wmi* to uniwill-wmi-
>> event*, then the new code can live in uniwill-wmi.c
>>
>> However we also need some synchronization mechanism between uniwill-
>> acpi and the new uniwill-wmi because some code path need to check EC
>> registers before enabling support for local dimming. I suggest that
>> you use the component framework for that. Basically the new WMI driver
>> registers a component during probing, while the EC acts as a component
>> master _if_ local dimming support is present. When the component and
>> the component master match a sysfs attribute is registered to allow
>> userspace application to control this feature.
>
> Calling the old uniwill-wmi uniwill-wmi-event and the new driver
> uniwill-wmi from here on:
>
> I haven't yet worked with the component framework, but i wonder: since
> the same manual register call structure that we already have for
> uniwill-wmi-event will be also required for uniwill-wmi, can't this call
> not also be used to exchange callbacks like for uniwill-wmi-event and
> the notifier block? just the other way around with uniwill-acpi
> receiving a callback instead of providing one.
>
> ofc these callbacks must be guarded in some way to not accidentally call
> uninitialized code, if uniwill-wmi fails to init or probe
This would indeed be possible, but where would be no mechanism for
detecting when the WMI driver has finished probing.
I was thinking that the WMI driver uses the component callbacks to pass
a pointer to its data struct to the component master. Said data struct
can then by used to change the local dimming status.
I am still not sure when the associated sysfs files should be created.
We can create them during probing of the EC, but then there will be
problems should the WMI device take too long/fail to probe.
Alternatively we can create the sysfs file when the component master
binds the WMI component, so that the sysfs file will only become visible
once it is operational. We can then issue a uevent towards userspace to
signal userspace applications that the sysfs attributes of our device
have changed.
Thanks,
Armin Wolf
>
>>
>> Thanks,
>> Armin Wolf
>>
>>>
>>> Werner Sembach (3):
>>> platform/x86: uniwill-laptop: Make super key init lineup with other
>>> inits
>>> platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
>>> platform/x86: uniwill-laptop: Offer support to activate local dimming
>>>
>>> drivers/platform/x86/uniwill/uniwill-acpi.c | 195 ++++++++++++++++++--
>>> 1 file changed, 182 insertions(+), 13 deletions(-)
>>>
>>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature
2026-04-22 16:12 ` Armin Wolf
@ 2026-04-24 12:28 ` Werner Sembach
0 siblings, 0 replies; 15+ messages in thread
From: Werner Sembach @ 2026-04-24 12:28 UTC (permalink / raw)
To: Armin Wolf, hansg, ilpo.jarvinen; +Cc: platform-driver-x86, linux-kernel
Am 22.04.26 um 18:12 schrieb Armin Wolf:
> Am 22.04.26 um 17:30 schrieb Werner Sembach:
>>
>> Am 22.04.26 um 13:28 schrieb Armin Wolf:
>>> Am 21.04.26 um 22:01 schrieb Werner Sembach:
>>>> Hi,
>>>>
>>>> This series is based on another not yet accepted series
>>>> https://lore.kernel.org/all/20260417050912.5582-1-W_Armin@gmx.de/
>>>>
>>>> RFC because of that, because the third patch is not yet tested, and because
>>>> I have a question regarding the 3rd patch:
>>>>
>>>> Should I abstract the call to wmi_evaluate_method away in a wrapper
>>>> function in uniwill-wmi somehow, or is it ok to have it straight in the
>>>> uniwill-laptop code like that? It is quite self contained.
>>>>
>>>> Best regards,
>>>>
>>>> Werner
>>>
>>> Hi,
>>>
>>> i prefer having the code for this WMI interface inside a separate file. I
>>> think we have to first rename uniwill-wmi* to uniwill-wmi- event*, then the
>>> new code can live in uniwill-wmi.c
>>>
>>> However we also need some synchronization mechanism between uniwill- acpi
>>> and the new uniwill-wmi because some code path need to check EC registers
>>> before enabling support for local dimming. I suggest that you use the
>>> component framework for that. Basically the new WMI driver registers a
>>> component during probing, while the EC acts as a component master _if_ local
>>> dimming support is present. When the component and the component master
>>> match a sysfs attribute is registered to allow userspace application to
>>> control this feature.
>>
>> Calling the old uniwill-wmi uniwill-wmi-event and the new driver uniwill-wmi
>> from here on:
>>
>> I haven't yet worked with the component framework, but i wonder: since the
>> same manual register call structure that we already have for
>> uniwill-wmi-event will be also required for uniwill-wmi, can't this call not
>> also be used to exchange callbacks like for uniwill-wmi-event and the
>> notifier block? just the other way around with uniwill-acpi receiving a
>> callback instead of providing one.
>>
>> ofc these callbacks must be guarded in some way to not accidentally call
>> uninitialized code, if uniwill-wmi fails to init or probe
>
> This would indeed be possible, but where would be no mechanism for detecting
> when the WMI driver has finished probing.
>
> I was thinking that the WMI driver uses the component callbacks to pass a
> pointer to its data struct to the component master. Said data struct can then
> by used to change the local dimming status.
ok i will look into this, but first a week of hollyday ^^
best regards,
Werner
>
> I am still not sure when the associated sysfs files should be created. We can
> create them during probing of the EC, but then there will be problems should
> the WMI device take too long/fail to probe. Alternatively we can create the
> sysfs file when the component master binds the WMI component, so that the
> sysfs file will only become visible
> once it is operational. We can then issue a uevent towards userspace to signal
> userspace applications that the sysfs attributes of our device have changed.
>
> Thanks,
> Armin Wolf
>
>>
>>>
>>> Thanks,
>>> Armin Wolf
>>>
>>>>
>>>> Werner Sembach (3):
>>>> platform/x86: uniwill-laptop: Make super key init lineup with other
>>>> inits
>>>> platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19)
>>>> platform/x86: uniwill-laptop: Offer support to activate local dimming
>>>>
>>>> drivers/platform/x86/uniwill/uniwill-acpi.c | 195 ++++++++++++++++++--
>>>> 1 file changed, 182 insertions(+), 13 deletions(-)
>>>>
>>>
>>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-04-24 12:35 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-21 20:01 [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Werner Sembach
2026-04-21 20:01 ` [RFC PATCH 1/3] platform/x86: uniwill-laptop: Make super key init lineup with other inits Werner Sembach
2026-04-22 9:33 ` Ilpo Järvinen
2026-04-22 11:11 ` Armin Wolf
2026-04-21 20:01 ` [RFC PATCH 2/3] platform/x86: uniwill-laptop: Implement lightbar for XMG Fusion (L19) Werner Sembach
2026-04-22 9:34 ` Ilpo Järvinen
2026-04-22 11:17 ` Armin Wolf
2026-04-22 11:29 ` Armin Wolf
2026-04-22 13:13 ` Werner Sembach
2026-04-21 20:01 ` [RFC PATCH 3/3] platform/x86: uniwill-laptop: Offer support to activate local dimming Werner Sembach
2026-04-21 22:03 ` Armin Wolf
2026-04-22 11:28 ` [RFC PATCH 0/3] platform/x86: uniwill-laptop: Another improvement and another feature Armin Wolf
2026-04-22 15:30 ` Werner Sembach
2026-04-22 16:12 ` Armin Wolf
2026-04-24 12:28 ` Werner Sembach
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox