root/drivers/platform/x86/asus-nb-wmi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. asus_q500a_i8042_filter
  2. dmi_matched
  3. asus_nb_wmi_quirks
  4. asus_nb_wmi_init
  5. asus_nb_wmi_exit

   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 int dmi_matched(const struct dmi_system_id *dmi)
 114 {
 115         pr_info("Identified laptop model '%s'\n", dmi->ident);
 116         quirks = dmi->driver_data;
 117         return 1;
 118 }
 119 
 120 static const struct dmi_system_id asus_quirks[] = {
 121         {
 122                 .callback = dmi_matched,
 123                 .ident = "ASUSTeK COMPUTER INC. Q500A",
 124                 .matches = {
 125                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 126                         DMI_MATCH(DMI_PRODUCT_NAME, "Q500A"),
 127                 },
 128                 .driver_data = &quirk_asus_q500a,
 129         },
 130         {
 131                 .callback = dmi_matched,
 132                 .ident = "ASUSTeK COMPUTER INC. U32U",
 133                 .matches = {
 134                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 135                         DMI_MATCH(DMI_PRODUCT_NAME, "U32U"),
 136                 },
 137                 /*
 138                  * Note this machine has a Brazos APU, and most Brazos Asus
 139                  * machines need quirk_asus_x55u / wmi_backlight_power but
 140                  * here acpi-video seems to work fine for backlight control.
 141                  */
 142                 .driver_data = &quirk_asus_wapf4,
 143         },
 144         {
 145                 .callback = dmi_matched,
 146                 .ident = "ASUSTeK COMPUTER INC. X302UA",
 147                 .matches = {
 148                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 149                         DMI_MATCH(DMI_PRODUCT_NAME, "X302UA"),
 150                 },
 151                 .driver_data = &quirk_asus_wapf4,
 152         },
 153         {
 154                 .callback = dmi_matched,
 155                 .ident = "ASUSTeK COMPUTER INC. X401U",
 156                 .matches = {
 157                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 158                         DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
 159                 },
 160                 .driver_data = &quirk_asus_x55u,
 161         },
 162         {
 163                 .callback = dmi_matched,
 164                 .ident = "ASUSTeK COMPUTER INC. X401A",
 165                 .matches = {
 166                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 167                         DMI_MATCH(DMI_PRODUCT_NAME, "X401A"),
 168                 },
 169                 .driver_data = &quirk_asus_wapf4,
 170         },
 171         {
 172                 .callback = dmi_matched,
 173                 .ident = "ASUSTeK COMPUTER INC. X401A1",
 174                 .matches = {
 175                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 176                         DMI_MATCH(DMI_PRODUCT_NAME, "X401A1"),
 177                 },
 178                 .driver_data = &quirk_asus_wapf4,
 179         },
 180         {
 181                 .callback = dmi_matched,
 182                 .ident = "ASUSTeK COMPUTER INC. X45U",
 183                 .matches = {
 184                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 185                         DMI_MATCH(DMI_PRODUCT_NAME, "X45U"),
 186                 },
 187                 .driver_data = &quirk_asus_wapf4,
 188         },
 189         {
 190                 .callback = dmi_matched,
 191                 .ident = "ASUSTeK COMPUTER INC. X456UA",
 192                 .matches = {
 193                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 194                         DMI_MATCH(DMI_PRODUCT_NAME, "X456UA"),
 195                 },
 196                 .driver_data = &quirk_asus_wapf4,
 197         },
 198         {
 199                 .callback = dmi_matched,
 200                 .ident = "ASUSTeK COMPUTER INC. X456UF",
 201                 .matches = {
 202                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 203                         DMI_MATCH(DMI_PRODUCT_NAME, "X456UF"),
 204                 },
 205                 .driver_data = &quirk_asus_wapf4,
 206         },
 207         {
 208                 .callback = dmi_matched,
 209                 .ident = "ASUSTeK COMPUTER INC. X501U",
 210                 .matches = {
 211                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 212                         DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
 213                 },
 214                 .driver_data = &quirk_asus_x55u,
 215         },
 216         {
 217                 .callback = dmi_matched,
 218                 .ident = "ASUSTeK COMPUTER INC. X501A",
 219                 .matches = {
 220                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 221                         DMI_MATCH(DMI_PRODUCT_NAME, "X501A"),
 222                 },
 223                 .driver_data = &quirk_asus_wapf4,
 224         },
 225         {
 226                 .callback = dmi_matched,
 227                 .ident = "ASUSTeK COMPUTER INC. X501A1",
 228                 .matches = {
 229                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 230                         DMI_MATCH(DMI_PRODUCT_NAME, "X501A1"),
 231                 },
 232                 .driver_data = &quirk_asus_wapf4,
 233         },
 234         {
 235                 .callback = dmi_matched,
 236                 .ident = "ASUSTeK COMPUTER INC. X550CA",
 237                 .matches = {
 238                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 239                         DMI_MATCH(DMI_PRODUCT_NAME, "X550CA"),
 240                 },
 241                 .driver_data = &quirk_asus_wapf4,
 242         },
 243         {
 244                 .callback = dmi_matched,
 245                 .ident = "ASUSTeK COMPUTER INC. X550CC",
 246                 .matches = {
 247                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 248                         DMI_MATCH(DMI_PRODUCT_NAME, "X550CC"),
 249                 },
 250                 .driver_data = &quirk_asus_wapf4,
 251         },
 252         {
 253                 .callback = dmi_matched,
 254                 .ident = "ASUSTeK COMPUTER INC. X550CL",
 255                 .matches = {
 256                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 257                         DMI_MATCH(DMI_PRODUCT_NAME, "X550CL"),
 258                 },
 259                 .driver_data = &quirk_asus_wapf4,
 260         },
 261         {
 262                 .callback = dmi_matched,
 263                 .ident = "ASUSTeK COMPUTER INC. X550VB",
 264                 .matches = {
 265                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 266                         DMI_MATCH(DMI_PRODUCT_NAME, "X550VB"),
 267                 },
 268                 .driver_data = &quirk_asus_wapf4,
 269         },
 270         {
 271                 .callback = dmi_matched,
 272                 .ident = "ASUSTeK COMPUTER INC. X551CA",
 273                 .matches = {
 274                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 275                         DMI_MATCH(DMI_PRODUCT_NAME, "X551CA"),
 276                 },
 277                 .driver_data = &quirk_asus_wapf4,
 278         },
 279         {
 280                 .callback = dmi_matched,
 281                 .ident = "ASUSTeK COMPUTER INC. X55A",
 282                 .matches = {
 283                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 284                         DMI_MATCH(DMI_PRODUCT_NAME, "X55A"),
 285                 },
 286                 .driver_data = &quirk_asus_wapf4,
 287         },
 288         {
 289                 .callback = dmi_matched,
 290                 .ident = "ASUSTeK COMPUTER INC. X55C",
 291                 .matches = {
 292                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 293                         DMI_MATCH(DMI_PRODUCT_NAME, "X55C"),
 294                 },
 295                 .driver_data = &quirk_asus_wapf4,
 296         },
 297         {
 298                 .callback = dmi_matched,
 299                 .ident = "ASUSTeK COMPUTER INC. X55U",
 300                 .matches = {
 301                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 302                         DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
 303                 },
 304                 .driver_data = &quirk_asus_x55u,
 305         },
 306         {
 307                 .callback = dmi_matched,
 308                 .ident = "ASUSTeK COMPUTER INC. X55VD",
 309                 .matches = {
 310                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 311                         DMI_MATCH(DMI_PRODUCT_NAME, "X55VD"),
 312                 },
 313                 .driver_data = &quirk_asus_wapf4,
 314         },
 315         {
 316                 .callback = dmi_matched,
 317                 .ident = "ASUSTeK COMPUTER INC. X75A",
 318                 .matches = {
 319                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 320                         DMI_MATCH(DMI_PRODUCT_NAME, "X75A"),
 321                 },
 322                 .driver_data = &quirk_asus_wapf4,
 323         },
 324         {
 325                 .callback = dmi_matched,
 326                 .ident = "ASUSTeK COMPUTER INC. X75VBP",
 327                 .matches = {
 328                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 329                         DMI_MATCH(DMI_PRODUCT_NAME, "X75VBP"),
 330                 },
 331                 .driver_data = &quirk_asus_wapf4,
 332         },
 333         {
 334                 .callback = dmi_matched,
 335                 .ident = "ASUSTeK COMPUTER INC. X75VD",
 336                 .matches = {
 337                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 338                         DMI_MATCH(DMI_PRODUCT_NAME, "X75VD"),
 339                 },
 340                 .driver_data = &quirk_asus_wapf4,
 341         },
 342         {
 343                 .callback = dmi_matched,
 344                 .ident = "ASUSTeK COMPUTER INC. 1015E",
 345                 .matches = {
 346                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 347                         DMI_MATCH(DMI_PRODUCT_NAME, "1015E"),
 348                 },
 349                 .driver_data = &quirk_asus_wapf4,
 350         },
 351         {
 352                 .callback = dmi_matched,
 353                 .ident = "ASUSTeK COMPUTER INC. 1015U",
 354                 .matches = {
 355                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 356                         DMI_MATCH(DMI_PRODUCT_NAME, "1015U"),
 357                 },
 358                 .driver_data = &quirk_asus_wapf4,
 359         },
 360         {
 361                 .callback = dmi_matched,
 362                 .ident = "ASUSTeK COMPUTER INC. X200CA",
 363                 .matches = {
 364                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 365                         DMI_MATCH(DMI_PRODUCT_NAME, "X200CA"),
 366                 },
 367                 .driver_data = &quirk_asus_x200ca,
 368         },
 369         {
 370                 .callback = dmi_matched,
 371                 .ident = "ASUSTeK COMPUTER INC. UX303UB",
 372                 .matches = {
 373                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 374                         DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"),
 375                 },
 376                 .driver_data = &quirk_asus_ux303ub,
 377         },
 378         {
 379                 .callback = dmi_matched,
 380                 .ident = "ASUSTeK COMPUTER INC. UX330UAK",
 381                 .matches = {
 382                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 383                         DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"),
 384                 },
 385                 .driver_data = &quirk_asus_forceals,
 386         },
 387         {
 388                 .callback = dmi_matched,
 389                 .ident = "ASUSTeK COMPUTER INC. X550LB",
 390                 .matches = {
 391                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 392                         DMI_MATCH(DMI_PRODUCT_NAME, "X550LB"),
 393                 },
 394                 .driver_data = &quirk_asus_x550lb,
 395         },
 396         {
 397                 .callback = dmi_matched,
 398                 .ident = "ASUSTeK COMPUTER INC. UX430UQ",
 399                 .matches = {
 400                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 401                         DMI_MATCH(DMI_PRODUCT_NAME, "UX430UQ"),
 402                 },
 403                 .driver_data = &quirk_asus_forceals,
 404         },
 405         {
 406                 .callback = dmi_matched,
 407                 .ident = "ASUSTeK COMPUTER INC. UX430UNR",
 408                 .matches = {
 409                         DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 410                         DMI_MATCH(DMI_PRODUCT_NAME, "UX430UNR"),
 411                 },
 412                 .driver_data = &quirk_asus_forceals,
 413         },
 414         {},
 415 };
 416 
 417 static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
 418 {
 419         int ret;
 420 
 421         quirks = &quirk_asus_unknown;
 422         dmi_check_system(asus_quirks);
 423 
 424         driver->quirks = quirks;
 425         driver->panel_power = FB_BLANK_UNBLANK;
 426 
 427         /* overwrite the wapf setting if the wapf paramater is specified */
 428         if (wapf != -1)
 429                 quirks->wapf = wapf;
 430         else
 431                 wapf = quirks->wapf;
 432 
 433         if (quirks->i8042_filter) {
 434                 ret = i8042_install_filter(quirks->i8042_filter);
 435                 if (ret) {
 436                         pr_warn("Unable to install key filter\n");
 437                         return;
 438                 }
 439                 pr_info("Using i8042 filter function for receiving events\n");
 440         }
 441 }
 442 
 443 static const struct key_entry asus_nb_wmi_keymap[] = {
 444         { KE_KEY, ASUS_WMI_BRN_DOWN, { KEY_BRIGHTNESSDOWN } },
 445         { KE_KEY, ASUS_WMI_BRN_UP, { KEY_BRIGHTNESSUP } },
 446         { KE_KEY, 0x30, { KEY_VOLUMEUP } },
 447         { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
 448         { KE_KEY, 0x32, { KEY_MUTE } },
 449         { KE_KEY, 0x35, { KEY_SCREENLOCK } },
 450         { KE_KEY, 0x40, { KEY_PREVIOUSSONG } },
 451         { KE_KEY, 0x41, { KEY_NEXTSONG } },
 452         { KE_KEY, 0x43, { KEY_STOPCD } }, /* Stop/Eject */
 453         { KE_KEY, 0x45, { KEY_PLAYPAUSE } },
 454         { KE_KEY, 0x4c, { KEY_MEDIA } }, /* WMP Key */
 455         { KE_KEY, 0x50, { KEY_EMAIL } },
 456         { KE_KEY, 0x51, { KEY_WWW } },
 457         { KE_KEY, 0x55, { KEY_CALC } },
 458         { KE_IGNORE, 0x57, },  /* Battery mode */
 459         { KE_IGNORE, 0x58, },  /* AC mode */
 460         { KE_KEY, 0x5C, { KEY_F15 } },  /* Power Gear key */
 461         { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */
 462         { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */
 463         { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */
 464         { KE_KEY, 0x60, { KEY_TOUCHPAD_ON } },
 465         { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD only */
 466         { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT only */
 467         { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT */
 468         { KE_KEY, 0x64, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV */
 469         { KE_KEY, 0x65, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV */
 470         { KE_KEY, 0x66, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV */
 471         { KE_KEY, 0x67, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV */
 472         { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } },
 473         { KE_IGNORE, 0x6E, },  /* Low Battery notification */
 474         { KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */
 475         { KE_KEY, 0x7c, { KEY_MICMUTE } },
 476         { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */
 477         { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */
 478         { KE_KEY, 0x82, { KEY_CAMERA } },
 479         { KE_KEY, 0x88, { KEY_RFKILL  } }, /* Radio Toggle Key */
 480         { KE_KEY, 0x8A, { KEY_PROG1 } }, /* Color enhancement mode */
 481         { KE_KEY, 0x8C, { KEY_SWITCHVIDEOMODE } }, /* SDSP DVI only */
 482         { KE_KEY, 0x8D, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + DVI */
 483         { KE_KEY, 0x8E, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + DVI */
 484         { KE_KEY, 0x8F, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + DVI */
 485         { KE_KEY, 0x90, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + DVI */
 486         { KE_KEY, 0x91, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + DVI */
 487         { KE_KEY, 0x92, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + DVI */
 488         { KE_KEY, 0x93, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + DVI */
 489         { KE_KEY, 0x95, { KEY_MEDIA } },
 490         { KE_KEY, 0x99, { KEY_PHONE } }, /* Conflicts with fan mode switch */
 491         { KE_KEY, 0xA0, { KEY_SWITCHVIDEOMODE } }, /* SDSP HDMI only */
 492         { KE_KEY, 0xA1, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + HDMI */
 493         { KE_KEY, 0xA2, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + HDMI */
 494         { KE_KEY, 0xA3, { KEY_SWITCHVIDEOMODE } }, /* SDSP TV + HDMI */
 495         { KE_KEY, 0xA4, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + HDMI */
 496         { KE_KEY, 0xA5, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + TV + HDMI */
 497         { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */
 498         { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */
 499         { KE_KEY, 0xB5, { KEY_CALC } },
 500         { KE_KEY, 0xC4, { KEY_KBDILLUMUP } },
 501         { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
 502         { KE_IGNORE, 0xC6, },  /* Ambient Light Sensor notification */
 503         { KE_KEY, 0xFA, { KEY_PROG2 } },           /* Lid flip action */
 504         { KE_END, 0},
 505 };
 506 
 507 static struct asus_wmi_driver asus_nb_wmi_driver = {
 508         .name = ASUS_NB_WMI_FILE,
 509         .owner = THIS_MODULE,
 510         .event_guid = ASUS_NB_WMI_EVENT_GUID,
 511         .keymap = asus_nb_wmi_keymap,
 512         .input_name = "Asus WMI hotkeys",
 513         .input_phys = ASUS_NB_WMI_FILE "/input0",
 514         .detect_quirks = asus_nb_wmi_quirks,
 515 };
 516 
 517 static const struct dmi_system_id asus_nb_wmi_blacklist[] __initconst = {
 518         {
 519                 /*
 520                  * asus-nb-wm adds no functionality. The T100TA has a detachable
 521                  * USB kbd, so no hotkeys and it has no WMI rfkill; and loading
 522                  * asus-nb-wm causes the camera LED to turn and _stay_ on.
 523                  */
 524                 .matches = {
 525                         DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 526                         DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
 527                 },
 528         },
 529         {
 530                 /* The Asus T200TA has the same issue as the T100TA */
 531                 .matches = {
 532                         DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 533                         DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T200TA"),
 534                 },
 535         },
 536         {} /* Terminating entry */
 537 };
 538 
 539 static int __init asus_nb_wmi_init(void)
 540 {
 541         if (dmi_check_system(asus_nb_wmi_blacklist))
 542                 return -ENODEV;
 543 
 544         return asus_wmi_register_driver(&asus_nb_wmi_driver);
 545 }
 546 
 547 static void __exit asus_nb_wmi_exit(void)
 548 {
 549         asus_wmi_unregister_driver(&asus_nb_wmi_driver);
 550 }
 551 
 552 module_init(asus_nb_wmi_init);
 553 module_exit(asus_nb_wmi_exit);

/* [<][>][^][v][top][bottom][index][help] */