Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/hid/hid-asus.c
49633 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* HID driver for Asus notebook built-in keyboard.
4
* Fixes small logical maximum to match usage maximum.
5
*
6
* Currently supported devices are:
7
* EeeBook X205TA
8
* VivoBook E200HA
9
*
10
* Copyright (c) 2016 Yusuke Fujimaki <[email protected]>
11
*
12
* This module based on hid-ortek by
13
* Copyright (c) 2010 Johnathon Harris <[email protected]>
14
* Copyright (c) 2011 Jiri Kosina
15
*
16
* This module has been updated to add support for Asus i2c touchpad.
17
*
18
* Copyright (c) 2016 Brendan McGrath <[email protected]>
19
* Copyright (c) 2016 Victor Vlasenko <[email protected]>
20
* Copyright (c) 2016 Frederik Wenigwieser <[email protected]>
21
*/
22
23
/*
24
*/
25
26
#include <linux/dmi.h>
27
#include <linux/hid.h>
28
#include <linux/module.h>
29
#include <linux/platform_data/x86/asus-wmi.h>
30
#include <linux/platform_data/x86/asus-wmi-leds-ids.h>
31
#include <linux/input/mt.h>
32
#include <linux/usb.h> /* For to_usb_interface for T100 touchpad intf check */
33
#include <linux/power_supply.h>
34
#include <linux/leds.h>
35
36
#include "hid-ids.h"
37
38
MODULE_AUTHOR("Yusuke Fujimaki <[email protected]>");
39
MODULE_AUTHOR("Brendan McGrath <[email protected]>");
40
MODULE_AUTHOR("Victor Vlasenko <[email protected]>");
41
MODULE_AUTHOR("Frederik Wenigwieser <[email protected]>");
42
MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
43
44
#define T100_TPAD_INTF 2
45
#define MEDION_E1239T_TPAD_INTF 1
46
47
#define E1239T_TP_TOGGLE_REPORT_ID 0x05
48
#define T100CHI_MOUSE_REPORT_ID 0x06
49
#define FEATURE_REPORT_ID 0x0d
50
#define INPUT_REPORT_ID 0x5d
51
#define FEATURE_KBD_REPORT_ID 0x5a
52
#define FEATURE_KBD_REPORT_SIZE 16
53
#define FEATURE_KBD_LED_REPORT_ID1 0x5d
54
#define FEATURE_KBD_LED_REPORT_ID2 0x5e
55
56
#define ROG_ALLY_REPORT_SIZE 64
57
#define ROG_ALLY_X_MIN_MCU 313
58
#define ROG_ALLY_MIN_MCU 319
59
60
#define SUPPORT_KBD_BACKLIGHT BIT(0)
61
62
#define MAX_TOUCH_MAJOR 8
63
#define MAX_PRESSURE 128
64
65
#define BTN_LEFT_MASK 0x01
66
#define CONTACT_TOOL_TYPE_MASK 0x80
67
#define CONTACT_X_MSB_MASK 0xf0
68
#define CONTACT_Y_MSB_MASK 0x0f
69
#define CONTACT_TOUCH_MAJOR_MASK 0x07
70
#define CONTACT_PRESSURE_MASK 0x7f
71
72
#define BATTERY_REPORT_ID (0x03)
73
#define BATTERY_REPORT_SIZE (1 + 8)
74
#define BATTERY_LEVEL_MAX ((u8)255)
75
#define BATTERY_STAT_DISCONNECT (0)
76
#define BATTERY_STAT_CHARGING (1)
77
#define BATTERY_STAT_FULL (2)
78
79
#define QUIRK_FIX_NOTEBOOK_REPORT BIT(0)
80
#define QUIRK_NO_INIT_REPORTS BIT(1)
81
#define QUIRK_SKIP_INPUT_MAPPING BIT(2)
82
#define QUIRK_IS_MULTITOUCH BIT(3)
83
#define QUIRK_NO_CONSUMER_USAGES BIT(4)
84
#define QUIRK_USE_KBD_BACKLIGHT BIT(5)
85
#define QUIRK_T100_KEYBOARD BIT(6)
86
#define QUIRK_T100CHI BIT(7)
87
#define QUIRK_G752_KEYBOARD BIT(8)
88
#define QUIRK_T90CHI BIT(9)
89
#define QUIRK_MEDION_E1239T BIT(10)
90
#define QUIRK_ROG_NKEY_KEYBOARD BIT(11)
91
#define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
92
#define QUIRK_ROG_ALLY_XPAD BIT(13)
93
94
#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
95
QUIRK_NO_INIT_REPORTS | \
96
QUIRK_NO_CONSUMER_USAGES)
97
#define I2C_TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
98
QUIRK_SKIP_INPUT_MAPPING | \
99
QUIRK_IS_MULTITOUCH)
100
101
#define TRKID_SGN ((TRKID_MAX + 1) >> 1)
102
103
struct asus_kbd_leds {
104
struct led_classdev cdev;
105
struct hid_device *hdev;
106
struct work_struct work;
107
unsigned int brightness;
108
spinlock_t lock;
109
bool removed;
110
};
111
112
struct asus_touchpad_info {
113
int max_x;
114
int max_y;
115
int res_x;
116
int res_y;
117
int contact_size;
118
int max_contacts;
119
int report_size;
120
};
121
122
struct asus_drvdata {
123
unsigned long quirks;
124
struct hid_device *hdev;
125
struct input_dev *input;
126
struct input_dev *tp_kbd_input;
127
struct asus_kbd_leds *kbd_backlight;
128
const struct asus_touchpad_info *tp;
129
bool enable_backlight;
130
struct power_supply *battery;
131
struct power_supply_desc battery_desc;
132
int battery_capacity;
133
int battery_stat;
134
bool battery_in_query;
135
unsigned long battery_next_query;
136
};
137
138
static int asus_report_battery(struct asus_drvdata *, u8 *, int);
139
140
static const struct asus_touchpad_info asus_i2c_tp = {
141
.max_x = 2794,
142
.max_y = 1758,
143
.contact_size = 5,
144
.max_contacts = 5,
145
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
146
};
147
148
static const struct asus_touchpad_info asus_t100ta_tp = {
149
.max_x = 2240,
150
.max_y = 1120,
151
.res_x = 30, /* units/mm */
152
.res_y = 27, /* units/mm */
153
.contact_size = 5,
154
.max_contacts = 5,
155
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
156
};
157
158
static const struct asus_touchpad_info asus_t100ha_tp = {
159
.max_x = 2640,
160
.max_y = 1320,
161
.res_x = 30, /* units/mm */
162
.res_y = 29, /* units/mm */
163
.contact_size = 5,
164
.max_contacts = 5,
165
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
166
};
167
168
static const struct asus_touchpad_info asus_t200ta_tp = {
169
.max_x = 3120,
170
.max_y = 1716,
171
.res_x = 30, /* units/mm */
172
.res_y = 28, /* units/mm */
173
.contact_size = 5,
174
.max_contacts = 5,
175
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
176
};
177
178
static const struct asus_touchpad_info asus_t100chi_tp = {
179
.max_x = 2640,
180
.max_y = 1320,
181
.res_x = 31, /* units/mm */
182
.res_y = 29, /* units/mm */
183
.contact_size = 3,
184
.max_contacts = 4,
185
.report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */,
186
};
187
188
static const struct asus_touchpad_info medion_e1239t_tp = {
189
.max_x = 2640,
190
.max_y = 1380,
191
.res_x = 29, /* units/mm */
192
.res_y = 28, /* units/mm */
193
.contact_size = 5,
194
.max_contacts = 5,
195
.report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */,
196
};
197
198
static void asus_report_contact_down(struct asus_drvdata *drvdat,
199
int toolType, u8 *data)
200
{
201
struct input_dev *input = drvdat->input;
202
int touch_major, pressure, x, y;
203
204
x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1];
205
y = drvdat->tp->max_y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]);
206
207
input_report_abs(input, ABS_MT_POSITION_X, x);
208
input_report_abs(input, ABS_MT_POSITION_Y, y);
209
210
if (drvdat->tp->contact_size < 5)
211
return;
212
213
if (toolType == MT_TOOL_PALM) {
214
touch_major = MAX_TOUCH_MAJOR;
215
pressure = MAX_PRESSURE;
216
} else {
217
touch_major = (data[3] >> 4) & CONTACT_TOUCH_MAJOR_MASK;
218
pressure = data[4] & CONTACT_PRESSURE_MASK;
219
}
220
221
input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major);
222
input_report_abs(input, ABS_MT_PRESSURE, pressure);
223
}
224
225
/* Required for Synaptics Palm Detection */
226
static void asus_report_tool_width(struct asus_drvdata *drvdat)
227
{
228
struct input_mt *mt = drvdat->input->mt;
229
struct input_mt_slot *oldest;
230
int oldid, i;
231
232
if (drvdat->tp->contact_size < 5)
233
return;
234
235
oldest = NULL;
236
oldid = mt->trkid;
237
238
for (i = 0; i < mt->num_slots; ++i) {
239
struct input_mt_slot *ps = &mt->slots[i];
240
int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
241
242
if (id < 0)
243
continue;
244
if ((id - oldid) & TRKID_SGN) {
245
oldest = ps;
246
oldid = id;
247
}
248
}
249
250
if (oldest) {
251
input_report_abs(drvdat->input, ABS_TOOL_WIDTH,
252
input_mt_get_value(oldest, ABS_MT_TOUCH_MAJOR));
253
}
254
}
255
256
static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
257
{
258
int i, toolType = MT_TOOL_FINGER;
259
u8 *contactData = data + 2;
260
261
if (size != drvdat->tp->report_size)
262
return 0;
263
264
for (i = 0; i < drvdat->tp->max_contacts; i++) {
265
bool down = !!(data[1] & BIT(i+3));
266
267
if (drvdat->tp->contact_size >= 5)
268
toolType = contactData[3] & CONTACT_TOOL_TYPE_MASK ?
269
MT_TOOL_PALM : MT_TOOL_FINGER;
270
271
input_mt_slot(drvdat->input, i);
272
input_mt_report_slot_state(drvdat->input, toolType, down);
273
274
if (down) {
275
asus_report_contact_down(drvdat, toolType, contactData);
276
contactData += drvdat->tp->contact_size;
277
}
278
}
279
280
input_report_key(drvdat->input, BTN_LEFT, data[1] & BTN_LEFT_MASK);
281
asus_report_tool_width(drvdat);
282
283
input_mt_sync_frame(drvdat->input);
284
input_sync(drvdat->input);
285
286
return 1;
287
}
288
289
static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
290
{
291
if (size != 3)
292
return 0;
293
294
/* Handle broken mute key which only sends press events */
295
if (!drvdat->tp &&
296
data[0] == 0x02 && data[1] == 0xe2 && data[2] == 0x00) {
297
input_report_key(drvdat->input, KEY_MUTE, 1);
298
input_sync(drvdat->input);
299
input_report_key(drvdat->input, KEY_MUTE, 0);
300
input_sync(drvdat->input);
301
return 1;
302
}
303
304
/* Handle custom touchpad toggle key which only sends press events */
305
if (drvdat->tp_kbd_input &&
306
data[0] == 0x05 && data[1] == 0x02 && data[2] == 0x28) {
307
input_report_key(drvdat->tp_kbd_input, KEY_F21, 1);
308
input_sync(drvdat->tp_kbd_input);
309
input_report_key(drvdat->tp_kbd_input, KEY_F21, 0);
310
input_sync(drvdat->tp_kbd_input);
311
return 1;
312
}
313
314
return 0;
315
}
316
317
static int asus_event(struct hid_device *hdev, struct hid_field *field,
318
struct hid_usage *usage, __s32 value)
319
{
320
if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 &&
321
(usage->hid & HID_USAGE) != 0x00 &&
322
(usage->hid & HID_USAGE) != 0xff && !usage->type) {
323
hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n",
324
usage->hid & HID_USAGE);
325
}
326
327
return 0;
328
}
329
330
static int asus_raw_event(struct hid_device *hdev,
331
struct hid_report *report, u8 *data, int size)
332
{
333
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
334
335
if (drvdata->battery && data[0] == BATTERY_REPORT_ID)
336
return asus_report_battery(drvdata, data, size);
337
338
if (drvdata->tp && data[0] == INPUT_REPORT_ID)
339
return asus_report_input(drvdata, data, size);
340
341
if (drvdata->quirks & QUIRK_MEDION_E1239T)
342
return asus_e1239t_event(drvdata, data, size);
343
344
/*
345
* Skip these report ID, the device emits a continuous stream associated
346
* with the AURA mode it is in which looks like an 'echo'.
347
*/
348
if (report->id == FEATURE_KBD_LED_REPORT_ID1 || report->id == FEATURE_KBD_LED_REPORT_ID2)
349
return -1;
350
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
351
/*
352
* G713 and G733 send these codes on some keypresses, depending on
353
* the key pressed it can trigger a shutdown event if not caught.
354
*/
355
if (data[0] == 0x02 && data[1] == 0x30) {
356
return -1;
357
}
358
}
359
360
if (drvdata->quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD) {
361
/*
362
* CLAYMORE II keyboard sends this packet when it goes to sleep
363
* this causes the whole system to go into suspend.
364
*/
365
366
if(size == 2 && data[0] == 0x02 && data[1] == 0x00) {
367
return -1;
368
}
369
}
370
371
return 0;
372
}
373
374
static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size)
375
{
376
unsigned char *dmabuf;
377
int ret;
378
379
dmabuf = kmemdup(buf, buf_size, GFP_KERNEL);
380
if (!dmabuf)
381
return -ENOMEM;
382
383
/*
384
* The report ID should be set from the incoming buffer due to LED and key
385
* interfaces having different pages
386
*/
387
ret = hid_hw_raw_request(hdev, buf[0], dmabuf,
388
buf_size, HID_FEATURE_REPORT,
389
HID_REQ_SET_REPORT);
390
kfree(dmabuf);
391
392
return ret;
393
}
394
395
static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
396
{
397
const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
398
0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
399
int ret;
400
401
ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
402
if (ret < 0)
403
hid_err(hdev, "Asus failed to send init command: %d\n", ret);
404
405
return ret;
406
}
407
408
static int asus_kbd_get_functions(struct hid_device *hdev,
409
unsigned char *kbd_func,
410
u8 report_id)
411
{
412
const u8 buf[] = { report_id, 0x05, 0x20, 0x31, 0x00, 0x08 };
413
u8 *readbuf;
414
int ret;
415
416
ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
417
if (ret < 0) {
418
hid_err(hdev, "Asus failed to send configuration command: %d\n", ret);
419
return ret;
420
}
421
422
readbuf = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL);
423
if (!readbuf)
424
return -ENOMEM;
425
426
ret = hid_hw_raw_request(hdev, FEATURE_KBD_REPORT_ID, readbuf,
427
FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT,
428
HID_REQ_GET_REPORT);
429
if (ret < 0) {
430
hid_err(hdev, "Asus failed to request functions: %d\n", ret);
431
kfree(readbuf);
432
return ret;
433
}
434
435
*kbd_func = readbuf[6];
436
437
kfree(readbuf);
438
return ret;
439
}
440
441
static int asus_kbd_disable_oobe(struct hid_device *hdev)
442
{
443
const u8 init[][6] = {
444
{ FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 },
445
{ FEATURE_KBD_REPORT_ID, 0xBA, 0xC5, 0xC4 },
446
{ FEATURE_KBD_REPORT_ID, 0xD0, 0x8F, 0x01 },
447
{ FEATURE_KBD_REPORT_ID, 0xD0, 0x85, 0xFF }
448
};
449
int ret;
450
451
for (size_t i = 0; i < ARRAY_SIZE(init); i++) {
452
ret = asus_kbd_set_report(hdev, init[i], sizeof(init[i]));
453
if (ret < 0)
454
return ret;
455
}
456
457
hid_info(hdev, "Disabled OOBE for keyboard\n");
458
return 0;
459
}
460
461
static void asus_schedule_work(struct asus_kbd_leds *led)
462
{
463
unsigned long flags;
464
465
spin_lock_irqsave(&led->lock, flags);
466
if (!led->removed)
467
schedule_work(&led->work);
468
spin_unlock_irqrestore(&led->lock, flags);
469
}
470
471
static void asus_kbd_backlight_set(struct led_classdev *led_cdev,
472
enum led_brightness brightness)
473
{
474
struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
475
cdev);
476
unsigned long flags;
477
478
spin_lock_irqsave(&led->lock, flags);
479
led->brightness = brightness;
480
spin_unlock_irqrestore(&led->lock, flags);
481
482
asus_schedule_work(led);
483
}
484
485
static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev)
486
{
487
struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds,
488
cdev);
489
enum led_brightness brightness;
490
unsigned long flags;
491
492
spin_lock_irqsave(&led->lock, flags);
493
brightness = led->brightness;
494
spin_unlock_irqrestore(&led->lock, flags);
495
496
return brightness;
497
}
498
499
static void asus_kbd_backlight_work(struct work_struct *work)
500
{
501
struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work);
502
u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 };
503
int ret;
504
unsigned long flags;
505
506
spin_lock_irqsave(&led->lock, flags);
507
buf[4] = led->brightness;
508
spin_unlock_irqrestore(&led->lock, flags);
509
510
ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf));
511
if (ret < 0)
512
hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret);
513
}
514
515
/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
516
* precedence. We only activate HID-based backlight control when the
517
* WMI control is not available.
518
*/
519
static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
520
{
521
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
522
u32 value;
523
int ret;
524
525
if (!IS_ENABLED(CONFIG_ASUS_WMI))
526
return false;
527
528
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
529
dmi_check_system(asus_use_hid_led_dmi_ids)) {
530
hid_info(hdev, "using HID for asus::kbd_backlight\n");
531
return false;
532
}
533
534
ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
535
ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
536
hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
537
if (ret)
538
return false;
539
540
return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT);
541
}
542
543
/*
544
* We don't care about any other part of the string except the version section.
545
* Example strings: FGA80100.RC72LA.312_T01, FGA80100.RC71LS.318_T01
546
* The bytes "5a 05 03 31 00 1a 13" and possibly more come before the version
547
* string, and there may be additional bytes after the version string such as
548
* "75 00 74 00 65 00" or a postfix such as "_T01"
549
*/
550
static int mcu_parse_version_string(const u8 *response, size_t response_size)
551
{
552
const u8 *end = response + response_size;
553
const u8 *p = response;
554
int dots, err, version;
555
char buf[4];
556
557
dots = 0;
558
while (p < end && dots < 2) {
559
if (*p++ == '.')
560
dots++;
561
}
562
563
if (dots != 2 || p >= end || (p + 3) >= end)
564
return -EINVAL;
565
566
memcpy(buf, p, 3);
567
buf[3] = '\0';
568
569
err = kstrtoint(buf, 10, &version);
570
if (err || version < 0)
571
return -EINVAL;
572
573
return version;
574
}
575
576
static int mcu_request_version(struct hid_device *hdev)
577
{
578
u8 *response __free(kfree) = kzalloc(ROG_ALLY_REPORT_SIZE, GFP_KERNEL);
579
const u8 request[] = { 0x5a, 0x05, 0x03, 0x31, 0x00, 0x20 };
580
int ret;
581
582
if (!response)
583
return -ENOMEM;
584
585
ret = asus_kbd_set_report(hdev, request, sizeof(request));
586
if (ret < 0)
587
return ret;
588
589
ret = hid_hw_raw_request(hdev, FEATURE_REPORT_ID, response,
590
ROG_ALLY_REPORT_SIZE, HID_FEATURE_REPORT,
591
HID_REQ_GET_REPORT);
592
if (ret < 0)
593
return ret;
594
595
ret = mcu_parse_version_string(response, ROG_ALLY_REPORT_SIZE);
596
if (ret < 0) {
597
pr_err("Failed to parse MCU version: %d\n", ret);
598
print_hex_dump(KERN_ERR, "MCU: ", DUMP_PREFIX_NONE,
599
16, 1, response, ROG_ALLY_REPORT_SIZE, false);
600
}
601
602
return ret;
603
}
604
605
static void validate_mcu_fw_version(struct hid_device *hdev, int idProduct)
606
{
607
int min_version, version;
608
609
version = mcu_request_version(hdev);
610
if (version < 0)
611
return;
612
613
switch (idProduct) {
614
case USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY:
615
min_version = ROG_ALLY_MIN_MCU;
616
break;
617
case USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X:
618
min_version = ROG_ALLY_X_MIN_MCU;
619
break;
620
default:
621
min_version = 0;
622
}
623
624
if (version < min_version) {
625
hid_warn(hdev,
626
"The MCU firmware version must be %d or greater to avoid issues with suspend.\n",
627
min_version);
628
} else {
629
set_ally_mcu_hack(ASUS_WMI_ALLY_MCU_HACK_DISABLED);
630
set_ally_mcu_powersave(true);
631
}
632
}
633
634
static int asus_kbd_register_leds(struct hid_device *hdev)
635
{
636
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
637
struct usb_interface *intf;
638
struct usb_device *udev;
639
unsigned char kbd_func;
640
int ret;
641
642
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
643
/* Initialize keyboard */
644
ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID);
645
if (ret < 0)
646
return ret;
647
648
/* The LED endpoint is initialised in two HID */
649
ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1);
650
if (ret < 0)
651
return ret;
652
653
ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2);
654
if (ret < 0)
655
return ret;
656
657
if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) {
658
ret = asus_kbd_disable_oobe(hdev);
659
if (ret < 0)
660
return ret;
661
}
662
663
if (drvdata->quirks & QUIRK_ROG_ALLY_XPAD) {
664
intf = to_usb_interface(hdev->dev.parent);
665
udev = interface_to_usbdev(intf);
666
validate_mcu_fw_version(hdev,
667
le16_to_cpu(udev->descriptor.idProduct));
668
}
669
670
} else {
671
/* Initialize keyboard */
672
ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID);
673
if (ret < 0)
674
return ret;
675
676
/* Get keyboard functions */
677
ret = asus_kbd_get_functions(hdev, &kbd_func, FEATURE_KBD_REPORT_ID);
678
if (ret < 0)
679
return ret;
680
681
/* Check for backlight support */
682
if (!(kbd_func & SUPPORT_KBD_BACKLIGHT))
683
return -ENODEV;
684
}
685
686
drvdata->kbd_backlight = devm_kzalloc(&hdev->dev,
687
sizeof(struct asus_kbd_leds),
688
GFP_KERNEL);
689
if (!drvdata->kbd_backlight)
690
return -ENOMEM;
691
692
drvdata->kbd_backlight->removed = false;
693
drvdata->kbd_backlight->brightness = 0;
694
drvdata->kbd_backlight->hdev = hdev;
695
drvdata->kbd_backlight->cdev.name = "asus::kbd_backlight";
696
drvdata->kbd_backlight->cdev.max_brightness = 3;
697
drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set;
698
drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get;
699
INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work);
700
spin_lock_init(&drvdata->kbd_backlight->lock);
701
702
ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev);
703
if (ret < 0) {
704
/* No need to have this still around */
705
devm_kfree(&hdev->dev, drvdata->kbd_backlight);
706
}
707
708
return ret;
709
}
710
711
/*
712
* [0] REPORT_ID (same value defined in report descriptor)
713
* [1] rest battery level. range [0..255]
714
* [2]..[7] Bluetooth hardware address (MAC address)
715
* [8] charging status
716
* = 0 : AC offline / discharging
717
* = 1 : AC online / charging
718
* = 2 : AC online / fully charged
719
*/
720
static int asus_parse_battery(struct asus_drvdata *drvdata, u8 *data, int size)
721
{
722
u8 sts;
723
u8 lvl;
724
int val;
725
726
lvl = data[1];
727
sts = data[8];
728
729
drvdata->battery_capacity = ((int)lvl * 100) / (int)BATTERY_LEVEL_MAX;
730
731
switch (sts) {
732
case BATTERY_STAT_CHARGING:
733
val = POWER_SUPPLY_STATUS_CHARGING;
734
break;
735
case BATTERY_STAT_FULL:
736
val = POWER_SUPPLY_STATUS_FULL;
737
break;
738
case BATTERY_STAT_DISCONNECT:
739
default:
740
val = POWER_SUPPLY_STATUS_DISCHARGING;
741
break;
742
}
743
drvdata->battery_stat = val;
744
745
return 0;
746
}
747
748
static int asus_report_battery(struct asus_drvdata *drvdata, u8 *data, int size)
749
{
750
/* notify only the autonomous event by device */
751
if ((drvdata->battery_in_query == false) &&
752
(size == BATTERY_REPORT_SIZE))
753
power_supply_changed(drvdata->battery);
754
755
return 0;
756
}
757
758
static int asus_battery_query(struct asus_drvdata *drvdata)
759
{
760
u8 *buf;
761
int ret = 0;
762
763
buf = kmalloc(BATTERY_REPORT_SIZE, GFP_KERNEL);
764
if (!buf)
765
return -ENOMEM;
766
767
drvdata->battery_in_query = true;
768
ret = hid_hw_raw_request(drvdata->hdev, BATTERY_REPORT_ID,
769
buf, BATTERY_REPORT_SIZE,
770
HID_INPUT_REPORT, HID_REQ_GET_REPORT);
771
drvdata->battery_in_query = false;
772
if (ret == BATTERY_REPORT_SIZE)
773
ret = asus_parse_battery(drvdata, buf, BATTERY_REPORT_SIZE);
774
else
775
ret = -ENODATA;
776
777
kfree(buf);
778
779
return ret;
780
}
781
782
static enum power_supply_property asus_battery_props[] = {
783
POWER_SUPPLY_PROP_STATUS,
784
POWER_SUPPLY_PROP_PRESENT,
785
POWER_SUPPLY_PROP_CAPACITY,
786
POWER_SUPPLY_PROP_SCOPE,
787
POWER_SUPPLY_PROP_MODEL_NAME,
788
};
789
790
#define QUERY_MIN_INTERVAL (60 * HZ) /* 60[sec] */
791
792
static int asus_battery_get_property(struct power_supply *psy,
793
enum power_supply_property psp,
794
union power_supply_propval *val)
795
{
796
struct asus_drvdata *drvdata = power_supply_get_drvdata(psy);
797
int ret = 0;
798
799
switch (psp) {
800
case POWER_SUPPLY_PROP_STATUS:
801
case POWER_SUPPLY_PROP_CAPACITY:
802
if (time_before(drvdata->battery_next_query, jiffies)) {
803
drvdata->battery_next_query =
804
jiffies + QUERY_MIN_INTERVAL;
805
ret = asus_battery_query(drvdata);
806
if (ret)
807
return ret;
808
}
809
if (psp == POWER_SUPPLY_PROP_STATUS)
810
val->intval = drvdata->battery_stat;
811
else
812
val->intval = drvdata->battery_capacity;
813
break;
814
case POWER_SUPPLY_PROP_PRESENT:
815
val->intval = 1;
816
break;
817
case POWER_SUPPLY_PROP_SCOPE:
818
val->intval = POWER_SUPPLY_SCOPE_DEVICE;
819
break;
820
case POWER_SUPPLY_PROP_MODEL_NAME:
821
val->strval = drvdata->hdev->name;
822
break;
823
default:
824
ret = -EINVAL;
825
break;
826
}
827
828
return ret;
829
}
830
831
static int asus_battery_probe(struct hid_device *hdev)
832
{
833
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
834
struct power_supply_config pscfg = { .drv_data = drvdata };
835
int ret = 0;
836
837
drvdata->battery_capacity = 0;
838
drvdata->battery_stat = POWER_SUPPLY_STATUS_UNKNOWN;
839
drvdata->battery_in_query = false;
840
841
drvdata->battery_desc.properties = asus_battery_props;
842
drvdata->battery_desc.num_properties = ARRAY_SIZE(asus_battery_props);
843
drvdata->battery_desc.get_property = asus_battery_get_property;
844
drvdata->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
845
drvdata->battery_desc.use_for_apm = 0;
846
drvdata->battery_desc.name = devm_kasprintf(&hdev->dev, GFP_KERNEL,
847
"asus-keyboard-%s-battery",
848
strlen(hdev->uniq) ?
849
hdev->uniq : dev_name(&hdev->dev));
850
if (!drvdata->battery_desc.name)
851
return -ENOMEM;
852
853
drvdata->battery_next_query = jiffies;
854
855
drvdata->battery = devm_power_supply_register(&hdev->dev,
856
&(drvdata->battery_desc), &pscfg);
857
if (IS_ERR(drvdata->battery)) {
858
ret = PTR_ERR(drvdata->battery);
859
drvdata->battery = NULL;
860
hid_err(hdev, "Unable to register battery device\n");
861
return ret;
862
}
863
864
power_supply_powers(drvdata->battery, &hdev->dev);
865
866
return ret;
867
}
868
869
static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
870
{
871
struct input_dev *input = hi->input;
872
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
873
874
/* T100CHI uses MULTI_INPUT, bind the touchpad to the mouse hid_input */
875
if (drvdata->quirks & QUIRK_T100CHI &&
876
hi->report->id != T100CHI_MOUSE_REPORT_ID)
877
return 0;
878
879
/* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */
880
if (drvdata->tp && (drvdata->quirks & QUIRK_MEDION_E1239T)) {
881
switch (hi->report->id) {
882
case E1239T_TP_TOGGLE_REPORT_ID:
883
input_set_capability(input, EV_KEY, KEY_F21);
884
input->name = "Asus Touchpad Keys";
885
drvdata->tp_kbd_input = input;
886
return 0;
887
case INPUT_REPORT_ID:
888
break; /* Touchpad report, handled below */
889
default:
890
return 0; /* Ignore other reports */
891
}
892
}
893
894
if (drvdata->tp) {
895
int ret;
896
897
input_set_abs_params(input, ABS_MT_POSITION_X, 0,
898
drvdata->tp->max_x, 0, 0);
899
input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
900
drvdata->tp->max_y, 0, 0);
901
input_abs_set_res(input, ABS_MT_POSITION_X, drvdata->tp->res_x);
902
input_abs_set_res(input, ABS_MT_POSITION_Y, drvdata->tp->res_y);
903
904
if (drvdata->tp->contact_size >= 5) {
905
input_set_abs_params(input, ABS_TOOL_WIDTH, 0,
906
MAX_TOUCH_MAJOR, 0, 0);
907
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0,
908
MAX_TOUCH_MAJOR, 0, 0);
909
input_set_abs_params(input, ABS_MT_PRESSURE, 0,
910
MAX_PRESSURE, 0, 0);
911
}
912
913
__set_bit(BTN_LEFT, input->keybit);
914
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
915
916
ret = input_mt_init_slots(input, drvdata->tp->max_contacts,
917
INPUT_MT_POINTER);
918
919
if (ret) {
920
hid_err(hdev, "Asus input mt init slots failed: %d\n", ret);
921
return ret;
922
}
923
}
924
925
drvdata->input = input;
926
927
if (drvdata->enable_backlight &&
928
!asus_kbd_wmi_led_control_present(hdev) &&
929
asus_kbd_register_leds(hdev))
930
hid_warn(hdev, "Failed to initialize backlight.\n");
931
932
return 0;
933
}
934
935
#define asus_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, \
936
max, EV_KEY, (c))
937
static int asus_input_mapping(struct hid_device *hdev,
938
struct hid_input *hi, struct hid_field *field,
939
struct hid_usage *usage, unsigned long **bit,
940
int *max)
941
{
942
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
943
944
if (drvdata->quirks & QUIRK_SKIP_INPUT_MAPPING) {
945
/* Don't map anything from the HID report.
946
* We do it all manually in asus_input_configured
947
*/
948
return -1;
949
}
950
951
/*
952
* Ignore a bunch of bogus collections in the T100CHI descriptor.
953
* This avoids a bunch of non-functional hid_input devices getting
954
* created because of the T100CHI using HID_QUIRK_MULTI_INPUT.
955
*/
956
if ((drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) &&
957
(field->application == (HID_UP_GENDESK | 0x0080) ||
958
field->application == HID_GD_MOUSE ||
959
usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) ||
960
usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) ||
961
usage->hid == (HID_UP_GENDEVCTRLS | 0x0026)))
962
return -1;
963
964
/* ASUS-specific keyboard hotkeys and led backlight */
965
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ASUSVENDOR) {
966
switch (usage->hid & HID_USAGE) {
967
case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break;
968
case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break;
969
case 0x35: asus_map_key_clear(KEY_DISPLAY_OFF); break;
970
case 0x6c: asus_map_key_clear(KEY_SLEEP); break;
971
case 0x7c: asus_map_key_clear(KEY_MICMUTE); break;
972
case 0x82: asus_map_key_clear(KEY_CAMERA); break;
973
case 0x88: asus_map_key_clear(KEY_RFKILL); break;
974
case 0xb5: asus_map_key_clear(KEY_CALC); break;
975
case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP); break;
976
case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN); break;
977
case 0xc7: asus_map_key_clear(KEY_KBDILLUMTOGGLE); break;
978
case 0x4e: asus_map_key_clear(KEY_FN_ESC); break;
979
case 0x7e: asus_map_key_clear(KEY_EMOJI_PICKER); break;
980
981
case 0x8b: asus_map_key_clear(KEY_PROG1); break; /* ProArt Creator Hub key */
982
case 0x6b: asus_map_key_clear(KEY_F21); break; /* ASUS touchpad toggle */
983
case 0x38: asus_map_key_clear(KEY_PROG1); break; /* ROG key */
984
case 0xba: asus_map_key_clear(KEY_PROG2); break; /* Fn+C ASUS Splendid */
985
case 0x5c: asus_map_key_clear(KEY_PROG3); break; /* Fn+Space Power4Gear */
986
case 0x99: asus_map_key_clear(KEY_PROG4); break; /* Fn+F5 "fan" symbol */
987
case 0xae: asus_map_key_clear(KEY_PROG4); break; /* Fn+F5 "fan" symbol */
988
case 0x92: asus_map_key_clear(KEY_CALC); break; /* Fn+Ret "Calc" symbol */
989
case 0xb2: asus_map_key_clear(KEY_PROG2); break; /* Fn+Left previous aura */
990
case 0xb3: asus_map_key_clear(KEY_PROG3); break; /* Fn+Left next aura */
991
case 0x6a: asus_map_key_clear(KEY_F13); break; /* Screenpad toggle */
992
case 0x4b: asus_map_key_clear(KEY_F14); break; /* Arrows/Pg-Up/Dn toggle */
993
case 0xa5: asus_map_key_clear(KEY_F15); break; /* ROG Ally left back */
994
case 0xa6: asus_map_key_clear(KEY_F16); break; /* ROG Ally QAM button */
995
case 0xa7: asus_map_key_clear(KEY_F17); break; /* ROG Ally ROG long-press */
996
case 0xa8: asus_map_key_clear(KEY_F18); break; /* ROG Ally ROG long-press-release */
997
998
default:
999
/* ASUS lazily declares 256 usages, ignore the rest,
1000
* as some make the keyboard appear as a pointer device. */
1001
return -1;
1002
}
1003
1004
/*
1005
* Check and enable backlight only on devices with UsagePage ==
1006
* 0xff31 to avoid initializing the keyboard firmware multiple
1007
* times on devices with multiple HID descriptors but same
1008
* PID/VID.
1009
*/
1010
if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT)
1011
drvdata->enable_backlight = true;
1012
1013
set_bit(EV_REP, hi->input->evbit);
1014
return 1;
1015
}
1016
1017
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) {
1018
switch (usage->hid & HID_USAGE) {
1019
case 0xff01: asus_map_key_clear(BTN_1); break;
1020
case 0xff02: asus_map_key_clear(BTN_2); break;
1021
case 0xff03: asus_map_key_clear(BTN_3); break;
1022
case 0xff04: asus_map_key_clear(BTN_4); break;
1023
case 0xff05: asus_map_key_clear(BTN_5); break;
1024
case 0xff06: asus_map_key_clear(BTN_6); break;
1025
case 0xff07: asus_map_key_clear(BTN_7); break;
1026
case 0xff08: asus_map_key_clear(BTN_8); break;
1027
case 0xff09: asus_map_key_clear(BTN_9); break;
1028
case 0xff0a: asus_map_key_clear(BTN_A); break;
1029
case 0xff0b: asus_map_key_clear(BTN_B); break;
1030
case 0x00f1: asus_map_key_clear(KEY_WLAN); break;
1031
case 0x00f2: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break;
1032
case 0x00f3: asus_map_key_clear(KEY_BRIGHTNESSUP); break;
1033
case 0x00f4: asus_map_key_clear(KEY_DISPLAY_OFF); break;
1034
case 0x00f7: asus_map_key_clear(KEY_CAMERA); break;
1035
case 0x00f8: asus_map_key_clear(KEY_PROG1); break;
1036
default:
1037
return 0;
1038
}
1039
1040
set_bit(EV_REP, hi->input->evbit);
1041
return 1;
1042
}
1043
1044
if (drvdata->quirks & QUIRK_NO_CONSUMER_USAGES &&
1045
(usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) {
1046
switch (usage->hid & HID_USAGE) {
1047
case 0xe2: /* Mute */
1048
case 0xe9: /* Volume up */
1049
case 0xea: /* Volume down */
1050
return 0;
1051
default:
1052
/* Ignore dummy Consumer usages which make the
1053
* keyboard incorrectly appear as a pointer device.
1054
*/
1055
return -1;
1056
}
1057
}
1058
1059
/*
1060
* The mute button is broken and only sends press events, we
1061
* deal with this in our raw_event handler, so do not map it.
1062
*/
1063
if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
1064
usage->hid == (HID_UP_CONSUMER | 0xe2)) {
1065
input_set_capability(hi->input, EV_KEY, KEY_MUTE);
1066
return -1;
1067
}
1068
1069
return 0;
1070
}
1071
1072
static int asus_start_multitouch(struct hid_device *hdev)
1073
{
1074
int ret;
1075
static const unsigned char buf[] = {
1076
FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00
1077
};
1078
unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
1079
1080
if (!dmabuf) {
1081
ret = -ENOMEM;
1082
hid_err(hdev, "Asus failed to alloc dma buf: %d\n", ret);
1083
return ret;
1084
}
1085
1086
ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf),
1087
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
1088
1089
kfree(dmabuf);
1090
1091
if (ret != sizeof(buf)) {
1092
hid_err(hdev, "Asus failed to start multitouch: %d\n", ret);
1093
return ret;
1094
}
1095
1096
return 0;
1097
}
1098
1099
static int __maybe_unused asus_resume(struct hid_device *hdev) {
1100
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
1101
int ret = 0;
1102
1103
if (drvdata->kbd_backlight) {
1104
const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4,
1105
drvdata->kbd_backlight->cdev.brightness };
1106
ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
1107
if (ret < 0) {
1108
hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret);
1109
goto asus_resume_err;
1110
}
1111
}
1112
1113
asus_resume_err:
1114
return ret;
1115
}
1116
1117
static int __maybe_unused asus_reset_resume(struct hid_device *hdev)
1118
{
1119
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
1120
1121
if (drvdata->tp)
1122
return asus_start_multitouch(hdev);
1123
1124
return 0;
1125
}
1126
1127
static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
1128
{
1129
int ret;
1130
struct asus_drvdata *drvdata;
1131
1132
drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
1133
if (drvdata == NULL) {
1134
hid_err(hdev, "Can't alloc Asus descriptor\n");
1135
return -ENOMEM;
1136
}
1137
1138
hid_set_drvdata(hdev, drvdata);
1139
1140
drvdata->quirks = id->driver_data;
1141
1142
/*
1143
* T90CHI's keyboard dock returns same ID values as T100CHI's dock.
1144
* Thus, identify T90CHI dock with product name string.
1145
*/
1146
if (strstr(hdev->name, "T90CHI")) {
1147
drvdata->quirks &= ~QUIRK_T100CHI;
1148
drvdata->quirks |= QUIRK_T90CHI;
1149
}
1150
1151
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
1152
drvdata->tp = &asus_i2c_tp;
1153
1154
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) {
1155
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
1156
1157
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
1158
drvdata->quirks = QUIRK_SKIP_INPUT_MAPPING;
1159
/*
1160
* The T100HA uses the same USB-ids as the T100TAF and
1161
* the T200TA uses the same USB-ids as the T100TA, while
1162
* both have different max x/y values as the T100TA[F].
1163
*/
1164
if (dmi_match(DMI_PRODUCT_NAME, "T100HAN"))
1165
drvdata->tp = &asus_t100ha_tp;
1166
else if (dmi_match(DMI_PRODUCT_NAME, "T200TA"))
1167
drvdata->tp = &asus_t200ta_tp;
1168
else
1169
drvdata->tp = &asus_t100ta_tp;
1170
}
1171
}
1172
1173
if (drvdata->quirks & QUIRK_T100CHI) {
1174
/*
1175
* All functionality is on a single HID interface and for
1176
* userspace the touchpad must be a separate input_dev.
1177
*/
1178
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
1179
drvdata->tp = &asus_t100chi_tp;
1180
}
1181
1182
if ((drvdata->quirks & QUIRK_MEDION_E1239T) && hid_is_usb(hdev)) {
1183
struct usb_host_interface *alt =
1184
to_usb_interface(hdev->dev.parent)->altsetting;
1185
1186
if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) {
1187
/* For separate input-devs for tp and tp toggle key */
1188
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
1189
drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING;
1190
drvdata->tp = &medion_e1239t_tp;
1191
}
1192
}
1193
1194
if (drvdata->quirks & QUIRK_NO_INIT_REPORTS)
1195
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
1196
1197
drvdata->hdev = hdev;
1198
1199
if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) {
1200
ret = asus_battery_probe(hdev);
1201
if (ret) {
1202
hid_err(hdev,
1203
"Asus hid battery_probe failed: %d\n", ret);
1204
return ret;
1205
}
1206
}
1207
1208
ret = hid_parse(hdev);
1209
if (ret) {
1210
hid_err(hdev, "Asus hid parse failed: %d\n", ret);
1211
return ret;
1212
}
1213
1214
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
1215
if (ret) {
1216
hid_err(hdev, "Asus hw start failed: %d\n", ret);
1217
return ret;
1218
}
1219
1220
/*
1221
* Check that input registration succeeded. Checking that
1222
* HID_CLAIMED_INPUT is set prevents a UAF when all input devices
1223
* were freed during registration due to no usages being mapped,
1224
* leaving drvdata->input pointing to freed memory.
1225
*/
1226
if (!drvdata->input || !(hdev->claimed & HID_CLAIMED_INPUT)) {
1227
hid_err(hdev, "Asus input not registered\n");
1228
ret = -ENOMEM;
1229
goto err_stop_hw;
1230
}
1231
1232
if (drvdata->tp) {
1233
drvdata->input->name = "Asus TouchPad";
1234
} else {
1235
drvdata->input->name = "Asus Keyboard";
1236
}
1237
1238
if (drvdata->tp) {
1239
ret = asus_start_multitouch(hdev);
1240
if (ret)
1241
goto err_stop_hw;
1242
}
1243
1244
return 0;
1245
err_stop_hw:
1246
hid_hw_stop(hdev);
1247
return ret;
1248
}
1249
1250
static void asus_remove(struct hid_device *hdev)
1251
{
1252
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
1253
unsigned long flags;
1254
1255
if (drvdata->kbd_backlight) {
1256
spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags);
1257
drvdata->kbd_backlight->removed = true;
1258
spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags);
1259
1260
cancel_work_sync(&drvdata->kbd_backlight->work);
1261
}
1262
1263
hid_hw_stop(hdev);
1264
}
1265
1266
static const __u8 asus_g752_fixed_rdesc[] = {
1267
0x19, 0x00, /* Usage Minimum (0x00) */
1268
0x2A, 0xFF, 0x00, /* Usage Maximum (0xFF) */
1269
};
1270
1271
static const __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
1272
unsigned int *rsize)
1273
{
1274
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
1275
1276
if (drvdata->quirks & QUIRK_FIX_NOTEBOOK_REPORT &&
1277
*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x65) {
1278
hid_info(hdev, "Fixing up Asus notebook report descriptor\n");
1279
rdesc[55] = 0xdd;
1280
}
1281
/* For the T100TA/T200TA keyboard dock */
1282
if (drvdata->quirks & QUIRK_T100_KEYBOARD &&
1283
(*rsize == 76 || *rsize == 101) &&
1284
rdesc[73] == 0x81 && rdesc[74] == 0x01) {
1285
hid_info(hdev, "Fixing up Asus T100 keyb report descriptor\n");
1286
rdesc[74] &= ~HID_MAIN_ITEM_CONSTANT;
1287
}
1288
/* For the T100CHI/T90CHI keyboard dock */
1289
if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) {
1290
int rsize_orig;
1291
int offs;
1292
1293
if (drvdata->quirks & QUIRK_T100CHI) {
1294
rsize_orig = 403;
1295
offs = 388;
1296
} else {
1297
rsize_orig = 306;
1298
offs = 291;
1299
}
1300
1301
/*
1302
* Change Usage (76h) to Usage Minimum (00h), Usage Maximum
1303
* (FFh) and clear the flags in the Input() byte.
1304
* Note the descriptor has a bogus 0 byte at the end so we
1305
* only need 1 extra byte.
1306
*/
1307
if (*rsize == rsize_orig &&
1308
rdesc[offs] == 0x09 && rdesc[offs + 1] == 0x76) {
1309
*rsize = rsize_orig + 1;
1310
rdesc = kmemdup(rdesc, *rsize, GFP_KERNEL);
1311
if (!rdesc)
1312
return NULL;
1313
1314
hid_info(hdev, "Fixing up %s keyb report descriptor\n",
1315
drvdata->quirks & QUIRK_T100CHI ?
1316
"T100CHI" : "T90CHI");
1317
memmove(rdesc + offs + 4, rdesc + offs + 2, 12);
1318
rdesc[offs] = 0x19;
1319
rdesc[offs + 1] = 0x00;
1320
rdesc[offs + 2] = 0x29;
1321
rdesc[offs + 3] = 0xff;
1322
rdesc[offs + 14] = 0x00;
1323
}
1324
}
1325
1326
if (drvdata->quirks & QUIRK_G752_KEYBOARD &&
1327
*rsize == 75 && rdesc[61] == 0x15 && rdesc[62] == 0x00) {
1328
/* report is missing usage minimum and maximum */
1329
__u8 *new_rdesc;
1330
size_t new_size = *rsize + sizeof(asus_g752_fixed_rdesc);
1331
1332
new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL);
1333
if (new_rdesc == NULL)
1334
return rdesc;
1335
1336
hid_info(hdev, "Fixing up Asus G752 keyb report descriptor\n");
1337
/* copy the valid part */
1338
memcpy(new_rdesc, rdesc, 61);
1339
/* insert missing part */
1340
memcpy(new_rdesc + 61, asus_g752_fixed_rdesc, sizeof(asus_g752_fixed_rdesc));
1341
/* copy remaining data */
1342
memcpy(new_rdesc + 61 + sizeof(asus_g752_fixed_rdesc), rdesc + 61, *rsize - 61);
1343
1344
*rsize = new_size;
1345
rdesc = new_rdesc;
1346
}
1347
1348
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
1349
*rsize == 331 && rdesc[190] == 0x85 && rdesc[191] == 0x5a &&
1350
rdesc[204] == 0x95 && rdesc[205] == 0x05) {
1351
hid_info(hdev, "Fixing up Asus N-KEY keyb report descriptor\n");
1352
rdesc[205] = 0x01;
1353
}
1354
1355
/* match many more n-key devices */
1356
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) {
1357
for (int i = 0; i < *rsize - 15; i++) {
1358
/* offset to the count from 0x5a report part always 14 */
1359
if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
1360
rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {
1361
hid_info(hdev, "Fixing up Asus N-Key report descriptor\n");
1362
rdesc[i + 15] = 0x01;
1363
break;
1364
}
1365
}
1366
}
1367
1368
return rdesc;
1369
}
1370
1371
static const struct hid_device_id asus_devices[] = {
1372
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
1373
USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD), I2C_KEYBOARD_QUIRKS},
1374
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
1375
USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD), I2C_TOUCHPAD_QUIRKS },
1376
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1377
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1), QUIRK_USE_KBD_BACKLIGHT },
1378
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1379
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT },
1380
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1381
USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3), QUIRK_G752_KEYBOARD },
1382
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1383
USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD),
1384
QUIRK_USE_KBD_BACKLIGHT },
1385
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1386
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD),
1387
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
1388
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1389
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2),
1390
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
1391
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1392
USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR),
1393
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
1394
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1395
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
1396
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD},
1397
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1398
USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
1399
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_ALLY_XPAD },
1400
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1401
USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
1402
QUIRK_ROG_CLAYMORE_II_KEYBOARD },
1403
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1404
USB_DEVICE_ID_ASUSTEK_T100TA_KEYBOARD),
1405
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
1406
{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
1407
USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD),
1408
QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
1409
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_ASUS_AK1D) },
1410
{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_ASUS_MD_5110) },
1411
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
1412
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
1413
USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI },
1414
{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_MEDION_E1239T),
1415
QUIRK_MEDION_E1239T },
1416
/*
1417
* Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard
1418
* part, while letting hid-multitouch.c handle the touchpad.
1419
*/
1420
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
1421
USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_Z13_FOLIO),
1422
QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
1423
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
1424
USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) },
1425
{ }
1426
};
1427
MODULE_DEVICE_TABLE(hid, asus_devices);
1428
1429
static struct hid_driver asus_driver = {
1430
.name = "asus",
1431
.id_table = asus_devices,
1432
.report_fixup = asus_report_fixup,
1433
.probe = asus_probe,
1434
.remove = asus_remove,
1435
.input_mapping = asus_input_mapping,
1436
.input_configured = asus_input_configured,
1437
#ifdef CONFIG_PM
1438
.reset_resume = asus_reset_resume,
1439
.resume = asus_resume,
1440
#endif
1441
.event = asus_event,
1442
.raw_event = asus_raw_event
1443
};
1444
module_hid_driver(asus_driver);
1445
1446
MODULE_IMPORT_NS("ASUS_WMI");
1447
MODULE_LICENSE("GPL");
1448
1449