@@ -100,6 +100,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
100100#define QUIRK_ROG_NKEY_KEYBOARD BIT(11)
101101#define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
102102#define QUIRK_ROG_ALLY_XPAD BIT(13)
103+ #define QUIRK_HID_FN_LOCK BIT(14)
103104
104105#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
105106 QUIRK_NO_INIT_REPORTS | \
@@ -143,6 +144,8 @@ struct asus_drvdata {
143144 int battery_stat ;
144145 bool battery_in_query ;
145146 unsigned long battery_next_query ;
147+ struct work_struct fn_lock_sync_work ;
148+ bool fn_lock ;
146149};
147150
148151static int asus_report_battery (struct asus_drvdata * , u8 * , int );
@@ -350,13 +353,21 @@ static int asus_wmi_send_event(struct asus_drvdata *drvdata, u8 code)
350353static int asus_event (struct hid_device * hdev , struct hid_field * field ,
351354 struct hid_usage * usage , __s32 value )
352355{
356+ struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
357+
353358 if ((usage -> hid & HID_USAGE_PAGE ) == HID_UP_ASUSVENDOR &&
354359 (usage -> hid & HID_USAGE ) != 0x00 &&
355360 (usage -> hid & HID_USAGE ) != 0xff && !usage -> type ) {
356361 hid_warn (hdev , "Unmapped Asus vendor usagepage code 0x%02x\n" ,
357362 usage -> hid & HID_USAGE );
358363 }
359364
365+ if (drvdata -> quirks & QUIRK_HID_FN_LOCK &&
366+ usage -> type == EV_KEY && usage -> code == KEY_FN_ESC && value == 1 ) {
367+ drvdata -> fn_lock = !drvdata -> fn_lock ;
368+ schedule_work (& drvdata -> fn_lock_sync_work );
369+ }
370+
360371 return 0 ;
361372}
362373
@@ -528,6 +539,21 @@ static int asus_kbd_disable_oobe(struct hid_device *hdev)
528539 return 0 ;
529540}
530541
542+ static int asus_kbd_set_fn_lock (struct hid_device * hdev , bool enabled )
543+ {
544+ u8 buf [] = { FEATURE_KBD_REPORT_ID , 0xd0 , 0x4e , !!enabled };
545+
546+ return asus_kbd_set_report (hdev , buf , sizeof (buf ));
547+ }
548+
549+ static void asus_sync_fn_lock (struct work_struct * work )
550+ {
551+ struct asus_drvdata * drvdata =
552+ container_of (work , struct asus_drvdata , fn_lock_sync_work );
553+
554+ asus_kbd_set_fn_lock (drvdata -> hdev , drvdata -> fn_lock );
555+ }
556+
531557static void asus_schedule_work (struct asus_kbd_leds * led )
532558{
533559 unsigned long flags ;
@@ -999,6 +1025,12 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
9991025 asus_kbd_register_leds (hdev ))
10001026 hid_warn (hdev , "Failed to initialize backlight.\n" );
10011027
1028+ if (drvdata -> quirks & QUIRK_HID_FN_LOCK ) {
1029+ drvdata -> fn_lock = true;
1030+ INIT_WORK (& drvdata -> fn_lock_sync_work , asus_sync_fn_lock );
1031+ asus_kbd_set_fn_lock (hdev , true);
1032+ }
1033+
10021034 return 0 ;
10031035}
10041036
@@ -1330,6 +1362,9 @@ static void asus_remove(struct hid_device *hdev)
13301362 cancel_work_sync (& drvdata -> kbd_backlight -> work );
13311363 }
13321364
1365+ if (drvdata -> quirks & QUIRK_HID_FN_LOCK )
1366+ cancel_work_sync (& drvdata -> fn_lock_sync_work );
1367+
13331368 hid_hw_stop (hdev );
13341369}
13351370
@@ -1457,7 +1492,7 @@ static const struct hid_device_id asus_devices[] = {
14571492 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
14581493 { HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
14591494 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 ),
1460- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
1495+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK },
14611496 { HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
14621497 USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR ),
14631498 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
0 commit comments