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/kernel.h> 11 #include <linux/module.h> 12 #include <linux/init.h> 13 #include <linux/input.h> 14 #include <linux/input/sparse-keymap.h> 15 #include <linux/fb.h> 16 #include <linux/dmi.h> 17 #include <linux/i8042.h> 18 19 #include "asus-wmi.h" 20 21 #define ASUS_NB_WMI_FILE "asus-nb-wmi" 22 23 MODULE_AUTHOR("Corentin Chary <corentin.chary@gmail.com>"); 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 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 */ 40 static int wapf = -1; 41 module_param(wapf, uint, 0444); 42 MODULE_PARM_DESC(wapf, "WAPF value"); 43 44 static struct quirk_entry *quirks; 45 46 static bool asus_q500a_i8042_filter(unsigned char data, unsigned char str, 47 struct serio *port) 48 { 49 static bool extended; 50 bool ret = false; 51 52 if (str & I8042_STR_AUXDATA) 53 return false; 54 55 if (unlikely(data == 0xe1)) { 56 extended = true; 57 ret = true; 58 } else if (unlikely(extended)) { 59 extended = false; 60 ret = true; 61 } 62 63 return ret; 64 } 65 66 static struct quirk_entry quirk_asus_unknown = { 67 .wapf = 0, 68 .wmi_backlight_set_devstate = true, 69 }; 70 71 static struct quirk_entry quirk_asus_q500a = { 72 .i8042_filter = asus_q500a_i8042_filter, 73 .wmi_backlight_set_devstate = true, 74 }; 75 76 /* 77 * For those machines that need software to control bt/wifi status 78 * and can't adjust brightness through ACPI interface 79 * and have duplicate events(ACPI and WMI) for display toggle 80 */ 81 static struct quirk_entry quirk_asus_x55u = { 82 .wapf = 4, 83 .wmi_backlight_power = true, 84 .wmi_backlight_set_devstate = true, 85 .no_display_toggle = true, 86 }; 87 88 static struct quirk_entry quirk_asus_wapf4 = { 89 .wapf = 4, 90 .wmi_backlight_set_devstate = true, 91 }; 92 93 static struct quirk_entry quirk_asus_x200ca = { 94 .wapf = 2, 95 .wmi_backlight_set_devstate = true, 96 }; 97 98 static struct quirk_entry quirk_asus_ux303ub = { 99 .wmi_backlight_native = true, 100 .wmi_backlight_set_devstate = true, 101 }; 102 103 static struct quirk_entry quirk_asus_x550lb = { 104 .wmi_backlight_set_devstate = true, 105 .xusb2pr = 0x01D9, 106 }; 107 108 static struct quirk_entry quirk_asus_forceals = { 109 .wmi_backlight_set_devstate = true, 110 .wmi_force_als_set = true, 111 }; 112 113 static struct quirk_entry quirk_asus_vendor_backlight = { 114 .wmi_backlight_power = true, 115 .wmi_backlight_set_devstate = true, 116 }; 117 118 static struct quirk_entry quirk_asus_use_kbd_dock_devid = { 119 .use_kbd_dock_devid = true, 120 }; 121 122 static struct quirk_entry quirk_asus_use_lid_flip_devid = { 123 .wmi_backlight_set_devstate = true, 124 .use_lid_flip_devid = true, 125 }; 126 127 static int dmi_matched(const struct dmi_system_id *dmi) 128 { 129 pr_info("Identified laptop model '%s'\n", dmi->ident); 130 quirks = dmi->driver_data; 131 return 1; 132 } 133 134 static const struct dmi_system_id asus_quirks[] = { 135 { 136 .callback = dmi_matched, 137 .ident = "ASUSTeK COMPUTER INC. Q500A", 138 .matches = { 139 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 140 DMI_MATCH(DMI_PRODUCT_NAME, "Q500A"), 141 }, 142 .driver_data = &quirk_asus_q500a, 143 }, 144 { 145 .callback = dmi_matched, 146 .ident = "ASUSTeK COMPUTER INC. U32U", 147 .matches = { 148 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), 149 DMI_MATCH(DMI_PRODUCT_NAME, "U32U"), 150 }, 151 /* 152 * Note this machine has a Brazos APU, and most Brazos Asus 153 * machines need quirk_asus_x55u / wmi_backlight_power but 154 * here acpi-video seems to work fine for backlight control. 155 */ 156 .driver_data = &quirk_asus_wapf4, 157 }, 158 { 159 .callback = dmi_matched, 160 .ident = "ASUSTeK COMPUTER INC. X302UA", 161 .matches = { 162 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 163 DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"), 164 }, 165 .driver_data = &quirk_asus_wapf4, 166 }, 167 { 168 .callback = dmi_matched, 169 .ident = "ASUSTeK COMPUTER INC. X401U", 170 .matches = { 171 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 172 DMI_MATCH(DMI_PRODUCT_NAME, "X401U"), 173 }, 174 .driver_data = &quirk_asus_x55u, 175 }, 176 { 177 .callback = dmi_matched, 178 .ident = "ASUSTeK COMPUTER INC. X401A", 179 .matches = { 180 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 181 DMI_MATCH(DMI_PRODUCT_NAME, "X401A"), 182 }, 183 .driver_data = &quirk_asus_wapf4, 184 }, 185 { 186 .callback = dmi_matched, 187 .ident = "ASUSTeK COMPUTER INC. X401A1", 188 .matches = { 189 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 190 DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"), 191 }, 192 .driver_data = &quirk_asus_wapf4, 193 }, 194 { 195 .callback = dmi_matched, 196 .ident = "ASUSTeK COMPUTER INC. X45U", 197 .matches = { 198 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 199 DMI_MATCH(DMI_PRODUCT_NAME, "X45U"), 200 }, 201 .driver_data = &quirk_asus_wapf4, 202 }, 203 { 204 .callback = dmi_matched, 205 .ident = "ASUSTeK COMPUTER INC. X456UA", 206 .matches = { 207 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 208 DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"), 209 }, 210 .driver_data = &quirk_asus_wapf4, 211 }, 212 { 213 .callback = dmi_matched, 214 .ident = "ASUSTeK COMPUTER INC. X456UF", 215 .matches = { 216 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 217 DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"), 218 }, 219 .driver_data = &quirk_asus_wapf4, 220 }, 221 { 222 .callback = dmi_matched, 223 .ident = "ASUSTeK COMPUTER INC. X501U", 224 .matches = { 225 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 226 DMI_MATCH(DMI_PRODUCT_NAME, "X501U"), 227 }, 228 .driver_data = &quirk_asus_x55u, 229 }, 230 { 231 .callback = dmi_matched, 232 .ident = "ASUSTeK COMPUTER INC. X501A", 233 .matches = { 234 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 235 DMI_MATCH(DMI_PRODUCT_NAME, "X501A"), 236 }, 237 .driver_data = &quirk_asus_wapf4, 238 }, 239 { 240 .callback = dmi_matched, 241 .ident = "ASUSTeK COMPUTER INC. X501A1", 242 .matches = { 243 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 244 DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"), 245 }, 246 .driver_data = &quirk_asus_wapf4, 247 }, 248 { 249 .callback = dmi_matched, 250 .ident = "ASUSTeK COMPUTER INC. X550CA", 251 .matches = { 252 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 253 DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"), 254 }, 255 .driver_data = &quirk_asus_wapf4, 256 }, 257 { 258 .callback = dmi_matched, 259 .ident = "ASUSTeK COMPUTER INC. X550CC", 260 .matches = { 261 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 262 DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"), 263 }, 264 .driver_data = &quirk_asus_wapf4, 265 }, 266 { 267 .callback = dmi_matched, 268 .ident = "ASUSTeK COMPUTER INC. X550CL", 269 .matches = { 270 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 271 DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"), 272 }, 273 .driver_data = &quirk_asus_wapf4, 274 }, 275 { 276 .callback = dmi_matched, 277 .ident = "ASUSTeK COMPUTER INC. X550VB", 278 .matches = { 279 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 280 DMI_MATCH(DMI_PRODUCT_NAME, "X550VB"), 281 }, 282 .driver_data = &quirk_asus_wapf4, 283 }, 284 { 285 .callback = dmi_matched, 286 .ident = "ASUSTeK COMPUTER INC. X551CA", 287 .matches = { 288 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 289 DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"), 290 }, 291 .driver_data = &quirk_asus_wapf4, 292 }, 293 { 294 .callback = dmi_matched, 295 .ident = "ASUSTeK COMPUTER INC. X55A", 296 .matches = { 297 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 298 DMI_MATCH(DMI_PRODUCT_NAME, "X55A"), 299 }, 300 .driver_data = &quirk_asus_wapf4, 301 }, 302 { 303 .callback = dmi_matched, 304 .ident = "ASUSTeK COMPUTER INC. X55C", 305 .matches = { 306 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 307 DMI_MATCH(DMI_PRODUCT_NAME, "X55C"), 308 }, 309 .driver_data = &quirk_asus_wapf4, 310 }, 311 { 312 .callback = dmi_matched, 313 .ident = "ASUSTeK COMPUTER INC. X55U", 314 .matches = { 315 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 316 DMI_MATCH(DMI_PRODUCT_NAME, "X55U"), 317 }, 318 .driver_data = &quirk_asus_x55u, 319 }, 320 { 321 .callback = dmi_matched, 322 .ident = "ASUSTeK COMPUTER INC. X55VD", 323 .matches = { 324 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 325 DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"), 326 }, 327 .driver_data = &quirk_asus_wapf4, 328 }, 329 { 330 .callback = dmi_matched, 331 .ident = "ASUSTeK COMPUTER INC. X75A", 332 .matches = { 333 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 334 DMI_MATCH(DMI_PRODUCT_NAME, "X75A"), 335 }, 336 .driver_data = &quirk_asus_wapf4, 337 }, 338 { 339 .callback = dmi_matched, 340 .ident = "ASUSTeK COMPUTER INC. X75VBP", 341 .matches = { 342 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 343 DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"), 344 }, 345 .driver_data = &quirk_asus_wapf4, 346 }, 347 { 348 .callback = dmi_matched, 349 .ident = "ASUSTeK COMPUTER INC. X75VD", 350 .matches = { 351 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 352 DMI_MATCH(DMI_PRODUCT_NAME, "X75VD"), 353 }, 354 .driver_data = &quirk_asus_wapf4, 355 }, 356 { 357 .callback = dmi_matched, 358 .ident = "ASUSTeK COMPUTER INC. 1015E", 359 .matches = { 360 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 361 DMI_MATCH(DMI_PRODUCT_NAME, "1015E"), 362 }, 363 .driver_data = &quirk_asus_wapf4, 364 }, 365 { 366 .callback = dmi_matched, 367 .ident = "ASUSTeK COMPUTER INC. 1015U", 368 .matches = { 369 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 370 DMI_MATCH(DMI_PRODUCT_NAME, "1015U"), 371 }, 372 .driver_data = &quirk_asus_wapf4, 373 }, 374 { 375 .callback = dmi_matched, 376 .ident = "ASUSTeK COMPUTER INC. X200CA", 377 .matches = { 378 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 379 DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"), 380 }, 381 .driver_data = &quirk_asus_x200ca, 382 }, 383 { 384 .callback = dmi_matched, 385 .ident = "ASUSTeK COMPUTER INC. UX303UB", 386 .matches = { 387 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 388 DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"), 389 }, 390 .driver_data = &quirk_asus_ux303ub, 391 }, 392 { 393 .callback = dmi_matched, 394 .ident = "ASUSTeK COMPUTER INC. UX330UAK", 395 .matches = { 396 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 397 DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"), 398 }, 399 .driver_data = &quirk_asus_forceals, 400 }, 401 { 402 .callback = dmi_matched, 403 .ident = "ASUSTeK COMPUTER INC. X550LB", 404 .matches = { 405 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 406 DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"), 407 }, 408 .driver_data = &quirk_asus_x550lb, 409 }, 410 { 411 .callback = dmi_matched, 412 .ident = "ASUSTeK COMPUTER INC. UX430UQ", 413 .matches = { 414 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 415 DMI_MATCH(DMI_PRODUCT_NAME, "UX430UQ"), 416 }, 417 .driver_data = &quirk_asus_forceals, 418 }, 419 { 420 .callback = dmi_matched, 421 .ident = "ASUSTeK COMPUTER INC. UX430UNR", 422 .matches = { 423 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 424 DMI_MATCH(DMI_PRODUCT_NAME, "UX430UNR"), 425 }, 426 .driver_data = &quirk_asus_forceals, 427 }, 428 { 429 .callback = dmi_matched, 430 .ident = "ASUSTeK COMPUTER INC. GA401IH", 431 .matches = { 432 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 433 DMI_MATCH(DMI_PRODUCT_NAME, "GA401IH"), 434 }, 435 .driver_data = &quirk_asus_vendor_backlight, 436 }, 437 { 438 .callback = dmi_matched, 439 .ident = "ASUSTeK COMPUTER INC. GA401II", 440 .matches = { 441 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 442 DMI_MATCH(DMI_PRODUCT_NAME, "GA401II"), 443 }, 444 .driver_data = &quirk_asus_vendor_backlight, 445 }, 446 { 447 .callback = dmi_matched, 448 .ident = "ASUSTeK COMPUTER INC. GA401IU", 449 .matches = { 450 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 451 DMI_MATCH(DMI_PRODUCT_NAME, "GA401IU"), 452 }, 453 .driver_data = &quirk_asus_vendor_backlight, 454 }, 455 { 456 .callback = dmi_matched, 457 .ident = "ASUSTeK COMPUTER INC. GA401IV", 458 .matches = { 459 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 460 DMI_MATCH(DMI_PRODUCT_NAME, "GA401IV"), 461 }, 462 .driver_data = &quirk_asus_vendor_backlight, 463 }, 464 { 465 .callback = dmi_matched, 466 .ident = "ASUSTeK COMPUTER INC. GA401IVC", 467 .matches = { 468 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 469 DMI_MATCH(DMI_PRODUCT_NAME, "GA401IVC"), 470 }, 471 .driver_data = &quirk_asus_vendor_backlight, 472 }, 473 { 474 .callback = dmi_matched, 475 .ident = "ASUSTeK COMPUTER INC. GA502II", 476 .matches = { 477 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 478 DMI_MATCH(DMI_PRODUCT_NAME, "GA502II"), 479 }, 480 .driver_data = &quirk_asus_vendor_backlight, 481 }, 482 { 483 .callback = dmi_matched, 484 .ident = "ASUSTeK COMPUTER INC. GA502IU", 485 .matches = { 486 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 487 DMI_MATCH(DMI_PRODUCT_NAME, "GA502IU"), 488 }, 489 .driver_data = &quirk_asus_vendor_backlight, 490 }, 491 { 492 .callback = dmi_matched, 493 .ident = "ASUSTeK COMPUTER INC. GA502IV", 494 .matches = { 495 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 496 DMI_MATCH(DMI_PRODUCT_NAME, "GA502IV"), 497 }, 498 .driver_data = &quirk_asus_vendor_backlight, 499 }, 500 { 501 .callback = dmi_matched, 502 .ident = "Asus Transformer T100TA / T100HA / T100CHI", 503 .matches = { 504 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 505 /* Match *T100* */ 506 DMI_MATCH(DMI_PRODUCT_NAME, "T100"), 507 }, 508 .driver_data = &quirk_asus_use_kbd_dock_devid, 509 }, 510 { 511 .callback = dmi_matched, 512 .ident = "Asus Transformer T101HA", 513 .matches = { 514 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 515 DMI_MATCH(DMI_PRODUCT_NAME, "T101HA"), 516 }, 517 .driver_data = &quirk_asus_use_kbd_dock_devid, 518 }, 519 { 520 .callback = dmi_matched, 521 .ident = "Asus Transformer T200TA", 522 .matches = { 523 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 524 DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"), 525 }, 526 .driver_data = &quirk_asus_use_kbd_dock_devid, 527 }, 528 { 529 .callback = dmi_matched, 530 .ident = "ASUS ZenBook Flip UX360", 531 .matches = { 532 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 533 /* Match UX360* */ 534 DMI_MATCH(DMI_PRODUCT_NAME, "UX360"), 535 }, 536 .driver_data = &quirk_asus_use_lid_flip_devid, 537 }, 538 {}, 539 }; 540 541 static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) 542 { 543 int ret; 544 545 quirks = &quirk_asus_unknown; 546 dmi_check_system(asus_quirks); 547 548 driver->quirks = quirks; 549 driver->panel_power = FB_BLANK_UNBLANK; 550 551 /* overwrite the wapf setting if the wapf paramater is specified */ 552 if (wapf != -1) 553 quirks->wapf = wapf; 554 else 555 wapf = quirks->wapf; 556 557 if (quirks->i8042_filter) { 558 ret = i8042_install_filter(quirks->i8042_filter); 559 if (ret) { 560 pr_warn("Unable to install key filter\n"); 561 return; 562 } 563 pr_info("Using i8042 filter function for receiving events\n"); 564 } 565 } 566 567 static const struct key_entry asus_nb_wmi_keymap[] = { 568 { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } }, 569 { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } }, 570 { KE_KEY, 0x30, { KEY_VOLUMEUP } }, 571 { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, 572 { KE_KEY, 0x32, { KEY_MUTE } }, 573 { KE_KEY, 0x35, { KEY_SCREENLOCK } }, 574 { KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, 575 { KE_KEY, 0x41, { KEY_NEXTSONG } }, 576 { KE_KEY, 0x43, { KEY_STOPCD } }, /* Stop/Eject */ 577 { KE_KEY, 0x45, { KEY_PLAYPAUSE } }, 578 { KE_KEY, 0x4c, { KEY_MEDIA } }, /* WMP Key */ 579 { KE_KEY, 0x50, { KEY_EMAIL } }, 580 { KE_KEY, 0x51, { KEY_WWW } }, 581 { KE_KEY, 0x55, { KEY_CALC } }, 582 { KE_IGNORE, 0x57, }, /* Battery mode */ 583 { KE_IGNORE, 0x58, }, /* AC mode */ 584 { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ 585 { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */ 586 { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */ 587 { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */ 588 { KE_KEY, 0x60, { KEY_TOUCHPAD_ON } }, 589 { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD only */ 590 { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT only */ 591 { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT */ 592 { KE_KEY, 0x64, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV */ 593 { KE_KEY, 0x65, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV */ 594 { KE_KEY, 0x66, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV */ 595 { KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */ 596 { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, 597 { KE_IGNORE, 0x6E, }, /* Low Battery notification */ 598 { KE_KEY, 0x71, { KEY_F13 } }, /* General-purpose button */ 599 { KE_IGNORE, 0x79, }, /* Charger type dectection notification */ 600 { KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */ 601 { KE_KEY, 0x7c, { KEY_MICMUTE } }, 602 { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */ 603 { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */ 604 { KE_KEY, 0x82, { KEY_CAMERA } }, 605 { KE_KEY, 0x88, { KEY_RFKILL } }, /* Radio Toggle Key */ 606 { KE_KEY, 0x8A, { KEY_PROG1 } }, /* Color enhancement mode */ 607 { KE_KEY, 0x8C, { KEY_SWITCHVIDEOMODE } }, /* SDSP DVI only */ 608 { KE_KEY, 0x8D, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + DVI */ 609 { KE_KEY, 0x8E, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + DVI */ 610 { KE_KEY, 0x8F, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + DVI */ 611 { KE_KEY, 0x90, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + DVI */ 612 { KE_KEY, 0x91, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + DVI */ 613 { KE_KEY, 0x92, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + DVI */ 614 { KE_KEY, 0x93, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + DVI */ 615 { KE_KEY, 0x95, { KEY_MEDIA } }, 616 { KE_KEY, 0x99, { KEY_PHONE } }, /* Conflicts with fan mode switch */ 617 { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */ 618 { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */ 619 { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */ 620 { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */ 621 { KE_KEY, 0xA4, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + HDMI */ 622 { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */ 623 { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ 624 { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ 625 { KE_KEY, 0xB5, { KEY_CALC } }, 626 { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, 627 { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, 628 { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ 629 { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */ 630 { KE_END, 0}, 631 }; 632 633 static struct asus_wmi_driver asus_nb_wmi_driver = { 634 .name = ASUS_NB_WMI_FILE, 635 .owner = THIS_MODULE, 636 .event_guid = ASUS_NB_WMI_EVENT_GUID, 637 .keymap = asus_nb_wmi_keymap, 638 .input_name = "Asus WMI hotkeys", 639 .input_phys = ASUS_NB_WMI_FILE "/input0", 640 .detect_quirks = asus_nb_wmi_quirks, 641 }; 642 643 644 static int __init asus_nb_wmi_init(void) 645 { 646 return asus_wmi_register_driver(&asus_nb_wmi_driver); 647 } 648 649 static void __exit asus_nb_wmi_exit(void) 650 { 651 asus_wmi_unregister_driver(&asus_nb_wmi_driver); 652 } 653 654 module_init(asus_nb_wmi_init); 655 module_exit(asus_nb_wmi_exit); 656