1 /* 2 * Acer WMI Laptop Extras 3 * 4 * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk> 5 * 6 * Based on acer_acpi: 7 * Copyright (C) 2005-2007 E.M. Smith 8 * Copyright (C) 2007-2008 Carlos Corbacho <cathectic@gmail.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 27 #include <linux/kernel.h> 28 #include <linux/module.h> 29 #include <linux/init.h> 30 #include <linux/types.h> 31 #include <linux/dmi.h> 32 #include <linux/fb.h> 33 #include <linux/backlight.h> 34 #include <linux/leds.h> 35 #include <linux/platform_device.h> 36 #include <linux/acpi.h> 37 #include <linux/i8042.h> 38 #include <linux/rfkill.h> 39 #include <linux/workqueue.h> 40 #include <linux/debugfs.h> 41 #include <linux/slab.h> 42 #include <linux/input.h> 43 #include <linux/input/sparse-keymap.h> 44 #include <acpi/video.h> 45 46 MODULE_AUTHOR("Carlos Corbacho"); 47 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); 48 MODULE_LICENSE("GPL"); 49 50 /* 51 * Magic Number 52 * Meaning is unknown - this number is required for writing to ACPI for AMW0 53 * (it's also used in acerhk when directly accessing the BIOS) 54 */ 55 #define ACER_AMW0_WRITE 0x9610 56 57 /* 58 * Bit masks for the AMW0 interface 59 */ 60 #define ACER_AMW0_WIRELESS_MASK 0x35 61 #define ACER_AMW0_BLUETOOTH_MASK 0x34 62 #define ACER_AMW0_MAILLED_MASK 0x31 63 64 /* 65 * Method IDs for WMID interface 66 */ 67 #define ACER_WMID_GET_WIRELESS_METHODID 1 68 #define ACER_WMID_GET_BLUETOOTH_METHODID 2 69 #define ACER_WMID_GET_BRIGHTNESS_METHODID 3 70 #define ACER_WMID_SET_WIRELESS_METHODID 4 71 #define ACER_WMID_SET_BLUETOOTH_METHODID 5 72 #define ACER_WMID_SET_BRIGHTNESS_METHODID 6 73 #define ACER_WMID_GET_THREEG_METHODID 10 74 #define ACER_WMID_SET_THREEG_METHODID 11 75 76 /* 77 * Acer ACPI method GUIDs 78 */ 79 #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" 80 #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" 81 #define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3" 82 #define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A" 83 #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531" 84 85 /* 86 * Acer ACPI event GUIDs 87 */ 88 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" 89 90 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); 91 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"); 92 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); 93 94 enum acer_wmi_event_ids { 95 WMID_HOTKEY_EVENT = 0x1, 96 WMID_ACCEL_EVENT = 0x5, 97 }; 98 99 static const struct key_entry acer_wmi_keymap[] __initconst = { 100 {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ 101 {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ 102 {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ 103 {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ 104 {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ 105 {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ 106 {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ 107 {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ 108 {KE_KEY, 0x29, {KEY_PROG3} }, /* P_Key for TM8372 */ 109 {KE_IGNORE, 0x41, {KEY_MUTE} }, 110 {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, 111 {KE_IGNORE, 0x4d, {KEY_PREVIOUSSONG} }, 112 {KE_IGNORE, 0x43, {KEY_NEXTSONG} }, 113 {KE_IGNORE, 0x4e, {KEY_NEXTSONG} }, 114 {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} }, 115 {KE_IGNORE, 0x4f, {KEY_PLAYPAUSE} }, 116 {KE_IGNORE, 0x45, {KEY_STOP} }, 117 {KE_IGNORE, 0x50, {KEY_STOP} }, 118 {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, 119 {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, 120 {KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} }, 121 {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} }, 122 {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, 123 {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, 124 {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ 125 {KE_IGNORE, 0x81, {KEY_SLEEP} }, 126 {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ 127 {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, 128 {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, 129 {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, 130 {KE_KEY, 0x85, {KEY_TOUCHPAD_TOGGLE} }, 131 {KE_KEY, 0x86, {KEY_WLAN} }, 132 {KE_KEY, 0x87, {KEY_POWER} }, 133 {KE_END, 0} 134 }; 135 136 static struct input_dev *acer_wmi_input_dev; 137 static struct input_dev *acer_wmi_accel_dev; 138 139 struct event_return_value { 140 u8 function; 141 u8 key_num; 142 u16 device_state; 143 u32 reserved; 144 } __attribute__((packed)); 145 146 /* 147 * GUID3 Get Device Status device flags 148 */ 149 #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ 150 #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ 151 #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ 152 #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ 153 #define ACER_WMID3_GDS_RFBTN (1<<14) /* RF Button */ 154 155 #define ACER_WMID3_GDS_TOUCHPAD (1<<1) /* Touchpad */ 156 157 /* Hotkey Customized Setting and Acer Application Status. 158 * Set Device Default Value and Report Acer Application Status. 159 * When Acer Application starts, it will run this method to inform 160 * BIOS/EC that Acer Application is on. 161 * App Status 162 * Bit[0]: Launch Manager Status 163 * Bit[1]: ePM Status 164 * Bit[2]: Device Control Status 165 * Bit[3]: Acer Power Button Utility Status 166 * Bit[4]: RF Button Status 167 * Bit[5]: ODD PM Status 168 * Bit[6]: Device Default Value Control 169 * Bit[7]: Hall Sensor Application Status 170 */ 171 struct func_input_params { 172 u8 function_num; /* Function Number */ 173 u16 commun_devices; /* Communication type devices default status */ 174 u16 devices; /* Other type devices default status */ 175 u8 app_status; /* Acer Device Status. LM, ePM, RF Button... */ 176 u8 app_mask; /* Bit mask to app_status */ 177 u8 reserved; 178 } __attribute__((packed)); 179 180 struct func_return_value { 181 u8 error_code; /* Error Code */ 182 u8 ec_return_value; /* EC Return Value */ 183 u16 reserved; 184 } __attribute__((packed)); 185 186 struct wmid3_gds_set_input_param { /* Set Device Status input parameter */ 187 u8 function_num; /* Function Number */ 188 u8 hotkey_number; /* Hotkey Number */ 189 u16 devices; /* Set Device */ 190 u8 volume_value; /* Volume Value */ 191 } __attribute__((packed)); 192 193 struct wmid3_gds_get_input_param { /* Get Device Status input parameter */ 194 u8 function_num; /* Function Number */ 195 u8 hotkey_number; /* Hotkey Number */ 196 u16 devices; /* Get Device */ 197 } __attribute__((packed)); 198 199 struct wmid3_gds_return_value { /* Get Device Status return value*/ 200 u8 error_code; /* Error Code */ 201 u8 ec_return_value; /* EC Return Value */ 202 u16 devices; /* Current Device Status */ 203 u32 reserved; 204 } __attribute__((packed)); 205 206 struct hotkey_function_type_aa { 207 u8 type; 208 u8 length; 209 u16 handle; 210 u16 commun_func_bitmap; 211 u16 application_func_bitmap; 212 u16 media_func_bitmap; 213 u16 display_func_bitmap; 214 u16 others_func_bitmap; 215 u8 commun_fn_key_number; 216 } __attribute__((packed)); 217 218 /* 219 * Interface capability flags 220 */ 221 #define ACER_CAP_MAILLED (1<<0) 222 #define ACER_CAP_WIRELESS (1<<1) 223 #define ACER_CAP_BLUETOOTH (1<<2) 224 #define ACER_CAP_BRIGHTNESS (1<<3) 225 #define ACER_CAP_THREEG (1<<4) 226 #define ACER_CAP_ACCEL (1<<5) 227 #define ACER_CAP_RFBTN (1<<6) 228 #define ACER_CAP_ANY (0xFFFFFFFF) 229 230 /* 231 * Interface type flags 232 */ 233 enum interface_flags { 234 ACER_AMW0, 235 ACER_AMW0_V2, 236 ACER_WMID, 237 ACER_WMID_v2, 238 }; 239 240 #define ACER_DEFAULT_WIRELESS 0 241 #define ACER_DEFAULT_BLUETOOTH 0 242 #define ACER_DEFAULT_MAILLED 0 243 #define ACER_DEFAULT_THREEG 0 244 245 static int max_brightness = 0xF; 246 247 static int mailled = -1; 248 static int brightness = -1; 249 static int threeg = -1; 250 static int force_series; 251 static bool ec_raw_mode; 252 static bool has_type_aa; 253 static u16 commun_func_bitmap; 254 static u8 commun_fn_key_number; 255 256 module_param(mailled, int, 0444); 257 module_param(brightness, int, 0444); 258 module_param(threeg, int, 0444); 259 module_param(force_series, int, 0444); 260 module_param(ec_raw_mode, bool, 0444); 261 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); 262 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); 263 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); 264 MODULE_PARM_DESC(force_series, "Force a different laptop series"); 265 MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); 266 267 struct acer_data { 268 int mailled; 269 int threeg; 270 int brightness; 271 }; 272 273 struct acer_debug { 274 struct dentry *root; 275 struct dentry *devices; 276 u32 wmid_devices; 277 }; 278 279 static struct rfkill *wireless_rfkill; 280 static struct rfkill *bluetooth_rfkill; 281 static struct rfkill *threeg_rfkill; 282 static bool rfkill_inited; 283 284 /* Each low-level interface must define at least some of the following */ 285 struct wmi_interface { 286 /* The WMI device type */ 287 u32 type; 288 289 /* The capabilities this interface provides */ 290 u32 capability; 291 292 /* Private data for the current interface */ 293 struct acer_data data; 294 295 /* debugfs entries associated with this interface */ 296 struct acer_debug debug; 297 }; 298 299 /* The static interface pointer, points to the currently detected interface */ 300 static struct wmi_interface *interface; 301 302 /* 303 * Embedded Controller quirks 304 * Some laptops require us to directly access the EC to either enable or query 305 * features that are not available through WMI. 306 */ 307 308 struct quirk_entry { 309 u8 wireless; 310 u8 mailled; 311 s8 brightness; 312 u8 bluetooth; 313 }; 314 315 static struct quirk_entry *quirks; 316 317 static void __init set_quirks(void) 318 { 319 if (!interface) 320 return; 321 322 if (quirks->mailled) 323 interface->capability |= ACER_CAP_MAILLED; 324 325 if (quirks->brightness) 326 interface->capability |= ACER_CAP_BRIGHTNESS; 327 } 328 329 static int __init dmi_matched(const struct dmi_system_id *dmi) 330 { 331 quirks = dmi->driver_data; 332 return 1; 333 } 334 335 static struct quirk_entry quirk_unknown = { 336 }; 337 338 static struct quirk_entry quirk_acer_aspire_1520 = { 339 .brightness = -1, 340 }; 341 342 static struct quirk_entry quirk_acer_travelmate_2490 = { 343 .mailled = 1, 344 }; 345 346 /* This AMW0 laptop has no bluetooth */ 347 static struct quirk_entry quirk_medion_md_98300 = { 348 .wireless = 1, 349 }; 350 351 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { 352 .wireless = 2, 353 }; 354 355 static struct quirk_entry quirk_lenovo_ideapad_s205 = { 356 .wireless = 3, 357 }; 358 359 /* The Aspire One has a dummy ACPI-WMI interface - disable it */ 360 static const struct dmi_system_id acer_blacklist[] __initconst = { 361 { 362 .ident = "Acer Aspire One (SSD)", 363 .matches = { 364 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 365 DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), 366 }, 367 }, 368 { 369 .ident = "Acer Aspire One (HDD)", 370 .matches = { 371 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 372 DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), 373 }, 374 }, 375 {} 376 }; 377 378 static const struct dmi_system_id amw0_whitelist[] __initconst = { 379 { 380 .ident = "Acer", 381 .matches = { 382 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 383 }, 384 }, 385 { 386 .ident = "Gateway", 387 .matches = { 388 DMI_MATCH(DMI_SYS_VENDOR, "Gateway"), 389 }, 390 }, 391 { 392 .ident = "Packard Bell", 393 .matches = { 394 DMI_MATCH(DMI_SYS_VENDOR, "Packard Bell"), 395 }, 396 }, 397 {} 398 }; 399 400 /* 401 * This quirk table is only for Acer/Gateway/Packard Bell family 402 * that those machines are supported by acer-wmi driver. 403 */ 404 static const struct dmi_system_id acer_quirks[] __initconst = { 405 { 406 .callback = dmi_matched, 407 .ident = "Acer Aspire 1360", 408 .matches = { 409 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 410 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), 411 }, 412 .driver_data = &quirk_acer_aspire_1520, 413 }, 414 { 415 .callback = dmi_matched, 416 .ident = "Acer Aspire 1520", 417 .matches = { 418 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 419 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"), 420 }, 421 .driver_data = &quirk_acer_aspire_1520, 422 }, 423 { 424 .callback = dmi_matched, 425 .ident = "Acer Aspire 3100", 426 .matches = { 427 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 428 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"), 429 }, 430 .driver_data = &quirk_acer_travelmate_2490, 431 }, 432 { 433 .callback = dmi_matched, 434 .ident = "Acer Aspire 3610", 435 .matches = { 436 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 437 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"), 438 }, 439 .driver_data = &quirk_acer_travelmate_2490, 440 }, 441 { 442 .callback = dmi_matched, 443 .ident = "Acer Aspire 5100", 444 .matches = { 445 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 446 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), 447 }, 448 .driver_data = &quirk_acer_travelmate_2490, 449 }, 450 { 451 .callback = dmi_matched, 452 .ident = "Acer Aspire 5610", 453 .matches = { 454 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 455 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), 456 }, 457 .driver_data = &quirk_acer_travelmate_2490, 458 }, 459 { 460 .callback = dmi_matched, 461 .ident = "Acer Aspire 5630", 462 .matches = { 463 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 464 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), 465 }, 466 .driver_data = &quirk_acer_travelmate_2490, 467 }, 468 { 469 .callback = dmi_matched, 470 .ident = "Acer Aspire 5650", 471 .matches = { 472 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 473 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), 474 }, 475 .driver_data = &quirk_acer_travelmate_2490, 476 }, 477 { 478 .callback = dmi_matched, 479 .ident = "Acer Aspire 5680", 480 .matches = { 481 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 482 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), 483 }, 484 .driver_data = &quirk_acer_travelmate_2490, 485 }, 486 { 487 .callback = dmi_matched, 488 .ident = "Acer Aspire 9110", 489 .matches = { 490 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 491 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), 492 }, 493 .driver_data = &quirk_acer_travelmate_2490, 494 }, 495 { 496 .callback = dmi_matched, 497 .ident = "Acer TravelMate 2490", 498 .matches = { 499 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 500 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 501 }, 502 .driver_data = &quirk_acer_travelmate_2490, 503 }, 504 { 505 .callback = dmi_matched, 506 .ident = "Acer TravelMate 4200", 507 .matches = { 508 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 509 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"), 510 }, 511 .driver_data = &quirk_acer_travelmate_2490, 512 }, 513 {} 514 }; 515 516 /* 517 * This quirk list is for those non-acer machines that have AMW0_GUID1 518 * but supported by acer-wmi in past days. Keeping this quirk list here 519 * is only for backward compatible. Please do not add new machine to 520 * here anymore. Those non-acer machines should be supported by 521 * appropriate wmi drivers. 522 */ 523 static const struct dmi_system_id non_acer_quirks[] __initconst = { 524 { 525 .callback = dmi_matched, 526 .ident = "Fujitsu Siemens Amilo Li 1718", 527 .matches = { 528 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 529 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"), 530 }, 531 .driver_data = &quirk_fujitsu_amilo_li_1718, 532 }, 533 { 534 .callback = dmi_matched, 535 .ident = "Medion MD 98300", 536 .matches = { 537 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 538 DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"), 539 }, 540 .driver_data = &quirk_medion_md_98300, 541 }, 542 { 543 .callback = dmi_matched, 544 .ident = "Lenovo Ideapad S205", 545 .matches = { 546 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 547 DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"), 548 }, 549 .driver_data = &quirk_lenovo_ideapad_s205, 550 }, 551 { 552 .callback = dmi_matched, 553 .ident = "Lenovo Ideapad S205 (Brazos)", 554 .matches = { 555 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 556 DMI_MATCH(DMI_PRODUCT_NAME, "Brazos"), 557 }, 558 .driver_data = &quirk_lenovo_ideapad_s205, 559 }, 560 { 561 .callback = dmi_matched, 562 .ident = "Lenovo 3000 N200", 563 .matches = { 564 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 565 DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"), 566 }, 567 .driver_data = &quirk_fujitsu_amilo_li_1718, 568 }, 569 { 570 .callback = dmi_matched, 571 .ident = "Lenovo Ideapad S205-10382JG", 572 .matches = { 573 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 574 DMI_MATCH(DMI_PRODUCT_NAME, "10382JG"), 575 }, 576 .driver_data = &quirk_lenovo_ideapad_s205, 577 }, 578 { 579 .callback = dmi_matched, 580 .ident = "Lenovo Ideapad S205-1038DPG", 581 .matches = { 582 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 583 DMI_MATCH(DMI_PRODUCT_NAME, "1038DPG"), 584 }, 585 .driver_data = &quirk_lenovo_ideapad_s205, 586 }, 587 {} 588 }; 589 590 static int __init 591 video_set_backlight_video_vendor(const struct dmi_system_id *d) 592 { 593 interface->capability &= ~ACER_CAP_BRIGHTNESS; 594 pr_info("Brightness must be controlled by generic video driver\n"); 595 return 0; 596 } 597 598 static const struct dmi_system_id video_vendor_dmi_table[] __initconst = { 599 { 600 .callback = video_set_backlight_video_vendor, 601 .ident = "Acer TravelMate 4750", 602 .matches = { 603 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 604 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"), 605 }, 606 }, 607 { 608 .callback = video_set_backlight_video_vendor, 609 .ident = "Acer Extensa 5235", 610 .matches = { 611 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 612 DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"), 613 }, 614 }, 615 { 616 .callback = video_set_backlight_video_vendor, 617 .ident = "Acer TravelMate 5760", 618 .matches = { 619 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 620 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"), 621 }, 622 }, 623 { 624 .callback = video_set_backlight_video_vendor, 625 .ident = "Acer Aspire 5750", 626 .matches = { 627 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 628 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), 629 }, 630 }, 631 { 632 .callback = video_set_backlight_video_vendor, 633 .ident = "Acer Aspire 5741", 634 .matches = { 635 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), 636 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"), 637 }, 638 }, 639 { 640 /* 641 * Note no video_set_backlight_video_vendor, we must use the 642 * acer interface, as there is no native backlight interface. 643 */ 644 .ident = "Acer KAV80", 645 .matches = { 646 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 647 DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"), 648 }, 649 }, 650 {} 651 }; 652 653 /* Find which quirks are needed for a particular vendor/ model pair */ 654 static void __init find_quirks(void) 655 { 656 if (!force_series) { 657 dmi_check_system(acer_quirks); 658 dmi_check_system(non_acer_quirks); 659 } else if (force_series == 2490) { 660 quirks = &quirk_acer_travelmate_2490; 661 } 662 663 if (quirks == NULL) 664 quirks = &quirk_unknown; 665 666 set_quirks(); 667 } 668 669 /* 670 * General interface convenience methods 671 */ 672 673 static bool has_cap(u32 cap) 674 { 675 return interface->capability & cap; 676 } 677 678 /* 679 * AMW0 (V1) interface 680 */ 681 struct wmab_args { 682 u32 eax; 683 u32 ebx; 684 u32 ecx; 685 u32 edx; 686 }; 687 688 struct wmab_ret { 689 u32 eax; 690 u32 ebx; 691 u32 ecx; 692 u32 edx; 693 u32 eex; 694 }; 695 696 static acpi_status wmab_execute(struct wmab_args *regbuf, 697 struct acpi_buffer *result) 698 { 699 struct acpi_buffer input; 700 acpi_status status; 701 input.length = sizeof(struct wmab_args); 702 input.pointer = (u8 *)regbuf; 703 704 status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result); 705 706 return status; 707 } 708 709 static acpi_status AMW0_get_u32(u32 *value, u32 cap) 710 { 711 int err; 712 u8 result; 713 714 switch (cap) { 715 case ACER_CAP_MAILLED: 716 switch (quirks->mailled) { 717 default: 718 err = ec_read(0xA, &result); 719 if (err) 720 return AE_ERROR; 721 *value = (result >> 7) & 0x1; 722 return AE_OK; 723 } 724 break; 725 case ACER_CAP_WIRELESS: 726 switch (quirks->wireless) { 727 case 1: 728 err = ec_read(0x7B, &result); 729 if (err) 730 return AE_ERROR; 731 *value = result & 0x1; 732 return AE_OK; 733 case 2: 734 err = ec_read(0x71, &result); 735 if (err) 736 return AE_ERROR; 737 *value = result & 0x1; 738 return AE_OK; 739 case 3: 740 err = ec_read(0x78, &result); 741 if (err) 742 return AE_ERROR; 743 *value = result & 0x1; 744 return AE_OK; 745 default: 746 err = ec_read(0xA, &result); 747 if (err) 748 return AE_ERROR; 749 *value = (result >> 2) & 0x1; 750 return AE_OK; 751 } 752 break; 753 case ACER_CAP_BLUETOOTH: 754 switch (quirks->bluetooth) { 755 default: 756 err = ec_read(0xA, &result); 757 if (err) 758 return AE_ERROR; 759 *value = (result >> 4) & 0x1; 760 return AE_OK; 761 } 762 break; 763 case ACER_CAP_BRIGHTNESS: 764 switch (quirks->brightness) { 765 default: 766 err = ec_read(0x83, &result); 767 if (err) 768 return AE_ERROR; 769 *value = result; 770 return AE_OK; 771 } 772 break; 773 default: 774 return AE_ERROR; 775 } 776 return AE_OK; 777 } 778 779 static acpi_status AMW0_set_u32(u32 value, u32 cap) 780 { 781 struct wmab_args args; 782 783 args.eax = ACER_AMW0_WRITE; 784 args.ebx = value ? (1<<8) : 0; 785 args.ecx = args.edx = 0; 786 787 switch (cap) { 788 case ACER_CAP_MAILLED: 789 if (value > 1) 790 return AE_BAD_PARAMETER; 791 args.ebx |= ACER_AMW0_MAILLED_MASK; 792 break; 793 case ACER_CAP_WIRELESS: 794 if (value > 1) 795 return AE_BAD_PARAMETER; 796 args.ebx |= ACER_AMW0_WIRELESS_MASK; 797 break; 798 case ACER_CAP_BLUETOOTH: 799 if (value > 1) 800 return AE_BAD_PARAMETER; 801 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 802 break; 803 case ACER_CAP_BRIGHTNESS: 804 if (value > max_brightness) 805 return AE_BAD_PARAMETER; 806 switch (quirks->brightness) { 807 default: 808 return ec_write(0x83, value); 809 break; 810 } 811 default: 812 return AE_ERROR; 813 } 814 815 /* Actually do the set */ 816 return wmab_execute(&args, NULL); 817 } 818 819 static acpi_status __init AMW0_find_mailled(void) 820 { 821 struct wmab_args args; 822 struct wmab_ret ret; 823 acpi_status status = AE_OK; 824 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 825 union acpi_object *obj; 826 827 args.eax = 0x86; 828 args.ebx = args.ecx = args.edx = 0; 829 830 status = wmab_execute(&args, &out); 831 if (ACPI_FAILURE(status)) 832 return status; 833 834 obj = (union acpi_object *) out.pointer; 835 if (obj && obj->type == ACPI_TYPE_BUFFER && 836 obj->buffer.length == sizeof(struct wmab_ret)) { 837 ret = *((struct wmab_ret *) obj->buffer.pointer); 838 } else { 839 kfree(out.pointer); 840 return AE_ERROR; 841 } 842 843 if (ret.eex & 0x1) 844 interface->capability |= ACER_CAP_MAILLED; 845 846 kfree(out.pointer); 847 848 return AE_OK; 849 } 850 851 static const struct acpi_device_id norfkill_ids[] __initconst = { 852 { "VPC2004", 0}, 853 { "IBM0068", 0}, 854 { "LEN0068", 0}, 855 { "SNY5001", 0}, /* sony-laptop in charge */ 856 { "HPQ6601", 0}, 857 { "", 0}, 858 }; 859 860 static int __init AMW0_set_cap_acpi_check_device(void) 861 { 862 const struct acpi_device_id *id; 863 864 for (id = norfkill_ids; id->id[0]; id++) 865 if (acpi_dev_found(id->id)) 866 return true; 867 868 return false; 869 } 870 871 static acpi_status __init AMW0_set_capabilities(void) 872 { 873 struct wmab_args args; 874 struct wmab_ret ret; 875 acpi_status status; 876 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 877 union acpi_object *obj; 878 879 /* 880 * On laptops with this strange GUID (non Acer), normal probing doesn't 881 * work. 882 */ 883 if (wmi_has_guid(AMW0_GUID2)) { 884 if ((quirks != &quirk_unknown) || 885 !AMW0_set_cap_acpi_check_device()) 886 interface->capability |= ACER_CAP_WIRELESS; 887 return AE_OK; 888 } 889 890 args.eax = ACER_AMW0_WRITE; 891 args.ecx = args.edx = 0; 892 893 args.ebx = 0xa2 << 8; 894 args.ebx |= ACER_AMW0_WIRELESS_MASK; 895 896 status = wmab_execute(&args, &out); 897 if (ACPI_FAILURE(status)) 898 return status; 899 900 obj = out.pointer; 901 if (obj && obj->type == ACPI_TYPE_BUFFER && 902 obj->buffer.length == sizeof(struct wmab_ret)) { 903 ret = *((struct wmab_ret *) obj->buffer.pointer); 904 } else { 905 status = AE_ERROR; 906 goto out; 907 } 908 909 if (ret.eax & 0x1) 910 interface->capability |= ACER_CAP_WIRELESS; 911 912 args.ebx = 2 << 8; 913 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 914 915 /* 916 * It's ok to use existing buffer for next wmab_execute call. 917 * But we need to kfree(out.pointer) if next wmab_execute fail. 918 */ 919 status = wmab_execute(&args, &out); 920 if (ACPI_FAILURE(status)) 921 goto out; 922 923 obj = (union acpi_object *) out.pointer; 924 if (obj && obj->type == ACPI_TYPE_BUFFER 925 && obj->buffer.length == sizeof(struct wmab_ret)) { 926 ret = *((struct wmab_ret *) obj->buffer.pointer); 927 } else { 928 status = AE_ERROR; 929 goto out; 930 } 931 932 if (ret.eax & 0x1) 933 interface->capability |= ACER_CAP_BLUETOOTH; 934 935 /* 936 * This appears to be safe to enable, since all Wistron based laptops 937 * appear to use the same EC register for brightness, even if they 938 * differ for wireless, etc 939 */ 940 if (quirks->brightness >= 0) 941 interface->capability |= ACER_CAP_BRIGHTNESS; 942 943 status = AE_OK; 944 out: 945 kfree(out.pointer); 946 return status; 947 } 948 949 static struct wmi_interface AMW0_interface = { 950 .type = ACER_AMW0, 951 }; 952 953 static struct wmi_interface AMW0_V2_interface = { 954 .type = ACER_AMW0_V2, 955 }; 956 957 /* 958 * New interface (The WMID interface) 959 */ 960 static acpi_status 961 WMI_execute_u32(u32 method_id, u32 in, u32 *out) 962 { 963 struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; 964 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 965 union acpi_object *obj; 966 u32 tmp = 0; 967 acpi_status status; 968 969 status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result); 970 971 if (ACPI_FAILURE(status)) 972 return status; 973 974 obj = (union acpi_object *) result.pointer; 975 if (obj) { 976 if (obj->type == ACPI_TYPE_BUFFER && 977 (obj->buffer.length == sizeof(u32) || 978 obj->buffer.length == sizeof(u64))) { 979 tmp = *((u32 *) obj->buffer.pointer); 980 } else if (obj->type == ACPI_TYPE_INTEGER) { 981 tmp = (u32) obj->integer.value; 982 } 983 } 984 985 if (out) 986 *out = tmp; 987 988 kfree(result.pointer); 989 990 return status; 991 } 992 993 static acpi_status WMID_get_u32(u32 *value, u32 cap) 994 { 995 acpi_status status; 996 u8 tmp; 997 u32 result, method_id = 0; 998 999 switch (cap) { 1000 case ACER_CAP_WIRELESS: 1001 method_id = ACER_WMID_GET_WIRELESS_METHODID; 1002 break; 1003 case ACER_CAP_BLUETOOTH: 1004 method_id = ACER_WMID_GET_BLUETOOTH_METHODID; 1005 break; 1006 case ACER_CAP_BRIGHTNESS: 1007 method_id = ACER_WMID_GET_BRIGHTNESS_METHODID; 1008 break; 1009 case ACER_CAP_THREEG: 1010 method_id = ACER_WMID_GET_THREEG_METHODID; 1011 break; 1012 case ACER_CAP_MAILLED: 1013 if (quirks->mailled == 1) { 1014 ec_read(0x9f, &tmp); 1015 *value = tmp & 0x1; 1016 return 0; 1017 } 1018 default: 1019 return AE_ERROR; 1020 } 1021 status = WMI_execute_u32(method_id, 0, &result); 1022 1023 if (ACPI_SUCCESS(status)) 1024 *value = (u8)result; 1025 1026 return status; 1027 } 1028 1029 static acpi_status WMID_set_u32(u32 value, u32 cap) 1030 { 1031 u32 method_id = 0; 1032 char param; 1033 1034 switch (cap) { 1035 case ACER_CAP_BRIGHTNESS: 1036 if (value > max_brightness) 1037 return AE_BAD_PARAMETER; 1038 method_id = ACER_WMID_SET_BRIGHTNESS_METHODID; 1039 break; 1040 case ACER_CAP_WIRELESS: 1041 if (value > 1) 1042 return AE_BAD_PARAMETER; 1043 method_id = ACER_WMID_SET_WIRELESS_METHODID; 1044 break; 1045 case ACER_CAP_BLUETOOTH: 1046 if (value > 1) 1047 return AE_BAD_PARAMETER; 1048 method_id = ACER_WMID_SET_BLUETOOTH_METHODID; 1049 break; 1050 case ACER_CAP_THREEG: 1051 if (value > 1) 1052 return AE_BAD_PARAMETER; 1053 method_id = ACER_WMID_SET_THREEG_METHODID; 1054 break; 1055 case ACER_CAP_MAILLED: 1056 if (value > 1) 1057 return AE_BAD_PARAMETER; 1058 if (quirks->mailled == 1) { 1059 param = value ? 0x92 : 0x93; 1060 i8042_lock_chip(); 1061 i8042_command(¶m, 0x1059); 1062 i8042_unlock_chip(); 1063 return 0; 1064 } 1065 break; 1066 default: 1067 return AE_ERROR; 1068 } 1069 return WMI_execute_u32(method_id, (u32)value, NULL); 1070 } 1071 1072 static acpi_status wmid3_get_device_status(u32 *value, u16 device) 1073 { 1074 struct wmid3_gds_return_value return_value; 1075 acpi_status status; 1076 union acpi_object *obj; 1077 struct wmid3_gds_get_input_param params = { 1078 .function_num = 0x1, 1079 .hotkey_number = commun_fn_key_number, 1080 .devices = device, 1081 }; 1082 struct acpi_buffer input = { 1083 sizeof(struct wmid3_gds_get_input_param), 1084 ¶ms 1085 }; 1086 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1087 1088 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); 1089 if (ACPI_FAILURE(status)) 1090 return status; 1091 1092 obj = output.pointer; 1093 1094 if (!obj) 1095 return AE_ERROR; 1096 else if (obj->type != ACPI_TYPE_BUFFER) { 1097 kfree(obj); 1098 return AE_ERROR; 1099 } 1100 if (obj->buffer.length != 8) { 1101 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1102 kfree(obj); 1103 return AE_ERROR; 1104 } 1105 1106 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1107 kfree(obj); 1108 1109 if (return_value.error_code || return_value.ec_return_value) 1110 pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n", 1111 device, 1112 return_value.error_code, 1113 return_value.ec_return_value); 1114 else 1115 *value = !!(return_value.devices & device); 1116 1117 return status; 1118 } 1119 1120 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap) 1121 { 1122 u16 device; 1123 1124 switch (cap) { 1125 case ACER_CAP_WIRELESS: 1126 device = ACER_WMID3_GDS_WIRELESS; 1127 break; 1128 case ACER_CAP_BLUETOOTH: 1129 device = ACER_WMID3_GDS_BLUETOOTH; 1130 break; 1131 case ACER_CAP_THREEG: 1132 device = ACER_WMID3_GDS_THREEG; 1133 break; 1134 default: 1135 return AE_ERROR; 1136 } 1137 return wmid3_get_device_status(value, device); 1138 } 1139 1140 static acpi_status wmid3_set_device_status(u32 value, u16 device) 1141 { 1142 struct wmid3_gds_return_value return_value; 1143 acpi_status status; 1144 union acpi_object *obj; 1145 u16 devices; 1146 struct wmid3_gds_get_input_param get_params = { 1147 .function_num = 0x1, 1148 .hotkey_number = commun_fn_key_number, 1149 .devices = commun_func_bitmap, 1150 }; 1151 struct acpi_buffer get_input = { 1152 sizeof(struct wmid3_gds_get_input_param), 1153 &get_params 1154 }; 1155 struct wmid3_gds_set_input_param set_params = { 1156 .function_num = 0x2, 1157 .hotkey_number = commun_fn_key_number, 1158 .devices = commun_func_bitmap, 1159 }; 1160 struct acpi_buffer set_input = { 1161 sizeof(struct wmid3_gds_set_input_param), 1162 &set_params 1163 }; 1164 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1165 struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; 1166 1167 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output); 1168 if (ACPI_FAILURE(status)) 1169 return status; 1170 1171 obj = output.pointer; 1172 1173 if (!obj) 1174 return AE_ERROR; 1175 else if (obj->type != ACPI_TYPE_BUFFER) { 1176 kfree(obj); 1177 return AE_ERROR; 1178 } 1179 if (obj->buffer.length != 8) { 1180 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1181 kfree(obj); 1182 return AE_ERROR; 1183 } 1184 1185 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1186 kfree(obj); 1187 1188 if (return_value.error_code || return_value.ec_return_value) { 1189 pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n", 1190 return_value.error_code, 1191 return_value.ec_return_value); 1192 return status; 1193 } 1194 1195 devices = return_value.devices; 1196 set_params.devices = (value) ? (devices | device) : (devices & ~device); 1197 1198 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2); 1199 if (ACPI_FAILURE(status)) 1200 return status; 1201 1202 obj = output2.pointer; 1203 1204 if (!obj) 1205 return AE_ERROR; 1206 else if (obj->type != ACPI_TYPE_BUFFER) { 1207 kfree(obj); 1208 return AE_ERROR; 1209 } 1210 if (obj->buffer.length != 4) { 1211 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1212 kfree(obj); 1213 return AE_ERROR; 1214 } 1215 1216 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1217 kfree(obj); 1218 1219 if (return_value.error_code || return_value.ec_return_value) 1220 pr_warn("Set Device Status failed: 0x%x - 0x%x\n", 1221 return_value.error_code, 1222 return_value.ec_return_value); 1223 1224 return status; 1225 } 1226 1227 static acpi_status wmid_v2_set_u32(u32 value, u32 cap) 1228 { 1229 u16 device; 1230 1231 switch (cap) { 1232 case ACER_CAP_WIRELESS: 1233 device = ACER_WMID3_GDS_WIRELESS; 1234 break; 1235 case ACER_CAP_BLUETOOTH: 1236 device = ACER_WMID3_GDS_BLUETOOTH; 1237 break; 1238 case ACER_CAP_THREEG: 1239 device = ACER_WMID3_GDS_THREEG; 1240 break; 1241 default: 1242 return AE_ERROR; 1243 } 1244 return wmid3_set_device_status(value, device); 1245 } 1246 1247 static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) 1248 { 1249 struct hotkey_function_type_aa *type_aa; 1250 1251 /* We are looking for OEM-specific Type AAh */ 1252 if (header->type != 0xAA) 1253 return; 1254 1255 has_type_aa = true; 1256 type_aa = (struct hotkey_function_type_aa *) header; 1257 1258 pr_info("Function bitmap for Communication Button: 0x%x\n", 1259 type_aa->commun_func_bitmap); 1260 commun_func_bitmap = type_aa->commun_func_bitmap; 1261 1262 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS) 1263 interface->capability |= ACER_CAP_WIRELESS; 1264 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG) 1265 interface->capability |= ACER_CAP_THREEG; 1266 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) 1267 interface->capability |= ACER_CAP_BLUETOOTH; 1268 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) { 1269 interface->capability |= ACER_CAP_RFBTN; 1270 commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; 1271 } 1272 1273 commun_fn_key_number = type_aa->commun_fn_key_number; 1274 } 1275 1276 static acpi_status __init WMID_set_capabilities(void) 1277 { 1278 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1279 union acpi_object *obj; 1280 acpi_status status; 1281 u32 devices; 1282 1283 status = wmi_query_block(WMID_GUID2, 0, &out); 1284 if (ACPI_FAILURE(status)) 1285 return status; 1286 1287 obj = (union acpi_object *) out.pointer; 1288 if (obj) { 1289 if (obj->type == ACPI_TYPE_BUFFER && 1290 (obj->buffer.length == sizeof(u32) || 1291 obj->buffer.length == sizeof(u64))) { 1292 devices = *((u32 *) obj->buffer.pointer); 1293 } else if (obj->type == ACPI_TYPE_INTEGER) { 1294 devices = (u32) obj->integer.value; 1295 } else { 1296 kfree(out.pointer); 1297 return AE_ERROR; 1298 } 1299 } else { 1300 kfree(out.pointer); 1301 return AE_ERROR; 1302 } 1303 1304 pr_info("Function bitmap for Communication Device: 0x%x\n", devices); 1305 if (devices & 0x07) 1306 interface->capability |= ACER_CAP_WIRELESS; 1307 if (devices & 0x40) 1308 interface->capability |= ACER_CAP_THREEG; 1309 if (devices & 0x10) 1310 interface->capability |= ACER_CAP_BLUETOOTH; 1311 1312 if (!(devices & 0x20)) 1313 max_brightness = 0x9; 1314 1315 kfree(out.pointer); 1316 return status; 1317 } 1318 1319 static struct wmi_interface wmid_interface = { 1320 .type = ACER_WMID, 1321 }; 1322 1323 static struct wmi_interface wmid_v2_interface = { 1324 .type = ACER_WMID_v2, 1325 }; 1326 1327 /* 1328 * Generic Device (interface-independent) 1329 */ 1330 1331 static acpi_status get_u32(u32 *value, u32 cap) 1332 { 1333 acpi_status status = AE_ERROR; 1334 1335 switch (interface->type) { 1336 case ACER_AMW0: 1337 status = AMW0_get_u32(value, cap); 1338 break; 1339 case ACER_AMW0_V2: 1340 if (cap == ACER_CAP_MAILLED) { 1341 status = AMW0_get_u32(value, cap); 1342 break; 1343 } 1344 case ACER_WMID: 1345 status = WMID_get_u32(value, cap); 1346 break; 1347 case ACER_WMID_v2: 1348 if (cap & (ACER_CAP_WIRELESS | 1349 ACER_CAP_BLUETOOTH | 1350 ACER_CAP_THREEG)) 1351 status = wmid_v2_get_u32(value, cap); 1352 else if (wmi_has_guid(WMID_GUID2)) 1353 status = WMID_get_u32(value, cap); 1354 break; 1355 } 1356 1357 return status; 1358 } 1359 1360 static acpi_status set_u32(u32 value, u32 cap) 1361 { 1362 acpi_status status; 1363 1364 if (interface->capability & cap) { 1365 switch (interface->type) { 1366 case ACER_AMW0: 1367 return AMW0_set_u32(value, cap); 1368 case ACER_AMW0_V2: 1369 if (cap == ACER_CAP_MAILLED) 1370 return AMW0_set_u32(value, cap); 1371 1372 /* 1373 * On some models, some WMID methods don't toggle 1374 * properly. For those cases, we want to run the AMW0 1375 * method afterwards to be certain we've really toggled 1376 * the device state. 1377 */ 1378 if (cap == ACER_CAP_WIRELESS || 1379 cap == ACER_CAP_BLUETOOTH) { 1380 status = WMID_set_u32(value, cap); 1381 if (ACPI_FAILURE(status)) 1382 return status; 1383 1384 return AMW0_set_u32(value, cap); 1385 } 1386 case ACER_WMID: 1387 return WMID_set_u32(value, cap); 1388 case ACER_WMID_v2: 1389 if (cap & (ACER_CAP_WIRELESS | 1390 ACER_CAP_BLUETOOTH | 1391 ACER_CAP_THREEG)) 1392 return wmid_v2_set_u32(value, cap); 1393 else if (wmi_has_guid(WMID_GUID2)) 1394 return WMID_set_u32(value, cap); 1395 default: 1396 return AE_BAD_PARAMETER; 1397 } 1398 } 1399 return AE_BAD_PARAMETER; 1400 } 1401 1402 static void __init acer_commandline_init(void) 1403 { 1404 /* 1405 * These will all fail silently if the value given is invalid, or the 1406 * capability isn't available on the given interface 1407 */ 1408 if (mailled >= 0) 1409 set_u32(mailled, ACER_CAP_MAILLED); 1410 if (!has_type_aa && threeg >= 0) 1411 set_u32(threeg, ACER_CAP_THREEG); 1412 if (brightness >= 0) 1413 set_u32(brightness, ACER_CAP_BRIGHTNESS); 1414 } 1415 1416 /* 1417 * LED device (Mail LED only, no other LEDs known yet) 1418 */ 1419 static void mail_led_set(struct led_classdev *led_cdev, 1420 enum led_brightness value) 1421 { 1422 set_u32(value, ACER_CAP_MAILLED); 1423 } 1424 1425 static struct led_classdev mail_led = { 1426 .name = "acer-wmi::mail", 1427 .brightness_set = mail_led_set, 1428 }; 1429 1430 static int acer_led_init(struct device *dev) 1431 { 1432 return led_classdev_register(dev, &mail_led); 1433 } 1434 1435 static void acer_led_exit(void) 1436 { 1437 set_u32(LED_OFF, ACER_CAP_MAILLED); 1438 led_classdev_unregister(&mail_led); 1439 } 1440 1441 /* 1442 * Backlight device 1443 */ 1444 static struct backlight_device *acer_backlight_device; 1445 1446 static int read_brightness(struct backlight_device *bd) 1447 { 1448 u32 value; 1449 get_u32(&value, ACER_CAP_BRIGHTNESS); 1450 return value; 1451 } 1452 1453 static int update_bl_status(struct backlight_device *bd) 1454 { 1455 int intensity = bd->props.brightness; 1456 1457 if (bd->props.power != FB_BLANK_UNBLANK) 1458 intensity = 0; 1459 if (bd->props.fb_blank != FB_BLANK_UNBLANK) 1460 intensity = 0; 1461 1462 set_u32(intensity, ACER_CAP_BRIGHTNESS); 1463 1464 return 0; 1465 } 1466 1467 static const struct backlight_ops acer_bl_ops = { 1468 .get_brightness = read_brightness, 1469 .update_status = update_bl_status, 1470 }; 1471 1472 static int acer_backlight_init(struct device *dev) 1473 { 1474 struct backlight_properties props; 1475 struct backlight_device *bd; 1476 1477 memset(&props, 0, sizeof(struct backlight_properties)); 1478 props.type = BACKLIGHT_PLATFORM; 1479 props.max_brightness = max_brightness; 1480 bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, 1481 &props); 1482 if (IS_ERR(bd)) { 1483 pr_err("Could not register Acer backlight device\n"); 1484 acer_backlight_device = NULL; 1485 return PTR_ERR(bd); 1486 } 1487 1488 acer_backlight_device = bd; 1489 1490 bd->props.power = FB_BLANK_UNBLANK; 1491 bd->props.brightness = read_brightness(bd); 1492 backlight_update_status(bd); 1493 return 0; 1494 } 1495 1496 static void acer_backlight_exit(void) 1497 { 1498 backlight_device_unregister(acer_backlight_device); 1499 } 1500 1501 /* 1502 * Accelerometer device 1503 */ 1504 static acpi_handle gsensor_handle; 1505 1506 static int acer_gsensor_init(void) 1507 { 1508 acpi_status status; 1509 struct acpi_buffer output; 1510 union acpi_object out_obj; 1511 1512 output.length = sizeof(out_obj); 1513 output.pointer = &out_obj; 1514 status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output); 1515 if (ACPI_FAILURE(status)) 1516 return -1; 1517 1518 return 0; 1519 } 1520 1521 static int acer_gsensor_open(struct input_dev *input) 1522 { 1523 return acer_gsensor_init(); 1524 } 1525 1526 static int acer_gsensor_event(void) 1527 { 1528 acpi_status status; 1529 struct acpi_buffer output; 1530 union acpi_object out_obj[5]; 1531 1532 if (!has_cap(ACER_CAP_ACCEL)) 1533 return -1; 1534 1535 output.length = sizeof(out_obj); 1536 output.pointer = out_obj; 1537 1538 status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output); 1539 if (ACPI_FAILURE(status)) 1540 return -1; 1541 1542 if (out_obj->package.count != 4) 1543 return -1; 1544 1545 input_report_abs(acer_wmi_accel_dev, ABS_X, 1546 (s16)out_obj->package.elements[0].integer.value); 1547 input_report_abs(acer_wmi_accel_dev, ABS_Y, 1548 (s16)out_obj->package.elements[1].integer.value); 1549 input_report_abs(acer_wmi_accel_dev, ABS_Z, 1550 (s16)out_obj->package.elements[2].integer.value); 1551 input_sync(acer_wmi_accel_dev); 1552 return 0; 1553 } 1554 1555 /* 1556 * Rfkill devices 1557 */ 1558 static void acer_rfkill_update(struct work_struct *ignored); 1559 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); 1560 static void acer_rfkill_update(struct work_struct *ignored) 1561 { 1562 u32 state; 1563 acpi_status status; 1564 1565 if (has_cap(ACER_CAP_WIRELESS)) { 1566 status = get_u32(&state, ACER_CAP_WIRELESS); 1567 if (ACPI_SUCCESS(status)) { 1568 if (quirks->wireless == 3) 1569 rfkill_set_hw_state(wireless_rfkill, !state); 1570 else 1571 rfkill_set_sw_state(wireless_rfkill, !state); 1572 } 1573 } 1574 1575 if (has_cap(ACER_CAP_BLUETOOTH)) { 1576 status = get_u32(&state, ACER_CAP_BLUETOOTH); 1577 if (ACPI_SUCCESS(status)) 1578 rfkill_set_sw_state(bluetooth_rfkill, !state); 1579 } 1580 1581 if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { 1582 status = get_u32(&state, ACER_WMID3_GDS_THREEG); 1583 if (ACPI_SUCCESS(status)) 1584 rfkill_set_sw_state(threeg_rfkill, !state); 1585 } 1586 1587 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 1588 } 1589 1590 static int acer_rfkill_set(void *data, bool blocked) 1591 { 1592 acpi_status status; 1593 u32 cap = (unsigned long)data; 1594 1595 if (rfkill_inited) { 1596 status = set_u32(!blocked, cap); 1597 if (ACPI_FAILURE(status)) 1598 return -ENODEV; 1599 } 1600 1601 return 0; 1602 } 1603 1604 static const struct rfkill_ops acer_rfkill_ops = { 1605 .set_block = acer_rfkill_set, 1606 }; 1607 1608 static struct rfkill *acer_rfkill_register(struct device *dev, 1609 enum rfkill_type type, 1610 char *name, u32 cap) 1611 { 1612 int err; 1613 struct rfkill *rfkill_dev; 1614 u32 state; 1615 acpi_status status; 1616 1617 rfkill_dev = rfkill_alloc(name, dev, type, 1618 &acer_rfkill_ops, 1619 (void *)(unsigned long)cap); 1620 if (!rfkill_dev) 1621 return ERR_PTR(-ENOMEM); 1622 1623 status = get_u32(&state, cap); 1624 1625 err = rfkill_register(rfkill_dev); 1626 if (err) { 1627 rfkill_destroy(rfkill_dev); 1628 return ERR_PTR(err); 1629 } 1630 1631 if (ACPI_SUCCESS(status)) 1632 rfkill_set_sw_state(rfkill_dev, !state); 1633 1634 return rfkill_dev; 1635 } 1636 1637 static int acer_rfkill_init(struct device *dev) 1638 { 1639 int err; 1640 1641 if (has_cap(ACER_CAP_WIRELESS)) { 1642 wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, 1643 "acer-wireless", ACER_CAP_WIRELESS); 1644 if (IS_ERR(wireless_rfkill)) { 1645 err = PTR_ERR(wireless_rfkill); 1646 goto error_wireless; 1647 } 1648 } 1649 1650 if (has_cap(ACER_CAP_BLUETOOTH)) { 1651 bluetooth_rfkill = acer_rfkill_register(dev, 1652 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1653 ACER_CAP_BLUETOOTH); 1654 if (IS_ERR(bluetooth_rfkill)) { 1655 err = PTR_ERR(bluetooth_rfkill); 1656 goto error_bluetooth; 1657 } 1658 } 1659 1660 if (has_cap(ACER_CAP_THREEG)) { 1661 threeg_rfkill = acer_rfkill_register(dev, 1662 RFKILL_TYPE_WWAN, "acer-threeg", 1663 ACER_CAP_THREEG); 1664 if (IS_ERR(threeg_rfkill)) { 1665 err = PTR_ERR(threeg_rfkill); 1666 goto error_threeg; 1667 } 1668 } 1669 1670 rfkill_inited = true; 1671 1672 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 1673 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 1674 schedule_delayed_work(&acer_rfkill_work, 1675 round_jiffies_relative(HZ)); 1676 1677 return 0; 1678 1679 error_threeg: 1680 if (has_cap(ACER_CAP_BLUETOOTH)) { 1681 rfkill_unregister(bluetooth_rfkill); 1682 rfkill_destroy(bluetooth_rfkill); 1683 } 1684 error_bluetooth: 1685 if (has_cap(ACER_CAP_WIRELESS)) { 1686 rfkill_unregister(wireless_rfkill); 1687 rfkill_destroy(wireless_rfkill); 1688 } 1689 error_wireless: 1690 return err; 1691 } 1692 1693 static void acer_rfkill_exit(void) 1694 { 1695 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 1696 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 1697 cancel_delayed_work_sync(&acer_rfkill_work); 1698 1699 if (has_cap(ACER_CAP_WIRELESS)) { 1700 rfkill_unregister(wireless_rfkill); 1701 rfkill_destroy(wireless_rfkill); 1702 } 1703 1704 if (has_cap(ACER_CAP_BLUETOOTH)) { 1705 rfkill_unregister(bluetooth_rfkill); 1706 rfkill_destroy(bluetooth_rfkill); 1707 } 1708 1709 if (has_cap(ACER_CAP_THREEG)) { 1710 rfkill_unregister(threeg_rfkill); 1711 rfkill_destroy(threeg_rfkill); 1712 } 1713 return; 1714 } 1715 1716 static void acer_wmi_notify(u32 value, void *context) 1717 { 1718 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 1719 union acpi_object *obj; 1720 struct event_return_value return_value; 1721 acpi_status status; 1722 u16 device_state; 1723 const struct key_entry *key; 1724 u32 scancode; 1725 1726 status = wmi_get_event_data(value, &response); 1727 if (status != AE_OK) { 1728 pr_warn("bad event status 0x%x\n", status); 1729 return; 1730 } 1731 1732 obj = (union acpi_object *)response.pointer; 1733 1734 if (!obj) 1735 return; 1736 if (obj->type != ACPI_TYPE_BUFFER) { 1737 pr_warn("Unknown response received %d\n", obj->type); 1738 kfree(obj); 1739 return; 1740 } 1741 if (obj->buffer.length != 8) { 1742 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1743 kfree(obj); 1744 return; 1745 } 1746 1747 return_value = *((struct event_return_value *)obj->buffer.pointer); 1748 kfree(obj); 1749 1750 switch (return_value.function) { 1751 case WMID_HOTKEY_EVENT: 1752 device_state = return_value.device_state; 1753 pr_debug("device state: 0x%x\n", device_state); 1754 1755 key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev, 1756 return_value.key_num); 1757 if (!key) { 1758 pr_warn("Unknown key number - 0x%x\n", 1759 return_value.key_num); 1760 } else { 1761 scancode = return_value.key_num; 1762 switch (key->keycode) { 1763 case KEY_WLAN: 1764 case KEY_BLUETOOTH: 1765 if (has_cap(ACER_CAP_WIRELESS)) 1766 rfkill_set_sw_state(wireless_rfkill, 1767 !(device_state & ACER_WMID3_GDS_WIRELESS)); 1768 if (has_cap(ACER_CAP_THREEG)) 1769 rfkill_set_sw_state(threeg_rfkill, 1770 !(device_state & ACER_WMID3_GDS_THREEG)); 1771 if (has_cap(ACER_CAP_BLUETOOTH)) 1772 rfkill_set_sw_state(bluetooth_rfkill, 1773 !(device_state & ACER_WMID3_GDS_BLUETOOTH)); 1774 break; 1775 case KEY_TOUCHPAD_TOGGLE: 1776 scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ? 1777 KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF; 1778 } 1779 sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); 1780 } 1781 break; 1782 case WMID_ACCEL_EVENT: 1783 acer_gsensor_event(); 1784 break; 1785 default: 1786 pr_warn("Unknown function number - %d - %d\n", 1787 return_value.function, return_value.key_num); 1788 break; 1789 } 1790 } 1791 1792 static acpi_status __init 1793 wmid3_set_function_mode(struct func_input_params *params, 1794 struct func_return_value *return_value) 1795 { 1796 acpi_status status; 1797 union acpi_object *obj; 1798 1799 struct acpi_buffer input = { sizeof(struct func_input_params), params }; 1800 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1801 1802 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output); 1803 if (ACPI_FAILURE(status)) 1804 return status; 1805 1806 obj = output.pointer; 1807 1808 if (!obj) 1809 return AE_ERROR; 1810 else if (obj->type != ACPI_TYPE_BUFFER) { 1811 kfree(obj); 1812 return AE_ERROR; 1813 } 1814 if (obj->buffer.length != 4) { 1815 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1816 kfree(obj); 1817 return AE_ERROR; 1818 } 1819 1820 *return_value = *((struct func_return_value *)obj->buffer.pointer); 1821 kfree(obj); 1822 1823 return status; 1824 } 1825 1826 static int __init acer_wmi_enable_ec_raw(void) 1827 { 1828 struct func_return_value return_value; 1829 acpi_status status; 1830 struct func_input_params params = { 1831 .function_num = 0x1, 1832 .commun_devices = 0xFFFF, 1833 .devices = 0xFFFF, 1834 .app_status = 0x00, /* Launch Manager Deactive */ 1835 .app_mask = 0x01, 1836 }; 1837 1838 status = wmid3_set_function_mode(¶ms, &return_value); 1839 1840 if (return_value.error_code || return_value.ec_return_value) 1841 pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n", 1842 return_value.error_code, 1843 return_value.ec_return_value); 1844 else 1845 pr_info("Enabled EC raw mode\n"); 1846 1847 return status; 1848 } 1849 1850 static int __init acer_wmi_enable_lm(void) 1851 { 1852 struct func_return_value return_value; 1853 acpi_status status; 1854 struct func_input_params params = { 1855 .function_num = 0x1, 1856 .commun_devices = 0xFFFF, 1857 .devices = 0xFFFF, 1858 .app_status = 0x01, /* Launch Manager Active */ 1859 .app_mask = 0x01, 1860 }; 1861 1862 status = wmid3_set_function_mode(¶ms, &return_value); 1863 1864 if (return_value.error_code || return_value.ec_return_value) 1865 pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n", 1866 return_value.error_code, 1867 return_value.ec_return_value); 1868 1869 return status; 1870 } 1871 1872 static int __init acer_wmi_enable_rf_button(void) 1873 { 1874 struct func_return_value return_value; 1875 acpi_status status; 1876 struct func_input_params params = { 1877 .function_num = 0x1, 1878 .commun_devices = 0xFFFF, 1879 .devices = 0xFFFF, 1880 .app_status = 0x10, /* RF Button Active */ 1881 .app_mask = 0x10, 1882 }; 1883 1884 status = wmid3_set_function_mode(¶ms, &return_value); 1885 1886 if (return_value.error_code || return_value.ec_return_value) 1887 pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n", 1888 return_value.error_code, 1889 return_value.ec_return_value); 1890 1891 return status; 1892 } 1893 1894 #define ACER_WMID_ACCEL_HID "BST0001" 1895 1896 static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level, 1897 void *ctx, void **retval) 1898 { 1899 struct acpi_device *dev; 1900 1901 if (!strcmp(ctx, "SENR")) { 1902 if (acpi_bus_get_device(ah, &dev)) 1903 return AE_OK; 1904 if (strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev))) 1905 return AE_OK; 1906 } else 1907 return AE_OK; 1908 1909 *(acpi_handle *)retval = ah; 1910 1911 return AE_CTRL_TERMINATE; 1912 } 1913 1914 static int __init acer_wmi_get_handle(const char *name, const char *prop, 1915 acpi_handle *ah) 1916 { 1917 acpi_status status; 1918 acpi_handle handle; 1919 1920 BUG_ON(!name || !ah); 1921 1922 handle = NULL; 1923 status = acpi_get_devices(prop, acer_wmi_get_handle_cb, 1924 (void *)name, &handle); 1925 if (ACPI_SUCCESS(status) && handle) { 1926 *ah = handle; 1927 return 0; 1928 } else { 1929 return -ENODEV; 1930 } 1931 } 1932 1933 static int __init acer_wmi_accel_setup(void) 1934 { 1935 int err; 1936 1937 err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle); 1938 if (err) 1939 return err; 1940 1941 interface->capability |= ACER_CAP_ACCEL; 1942 1943 acer_wmi_accel_dev = input_allocate_device(); 1944 if (!acer_wmi_accel_dev) 1945 return -ENOMEM; 1946 1947 acer_wmi_accel_dev->open = acer_gsensor_open; 1948 1949 acer_wmi_accel_dev->name = "Acer BMA150 accelerometer"; 1950 acer_wmi_accel_dev->phys = "wmi/input1"; 1951 acer_wmi_accel_dev->id.bustype = BUS_HOST; 1952 acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS); 1953 input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0); 1954 input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0); 1955 input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0); 1956 1957 err = input_register_device(acer_wmi_accel_dev); 1958 if (err) 1959 goto err_free_dev; 1960 1961 return 0; 1962 1963 err_free_dev: 1964 input_free_device(acer_wmi_accel_dev); 1965 return err; 1966 } 1967 1968 static void acer_wmi_accel_destroy(void) 1969 { 1970 input_unregister_device(acer_wmi_accel_dev); 1971 } 1972 1973 static int __init acer_wmi_input_setup(void) 1974 { 1975 acpi_status status; 1976 int err; 1977 1978 acer_wmi_input_dev = input_allocate_device(); 1979 if (!acer_wmi_input_dev) 1980 return -ENOMEM; 1981 1982 acer_wmi_input_dev->name = "Acer WMI hotkeys"; 1983 acer_wmi_input_dev->phys = "wmi/input0"; 1984 acer_wmi_input_dev->id.bustype = BUS_HOST; 1985 1986 err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL); 1987 if (err) 1988 goto err_free_dev; 1989 1990 status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, 1991 acer_wmi_notify, NULL); 1992 if (ACPI_FAILURE(status)) { 1993 err = -EIO; 1994 goto err_free_dev; 1995 } 1996 1997 err = input_register_device(acer_wmi_input_dev); 1998 if (err) 1999 goto err_uninstall_notifier; 2000 2001 return 0; 2002 2003 err_uninstall_notifier: 2004 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 2005 err_free_dev: 2006 input_free_device(acer_wmi_input_dev); 2007 return err; 2008 } 2009 2010 static void acer_wmi_input_destroy(void) 2011 { 2012 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 2013 input_unregister_device(acer_wmi_input_dev); 2014 } 2015 2016 /* 2017 * debugfs functions 2018 */ 2019 static u32 get_wmid_devices(void) 2020 { 2021 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 2022 union acpi_object *obj; 2023 acpi_status status; 2024 u32 devices = 0; 2025 2026 status = wmi_query_block(WMID_GUID2, 0, &out); 2027 if (ACPI_FAILURE(status)) 2028 return 0; 2029 2030 obj = (union acpi_object *) out.pointer; 2031 if (obj) { 2032 if (obj->type == ACPI_TYPE_BUFFER && 2033 (obj->buffer.length == sizeof(u32) || 2034 obj->buffer.length == sizeof(u64))) { 2035 devices = *((u32 *) obj->buffer.pointer); 2036 } else if (obj->type == ACPI_TYPE_INTEGER) { 2037 devices = (u32) obj->integer.value; 2038 } 2039 } 2040 2041 kfree(out.pointer); 2042 return devices; 2043 } 2044 2045 /* 2046 * Platform device 2047 */ 2048 static int acer_platform_probe(struct platform_device *device) 2049 { 2050 int err; 2051 2052 if (has_cap(ACER_CAP_MAILLED)) { 2053 err = acer_led_init(&device->dev); 2054 if (err) 2055 goto error_mailled; 2056 } 2057 2058 if (has_cap(ACER_CAP_BRIGHTNESS)) { 2059 err = acer_backlight_init(&device->dev); 2060 if (err) 2061 goto error_brightness; 2062 } 2063 2064 err = acer_rfkill_init(&device->dev); 2065 if (err) 2066 goto error_rfkill; 2067 2068 return err; 2069 2070 error_rfkill: 2071 if (has_cap(ACER_CAP_BRIGHTNESS)) 2072 acer_backlight_exit(); 2073 error_brightness: 2074 if (has_cap(ACER_CAP_MAILLED)) 2075 acer_led_exit(); 2076 error_mailled: 2077 return err; 2078 } 2079 2080 static int acer_platform_remove(struct platform_device *device) 2081 { 2082 if (has_cap(ACER_CAP_MAILLED)) 2083 acer_led_exit(); 2084 if (has_cap(ACER_CAP_BRIGHTNESS)) 2085 acer_backlight_exit(); 2086 2087 acer_rfkill_exit(); 2088 return 0; 2089 } 2090 2091 #ifdef CONFIG_PM_SLEEP 2092 static int acer_suspend(struct device *dev) 2093 { 2094 u32 value; 2095 struct acer_data *data = &interface->data; 2096 2097 if (!data) 2098 return -ENOMEM; 2099 2100 if (has_cap(ACER_CAP_MAILLED)) { 2101 get_u32(&value, ACER_CAP_MAILLED); 2102 set_u32(LED_OFF, ACER_CAP_MAILLED); 2103 data->mailled = value; 2104 } 2105 2106 if (has_cap(ACER_CAP_BRIGHTNESS)) { 2107 get_u32(&value, ACER_CAP_BRIGHTNESS); 2108 data->brightness = value; 2109 } 2110 2111 return 0; 2112 } 2113 2114 static int acer_resume(struct device *dev) 2115 { 2116 struct acer_data *data = &interface->data; 2117 2118 if (!data) 2119 return -ENOMEM; 2120 2121 if (has_cap(ACER_CAP_MAILLED)) 2122 set_u32(data->mailled, ACER_CAP_MAILLED); 2123 2124 if (has_cap(ACER_CAP_BRIGHTNESS)) 2125 set_u32(data->brightness, ACER_CAP_BRIGHTNESS); 2126 2127 if (has_cap(ACER_CAP_ACCEL)) 2128 acer_gsensor_init(); 2129 2130 return 0; 2131 } 2132 #else 2133 #define acer_suspend NULL 2134 #define acer_resume NULL 2135 #endif 2136 2137 static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); 2138 2139 static void acer_platform_shutdown(struct platform_device *device) 2140 { 2141 struct acer_data *data = &interface->data; 2142 2143 if (!data) 2144 return; 2145 2146 if (has_cap(ACER_CAP_MAILLED)) 2147 set_u32(LED_OFF, ACER_CAP_MAILLED); 2148 } 2149 2150 static struct platform_driver acer_platform_driver = { 2151 .driver = { 2152 .name = "acer-wmi", 2153 .pm = &acer_pm, 2154 }, 2155 .probe = acer_platform_probe, 2156 .remove = acer_platform_remove, 2157 .shutdown = acer_platform_shutdown, 2158 }; 2159 2160 static struct platform_device *acer_platform_device; 2161 2162 static void remove_debugfs(void) 2163 { 2164 debugfs_remove(interface->debug.devices); 2165 debugfs_remove(interface->debug.root); 2166 } 2167 2168 static int __init create_debugfs(void) 2169 { 2170 interface->debug.root = debugfs_create_dir("acer-wmi", NULL); 2171 if (!interface->debug.root) { 2172 pr_err("Failed to create debugfs directory"); 2173 return -ENOMEM; 2174 } 2175 2176 interface->debug.devices = debugfs_create_u32("devices", S_IRUGO, 2177 interface->debug.root, 2178 &interface->debug.wmid_devices); 2179 if (!interface->debug.devices) 2180 goto error_debugfs; 2181 2182 return 0; 2183 2184 error_debugfs: 2185 remove_debugfs(); 2186 return -ENOMEM; 2187 } 2188 2189 static int __init acer_wmi_init(void) 2190 { 2191 int err; 2192 2193 pr_info("Acer Laptop ACPI-WMI Extras\n"); 2194 2195 if (dmi_check_system(acer_blacklist)) { 2196 pr_info("Blacklisted hardware detected - not loading\n"); 2197 return -ENODEV; 2198 } 2199 2200 find_quirks(); 2201 2202 /* 2203 * The AMW0_GUID1 wmi is not only found on Acer family but also other 2204 * machines like Lenovo, Fujitsu and Medion. In the past days, 2205 * acer-wmi driver handled those non-Acer machines by quirks list. 2206 * But actually acer-wmi driver was loaded on any machines that have 2207 * AMW0_GUID1. This behavior is strange because those machines should 2208 * be supported by appropriate wmi drivers. e.g. fujitsu-laptop, 2209 * ideapad-laptop. So, here checks the machine that has AMW0_GUID1 2210 * should be in Acer/Gateway/Packard Bell white list, or it's already 2211 * in the past quirk list. 2212 */ 2213 if (wmi_has_guid(AMW0_GUID1) && 2214 !dmi_check_system(amw0_whitelist) && 2215 quirks == &quirk_unknown) { 2216 pr_debug("Unsupported machine has AMW0_GUID1, unable to load\n"); 2217 return -ENODEV; 2218 } 2219 2220 /* 2221 * Detect which ACPI-WMI interface we're using. 2222 */ 2223 if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 2224 interface = &AMW0_V2_interface; 2225 2226 if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 2227 interface = &wmid_interface; 2228 2229 if (wmi_has_guid(WMID_GUID3)) 2230 interface = &wmid_v2_interface; 2231 2232 if (interface) 2233 dmi_walk(type_aa_dmi_decode, NULL); 2234 2235 if (wmi_has_guid(WMID_GUID2) && interface) { 2236 if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) { 2237 pr_err("Unable to detect available WMID devices\n"); 2238 return -ENODEV; 2239 } 2240 /* WMID always provides brightness methods */ 2241 interface->capability |= ACER_CAP_BRIGHTNESS; 2242 } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { 2243 pr_err("No WMID device detection method found\n"); 2244 return -ENODEV; 2245 } 2246 2247 if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) { 2248 interface = &AMW0_interface; 2249 2250 if (ACPI_FAILURE(AMW0_set_capabilities())) { 2251 pr_err("Unable to detect available AMW0 devices\n"); 2252 return -ENODEV; 2253 } 2254 } 2255 2256 if (wmi_has_guid(AMW0_GUID1)) 2257 AMW0_find_mailled(); 2258 2259 if (!interface) { 2260 pr_err("No or unsupported WMI interface, unable to load\n"); 2261 return -ENODEV; 2262 } 2263 2264 set_quirks(); 2265 2266 if (dmi_check_system(video_vendor_dmi_table)) 2267 acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); 2268 2269 if (acpi_video_get_backlight_type() != acpi_backlight_vendor) 2270 interface->capability &= ~ACER_CAP_BRIGHTNESS; 2271 2272 if (wmi_has_guid(WMID_GUID3)) { 2273 if (ACPI_FAILURE(acer_wmi_enable_rf_button())) 2274 pr_warn("Cannot enable RF Button Driver\n"); 2275 2276 if (ec_raw_mode) { 2277 if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) { 2278 pr_err("Cannot enable EC raw mode\n"); 2279 return -ENODEV; 2280 } 2281 } else if (ACPI_FAILURE(acer_wmi_enable_lm())) { 2282 pr_err("Cannot enable Launch Manager mode\n"); 2283 return -ENODEV; 2284 } 2285 } else if (ec_raw_mode) { 2286 pr_info("No WMID EC raw mode enable method\n"); 2287 } 2288 2289 if (wmi_has_guid(ACERWMID_EVENT_GUID)) { 2290 err = acer_wmi_input_setup(); 2291 if (err) 2292 return err; 2293 err = acer_wmi_accel_setup(); 2294 if (err && err != -ENODEV) 2295 pr_warn("Cannot enable accelerometer\n"); 2296 } 2297 2298 err = platform_driver_register(&acer_platform_driver); 2299 if (err) { 2300 pr_err("Unable to register platform driver\n"); 2301 goto error_platform_register; 2302 } 2303 2304 acer_platform_device = platform_device_alloc("acer-wmi", -1); 2305 if (!acer_platform_device) { 2306 err = -ENOMEM; 2307 goto error_device_alloc; 2308 } 2309 2310 err = platform_device_add(acer_platform_device); 2311 if (err) 2312 goto error_device_add; 2313 2314 if (wmi_has_guid(WMID_GUID2)) { 2315 interface->debug.wmid_devices = get_wmid_devices(); 2316 err = create_debugfs(); 2317 if (err) 2318 goto error_create_debugfs; 2319 } 2320 2321 /* Override any initial settings with values from the commandline */ 2322 acer_commandline_init(); 2323 2324 return 0; 2325 2326 error_create_debugfs: 2327 platform_device_del(acer_platform_device); 2328 error_device_add: 2329 platform_device_put(acer_platform_device); 2330 error_device_alloc: 2331 platform_driver_unregister(&acer_platform_driver); 2332 error_platform_register: 2333 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 2334 acer_wmi_input_destroy(); 2335 if (has_cap(ACER_CAP_ACCEL)) 2336 acer_wmi_accel_destroy(); 2337 2338 return err; 2339 } 2340 2341 static void __exit acer_wmi_exit(void) 2342 { 2343 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 2344 acer_wmi_input_destroy(); 2345 2346 if (has_cap(ACER_CAP_ACCEL)) 2347 acer_wmi_accel_destroy(); 2348 2349 remove_debugfs(); 2350 platform_device_unregister(acer_platform_device); 2351 platform_driver_unregister(&acer_platform_driver); 2352 2353 pr_info("Acer Laptop WMI Extras unloaded\n"); 2354 return; 2355 } 2356 2357 module_init(acer_wmi_init); 2358 module_exit(acer_wmi_exit); 2359