#define NOTIFY_BRNUP_MAX               0x1f
 #define NOTIFY_BRNDOWN_MIN             0x20
 #define NOTIFY_BRNDOWN_MAX             0x2e
+#define NOTIFY_FNLOCK_TOGGLE           0x4e
 #define NOTIFY_KBD_BRTUP               0xc4
 #define NOTIFY_KBD_BRTDWN              0xc5
 #define NOTIFY_KBD_BRTTOGGLE           0xc7
 
+#define ASUS_WMI_FNLOCK_BIOS_DISABLED  BIT(0)
+
 #define ASUS_FAN_DESC                  "cpu_fan"
 #define ASUS_FAN_MFUN                  0x13
 #define ASUS_FAN_SFUN_READ             0x06
        struct workqueue_struct *hotplug_workqueue;
        struct work_struct hotplug_work;
 
+       bool fnlock_locked;
+
        struct asus_wmi_debug debug;
 
        struct asus_wmi_driver *driver;
        return 0;
 }
 
+static bool asus_wmi_has_fnlock_key(struct asus_wmi *asus)
+{
+       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;
                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;
        } 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)) {
        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;
 }
 
        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;
 }