1 | // SPDX-License-Identifier: GPL-2.0-or-later |
---|---|
2 | /* |
3 | * Asus Notebooks WMI hotkey driver |
4 | * |
5 | * Copyright(C) 2010 Corentin Chary <corentin.chary@gmail.com> |
6 | */ |
7 | |
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
9 | |
10 | #include <linux/backlight.h> |
11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> |
13 | #include <linux/init.h> |
14 | #include <linux/input.h> |
15 | #include <linux/input/sparse-keymap.h> |
16 | #include <linux/dmi.h> |
17 | #include <linux/i8042.h> |
18 | |
19 | #include <acpi/video.h> |
20 | |
21 | #include "asus-wmi.h" |
22 | |
23 | #define ASUS_NB_WMI_FILE "asus-nb-wmi" |
24 | |
25 | MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>"); |
26 | MODULE_DESCRIPTION("Asus Notebooks WMI Hotkey Driver"); |
27 | MODULE_LICENSE("GPL"); |
28 | |
29 | #define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" |
30 | |
31 | MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); |
32 | |
33 | /* |
34 | * WAPF defines the behavior of the Fn+Fx wlan key |
35 | * The significance of values is yet to be found, but |
36 | * most of the time: |
37 | * Bit | Bluetooth | WLAN |
38 | * 0 | Hardware | Hardware |
39 | * 1 | Hardware | Software |
40 | * 4 | Software | Software |
41 | */ |
42 | static int wapf = -1; |
43 | module_param(wapf, uint, 0444); |
44 | MODULE_PARM_DESC(wapf, "WAPF value"); |
45 | |
46 | static int tablet_mode_sw = -1; |
47 | module_param(tablet_mode_sw, uint, 0444); |
48 | MODULE_PARM_DESC(tablet_mode_sw, "Tablet mode detect: -1:auto 0:disable 1:kbd-dock 2:lid-flip 3:lid-flip-rog"); |
49 | |
50 | static struct quirk_entry *quirks; |
51 | static bool atkbd_reports_vol_keys; |
52 | |
53 | static bool asus_i8042_filter(unsigned char data, unsigned char str, struct serio *port, |
54 | void *context) |
55 | { |
56 | static bool extended_e0; |
57 | static bool extended_e1; |
58 | |
59 | if (str & I8042_STR_AUXDATA) |
60 | return false; |
61 | |
62 | if (quirks->filter_i8042_e1_extended_codes) { |
63 | if (data == 0xe1) { |
64 | extended_e1 = true; |
65 | return true; |
66 | } |
67 | |
68 | if (extended_e1) { |
69 | extended_e1 = false; |
70 | return true; |
71 | } |
72 | } |
73 | |
74 | if (data == 0xe0) { |
75 | extended_e0 = true; |
76 | } else if (extended_e0) { |
77 | extended_e0 = false; |
78 | |
79 | switch (data & 0x7f) { |
80 | case 0x20: /* e0 20 / e0 a0, Volume Mute press / release */ |
81 | case 0x2e: /* e0 2e / e0 ae, Volume Down press / release */ |
82 | case 0x30: /* e0 30 / e0 b0, Volume Up press / release */ |
83 | atkbd_reports_vol_keys = true; |
84 | break; |
85 | } |
86 | } |
87 | |
88 | return false; |
89 | } |
90 | |
91 | static struct quirk_entry quirk_asus_unknown = { |
92 | .wapf = 0, |
93 | .wmi_backlight_set_devstate = true, |
94 | }; |
95 | |
96 | static struct quirk_entry quirk_asus_q500a = { |
97 | .filter_i8042_e1_extended_codes = true, |
98 | .wmi_backlight_set_devstate = true, |
99 | }; |
100 | |
101 | /* |
102 | * For those machines that need software to control bt/wifi status |
103 | * and have duplicate events(ACPI and WMI) for display toggle |
104 | */ |
105 | static struct quirk_entry quirk_asus_x55u = { |
106 | .wapf = 4, |
107 | .wmi_backlight_set_devstate = true, |
108 | .no_display_toggle = true, |
109 | }; |
110 | |
111 | static struct quirk_entry quirk_asus_wapf4 = { |
112 | .wapf = 4, |
113 | .wmi_backlight_set_devstate = true, |
114 | }; |
115 | |
116 | static struct quirk_entry quirk_asus_x200ca = { |
117 | .wapf = 2, |
118 | .wmi_backlight_set_devstate = true, |
119 | }; |
120 | |
121 | static struct quirk_entry quirk_asus_x550lb = { |
122 | .wmi_backlight_set_devstate = true, |
123 | .xusb2pr = 0x01D9, |
124 | }; |
125 | |
126 | static struct quirk_entry quirk_asus_forceals = { |
127 | .wmi_backlight_set_devstate = true, |
128 | .wmi_force_als_set = true, |
129 | }; |
130 | |
131 | static struct quirk_entry quirk_asus_use_kbd_dock_devid = { |
132 | .tablet_switch_mode = asus_wmi_kbd_dock_devid, |
133 | }; |
134 | |
135 | static struct quirk_entry quirk_asus_use_lid_flip_devid = { |
136 | .wmi_backlight_set_devstate = true, |
137 | .tablet_switch_mode = asus_wmi_lid_flip_devid, |
138 | }; |
139 | |
140 | static struct quirk_entry quirk_asus_tablet_mode = { |
141 | .wmi_backlight_set_devstate = true, |
142 | .tablet_switch_mode = asus_wmi_lid_flip_rog_devid, |
143 | }; |
144 | |
145 | static struct quirk_entry quirk_asus_ignore_fan = { |
146 | .wmi_ignore_fan = true, |
147 | }; |
148 | |
149 | static struct quirk_entry quirk_asus_zenbook_duo_kbd = { |
150 | .ignore_key_wlan = true, |
151 | }; |
152 | |
153 | static int dmi_matched(const struct dmi_system_id *dmi) |
154 | { |
155 | pr_info("Identified laptop model '%s'\n", dmi->ident); |
156 | quirks = dmi->driver_data; |
157 | return 1; |
158 | } |
159 | |
160 | static const struct dmi_system_id asus_quirks[] = { |
161 | { |
162 | .callback = dmi_matched, |
163 | .ident = "ASUSTeK COMPUTER INC. Q500A", |
164 | .matches = { |
165 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
166 | DMI_MATCH(DMI_PRODUCT_NAME, "Q500A"), |
167 | }, |
168 | .driver_data = &quirk_asus_q500a, |
169 | }, |
170 | { |
171 | .callback = dmi_matched, |
172 | .ident = "ASUSTeK COMPUTER INC. U32U", |
173 | .matches = { |
174 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
175 | DMI_MATCH(DMI_PRODUCT_NAME, "U32U"), |
176 | }, |
177 | .driver_data = &quirk_asus_wapf4, |
178 | }, |
179 | { |
180 | .callback = dmi_matched, |
181 | .ident = "ASUSTeK COMPUTER INC. X302UA", |
182 | .matches = { |
183 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
184 | DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"), |
185 | }, |
186 | .driver_data = &quirk_asus_wapf4, |
187 | }, |
188 | { |
189 | .callback = dmi_matched, |
190 | .ident = "ASUSTeK COMPUTER INC. X401U", |
191 | .matches = { |
192 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
193 | DMI_MATCH(DMI_PRODUCT_NAME, "X401U"), |
194 | }, |
195 | .driver_data = &quirk_asus_x55u, |
196 | }, |
197 | { |
198 | .callback = dmi_matched, |
199 | .ident = "ASUSTeK COMPUTER INC. X401A", |
200 | .matches = { |
201 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
202 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A"), |
203 | }, |
204 | .driver_data = &quirk_asus_wapf4, |
205 | }, |
206 | { |
207 | .callback = dmi_matched, |
208 | .ident = "ASUSTeK COMPUTER INC. X401A1", |
209 | .matches = { |
210 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
211 | DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), |
212 | }, |
213 | .driver_data = &quirk_asus_wapf4, |
214 | }, |
215 | { |
216 | .callback = dmi_matched, |
217 | .ident = "ASUSTeK COMPUTER INC. X45U", |
218 | .matches = { |
219 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
220 | DMI_MATCH(DMI_PRODUCT_NAME, "X45U"), |
221 | }, |
222 | .driver_data = &quirk_asus_wapf4, |
223 | }, |
224 | { |
225 | .callback = dmi_matched, |
226 | .ident = "ASUSTeK COMPUTER INC. X456UA", |
227 | .matches = { |
228 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
229 | DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"), |
230 | }, |
231 | .driver_data = &quirk_asus_wapf4, |
232 | }, |
233 | { |
234 | .callback = dmi_matched, |
235 | .ident = "ASUSTeK COMPUTER INC. X456UF", |
236 | .matches = { |
237 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
238 | DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"), |
239 | }, |
240 | .driver_data = &quirk_asus_wapf4, |
241 | }, |
242 | { |
243 | .callback = dmi_matched, |
244 | .ident = "ASUSTeK COMPUTER INC. X501U", |
245 | .matches = { |
246 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
247 | DMI_MATCH(DMI_PRODUCT_NAME, "X501U"), |
248 | }, |
249 | .driver_data = &quirk_asus_x55u, |
250 | }, |
251 | { |
252 | .callback = dmi_matched, |
253 | .ident = "ASUSTeK COMPUTER INC. X501A", |
254 | .matches = { |
255 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
256 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A"), |
257 | }, |
258 | .driver_data = &quirk_asus_wapf4, |
259 | }, |
260 | { |
261 | .callback = dmi_matched, |
262 | .ident = "ASUSTeK COMPUTER INC. X501A1", |
263 | .matches = { |
264 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
265 | DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), |
266 | }, |
267 | .driver_data = &quirk_asus_wapf4, |
268 | }, |
269 | { |
270 | .callback = dmi_matched, |
271 | .ident = "ASUSTeK COMPUTER INC. X550CA", |
272 | .matches = { |
273 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
274 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"), |
275 | }, |
276 | .driver_data = &quirk_asus_wapf4, |
277 | }, |
278 | { |
279 | .callback = dmi_matched, |
280 | .ident = "ASUSTeK COMPUTER INC. X550CC", |
281 | .matches = { |
282 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
283 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"), |
284 | }, |
285 | .driver_data = &quirk_asus_wapf4, |
286 | }, |
287 | { |
288 | .callback = dmi_matched, |
289 | .ident = "ASUSTeK COMPUTER INC. X550CL", |
290 | .matches = { |
291 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
292 | DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"), |
293 | }, |
294 | .driver_data = &quirk_asus_wapf4, |
295 | }, |
296 | { |
297 | .callback = dmi_matched, |
298 | .ident = "ASUSTeK COMPUTER INC. X550VB", |
299 | .matches = { |
300 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
301 | DMI_MATCH(DMI_PRODUCT_NAME, "X550VB"), |
302 | }, |
303 | .driver_data = &quirk_asus_wapf4, |
304 | }, |
305 | { |
306 | .callback = dmi_matched, |
307 | .ident = "ASUSTeK COMPUTER INC. X551CA", |
308 | .matches = { |
309 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
310 | DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"), |
311 | }, |
312 | .driver_data = &quirk_asus_wapf4, |
313 | }, |
314 | { |
315 | .callback = dmi_matched, |
316 | .ident = "ASUSTeK COMPUTER INC. X55A", |
317 | .matches = { |
318 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
319 | DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), |
320 | }, |
321 | .driver_data = &quirk_asus_wapf4, |
322 | }, |
323 | { |
324 | .callback = dmi_matched, |
325 | .ident = "ASUSTeK COMPUTER INC. X55C", |
326 | .matches = { |
327 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
328 | DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), |
329 | }, |
330 | .driver_data = &quirk_asus_wapf4, |
331 | }, |
332 | { |
333 | .callback = dmi_matched, |
334 | .ident = "ASUSTeK COMPUTER INC. X55U", |
335 | .matches = { |
336 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
337 | DMI_MATCH(DMI_PRODUCT_NAME, "X55U"), |
338 | }, |
339 | .driver_data = &quirk_asus_x55u, |
340 | }, |
341 | { |
342 | .callback = dmi_matched, |
343 | .ident = "ASUSTeK COMPUTER INC. X55VD", |
344 | .matches = { |
345 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
346 | DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), |
347 | }, |
348 | .driver_data = &quirk_asus_wapf4, |
349 | }, |
350 | { |
351 | .callback = dmi_matched, |
352 | .ident = "ASUSTeK COMPUTER INC. X75A", |
353 | .matches = { |
354 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
355 | DMI_MATCH(DMI_PRODUCT_NAME, "X75A"), |
356 | }, |
357 | .driver_data = &quirk_asus_wapf4, |
358 | }, |
359 | { |
360 | .callback = dmi_matched, |
361 | .ident = "ASUSTeK COMPUTER INC. X75VBP", |
362 | .matches = { |
363 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
364 | DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"), |
365 | }, |
366 | .driver_data = &quirk_asus_wapf4, |
367 | }, |
368 | { |
369 | .callback = dmi_matched, |
370 | .ident = "ASUSTeK COMPUTER INC. X75VD", |
371 | .matches = { |
372 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
373 | DMI_MATCH(DMI_PRODUCT_NAME, "X75VD"), |
374 | }, |
375 | .driver_data = &quirk_asus_wapf4, |
376 | }, |
377 | { |
378 | .callback = dmi_matched, |
379 | .ident = "ASUSTeK COMPUTER INC. 1015E", |
380 | .matches = { |
381 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
382 | DMI_MATCH(DMI_PRODUCT_NAME, "1015E"), |
383 | }, |
384 | .driver_data = &quirk_asus_wapf4, |
385 | }, |
386 | { |
387 | .callback = dmi_matched, |
388 | .ident = "ASUSTeK COMPUTER INC. 1015U", |
389 | .matches = { |
390 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
391 | DMI_MATCH(DMI_PRODUCT_NAME, "1015U"), |
392 | }, |
393 | .driver_data = &quirk_asus_wapf4, |
394 | }, |
395 | { |
396 | .callback = dmi_matched, |
397 | .ident = "ASUSTeK COMPUTER INC. X200CA", |
398 | .matches = { |
399 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
400 | DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"), |
401 | }, |
402 | .driver_data = &quirk_asus_x200ca, |
403 | }, |
404 | { |
405 | .callback = dmi_matched, |
406 | .ident = "ASUSTeK COMPUTER INC. UX330UAK", |
407 | .matches = { |
408 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
409 | DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"), |
410 | }, |
411 | .driver_data = &quirk_asus_forceals, |
412 | }, |
413 | { |
414 | .callback = dmi_matched, |
415 | .ident = "ASUSTeK COMPUTER INC. X550LB", |
416 | .matches = { |
417 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
418 | DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"), |
419 | }, |
420 | .driver_data = &quirk_asus_x550lb, |
421 | }, |
422 | { |
423 | .callback = dmi_matched, |
424 | .ident = "ASUSTeK COMPUTER INC. UX430UQ", |
425 | .matches = { |
426 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
427 | DMI_MATCH(DMI_PRODUCT_NAME, "UX430UQ"), |
428 | }, |
429 | .driver_data = &quirk_asus_forceals, |
430 | }, |
431 | { |
432 | .callback = dmi_matched, |
433 | .ident = "ASUSTeK COMPUTER INC. UX430UNR", |
434 | .matches = { |
435 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
436 | DMI_MATCH(DMI_PRODUCT_NAME, "UX430UNR"), |
437 | }, |
438 | .driver_data = &quirk_asus_forceals, |
439 | }, |
440 | { |
441 | .callback = dmi_matched, |
442 | .ident = "Asus Transformer T100TA / T100HA / T100CHI", |
443 | .matches = { |
444 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
445 | /* Match *T100* */ |
446 | DMI_MATCH(DMI_PRODUCT_NAME, "T100"), |
447 | }, |
448 | .driver_data = &quirk_asus_use_kbd_dock_devid, |
449 | }, |
450 | { |
451 | .callback = dmi_matched, |
452 | .ident = "Asus Transformer T101HA", |
453 | .matches = { |
454 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
455 | DMI_MATCH(DMI_PRODUCT_NAME, "T101HA"), |
456 | }, |
457 | .driver_data = &quirk_asus_use_kbd_dock_devid, |
458 | }, |
459 | { |
460 | .callback = dmi_matched, |
461 | .ident = "Asus Transformer T200TA", |
462 | .matches = { |
463 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
464 | DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"), |
465 | }, |
466 | .driver_data = &quirk_asus_use_kbd_dock_devid, |
467 | }, |
468 | { |
469 | .callback = dmi_matched, |
470 | .ident = "ASUS ZenBook Flip UX360", |
471 | .matches = { |
472 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
473 | /* Match UX360* */ |
474 | DMI_MATCH(DMI_PRODUCT_NAME, "UX360"), |
475 | }, |
476 | .driver_data = &quirk_asus_use_lid_flip_devid, |
477 | }, |
478 | { |
479 | .callback = dmi_matched, |
480 | .ident = "ASUS TP200s / E205SA", |
481 | .matches = { |
482 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
483 | DMI_MATCH(DMI_PRODUCT_NAME, "E205SA"), |
484 | }, |
485 | .driver_data = &quirk_asus_use_lid_flip_devid, |
486 | }, |
487 | { |
488 | .callback = dmi_matched, |
489 | .ident = "ASUS ROG FLOW X13", |
490 | .matches = { |
491 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
492 | /* Match GV301** */ |
493 | DMI_MATCH(DMI_PRODUCT_NAME, "GV301"), |
494 | }, |
495 | .driver_data = &quirk_asus_tablet_mode, |
496 | }, |
497 | { |
498 | .callback = dmi_matched, |
499 | .ident = "ASUS ROG FLOW X16", |
500 | .matches = { |
501 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
502 | DMI_MATCH(DMI_PRODUCT_NAME, "GV601R"), |
503 | }, |
504 | .driver_data = &quirk_asus_tablet_mode, |
505 | }, |
506 | { |
507 | .callback = dmi_matched, |
508 | .ident = "ASUS ROG FLOW X16", |
509 | .matches = { |
510 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
511 | DMI_MATCH(DMI_PRODUCT_NAME, "GV601V"), |
512 | }, |
513 | .driver_data = &quirk_asus_tablet_mode, |
514 | }, |
515 | { |
516 | .callback = dmi_matched, |
517 | .ident = "ASUS VivoBook E410MA", |
518 | .matches = { |
519 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
520 | DMI_MATCH(DMI_PRODUCT_NAME, "E410MA"), |
521 | }, |
522 | .driver_data = &quirk_asus_ignore_fan, |
523 | }, |
524 | { |
525 | .callback = dmi_matched, |
526 | .ident = "ASUS Zenbook Duo UX8406MA", |
527 | .matches = { |
528 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
529 | DMI_MATCH(DMI_PRODUCT_NAME, "UX8406MA"), |
530 | }, |
531 | .driver_data = &quirk_asus_zenbook_duo_kbd, |
532 | }, |
533 | {}, |
534 | }; |
535 | |
536 | static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) |
537 | { |
538 | quirks = &quirk_asus_unknown; |
539 | dmi_check_system(list: asus_quirks); |
540 | |
541 | driver->quirks = quirks; |
542 | driver->panel_power = BACKLIGHT_POWER_ON; |
543 | |
544 | /* overwrite the wapf setting if the wapf paramater is specified */ |
545 | if (wapf != -1) |
546 | quirks->wapf = wapf; |
547 | else |
548 | wapf = quirks->wapf; |
549 | |
550 | if (tablet_mode_sw != -1) |
551 | quirks->tablet_switch_mode = tablet_mode_sw; |
552 | } |
553 | |
554 | static const struct key_entry asus_nb_wmi_keymap[] = { |
555 | { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } }, |
556 | { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } }, |
557 | { KE_KEY, 0x2a, { KEY_SELECTIVE_SCREENSHOT } }, |
558 | { KE_IGNORE, 0x2b, }, /* PrintScreen (also send via PS/2) on newer models */ |
559 | { KE_IGNORE, 0x2c, }, /* CapsLock (also send via PS/2) on newer models */ |
560 | { KE_KEY, 0x30, { KEY_VOLUMEUP } }, |
561 | { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, |
562 | { KE_KEY, 0x32, { KEY_MUTE } }, |
563 | { KE_KEY, 0x33, { KEY_SCREENLOCK } }, |
564 | { KE_KEY, 0x35, { KEY_SCREENLOCK } }, |
565 | { KE_KEY, 0x38, { KEY_PROG3 } }, /* Armoury Crate */ |
566 | { KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, |
567 | { KE_KEY, 0x41, { KEY_NEXTSONG } }, |
568 | { KE_KEY, 0x43, { KEY_STOPCD } }, /* Stop/Eject */ |
569 | { KE_KEY, 0x45, { KEY_PLAYPAUSE } }, |
570 | { KE_KEY, 0x4c, { KEY_MEDIA } }, /* WMP Key */ |
571 | { KE_KEY, 0x50, { KEY_EMAIL } }, |
572 | { KE_KEY, 0x51, { KEY_WWW } }, |
573 | { KE_KEY, 0x55, { KEY_CALC } }, |
574 | { KE_IGNORE, 0x57, }, /* Battery mode */ |
575 | { KE_IGNORE, 0x58, }, /* AC mode */ |
576 | { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ |
577 | { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */ |
578 | { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */ |
579 | { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */ |
580 | { KE_KEY, 0x60, { KEY_TOUCHPAD_ON } }, |
581 | { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD only */ |
582 | { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT only */ |
583 | { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT */ |
584 | { KE_KEY, 0x64, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV */ |
585 | { KE_KEY, 0x65, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV */ |
586 | { KE_KEY, 0x66, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV */ |
587 | { KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */ |
588 | { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, |
589 | { KE_IGNORE, 0x6E, }, /* Low Battery notification */ |
590 | { KE_KEY, 0x71, { KEY_F13 } }, /* General-purpose button */ |
591 | { KE_IGNORE, 0x79, }, /* Charger type dectection notification */ |
592 | { KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */ |
593 | { KE_IGNORE, 0x7B, }, /* Charger connect/disconnect notification */ |
594 | { KE_KEY, 0x7c, { KEY_MICMUTE } }, |
595 | { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */ |
596 | { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */ |
597 | { KE_KEY, 0x82, { KEY_CAMERA } }, |
598 | { KE_KEY, 0x85, { KEY_CAMERA } }, |
599 | { KE_KEY, 0x86, { KEY_PROG1 } }, /* MyASUS Key */ |
600 | { KE_KEY, 0x88, { KEY_RFKILL } }, /* Radio Toggle Key */ |
601 | { KE_KEY, 0x8A, { KEY_PROG1 } }, /* Color enhancement mode */ |
602 | { KE_KEY, 0x8C, { KEY_SWITCHVIDEOMODE } }, /* SDSP DVI only */ |
603 | { KE_KEY, 0x8D, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + DVI */ |
604 | { KE_KEY, 0x8E, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + DVI */ |
605 | { KE_KEY, 0x8F, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + DVI */ |
606 | { KE_KEY, 0x90, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + DVI */ |
607 | { KE_KEY, 0x91, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + DVI */ |
608 | { KE_KEY, 0x92, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + DVI */ |
609 | { KE_KEY, 0x93, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + DVI */ |
610 | { KE_KEY, 0x95, { KEY_MEDIA } }, |
611 | { KE_KEY, 0x99, { KEY_PHONE } }, /* Conflicts with fan mode switch */ |
612 | { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ |
613 | { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ |
614 | { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ |
615 | { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ |
616 | { KE_KEY, 0xA4, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + HDMI */ |
617 | { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */ |
618 | { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ |
619 | { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ |
620 | { KE_KEY, 0xAE, { KEY_FN_F5 } }, /* Fn+F5 fan mode on 2020+ */ |
621 | { KE_KEY, 0xB3, { KEY_PROG4 } }, /* AURA */ |
622 | { KE_KEY, 0xB5, { KEY_CALC } }, |
623 | { KE_IGNORE, 0xC0, }, /* External display connect/disconnect notification */ |
624 | { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, |
625 | { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, |
626 | { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ |
627 | { KE_IGNORE, 0xCF, }, /* AC mode */ |
628 | { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */ |
629 | { KE_KEY, 0xBD, { KEY_PROG2 } }, /* Lid flip action on ROG xflow laptops */ |
630 | { KE_END, 0}, |
631 | }; |
632 | |
633 | static void asus_nb_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, |
634 | unsigned int *value, bool *autorelease) |
635 | { |
636 | switch (*code) { |
637 | case ASUS_WMI_BRN_DOWN: |
638 | case ASUS_WMI_BRN_UP: |
639 | if (acpi_video_handles_brightness_key_presses()) |
640 | *code = ASUS_WMI_KEY_IGNORE; |
641 | |
642 | break; |
643 | case 0x30: /* Volume Up */ |
644 | case 0x31: /* Volume Down */ |
645 | case 0x32: /* Volume Mute */ |
646 | if (atkbd_reports_vol_keys) |
647 | *code = ASUS_WMI_KEY_IGNORE; |
648 | break; |
649 | case 0x5D: /* Wireless console Toggle */ |
650 | case 0x5E: /* Wireless console Enable */ |
651 | case 0x5F: /* Wireless console Disable */ |
652 | if (quirks->ignore_key_wlan) |
653 | *code = ASUS_WMI_KEY_IGNORE; |
654 | break; |
655 | } |
656 | } |
657 | |
658 | static struct asus_wmi_driver asus_nb_wmi_driver = { |
659 | .name = ASUS_NB_WMI_FILE, |
660 | .owner = THIS_MODULE, |
661 | .event_guid = ASUS_NB_WMI_EVENT_GUID, |
662 | .keymap = asus_nb_wmi_keymap, |
663 | .input_name = "Asus WMI hotkeys", |
664 | .input_phys = ASUS_NB_WMI_FILE "/input0", |
665 | .detect_quirks = asus_nb_wmi_quirks, |
666 | .key_filter = asus_nb_wmi_key_filter, |
667 | .i8042_filter = asus_i8042_filter, |
668 | }; |
669 | |
670 | |
671 | static int __init asus_nb_wmi_init(void) |
672 | { |
673 | return asus_wmi_register_driver(driver: &asus_nb_wmi_driver); |
674 | } |
675 | |
676 | static void __exit asus_nb_wmi_exit(void) |
677 | { |
678 | asus_wmi_unregister_driver(driver: &asus_nb_wmi_driver); |
679 | } |
680 | |
681 | module_init(asus_nb_wmi_init); |
682 | module_exit(asus_nb_wmi_exit); |
683 |
Definitions
- wapf
- tablet_mode_sw
- quirks
- atkbd_reports_vol_keys
- asus_i8042_filter
- quirk_asus_unknown
- quirk_asus_q500a
- quirk_asus_x55u
- quirk_asus_wapf4
- quirk_asus_x200ca
- quirk_asus_x550lb
- quirk_asus_forceals
- quirk_asus_use_kbd_dock_devid
- quirk_asus_use_lid_flip_devid
- quirk_asus_tablet_mode
- quirk_asus_ignore_fan
- quirk_asus_zenbook_duo_kbd
- dmi_matched
- asus_quirks
- asus_nb_wmi_quirks
- asus_nb_wmi_keymap
- asus_nb_wmi_key_filter
- asus_nb_wmi_driver
- asus_nb_wmi_init
Improve your Profiling and Debugging skills
Find out more