Skip to content

Commit 350bd24

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
HID: asus: Fix mute and touchpad-toggle keys on Medion Akoya E1239T
The mute key, is broken. All the consumer keys on the keyboard USB interface work normally, except for mute which only sends press events and never sends release events. The touchpad key sends the otherwise unused input report with a report-id of 5 on the touchpad interface. It too only sends press events. This also requires extra special handling since the multi-touch touchpad events and the KEY_F21 events for the touchpad toggle must not be send from the same input_dev (userspace cannot handle this). This commit adds special handlig for both, fixing these keys not working. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent e271f6c commit 350bd24

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

drivers/hid/hid-asus.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
4242
#define T100_TPAD_INTF 2
4343
#define MEDION_E1239T_TPAD_INTF 1
4444

45+
#define E1239T_TP_TOGGLE_REPORT_ID 0x05
4546
#define T100CHI_MOUSE_REPORT_ID 0x06
4647
#define FEATURE_REPORT_ID 0x0d
4748
#define INPUT_REPORT_ID 0x5d
@@ -111,6 +112,7 @@ struct asus_drvdata {
111112
unsigned long quirks;
112113
struct hid_device *hdev;
113114
struct input_dev *input;
115+
struct input_dev *tp_kbd_input;
114116
struct asus_kbd_leds *kbd_backlight;
115117
const struct asus_touchpad_info *tp;
116118
bool enable_backlight;
@@ -275,6 +277,34 @@ static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
275277
return 1;
276278
}
277279

280+
static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
281+
{
282+
if (size != 3)
283+
return 0;
284+
285+
/* Handle broken mute key which only sends press events */
286+
if (!drvdat->tp &&
287+
data[0] == 0x02 && data[1] == 0xe2 && data[2] == 0x00) {
288+
input_report_key(drvdat->input, KEY_MUTE, 1);
289+
input_sync(drvdat->input);
290+
input_report_key(drvdat->input, KEY_MUTE, 0);
291+
input_sync(drvdat->input);
292+
return 1;
293+
}
294+
295+
/* Handle custom touchpad toggle key which only sends press events */
296+
if (drvdat->tp_kbd_input &&
297+
data[0] == 0x05 && data[1] == 0x02 && data[2] == 0x28) {
298+
input_report_key(drvdat->tp_kbd_input, KEY_F21, 1);
299+
input_sync(drvdat->tp_kbd_input);
300+
input_report_key(drvdat->tp_kbd_input, KEY_F21, 0);
301+
input_sync(drvdat->tp_kbd_input);
302+
return 1;
303+
}
304+
305+
return 0;
306+
}
307+
278308
static int asus_event(struct hid_device *hdev, struct hid_field *field,
279309
struct hid_usage *usage, __s32 value)
280310
{
@@ -299,6 +329,9 @@ static int asus_raw_event(struct hid_device *hdev,
299329
if (drvdata->tp && data[0] == INPUT_REPORT_ID)
300330
return asus_report_input(drvdata, data, size);
301331

332+
if (drvdata->quirks & QUIRK_MEDION_E1239T)
333+
return asus_e1239t_event(drvdata, data, size);
334+
302335
return 0;
303336
}
304337

@@ -633,6 +666,21 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
633666
hi->report->id != T100CHI_MOUSE_REPORT_ID)
634667
return 0;
635668

669+
/* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */
670+
if (drvdata->tp && (drvdata->quirks & QUIRK_MEDION_E1239T)) {
671+
switch (hi->report->id) {
672+
case E1239T_TP_TOGGLE_REPORT_ID:
673+
input_set_capability(input, EV_KEY, KEY_F21);
674+
input->name = "Asus Touchpad Keys";
675+
drvdata->tp_kbd_input = input;
676+
return 0;
677+
case INPUT_REPORT_ID:
678+
break; /* Touchpad report, handled below */
679+
default:
680+
return 0; /* Ignore other reports */
681+
}
682+
}
683+
636684
if (drvdata->tp) {
637685
int ret;
638686

@@ -793,6 +841,16 @@ static int asus_input_mapping(struct hid_device *hdev,
793841
}
794842
}
795843

844+
/*
845+
* The mute button is broken and only sends press events, we
846+
* deal with this in our raw_event handler, so do not map it.
847+
*/
848+
if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
849+
usage->hid == (HID_UP_CONSUMER | 0xe2)) {
850+
input_set_capability(hi->input, EV_KEY, KEY_MUTE);
851+
return -1;
852+
}
853+
796854
return 0;
797855
}
798856

@@ -895,6 +953,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
895953
to_usb_interface(hdev->dev.parent)->altsetting;
896954

897955
if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) {
956+
/* For separate input-devs for tp and tp toggle key */
957+
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
898958
drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING;
899959
drvdata->tp = &medion_e1239t_tp;
900960
}

0 commit comments

Comments
 (0)