All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] platform/x86: acer-wmi: support PH317-51 hwmon and kbd backlight
@ 2026-09-18 15:55 Lucas Gillard
  2026-10-05 17:01 ` Ilpo Järvinen
  0 siblings, 1 reply; 3+ messages in thread
From: Lucas Gillard @ 2026-09-18 15:55 UTC (permalink / raw)
  To: platform-driver-x86; +Cc: jlee, hansg, ilpo.jarvinen, W_Armin, Lucas Gillard

The Predator Helios 300 PH317-51 (2017) has the Predator gaming WMI
interface, but an early revision of it. Sensor queries and fan control
answer; the platform-profile and OC methods (22/23) do not exist. So it
gets a quirk that turns on HWMON without predator_v4.

The keyboard backlight has no WMI method behind it on this machine. I
probed the LED methods (2/4) every way I could and they neither report
nor change its state. The EC owns it instead, in RAM at 0x30/0x31, the
same bytes Fn+F9 flips. The read hook reports the live EC value, so the
Fn key and sysfs never disagree.

The code is mine, written with help from an AI coding assistant to
understand the codebase and how this kind of change is usually done;
this is my first kernel contribution. I verified every behavior
claimed here myself, on the machine.

Tested on a PH317-51: both temperatures, both fans, and the light going
on and off from sysfs.

Signed-off-by: Lucas Gillard <mirsella1@gmail.com>
Assisted-by: LLM
---
 drivers/platform/x86/acer-wmi.c | 87 +++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 61ae622..f14b6e4 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -310,6 +310,7 @@ struct hotkey_function_type_aa {
 #define ACER_CAP_PLATFORM_PROFILE	BIT(10)
 #define ACER_CAP_HWMON			BIT(11)
 #define ACER_CAP_PWM			BIT(12)
+#define ACER_CAP_KBD_BACKLIGHT		BIT(13)
 
 /*
  * Interface type flags
@@ -359,6 +360,7 @@ struct acer_data {
 	int mailled;
 	int threeg;
 	int brightness;
+	int kbd_backlight;
 };
 
 struct acer_debug {
@@ -405,6 +407,8 @@ struct quirk_entry {
 	u8 gpu_fans;
 	u8 predator_v4;
 	u8 pwm;
+	u8 hwmon;
+	u8 kbd_backlight;
 };
 
 static struct quirk_entry *quirks;
@@ -425,6 +429,12 @@ static void __init set_quirks(void)
 		interface->capability |= ACER_CAP_PLATFORM_PROFILE |
 					 ACER_CAP_HWMON;
 
+	if (quirks->hwmon)
+		interface->capability |= ACER_CAP_HWMON;
+
+	if (quirks->kbd_backlight)
+		interface->capability |= ACER_CAP_KBD_BACKLIGHT;
+
 	if (quirks->pwm)
 		interface->capability |= ACER_CAP_PWM;
 }
@@ -466,6 +476,12 @@ static struct quirk_entry quirk_acer_predator_ph315_53 = {
 	.gpu_fans = 1,
 };
 
+/* Firmware lacks the profile/OC methods, so no predator_v4. */
+static struct quirk_entry quirk_acer_predator_ph317_51 = {
+	.hwmon = 1,
+	.kbd_backlight = 1,
+};
+
 static struct quirk_entry quirk_acer_predator_ph16_72 = {
 	.turbo = 1,
 	.cpu_fans = 1,
@@ -671,6 +687,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
 		},
 		.driver_data = &quirk_acer_predator_ph315_53,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "Acer Predator PH317-51",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH317-51"),
+		},
+		.driver_data = &quirk_acer_predator_ph317_51,
+	},
 	{
 		.callback = dmi_matched,
 		.ident = "Acer Predator PHN16-71",
@@ -1947,6 +1972,45 @@ static void acer_led_exit(void)
 	led_classdev_unregister(&mail_led);
 }
 
+/*
+ * No WMI method drives the backlight on this model; the EC keeps the
+ * state mirrored in both 0x30 and 0x31, so write both.
+ */
+static void kbd_led_set(struct led_classdev *led_cdev,
+			enum led_brightness value)
+{
+	value = !!value;
+	ec_write(0x30, value);
+	ec_write(0x31, value);
+}
+
+static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
+{
+	u8 result;
+
+	if (ec_read(0x30, &result))
+		return LED_OFF;
+	return (result & 0x1) ? LED_ON : LED_OFF;
+}
+
+static struct led_classdev kbd_led = {
+	.name = "acer-wmi::kbd_backlight",
+	.brightness_set = kbd_led_set,
+	.brightness_get = kbd_led_get,
+	.max_brightness = 1,
+};
+
+static int acer_kbd_led_init(struct device *dev)
+{
+	return led_classdev_register(dev, &kbd_led);
+}
+
+static void acer_kbd_led_exit(void)
+{
+	kbd_led_set(&kbd_led, LED_OFF);
+	led_classdev_unregister(&kbd_led);
+}
+
 /*
  * Backlight device
  */
@@ -2799,8 +2863,15 @@ static int acer_platform_probe(struct platform_device *device)
 			goto error_hwmon;
 	}
 
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT)) {
+		err = acer_kbd_led_init(&device->dev);
+		if (err)
+			goto error_kbd_backlight;
+	}
+
 	return 0;
 
+error_kbd_backlight:
 error_hwmon:
 error_platform_profile:
 	acer_rfkill_exit();
@@ -2816,6 +2887,8 @@ static int acer_platform_probe(struct platform_device *device)
 
 static void acer_platform_remove(struct platform_device *device)
 {
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
+		acer_kbd_led_exit();
 	if (has_cap(ACER_CAP_MAILLED))
 		acer_led_exit();
 	if (has_cap(ACER_CAP_BRIGHTNESS))
@@ -2844,6 +2917,14 @@ static int acer_suspend(struct device *dev)
 		data->brightness = value;
 	}
 
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT)) {
+		u8 state;
+
+		if (!ec_read(0x30, &state))
+			data->kbd_backlight = state & 0x1;
+		kbd_led_set(&kbd_led, LED_OFF);
+	}
+
 	return 0;
 }
 
@@ -2860,6 +2941,9 @@ static int acer_resume(struct device *dev)
 	if (has_cap(ACER_CAP_BRIGHTNESS))
 		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
 
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
+		kbd_led_set(&kbd_led, data->kbd_backlight);
+
 	if (acer_wmi_accel_dev)
 		acer_gsensor_init();
 
@@ -2881,6 +2965,9 @@ static void acer_platform_shutdown(struct platform_device *device)
 
 	if (has_cap(ACER_CAP_MAILLED))
 		set_u32(LED_OFF, ACER_CAP_MAILLED);
+
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
+		kbd_led_set(&kbd_led, LED_OFF);
 }
 
 static struct platform_driver acer_platform_driver = {
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] platform/x86: acer-wmi: support PH317-51 hwmon and kbd backlight
  2026-09-18 15:55 [PATCH] platform/x86: acer-wmi: support PH317-51 hwmon and kbd backlight Lucas Gillard
@ 2026-10-05 17:01 ` Ilpo Järvinen
  2026-10-27 11:21   ` [PATCH v2] " Lucas Gillard
  0 siblings, 1 reply; 3+ messages in thread
From: Ilpo Järvinen @ 2026-10-05 17:01 UTC (permalink / raw)
  To: Lucas Gillard; +Cc: platform-driver-x86, jlee, Hans de Goede, W_Armin

On Fri, 18 Sep 2026, Lucas Gillard wrote:

> The Predator Helios 300 PH317-51 (2017) has the Predator gaming WMI
> interface, but an early revision of it. Sensor queries and fan control
> answer; the platform-profile and OC methods (22/23) do not exist. So it
> gets a quirk that turns on HWMON without predator_v4.
> 
> The keyboard backlight has no WMI method behind it on this machine. I
> probed the LED methods (2/4) every way I could and they neither report
> nor change its state. The EC owns it instead, in RAM at 0x30/0x31, the
> same bytes Fn+F9 flips. The read hook reports the live EC value, so the
> Fn key and sysfs never disagree.
> 
> The code is mine, written with help from an AI coding assistant to
> understand the codebase and how this kind of change is usually done;
> this is my first kernel contribution. I verified every behavior
> claimed here myself, on the machine.
> 
> Tested on a PH317-51: both temperatures, both fans, and the light going
> on and off from sysfs.
> 
> Signed-off-by: Lucas Gillard <mirsella1@gmail.com>
> Assisted-by: LLM
> ---
>  drivers/platform/x86/acer-wmi.c | 87 +++++++++++++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
> 
> diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
> index 61ae622..f14b6e4 100644
> --- a/drivers/platform/x86/acer-wmi.c
> +++ b/drivers/platform/x86/acer-wmi.c
> @@ -310,6 +310,7 @@ struct hotkey_function_type_aa {
>  #define ACER_CAP_PLATFORM_PROFILE	BIT(10)
>  #define ACER_CAP_HWMON			BIT(11)
>  #define ACER_CAP_PWM			BIT(12)
> +#define ACER_CAP_KBD_BACKLIGHT		BIT(13)
>  
>  /*
>   * Interface type flags
> @@ -359,6 +360,7 @@ struct acer_data {
>  	int mailled;
>  	int threeg;
>  	int brightness;
> +	int kbd_backlight;
>  };
>  
>  struct acer_debug {
> @@ -405,6 +407,8 @@ struct quirk_entry {
>  	u8 gpu_fans;
>  	u8 predator_v4;
>  	u8 pwm;
> +	u8 hwmon;
> +	u8 kbd_backlight;

Can you please base this on my repo where predator_v4 is already split.

>  };
>  
>  static struct quirk_entry *quirks;
> @@ -425,6 +429,12 @@ static void __init set_quirks(void)
>  		interface->capability |= ACER_CAP_PLATFORM_PROFILE |
>  					 ACER_CAP_HWMON;
>  
> +	if (quirks->hwmon)
> +		interface->capability |= ACER_CAP_HWMON;
> +
> +	if (quirks->kbd_backlight)
> +		interface->capability |= ACER_CAP_KBD_BACKLIGHT;
> +
>  	if (quirks->pwm)
>  		interface->capability |= ACER_CAP_PWM;
>  }
> @@ -466,6 +476,12 @@ static struct quirk_entry quirk_acer_predator_ph315_53 = {
>  	.gpu_fans = 1,
>  };
>  
> +/* Firmware lacks the profile/OC methods, so no predator_v4. */
> +static struct quirk_entry quirk_acer_predator_ph317_51 = {
> +	.hwmon = 1,
> +	.kbd_backlight = 1,
> +};
> +
>  static struct quirk_entry quirk_acer_predator_ph16_72 = {
>  	.turbo = 1,
>  	.cpu_fans = 1,
> @@ -671,6 +687,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
>  		},
>  		.driver_data = &quirk_acer_predator_ph315_53,
>  	},
> +	{
> +		.callback = dmi_matched,
> +		.ident = "Acer Predator PH317-51",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH317-51"),
> +		},
> +		.driver_data = &quirk_acer_predator_ph317_51,
> +	},
>  	{
>  		.callback = dmi_matched,
>  		.ident = "Acer Predator PHN16-71",
> @@ -1947,6 +1972,45 @@ static void acer_led_exit(void)
>  	led_classdev_unregister(&mail_led);
>  }
>  
> +/*
> + * No WMI method drives the backlight on this model; the EC keeps the
> + * state mirrored in both 0x30 and 0x31, so write both.
> + */
> +static void kbd_led_set(struct led_classdev *led_cdev,
> +			enum led_brightness value)
> +{
> +	value = !!value;

Please make non-enum local variable and do not rely on !! (that relates to 
truth values) but use e.g. elvis operator to explicitly set the value you 
want to write.

> +	ec_write(0x30, value);
> +	ec_write(0x31, value);

Don't use literals but name these with defines.

> +}
> +
> +static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
> +{
> +	u8 result;
> +
> +	if (ec_read(0x30, &result))

Ditto.

> +		return LED_OFF;
> +	return (result & 0x1) ? LED_ON : LED_OFF;

Name the literal with a define ?

Extra parenthesis.

> +}
> +
> +static struct led_classdev kbd_led = {
> +	.name = "acer-wmi::kbd_backlight",
> +	.brightness_set = kbd_led_set,
> +	.brightness_get = kbd_led_get,
> +	.max_brightness = 1,
> +};
> +
> +static int acer_kbd_led_init(struct device *dev)
> +{
> +	return led_classdev_register(dev, &kbd_led);
> +}
> +
> +static void acer_kbd_led_exit(void)
> +{
> +	kbd_led_set(&kbd_led, LED_OFF);
> +	led_classdev_unregister(&kbd_led);

I don't see other drivers turning the LED off on unregister (there's just 
one exception that is in this same driver).

> +}
> +
>  /*
>   * Backlight device
>   */
> @@ -2799,8 +2863,15 @@ static int acer_platform_probe(struct platform_device *device)
>  			goto error_hwmon;
>  	}
>  
> +	if (has_cap(ACER_CAP_KBD_BACKLIGHT)) {
> +		err = acer_kbd_led_init(&device->dev);
> +		if (err)
> +			goto error_kbd_backlight;
> +	}
> +
>  	return 0;
>  
> +error_kbd_backlight:
>  error_hwmon:
>  error_platform_profile:
>  	acer_rfkill_exit();
> @@ -2816,6 +2887,8 @@ static int acer_platform_probe(struct platform_device *device)
>  
>  static void acer_platform_remove(struct platform_device *device)
>  {
> +	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
> +		acer_kbd_led_exit();
>  	if (has_cap(ACER_CAP_MAILLED))
>  		acer_led_exit();
>  	if (has_cap(ACER_CAP_BRIGHTNESS))
> @@ -2844,6 +2917,14 @@ static int acer_suspend(struct device *dev)
>  		data->brightness = value;
>  	}
>  
> +	if (has_cap(ACER_CAP_KBD_BACKLIGHT)) {
> +		u8 state;
> +
> +		if (!ec_read(0x30, &state))
> +			data->kbd_backlight = state & 0x1;

Use the same defines here as well.

> +		kbd_led_set(&kbd_led, LED_OFF);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -2860,6 +2941,9 @@ static int acer_resume(struct device *dev)
>  	if (has_cap(ACER_CAP_BRIGHTNESS))
>  		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
>  
> +	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
> +		kbd_led_set(&kbd_led, data->kbd_backlight);
> +
>  	if (acer_wmi_accel_dev)
>  		acer_gsensor_init();
>  
> @@ -2881,6 +2965,9 @@ static void acer_platform_shutdown(struct platform_device *device)
>  
>  	if (has_cap(ACER_CAP_MAILLED))
>  		set_u32(LED_OFF, ACER_CAP_MAILLED);
> +
> +	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
> +		kbd_led_set(&kbd_led, LED_OFF);
>  }
>  
>  static struct platform_driver acer_platform_driver = {
> 

-- 
 i.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2] platform/x86: acer-wmi: support PH317-51 hwmon and kbd backlight
  2026-10-05 17:01 ` Ilpo Järvinen
@ 2026-10-27 11:21   ` Lucas Gillard
  0 siblings, 0 replies; 3+ messages in thread
From: Lucas Gillard @ 2026-10-27 11:21 UTC (permalink / raw)
  To: platform-driver-x86; +Cc: ilpo.jarvinen, jlee, hansg, W_Armin, linux-kernel

The Predator Helios 300 PH317-51 exposes early gaming WMI methods for
temperature and fan sensors, but lacks the platform-profile and
overclocking methods (22 and 23). Enable hwmon for this model without
enabling platform-profile support.

Its keyboard backlight is controlled by EC registers 0x30 and 0x31;
the WMI LED methods do not report or change it. Fn+F9 updates both EC
registers. Register an on/off keyboard LED with a blocking setter and
read its brightness directly from the EC, so sysfs reflects changes
made with Fn+F9.

Write both registers to match the firmware's on/off states. Use the LED
core to suspend and resume the backlight, reading its current state from
the EC before suspend.

Signed-off-by: Lucas Gillard <mirsella1@gmail.com>
Assisted-by: LLM
---
Hi Ilpo,

Thanks for the review. This revision is based on the platform-drivers-x86
for-next tree at 9d3475065167197742b0882aff21cf8e78393277.

Changes in v2:
- Use the existing hwmon quirk after the predator_v4 split.
- Name both EC registers and the state mask, and use them throughout.
- Convert brightness to an explicit u8 on/off value without modifying
  the enum argument; remove the redundant mask parentheses.
- Use brightness_set_blocking and return EC write errors.
- Use managed LED registration and remove the explicit off-write on
  unregister. LED core handles teardown.
- Use LED-core helpers for suspend, resume and shutdown, draining pending
  LED work before suspend/shutdown. Read the live EC state before suspend
  to preserve Fn+F9 changes.

I'm currently away from the machine and haven't retested v2 on hardware. I'm sending this update for review.

I used an LLM for code changes, review and local validation.

v1: https://lore.kernel.org/r/6aad63a9.f9180b46.32931.492b@mx.google.com
Review: https://lore.kernel.org/r/ea6d7395-c70f-9346-fc3f-9465adb5fef1@linux.intel.com

Thanks,
Lucas

 drivers/platform/x86/acer-wmi.c | 85 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 3a018fdf513891a8a012aeaa7185a3de521ecf47..b893e04712966fb1d792e4eb27955f3dbc8fad1d 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -310,6 +310,11 @@ struct hotkey_function_type_aa {
 #define ACER_CAP_PLATFORM_PROFILE	BIT(10)
 #define ACER_CAP_HWMON			BIT(11)
 #define ACER_CAP_PWM			BIT(12)
+#define ACER_CAP_KBD_BACKLIGHT		BIT(13)
+
+#define ACER_KBD_BACKLIGHT_EC_STATE	0x30
+#define ACER_KBD_BACKLIGHT_EC_MIRROR	0x31
+#define ACER_KBD_BACKLIGHT_MASK		BIT(0)
 
 /*
  * Interface type flags
@@ -406,6 +411,7 @@ struct quirk_entry {
 	bool hwmon;
 	bool platform_profile;
 	bool pwm;
+	bool kbd_backlight;
 };
 
 static struct quirk_entry *quirks;
@@ -430,6 +436,9 @@ static void __init set_quirks(void)
 
 	if (quirks->pwm)
 		interface->capability |= ACER_CAP_PWM;
+
+	if (quirks->kbd_backlight)
+		interface->capability |= ACER_CAP_KBD_BACKLIGHT;
 }
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
@@ -474,6 +483,12 @@ static struct quirk_entry quirk_acer_predator_ph315_53 = {
 	.gpu_fans = 1,
 };
 
+/* Firmware supports sensors but lacks the platform-profile/OC methods. */
+static struct quirk_entry quirk_acer_predator_ph317_51 = {
+	.hwmon = true,
+	.kbd_backlight = true,
+};
+
 static struct quirk_entry quirk_acer_nitro_anv15_51 = {
 	.cpu_fans = 1,
 	.gpu_fans = 1,
@@ -717,6 +732,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
 		},
 		.driver_data = &quirk_acer_predator_ph315_53,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "Acer Predator PH317-51",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH317-51"),
+		},
+		.driver_data = &quirk_acer_predator_ph317_51,
+	},
 	{
 		.callback = dmi_matched,
 		.ident = "Acer Predator PHN16-71",
@@ -1968,7 +1992,7 @@ static void __init acer_commandline_init(void)
 }
 
 /*
- * LED device (Mail LED only, no other LEDs known yet)
+ * Mail LED device
  */
 static void mail_led_set(struct led_classdev *led_cdev,
 enum led_brightness value)
@@ -1992,6 +2016,40 @@ static void acer_led_exit(void)
 	led_classdev_unregister(&mail_led);
 }
 
+/*
+ * No WMI method drives this keyboard backlight. Fn+F9 changes both EC
+ * registers, so write both to reproduce the firmware's on/off states.
+ */
+static int kbd_led_set(struct led_classdev *led_cdev,
+		       enum led_brightness brightness)
+{
+	u8 value = brightness == LED_OFF ? 0 : ACER_KBD_BACKLIGHT_MASK;
+	int ret;
+
+	ret = ec_write(ACER_KBD_BACKLIGHT_EC_STATE, value);
+	if (ret)
+		return ret;
+
+	return ec_write(ACER_KBD_BACKLIGHT_EC_MIRROR, value);
+}
+
+static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
+{
+	u8 value;
+
+	if (ec_read(ACER_KBD_BACKLIGHT_EC_STATE, &value))
+		return LED_OFF;
+
+	return value & ACER_KBD_BACKLIGHT_MASK ? LED_ON : LED_OFF;
+}
+
+static struct led_classdev kbd_led = {
+	.name = "acer-wmi::kbd_backlight",
+	.brightness_set_blocking = kbd_led_set,
+	.brightness_get = kbd_led_get,
+	.max_brightness = LED_ON,
+};
+
 /*
  * Backlight device
  */
@@ -2847,8 +2905,15 @@ static int acer_platform_probe(struct platform_device *device)
 			goto error_hwmon;
 	}
 
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT)) {
+		err = devm_led_classdev_register(&device->dev, &kbd_led);
+		if (err)
+			goto error_kbd_backlight;
+	}
+
 	return 0;
 
+error_kbd_backlight:
 error_hwmon:
 error_platform_profile:
 	acer_rfkill_exit();
@@ -2877,6 +2942,7 @@ static int acer_suspend(struct device *dev)
 {
 	u32 value;
 	struct acer_data *data = &interface->data;
+	int ret;
 
 	if (!data)
 		return -ENOMEM;
@@ -2892,6 +2958,17 @@ static int acer_suspend(struct device *dev)
 		data->brightness = value;
 	}
 
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT)) {
+		u8 state;
+
+		ret = ec_read(ACER_KBD_BACKLIGHT_EC_STATE, &state);
+		if (ret)
+			return ret;
+
+		kbd_led.brightness = state & ACER_KBD_BACKLIGHT_MASK;
+		led_classdev_suspend(&kbd_led);
+	}
+
 	return 0;
 }
 
@@ -2908,6 +2985,9 @@ static int acer_resume(struct device *dev)
 	if (has_cap(ACER_CAP_BRIGHTNESS))
 		set_u32(data->brightness, ACER_CAP_BRIGHTNESS);
 
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
+		led_classdev_resume(&kbd_led);
+
 	if (acer_wmi_accel_dev)
 		acer_gsensor_init();
 
@@ -2929,6 +3009,9 @@ static void acer_platform_shutdown(struct platform_device *device)
 
 	if (has_cap(ACER_CAP_MAILLED))
 		set_u32(LED_OFF, ACER_CAP_MAILLED);
+
+	if (has_cap(ACER_CAP_KBD_BACKLIGHT))
+		led_classdev_suspend(&kbd_led);
 }
 
 static struct platform_driver acer_platform_driver = {

base-commit: 9d3475065167197742b0882aff21cf8e78393277

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-27 11:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-18 15:55 [PATCH] platform/x86: acer-wmi: support PH317-51 hwmon and kbd backlight Lucas Gillard
2026-10-05 17:01 ` Ilpo Järvinen
2026-10-27 11:21   ` [PATCH v2] " Lucas Gillard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.