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