On Wed, Apr 24, 2019 at 3:54 AM Chris Chiu <chiu@xxxxxxxxxxxx> wrote: > > On Thu, Apr 18, 2019 at 2:46 PM Chris Chiu <chiu@xxxxxxxxxxxx> wrote: > > > > Some of latest ASUS laptops support new fn-lock mode switching. > > This commit detect whether if the fn-lock option is enabled in > > BIOS setting, and toggle the fn-lock mode via a new WMI DEVID > > 0x00100023 when the corresponding notify code captured. > > > > The ASUS fn-lock mode switch is activated by pressing Fn+Esc. > > When on, keys F1 to F12 behave as applicable, with meanings > > defined by the application being used at the time. When off, > > F1 to F12 directly triggers hardware features, well known audio > > volume up/down, brightness up/down...etc, which were triggered > > by holding down Fn key and F-keys. > > > > Because there's no way to retrieve the fn-lock mode via existing > > WMI methods per ASUS spec, driver need to initialize and keep the > > fn-lock mode by itself. > > Pushed to my review and testing queue, thanks! > > Signed-off-by: Chris Chiu <chiu@xxxxxxxxxxxx> > > --- > > drivers/platform/x86/asus-wmi.c | 36 ++++++++++++++++++++++++++++++ > > include/linux/platform_data/x86/asus-wmi.h | 1 + > > 2 files changed, 37 insertions(+) > > > > diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c > > index 37b5de541270..5f52b66e40cb 100644 > > --- a/drivers/platform/x86/asus-wmi.c > > +++ b/drivers/platform/x86/asus-wmi.c > > @@ -69,6 +69,7 @@ MODULE_LICENSE("GPL"); > > #define NOTIFY_KBD_BRTUP 0xc4 > > #define NOTIFY_KBD_BRTDWN 0xc5 > > #define NOTIFY_KBD_BRTTOGGLE 0xc7 > > +#define NOTIFY_FNLOCK_TOGGLE 0x4e > > > > #define ASUS_FAN_DESC "cpu_fan" > > #define ASUS_FAN_MFUN 0x13 > > @@ -177,6 +178,8 @@ struct asus_wmi { > > struct workqueue_struct *hotplug_workqueue; > > struct work_struct hotplug_work; > > > > + bool fnlock_locked; > > + > > struct asus_wmi_debug debug; > > > > struct asus_wmi_driver *driver; > > @@ -1619,6 +1622,24 @@ static int is_display_toggle(int code) > > return 0; > > } > > > > +static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus) > > +{ > > +#define ASUS_WMI_FNLOCK_BIOS_DISABLED BIT(0) > > + u32 result; > > + > > + asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FNLOCK, &result); > > + > > + return (result & ASUS_WMI_DSTS_PRESENCE_BIT) && > > + !(result & ASUS_WMI_FNLOCK_BIOS_DISABLED); > > +} > > + > > +static void asus_wmi_fnlock_update(struct asus_wmi *asus) > > +{ > > + int mode = asus->fnlock_locked; > > + > > + asus_wmi_set_devstate(ASUS_WMI_DEVID_FNLOCK, mode, NULL); > > +} > > + > > static void asus_wmi_notify(u32 value, void *context) > > { > > struct asus_wmi *asus = context; > > @@ -1680,6 +1701,12 @@ static void asus_wmi_notify(u32 value, void *context) > > goto exit; > > } > > > > + if (code == NOTIFY_FNLOCK_TOGGLE) { > > + asus->fnlock_locked = !asus->fnlock_locked; > > + asus_wmi_fnlock_update(asus); > > + goto exit; > > + } > > + > > if (is_display_toggle(code) && > > asus->driver->quirks->no_display_toggle) > > goto exit; > > @@ -2134,6 +2161,11 @@ static int asus_wmi_add(struct platform_device *pdev) > > } else > > err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT, 2, NULL); > > > > + if (asus_wmi_has_fnlock_key(asus)) { > > + asus->fnlock_locked = true; > > + asus_wmi_fnlock_update(asus); > > + } > > + > > status = wmi_install_notify_handler(asus->driver->event_guid, > > asus_wmi_notify, asus); > > if (ACPI_FAILURE(status)) { > > @@ -2213,6 +2245,8 @@ static int asus_hotk_resume(struct device *device) > > if (!IS_ERR_OR_NULL(asus->kbd_led.dev)) > > kbd_led_update(asus); > > > > + if (asus_wmi_has_fnlock_key(asus)) > > + asus_wmi_fnlock_update(asus); > > return 0; > > } > > > > @@ -2249,6 +2283,8 @@ static int asus_hotk_restore(struct device *device) > > if (!IS_ERR_OR_NULL(asus->kbd_led.dev)) > > kbd_led_update(asus); > > > > + if (asus_wmi_has_fnlock_key(asus)) > > + asus_wmi_fnlock_update(asus); > > return 0; > > } > > > > diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h > > index 53dfc2541960..bfba245636a7 100644 > > --- a/include/linux/platform_data/x86/asus-wmi.h > > +++ b/include/linux/platform_data/x86/asus-wmi.h > > @@ -67,6 +67,7 @@ > > /* Input */ > > #define ASUS_WMI_DEVID_TOUCHPAD 0x00100011 > > #define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012 > > +#define ASUS_WMI_DEVID_FNLOCK 0x00100023 > > > > /* Fan, Thermal */ > > #define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011 > > -- > > 2.11.0 > > > > Gentle ping. Any comments or suggestions for this are appreciated. > > Chris -- With Best Regards, Andy Shevchenko