diff mbox series

[v2,1/1] hid-asus: use hid for brightness control on keyboard

Message ID 20240607040532.1074379-2-luke@ljones.dev (mailing list archive)
State Superseded
Headers show
Series hid-asus: use hid for keyboard brightness control | expand

Commit Message

Luke Jones June 7, 2024, 4:05 a.m. UTC
On almost all ASUS ROG series laptops the MCU used for the USB keyboard
also has a HID packet used for setting the brightness. This is usually
the same as the WMI method. But in some laptops the WMI method either
is missing or doesn't work, so we should default to the HID control.

Signed-off-by: Luke D. Jones <luke@ljones.dev>
---
 drivers/hid/hid-asus.c                     |  7 ++++
 drivers/platform/x86/asus-wmi.c            |  3 +-
 include/linux/platform_data/x86/asus-wmi.h | 45 ++++++++++++++++++++++
 3 files changed, 54 insertions(+), 1 deletion(-)

Comments

Luke Jones June 7, 2024, 11:24 p.m. UTC | #1
I thought this was finalised but I'm still getting conflicting reports.
Please don't merge until I confirm the fix.

On Fri, 7 Jun 2024, at 4:05 PM, Luke D. Jones wrote:
> On almost all ASUS ROG series laptops the MCU used for the USB keyboard
> also has a HID packet used for setting the brightness. This is usually
> the same as the WMI method. But in some laptops the WMI method either
> is missing or doesn't work, so we should default to the HID control.
> 
> Signed-off-by: Luke D. Jones <luke@ljones.dev>
> ---
> drivers/hid/hid-asus.c                     |  7 ++++
> drivers/platform/x86/asus-wmi.c            |  3 +-
> include/linux/platform_data/x86/asus-wmi.h | 45 ++++++++++++++++++++++
> 3 files changed, 54 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 02de2bf4f790..0ed3708ef7e2 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
>   */
> static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
> {
> + struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> u32 value;
> int ret;
>  
> if (!IS_ENABLED(CONFIG_ASUS_WMI))
> return false;
>  
> + if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
> + dmi_check_system(asus_use_hid_led_dmi_ids)) {
> + hid_info(hdev, "using HID for asus::kbd_backlight\n");
> + return false;
> + }
> +
> ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
>        ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
> hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 3f9b6285c9a6..799d928c7d3d 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -1681,7 +1681,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
> goto error;
> }
>  
> - if (!kbd_led_read(asus, &led_val, NULL)) {
> + if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
> + pr_info("using asus-wmi for asus::kbd_backlight\n");
> asus->kbd_led_wk = led_val;
> asus->kbd_led.name = "asus::kbd_backlight";
> asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index 3eb5cd6773ad..6ba0015e4386 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -4,6 +4,7 @@
>  
> #include <linux/errno.h>
> #include <linux/types.h>
> +#include <linux/dmi.h>
>  
> /* WMI Methods */
> #define ASUS_WMI_METHODID_SPEC         0x43455053 /* BIOS SPECification */
> @@ -160,4 +161,48 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
> }
> #endif
>  
> +/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
> +#if IS_ENABLED(CONFIG_ASUS_WMI)
> +bool asus_use_hid_led(void);
> +#else
> +static inline bool asus_use_hid_led(void)
> +{
> + return true;
> +}
> +#endif
> +
> +static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
> + {
> + .matches = {
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "GA403"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "GU605"),
> + },
> + },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
> + },
> + },
> + NULL,
> +};
> +
> #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
> -- 
> 2.45.1
> 
>
Luke Jones June 16, 2024, 5:25 a.m. UTC | #2
On Sat, 8 Jun 2024, at 11:24 AM, Luke Jones wrote:
> I thought this was finalised but I'm still getting conflicting reports.
> Please don't merge until I confirm the fix.

This is ready for merge now. I have more confirmation that the single patch with no adjustment to report_id works well.

> On Fri, 7 Jun 2024, at 4:05 PM, Luke D. Jones wrote:
> > On almost all ASUS ROG series laptops the MCU used for the USB keyboard
> > also has a HID packet used for setting the brightness. This is usually
> > the same as the WMI method. But in some laptops the WMI method either
> > is missing or doesn't work, so we should default to the HID control.
> > 
> > Signed-off-by: Luke D. Jones <luke@ljones.dev>
> > ---
> > drivers/hid/hid-asus.c                     |  7 ++++
> > drivers/platform/x86/asus-wmi.c            |  3 +-
> > include/linux/platform_data/x86/asus-wmi.h | 45 ++++++++++++++++++++++
> > 3 files changed, 54 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> > index 02de2bf4f790..0ed3708ef7e2 100644
> > --- a/drivers/hid/hid-asus.c
> > +++ b/drivers/hid/hid-asus.c
> > @@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
> >   */
> > static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
> > {
> > + struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
> > u32 value;
> > int ret;
> >  
> > if (!IS_ENABLED(CONFIG_ASUS_WMI))
> > return false;
> >  
> > + if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
> > + dmi_check_system(asus_use_hid_led_dmi_ids)) {
> > + hid_info(hdev, "using HID for asus::kbd_backlight\n");
> > + return false;
> > + }
> > +
> > ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
> >        ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
> > hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
> > diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> > index 3f9b6285c9a6..799d928c7d3d 100644
> > --- a/drivers/platform/x86/asus-wmi.c
> > +++ b/drivers/platform/x86/asus-wmi.c
> > @@ -1681,7 +1681,8 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
> > goto error;
> > }
> >  
> > - if (!kbd_led_read(asus, &led_val, NULL)) {
> > + if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
> > + pr_info("using asus-wmi for asus::kbd_backlight\n");
> > asus->kbd_led_wk = led_val;
> > asus->kbd_led.name = "asus::kbd_backlight";
> > asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> > diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> > index 3eb5cd6773ad..6ba0015e4386 100644
> > --- a/include/linux/platform_data/x86/asus-wmi.h
> > +++ b/include/linux/platform_data/x86/asus-wmi.h
> > @@ -4,6 +4,7 @@
> >  
> > #include <linux/errno.h>
> > #include <linux/types.h>
> > +#include <linux/dmi.h>
> >  
> > /* WMI Methods */
> > #define ASUS_WMI_METHODID_SPEC         0x43455053 /* BIOS SPECification */
> > @@ -160,4 +161,48 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
> > }
> > #endif
> >  
> > +/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
> > +#if IS_ENABLED(CONFIG_ASUS_WMI)
> > +bool asus_use_hid_led(void);
> > +#else
> > +static inline bool asus_use_hid_led(void)
> > +{
> > + return true;
> > +}
> > +#endif
> > +
> > +static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
> > + {
> > + .matches = {
> > + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
> > + },
> > + },
> > + {
> > + .matches = {
> > + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
> > + },
> > + },
> > + {
> > + .matches = {
> > + DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
> > + },
> > + },
> > + {
> > + .matches = {
> > + DMI_MATCH(DMI_BOARD_NAME, "GA403"),
> > + },
> > + },
> > + {
> > + .matches = {
> > + DMI_MATCH(DMI_BOARD_NAME, "GU605"),
> > + },
> > + },
> > + {
> > + .matches = {
> > + DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
> > + },
> > + },
> > + NULL,
> > +};
> > +
> > #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
> > -- 
> > 2.45.1
> > 
> >
Jiri Kosina June 19, 2024, 2:39 p.m. UTC | #3
On Sun, 16 Jun 2024, Luke Jones wrote:

> > I thought this was finalised but I'm still getting conflicting 
> > reports. Please don't merge until I confirm the fix.
> 
> This is ready for merge now. I have more confirmation that the single 
> patch with no adjustment to report_id works well.

Applied, thanks.
Benjamin Tissoires June 25, 2024, 3:02 p.m. UTC | #4
On Jun 19 2024, Jiri Kosina wrote:
> On Sun, 16 Jun 2024, Luke Jones wrote:
> 
> > > I thought this was finalised but I'm still getting conflicting 
> > > reports. Please don't merge until I confirm the fix.
> > 
> > This is ready for merge now. I have more confirmation that the single 
> > patch with no adjustment to report_id works well.
> 
> Applied, thanks.

This patch should have been taken through the platform x86 tree [0].

I have now reverted it (and it was buggy, it failed to compile on
linux-next).

Cheers,
Benjamin

[0] https://lore.kernel.org/all/b0d8eebc-5abb-4ec0-898c-af7eedc730d9@redhat.com/

> 
> -- 
> Jiri Kosina
> SUSE Labs
>
diff mbox series

Patch

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 02de2bf4f790..0ed3708ef7e2 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -492,12 +492,19 @@  static void asus_kbd_backlight_work(struct work_struct *work)
  */
 static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
 {
+	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
 	u32 value;
 	int ret;
 
 	if (!IS_ENABLED(CONFIG_ASUS_WMI))
 		return false;
 
+	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
+			dmi_check_system(asus_use_hid_led_dmi_ids)) {
+		hid_info(hdev, "using HID for asus::kbd_backlight\n");
+		return false;
+	}
+
 	ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
 				       ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
 	hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 3f9b6285c9a6..799d928c7d3d 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -1681,7 +1681,8 @@  static int asus_wmi_led_init(struct asus_wmi *asus)
 			goto error;
 	}
 
-	if (!kbd_led_read(asus, &led_val, NULL)) {
+	if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
+		pr_info("using asus-wmi for asus::kbd_backlight\n");
 		asus->kbd_led_wk = led_val;
 		asus->kbd_led.name = "asus::kbd_backlight";
 		asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
index 3eb5cd6773ad..6ba0015e4386 100644
--- a/include/linux/platform_data/x86/asus-wmi.h
+++ b/include/linux/platform_data/x86/asus-wmi.h
@@ -4,6 +4,7 @@ 
 
 #include <linux/errno.h>
 #include <linux/types.h>
+#include <linux/dmi.h>
 
 /* WMI Methods */
 #define ASUS_WMI_METHODID_SPEC	        0x43455053 /* BIOS SPECification */
@@ -160,4 +161,48 @@  static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
 }
 #endif
 
+/* To be used by both hid-asus and asus-wmi to determine which controls kbd_brightness */
+#if IS_ENABLED(CONFIG_ASUS_WMI)
+bool asus_use_hid_led(void);
+#else
+static inline bool asus_use_hid_led(void)
+{
+	return true;
+}
+#endif
+
+static const struct dmi_system_id asus_use_hid_led_dmi_ids[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Zephyrus"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Strix"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_FAMILY, "ROG Flow"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GA403"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GU605"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "RC71L"),
+		},
+	},
+	NULL,
+};
+
 #endif	/* __PLATFORM_DATA_X86_ASUS_WMI_H */