2020 * Copyright (c) 2016 Frederik Wenigwieser <frederik.wenigwieser@gmail.com>
2121 */
2222
23- /*
24- */
25-
2623#include <linux/acpi.h>
24+ #include <linux/cleanup.h>
2725#include <linux/dmi.h>
2826#include <linux/hid.h>
2927#include <linux/module.h>
@@ -101,7 +99,6 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
10199#define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
102100#define QUIRK_ROG_ALLY_XPAD BIT(13)
103101#define QUIRK_HID_FN_LOCK BIT(14)
104- #define QUIRK_ROG_NKEY_ID1ID2_INIT BIT(15)
105102
106103#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
107104 QUIRK_NO_INIT_REPORTS | \
@@ -208,6 +205,12 @@ static const struct asus_touchpad_info medion_e1239t_tp = {
208205 .report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */ ,
209206};
210207
208+ static const u8 asus_report_id_init [] = {
209+ FEATURE_KBD_REPORT_ID ,
210+ FEATURE_KBD_LED_REPORT_ID1 ,
211+ FEATURE_KBD_LED_REPORT_ID2
212+ };
213+
211214static void asus_report_contact_down (struct asus_drvdata * drvdat ,
212215 int toolType , u8 * data )
213216{
@@ -354,7 +357,7 @@ static int asus_event(struct hid_device *hdev, struct hid_field *field,
354357 struct hid_usage * usage , __s32 value )
355358{
356359 struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
357-
360+
358361 if ((usage -> hid & HID_USAGE_PAGE ) == HID_UP_ASUSVENDOR &&
359362 (usage -> hid & HID_USAGE ) != 0x00 &&
360363 (usage -> hid & HID_USAGE ) != 0xff && !usage -> type ) {
@@ -443,45 +446,35 @@ static int asus_raw_event(struct hid_device *hdev,
443446 /*
444447 * G713 and G733 send these codes on some keypresses, depending on
445448 * the key pressed it can trigger a shutdown event if not caught.
446- */
447- if (data [0 ] == 0x02 && data [1 ] == 0x30 ) {
449+ */
450+ if (data [0 ] == 0x02 && data [1 ] == 0x30 )
448451 return -1 ;
449- }
450452 }
451453
452454 if (drvdata -> quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD ) {
453455 /*
454456 * CLAYMORE II keyboard sends this packet when it goes to sleep
455457 * this causes the whole system to go into suspend.
456- */
457-
458- if (size == 2 && data [0 ] == 0x02 && data [1 ] == 0x00 ) {
458+ */
459+ if (size == 2 && data [0 ] == 0x02 && data [1 ] == 0x00 )
459460 return -1 ;
460- }
461461 }
462462
463463 return 0 ;
464464}
465465
466466static int asus_kbd_set_report (struct hid_device * hdev , const u8 * buf , size_t buf_size )
467467{
468- unsigned char * dmabuf ;
469- int ret ;
470-
471- dmabuf = kmemdup (buf , buf_size , GFP_KERNEL );
468+ u8 * dmabuf __free (kfree ) = kmemdup (buf , buf_size , GFP_KERNEL );
472469 if (!dmabuf )
473470 return - ENOMEM ;
474471
475472 /*
476473 * The report ID should be set from the incoming buffer due to LED and key
477474 * interfaces having different pages
478- */
479- ret = hid_hw_raw_request (hdev , buf [0 ], dmabuf ,
480- buf_size , HID_FEATURE_REPORT ,
481- HID_REQ_SET_REPORT );
482- kfree (dmabuf );
483-
484- return ret ;
475+ */
476+ return hid_hw_raw_request (hdev , buf [0 ], dmabuf , buf_size , HID_FEATURE_REPORT ,
477+ HID_REQ_SET_REPORT );
485478}
486479
487480static int asus_kbd_init (struct hid_device * hdev , u8 report_id )
@@ -722,6 +715,21 @@ static void validate_mcu_fw_version(struct hid_device *hdev, int idProduct)
722715 }
723716}
724717
718+ static bool asus_has_report_id (struct hid_device * hdev , u16 report_id )
719+ {
720+ struct hid_report * report ;
721+ int t ;
722+
723+ for (t = HID_INPUT_REPORT ; t <= HID_FEATURE_REPORT ; t ++ ) {
724+ list_for_each_entry (report , & hdev -> report_enum [t ].report_list , list ) {
725+ if (report -> id == report_id )
726+ return true;
727+ }
728+ }
729+
730+ return false;
731+ }
732+
725733static int asus_kbd_register_leds (struct hid_device * hdev )
726734{
727735 struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
@@ -730,10 +738,6 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
730738 unsigned char kbd_func ;
731739 int ret ;
732740
733- ret = asus_kbd_init (hdev , FEATURE_KBD_REPORT_ID );
734- if (ret < 0 )
735- return ret ;
736-
737741 /* Get keyboard functions */
738742 ret = asus_kbd_get_functions (hdev , & kbd_func , FEATURE_KBD_REPORT_ID );
739743 if (ret < 0 )
@@ -743,11 +747,6 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
743747 if (!(kbd_func & SUPPORT_KBD_BACKLIGHT ))
744748 return - ENODEV ;
745749
746- if (drvdata -> quirks & QUIRK_ROG_NKEY_ID1ID2_INIT ) {
747- asus_kbd_init (hdev , FEATURE_KBD_LED_REPORT_ID1 );
748- asus_kbd_init (hdev , FEATURE_KBD_LED_REPORT_ID2 );
749- }
750-
751750 if (dmi_match (DMI_PRODUCT_FAMILY , "ProArt P16" )) {
752751 ret = asus_kbd_disable_oobe (hdev );
753752 if (ret < 0 )
@@ -1163,7 +1162,8 @@ static int asus_start_multitouch(struct hid_device *hdev)
11631162 return 0 ;
11641163}
11651164
1166- static int __maybe_unused asus_resume (struct hid_device * hdev ) {
1165+ static int __maybe_unused asus_resume (struct hid_device * hdev )
1166+ {
11671167 struct asus_drvdata * drvdata = hid_get_drvdata (hdev );
11681168 int ret = 0 ;
11691169
@@ -1294,8 +1294,19 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
12941294 return ret ;
12951295 }
12961296
1297+ for (int r = 0 ; r < ARRAY_SIZE (asus_report_id_init ); r ++ ) {
1298+ if (asus_has_report_id (hdev , asus_report_id_init [r ])) {
1299+ ret = asus_kbd_init (hdev , asus_report_id_init [r ]);
1300+ if (ret < 0 )
1301+ hid_warn (hdev , "Failed to initialize 0x%x: %d.\n" ,
1302+ asus_report_id_init [r ], ret );
1303+ }
1304+ }
1305+
1306+ /* Laptops keyboard backlight is always at 0x5a */
12971307 if (is_vendor && (drvdata -> quirks & QUIRK_USE_KBD_BACKLIGHT ) &&
1298- asus_kbd_register_leds (hdev ))
1308+ (asus_has_report_id (hdev , FEATURE_KBD_REPORT_ID )) &&
1309+ (asus_kbd_register_leds (hdev )))
12991310 hid_warn (hdev , "Failed to initialize backlight.\n" );
13001311
13011312 /*
@@ -1311,22 +1322,17 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
13111322 * were freed during registration due to no usages being mapped,
13121323 * leaving drvdata->input pointing to freed memory.
13131324 */
1314- if (!drvdata -> input || !(hdev -> claimed & HID_CLAIMED_INPUT )) {
1315- hid_err (hdev , "Asus input not registered\n" );
1316- ret = - ENOMEM ;
1317- goto err_stop_hw ;
1318- }
1319-
1320- if (drvdata -> tp ) {
1321- drvdata -> input -> name = "Asus TouchPad" ;
1322- } else {
1323- drvdata -> input -> name = "Asus Keyboard" ;
1324- }
1325+ if (drvdata -> input && (hdev -> claimed & HID_CLAIMED_INPUT )) {
1326+ if (drvdata -> tp )
1327+ drvdata -> input -> name = "Asus TouchPad" ;
1328+ else
1329+ drvdata -> input -> name = "Asus Keyboard" ;
13251330
1326- if (drvdata -> tp ) {
1327- ret = asus_start_multitouch (hdev );
1328- if (ret )
1329- goto err_stop_hw ;
1331+ if (drvdata -> tp ) {
1332+ ret = asus_start_multitouch (hdev );
1333+ if (ret )
1334+ goto err_stop_hw ;
1335+ }
13301336 }
13311337
13321338 return 0 ;
@@ -1484,10 +1490,10 @@ static const struct hid_device_id asus_devices[] = {
14841490 QUIRK_USE_KBD_BACKLIGHT },
14851491 { HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
14861492 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD ),
1487- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_ID1ID2_INIT },
1493+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
14881494 { HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
14891495 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 ),
1490- QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK | QUIRK_ROG_NKEY_ID1ID2_INIT },
1496+ QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK },
14911497 { HID_USB_DEVICE (USB_VENDOR_ID_ASUSTEK ,
14921498 USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR ),
14931499 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
0 commit comments