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