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 if ((interface->capability & cap) != 0) 676 return 1; 677 678 return 0; 679 } 680 681 /* 682 * AMW0 (V1) interface 683 */ 684 struct wmab_args { 685 u32 eax; 686 u32 ebx; 687 u32 ecx; 688 u32 edx; 689 }; 690 691 struct wmab_ret { 692 u32 eax; 693 u32 ebx; 694 u32 ecx; 695 u32 edx; 696 u32 eex; 697 }; 698 699 static acpi_status wmab_execute(struct wmab_args *regbuf, 700 struct acpi_buffer *result) 701 { 702 struct acpi_buffer input; 703 acpi_status status; 704 input.length = sizeof(struct wmab_args); 705 input.pointer = (u8 *)regbuf; 706 707 status = wmi_evaluate_method(AMW0_GUID1, 0, 1, &input, result); 708 709 return status; 710 } 711 712 static acpi_status AMW0_get_u32(u32 *value, u32 cap) 713 { 714 int err; 715 u8 result; 716 717 switch (cap) { 718 case ACER_CAP_MAILLED: 719 switch (quirks->mailled) { 720 default: 721 err = ec_read(0xA, &result); 722 if (err) 723 return AE_ERROR; 724 *value = (result >> 7) & 0x1; 725 return AE_OK; 726 } 727 break; 728 case ACER_CAP_WIRELESS: 729 switch (quirks->wireless) { 730 case 1: 731 err = ec_read(0x7B, &result); 732 if (err) 733 return AE_ERROR; 734 *value = result & 0x1; 735 return AE_OK; 736 case 2: 737 err = ec_read(0x71, &result); 738 if (err) 739 return AE_ERROR; 740 *value = result & 0x1; 741 return AE_OK; 742 case 3: 743 err = ec_read(0x78, &result); 744 if (err) 745 return AE_ERROR; 746 *value = result & 0x1; 747 return AE_OK; 748 default: 749 err = ec_read(0xA, &result); 750 if (err) 751 return AE_ERROR; 752 *value = (result >> 2) & 0x1; 753 return AE_OK; 754 } 755 break; 756 case ACER_CAP_BLUETOOTH: 757 switch (quirks->bluetooth) { 758 default: 759 err = ec_read(0xA, &result); 760 if (err) 761 return AE_ERROR; 762 *value = (result >> 4) & 0x1; 763 return AE_OK; 764 } 765 break; 766 case ACER_CAP_BRIGHTNESS: 767 switch (quirks->brightness) { 768 default: 769 err = ec_read(0x83, &result); 770 if (err) 771 return AE_ERROR; 772 *value = result; 773 return AE_OK; 774 } 775 break; 776 default: 777 return AE_ERROR; 778 } 779 return AE_OK; 780 } 781 782 static acpi_status AMW0_set_u32(u32 value, u32 cap) 783 { 784 struct wmab_args args; 785 786 args.eax = ACER_AMW0_WRITE; 787 args.ebx = value ? (1<<8) : 0; 788 args.ecx = args.edx = 0; 789 790 switch (cap) { 791 case ACER_CAP_MAILLED: 792 if (value > 1) 793 return AE_BAD_PARAMETER; 794 args.ebx |= ACER_AMW0_MAILLED_MASK; 795 break; 796 case ACER_CAP_WIRELESS: 797 if (value > 1) 798 return AE_BAD_PARAMETER; 799 args.ebx |= ACER_AMW0_WIRELESS_MASK; 800 break; 801 case ACER_CAP_BLUETOOTH: 802 if (value > 1) 803 return AE_BAD_PARAMETER; 804 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 805 break; 806 case ACER_CAP_BRIGHTNESS: 807 if (value > max_brightness) 808 return AE_BAD_PARAMETER; 809 switch (quirks->brightness) { 810 default: 811 return ec_write(0x83, value); 812 break; 813 } 814 default: 815 return AE_ERROR; 816 } 817 818 /* Actually do the set */ 819 return wmab_execute(&args, NULL); 820 } 821 822 static acpi_status __init AMW0_find_mailled(void) 823 { 824 struct wmab_args args; 825 struct wmab_ret ret; 826 acpi_status status = AE_OK; 827 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 828 union acpi_object *obj; 829 830 args.eax = 0x86; 831 args.ebx = args.ecx = args.edx = 0; 832 833 status = wmab_execute(&args, &out); 834 if (ACPI_FAILURE(status)) 835 return status; 836 837 obj = (union acpi_object *) out.pointer; 838 if (obj && obj->type == ACPI_TYPE_BUFFER && 839 obj->buffer.length == sizeof(struct wmab_ret)) { 840 ret = *((struct wmab_ret *) obj->buffer.pointer); 841 } else { 842 kfree(out.pointer); 843 return AE_ERROR; 844 } 845 846 if (ret.eex & 0x1) 847 interface->capability |= ACER_CAP_MAILLED; 848 849 kfree(out.pointer); 850 851 return AE_OK; 852 } 853 854 static const struct acpi_device_id norfkill_ids[] __initconst = { 855 { "VPC2004", 0}, 856 { "IBM0068", 0}, 857 { "LEN0068", 0}, 858 { "SNY5001", 0}, /* sony-laptop in charge */ 859 { "HPQ6601", 0}, 860 { "", 0}, 861 }; 862 863 static int __init AMW0_set_cap_acpi_check_device(void) 864 { 865 const struct acpi_device_id *id; 866 867 for (id = norfkill_ids; id->id[0]; id++) 868 if (acpi_dev_found(id->id)) 869 return true; 870 871 return false; 872 } 873 874 static acpi_status __init AMW0_set_capabilities(void) 875 { 876 struct wmab_args args; 877 struct wmab_ret ret; 878 acpi_status status; 879 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 880 union acpi_object *obj; 881 882 /* 883 * On laptops with this strange GUID (non Acer), normal probing doesn't 884 * work. 885 */ 886 if (wmi_has_guid(AMW0_GUID2)) { 887 if ((quirks != &quirk_unknown) || 888 !AMW0_set_cap_acpi_check_device()) 889 interface->capability |= ACER_CAP_WIRELESS; 890 return AE_OK; 891 } 892 893 args.eax = ACER_AMW0_WRITE; 894 args.ecx = args.edx = 0; 895 896 args.ebx = 0xa2 << 8; 897 args.ebx |= ACER_AMW0_WIRELESS_MASK; 898 899 status = wmab_execute(&args, &out); 900 if (ACPI_FAILURE(status)) 901 return status; 902 903 obj = out.pointer; 904 if (obj && obj->type == ACPI_TYPE_BUFFER && 905 obj->buffer.length == sizeof(struct wmab_ret)) { 906 ret = *((struct wmab_ret *) obj->buffer.pointer); 907 } else { 908 status = AE_ERROR; 909 goto out; 910 } 911 912 if (ret.eax & 0x1) 913 interface->capability |= ACER_CAP_WIRELESS; 914 915 args.ebx = 2 << 8; 916 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 917 918 /* 919 * It's ok to use existing buffer for next wmab_execute call. 920 * But we need to kfree(out.pointer) if next wmab_execute fail. 921 */ 922 status = wmab_execute(&args, &out); 923 if (ACPI_FAILURE(status)) 924 goto out; 925 926 obj = (union acpi_object *) out.pointer; 927 if (obj && obj->type == ACPI_TYPE_BUFFER 928 && obj->buffer.length == sizeof(struct wmab_ret)) { 929 ret = *((struct wmab_ret *) obj->buffer.pointer); 930 } else { 931 status = AE_ERROR; 932 goto out; 933 } 934 935 if (ret.eax & 0x1) 936 interface->capability |= ACER_CAP_BLUETOOTH; 937 938 /* 939 * This appears to be safe to enable, since all Wistron based laptops 940 * appear to use the same EC register for brightness, even if they 941 * differ for wireless, etc 942 */ 943 if (quirks->brightness >= 0) 944 interface->capability |= ACER_CAP_BRIGHTNESS; 945 946 status = AE_OK; 947 out: 948 kfree(out.pointer); 949 return status; 950 } 951 952 static struct wmi_interface AMW0_interface = { 953 .type = ACER_AMW0, 954 }; 955 956 static struct wmi_interface AMW0_V2_interface = { 957 .type = ACER_AMW0_V2, 958 }; 959 960 /* 961 * New interface (The WMID interface) 962 */ 963 static acpi_status 964 WMI_execute_u32(u32 method_id, u32 in, u32 *out) 965 { 966 struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; 967 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 968 union acpi_object *obj; 969 u32 tmp = 0; 970 acpi_status status; 971 972 status = wmi_evaluate_method(WMID_GUID1, 0, method_id, &input, &result); 973 974 if (ACPI_FAILURE(status)) 975 return status; 976 977 obj = (union acpi_object *) result.pointer; 978 if (obj) { 979 if (obj->type == ACPI_TYPE_BUFFER && 980 (obj->buffer.length == sizeof(u32) || 981 obj->buffer.length == sizeof(u64))) { 982 tmp = *((u32 *) obj->buffer.pointer); 983 } else if (obj->type == ACPI_TYPE_INTEGER) { 984 tmp = (u32) obj->integer.value; 985 } 986 } 987 988 if (out) 989 *out = tmp; 990 991 kfree(result.pointer); 992 993 return status; 994 } 995 996 static acpi_status WMID_get_u32(u32 *value, u32 cap) 997 { 998 acpi_status status; 999 u8 tmp; 1000 u32 result, method_id = 0; 1001 1002 switch (cap) { 1003 case ACER_CAP_WIRELESS: 1004 method_id = ACER_WMID_GET_WIRELESS_METHODID; 1005 break; 1006 case ACER_CAP_BLUETOOTH: 1007 method_id = ACER_WMID_GET_BLUETOOTH_METHODID; 1008 break; 1009 case ACER_CAP_BRIGHTNESS: 1010 method_id = ACER_WMID_GET_BRIGHTNESS_METHODID; 1011 break; 1012 case ACER_CAP_THREEG: 1013 method_id = ACER_WMID_GET_THREEG_METHODID; 1014 break; 1015 case ACER_CAP_MAILLED: 1016 if (quirks->mailled == 1) { 1017 ec_read(0x9f, &tmp); 1018 *value = tmp & 0x1; 1019 return 0; 1020 } 1021 default: 1022 return AE_ERROR; 1023 } 1024 status = WMI_execute_u32(method_id, 0, &result); 1025 1026 if (ACPI_SUCCESS(status)) 1027 *value = (u8)result; 1028 1029 return status; 1030 } 1031 1032 static acpi_status WMID_set_u32(u32 value, u32 cap) 1033 { 1034 u32 method_id = 0; 1035 char param; 1036 1037 switch (cap) { 1038 case ACER_CAP_BRIGHTNESS: 1039 if (value > max_brightness) 1040 return AE_BAD_PARAMETER; 1041 method_id = ACER_WMID_SET_BRIGHTNESS_METHODID; 1042 break; 1043 case ACER_CAP_WIRELESS: 1044 if (value > 1) 1045 return AE_BAD_PARAMETER; 1046 method_id = ACER_WMID_SET_WIRELESS_METHODID; 1047 break; 1048 case ACER_CAP_BLUETOOTH: 1049 if (value > 1) 1050 return AE_BAD_PARAMETER; 1051 method_id = ACER_WMID_SET_BLUETOOTH_METHODID; 1052 break; 1053 case ACER_CAP_THREEG: 1054 if (value > 1) 1055 return AE_BAD_PARAMETER; 1056 method_id = ACER_WMID_SET_THREEG_METHODID; 1057 break; 1058 case ACER_CAP_MAILLED: 1059 if (value > 1) 1060 return AE_BAD_PARAMETER; 1061 if (quirks->mailled == 1) { 1062 param = value ? 0x92 : 0x93; 1063 i8042_lock_chip(); 1064 i8042_command(¶m, 0x1059); 1065 i8042_unlock_chip(); 1066 return 0; 1067 } 1068 break; 1069 default: 1070 return AE_ERROR; 1071 } 1072 return WMI_execute_u32(method_id, (u32)value, NULL); 1073 } 1074 1075 static acpi_status wmid3_get_device_status(u32 *value, u16 device) 1076 { 1077 struct wmid3_gds_return_value return_value; 1078 acpi_status status; 1079 union acpi_object *obj; 1080 struct wmid3_gds_get_input_param params = { 1081 .function_num = 0x1, 1082 .hotkey_number = commun_fn_key_number, 1083 .devices = device, 1084 }; 1085 struct acpi_buffer input = { 1086 sizeof(struct wmid3_gds_get_input_param), 1087 ¶ms 1088 }; 1089 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1090 1091 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); 1092 if (ACPI_FAILURE(status)) 1093 return status; 1094 1095 obj = output.pointer; 1096 1097 if (!obj) 1098 return AE_ERROR; 1099 else if (obj->type != ACPI_TYPE_BUFFER) { 1100 kfree(obj); 1101 return AE_ERROR; 1102 } 1103 if (obj->buffer.length != 8) { 1104 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1105 kfree(obj); 1106 return AE_ERROR; 1107 } 1108 1109 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1110 kfree(obj); 1111 1112 if (return_value.error_code || return_value.ec_return_value) 1113 pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n", 1114 device, 1115 return_value.error_code, 1116 return_value.ec_return_value); 1117 else 1118 *value = !!(return_value.devices & device); 1119 1120 return status; 1121 } 1122 1123 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap) 1124 { 1125 u16 device; 1126 1127 switch (cap) { 1128 case ACER_CAP_WIRELESS: 1129 device = ACER_WMID3_GDS_WIRELESS; 1130 break; 1131 case ACER_CAP_BLUETOOTH: 1132 device = ACER_WMID3_GDS_BLUETOOTH; 1133 break; 1134 case ACER_CAP_THREEG: 1135 device = ACER_WMID3_GDS_THREEG; 1136 break; 1137 default: 1138 return AE_ERROR; 1139 } 1140 return wmid3_get_device_status(value, device); 1141 } 1142 1143 static acpi_status wmid3_set_device_status(u32 value, u16 device) 1144 { 1145 struct wmid3_gds_return_value return_value; 1146 acpi_status status; 1147 union acpi_object *obj; 1148 u16 devices; 1149 struct wmid3_gds_get_input_param get_params = { 1150 .function_num = 0x1, 1151 .hotkey_number = commun_fn_key_number, 1152 .devices = commun_func_bitmap, 1153 }; 1154 struct acpi_buffer get_input = { 1155 sizeof(struct wmid3_gds_get_input_param), 1156 &get_params 1157 }; 1158 struct wmid3_gds_set_input_param set_params = { 1159 .function_num = 0x2, 1160 .hotkey_number = commun_fn_key_number, 1161 .devices = commun_func_bitmap, 1162 }; 1163 struct acpi_buffer set_input = { 1164 sizeof(struct wmid3_gds_set_input_param), 1165 &set_params 1166 }; 1167 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1168 struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; 1169 1170 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &get_input, &output); 1171 if (ACPI_FAILURE(status)) 1172 return status; 1173 1174 obj = output.pointer; 1175 1176 if (!obj) 1177 return AE_ERROR; 1178 else if (obj->type != ACPI_TYPE_BUFFER) { 1179 kfree(obj); 1180 return AE_ERROR; 1181 } 1182 if (obj->buffer.length != 8) { 1183 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1184 kfree(obj); 1185 return AE_ERROR; 1186 } 1187 1188 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1189 kfree(obj); 1190 1191 if (return_value.error_code || return_value.ec_return_value) { 1192 pr_warn("Get Current Device Status failed: 0x%x - 0x%x\n", 1193 return_value.error_code, 1194 return_value.ec_return_value); 1195 return status; 1196 } 1197 1198 devices = return_value.devices; 1199 set_params.devices = (value) ? (devices | device) : (devices & ~device); 1200 1201 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &set_input, &output2); 1202 if (ACPI_FAILURE(status)) 1203 return status; 1204 1205 obj = output2.pointer; 1206 1207 if (!obj) 1208 return AE_ERROR; 1209 else if (obj->type != ACPI_TYPE_BUFFER) { 1210 kfree(obj); 1211 return AE_ERROR; 1212 } 1213 if (obj->buffer.length != 4) { 1214 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1215 kfree(obj); 1216 return AE_ERROR; 1217 } 1218 1219 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1220 kfree(obj); 1221 1222 if (return_value.error_code || return_value.ec_return_value) 1223 pr_warn("Set Device Status failed: 0x%x - 0x%x\n", 1224 return_value.error_code, 1225 return_value.ec_return_value); 1226 1227 return status; 1228 } 1229 1230 static acpi_status wmid_v2_set_u32(u32 value, u32 cap) 1231 { 1232 u16 device; 1233 1234 switch (cap) { 1235 case ACER_CAP_WIRELESS: 1236 device = ACER_WMID3_GDS_WIRELESS; 1237 break; 1238 case ACER_CAP_BLUETOOTH: 1239 device = ACER_WMID3_GDS_BLUETOOTH; 1240 break; 1241 case ACER_CAP_THREEG: 1242 device = ACER_WMID3_GDS_THREEG; 1243 break; 1244 default: 1245 return AE_ERROR; 1246 } 1247 return wmid3_set_device_status(value, device); 1248 } 1249 1250 static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) 1251 { 1252 struct hotkey_function_type_aa *type_aa; 1253 1254 /* We are looking for OEM-specific Type AAh */ 1255 if (header->type != 0xAA) 1256 return; 1257 1258 has_type_aa = true; 1259 type_aa = (struct hotkey_function_type_aa *) header; 1260 1261 pr_info("Function bitmap for Communication Button: 0x%x\n", 1262 type_aa->commun_func_bitmap); 1263 commun_func_bitmap = type_aa->commun_func_bitmap; 1264 1265 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS) 1266 interface->capability |= ACER_CAP_WIRELESS; 1267 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG) 1268 interface->capability |= ACER_CAP_THREEG; 1269 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) 1270 interface->capability |= ACER_CAP_BLUETOOTH; 1271 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) { 1272 interface->capability |= ACER_CAP_RFBTN; 1273 commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; 1274 } 1275 1276 commun_fn_key_number = type_aa->commun_fn_key_number; 1277 } 1278 1279 static acpi_status __init WMID_set_capabilities(void) 1280 { 1281 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1282 union acpi_object *obj; 1283 acpi_status status; 1284 u32 devices; 1285 1286 status = wmi_query_block(WMID_GUID2, 0, &out); 1287 if (ACPI_FAILURE(status)) 1288 return status; 1289 1290 obj = (union acpi_object *) out.pointer; 1291 if (obj) { 1292 if (obj->type == ACPI_TYPE_BUFFER && 1293 (obj->buffer.length == sizeof(u32) || 1294 obj->buffer.length == sizeof(u64))) { 1295 devices = *((u32 *) obj->buffer.pointer); 1296 } else if (obj->type == ACPI_TYPE_INTEGER) { 1297 devices = (u32) obj->integer.value; 1298 } else { 1299 kfree(out.pointer); 1300 return AE_ERROR; 1301 } 1302 } else { 1303 kfree(out.pointer); 1304 return AE_ERROR; 1305 } 1306 1307 pr_info("Function bitmap for Communication Device: 0x%x\n", devices); 1308 if (devices & 0x07) 1309 interface->capability |= ACER_CAP_WIRELESS; 1310 if (devices & 0x40) 1311 interface->capability |= ACER_CAP_THREEG; 1312 if (devices & 0x10) 1313 interface->capability |= ACER_CAP_BLUETOOTH; 1314 1315 if (!(devices & 0x20)) 1316 max_brightness = 0x9; 1317 1318 kfree(out.pointer); 1319 return status; 1320 } 1321 1322 static struct wmi_interface wmid_interface = { 1323 .type = ACER_WMID, 1324 }; 1325 1326 static struct wmi_interface wmid_v2_interface = { 1327 .type = ACER_WMID_v2, 1328 }; 1329 1330 /* 1331 * Generic Device (interface-independent) 1332 */ 1333 1334 static acpi_status get_u32(u32 *value, u32 cap) 1335 { 1336 acpi_status status = AE_ERROR; 1337 1338 switch (interface->type) { 1339 case ACER_AMW0: 1340 status = AMW0_get_u32(value, cap); 1341 break; 1342 case ACER_AMW0_V2: 1343 if (cap == ACER_CAP_MAILLED) { 1344 status = AMW0_get_u32(value, cap); 1345 break; 1346 } 1347 case ACER_WMID: 1348 status = WMID_get_u32(value, cap); 1349 break; 1350 case ACER_WMID_v2: 1351 if (cap & (ACER_CAP_WIRELESS | 1352 ACER_CAP_BLUETOOTH | 1353 ACER_CAP_THREEG)) 1354 status = wmid_v2_get_u32(value, cap); 1355 else if (wmi_has_guid(WMID_GUID2)) 1356 status = WMID_get_u32(value, cap); 1357 break; 1358 } 1359 1360 return status; 1361 } 1362 1363 static acpi_status set_u32(u32 value, u32 cap) 1364 { 1365 acpi_status status; 1366 1367 if (interface->capability & cap) { 1368 switch (interface->type) { 1369 case ACER_AMW0: 1370 return AMW0_set_u32(value, cap); 1371 case ACER_AMW0_V2: 1372 if (cap == ACER_CAP_MAILLED) 1373 return AMW0_set_u32(value, cap); 1374 1375 /* 1376 * On some models, some WMID methods don't toggle 1377 * properly. For those cases, we want to run the AMW0 1378 * method afterwards to be certain we've really toggled 1379 * the device state. 1380 */ 1381 if (cap == ACER_CAP_WIRELESS || 1382 cap == ACER_CAP_BLUETOOTH) { 1383 status = WMID_set_u32(value, cap); 1384 if (ACPI_FAILURE(status)) 1385 return status; 1386 1387 return AMW0_set_u32(value, cap); 1388 } 1389 case ACER_WMID: 1390 return WMID_set_u32(value, cap); 1391 case ACER_WMID_v2: 1392 if (cap & (ACER_CAP_WIRELESS | 1393 ACER_CAP_BLUETOOTH | 1394 ACER_CAP_THREEG)) 1395 return wmid_v2_set_u32(value, cap); 1396 else if (wmi_has_guid(WMID_GUID2)) 1397 return WMID_set_u32(value, cap); 1398 default: 1399 return AE_BAD_PARAMETER; 1400 } 1401 } 1402 return AE_BAD_PARAMETER; 1403 } 1404 1405 static void __init acer_commandline_init(void) 1406 { 1407 /* 1408 * These will all fail silently if the value given is invalid, or the 1409 * capability isn't available on the given interface 1410 */ 1411 if (mailled >= 0) 1412 set_u32(mailled, ACER_CAP_MAILLED); 1413 if (!has_type_aa && threeg >= 0) 1414 set_u32(threeg, ACER_CAP_THREEG); 1415 if (brightness >= 0) 1416 set_u32(brightness, ACER_CAP_BRIGHTNESS); 1417 } 1418 1419 /* 1420 * LED device (Mail LED only, no other LEDs known yet) 1421 */ 1422 static void mail_led_set(struct led_classdev *led_cdev, 1423 enum led_brightness value) 1424 { 1425 set_u32(value, ACER_CAP_MAILLED); 1426 } 1427 1428 static struct led_classdev mail_led = { 1429 .name = "acer-wmi::mail", 1430 .brightness_set = mail_led_set, 1431 }; 1432 1433 static int acer_led_init(struct device *dev) 1434 { 1435 return led_classdev_register(dev, &mail_led); 1436 } 1437 1438 static void acer_led_exit(void) 1439 { 1440 set_u32(LED_OFF, ACER_CAP_MAILLED); 1441 led_classdev_unregister(&mail_led); 1442 } 1443 1444 /* 1445 * Backlight device 1446 */ 1447 static struct backlight_device *acer_backlight_device; 1448 1449 static int read_brightness(struct backlight_device *bd) 1450 { 1451 u32 value; 1452 get_u32(&value, ACER_CAP_BRIGHTNESS); 1453 return value; 1454 } 1455 1456 static int update_bl_status(struct backlight_device *bd) 1457 { 1458 int intensity = bd->props.brightness; 1459 1460 if (bd->props.power != FB_BLANK_UNBLANK) 1461 intensity = 0; 1462 if (bd->props.fb_blank != FB_BLANK_UNBLANK) 1463 intensity = 0; 1464 1465 set_u32(intensity, ACER_CAP_BRIGHTNESS); 1466 1467 return 0; 1468 } 1469 1470 static const struct backlight_ops acer_bl_ops = { 1471 .get_brightness = read_brightness, 1472 .update_status = update_bl_status, 1473 }; 1474 1475 static int acer_backlight_init(struct device *dev) 1476 { 1477 struct backlight_properties props; 1478 struct backlight_device *bd; 1479 1480 memset(&props, 0, sizeof(struct backlight_properties)); 1481 props.type = BACKLIGHT_PLATFORM; 1482 props.max_brightness = max_brightness; 1483 bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, 1484 &props); 1485 if (IS_ERR(bd)) { 1486 pr_err("Could not register Acer backlight device\n"); 1487 acer_backlight_device = NULL; 1488 return PTR_ERR(bd); 1489 } 1490 1491 acer_backlight_device = bd; 1492 1493 bd->props.power = FB_BLANK_UNBLANK; 1494 bd->props.brightness = read_brightness(bd); 1495 backlight_update_status(bd); 1496 return 0; 1497 } 1498 1499 static void acer_backlight_exit(void) 1500 { 1501 backlight_device_unregister(acer_backlight_device); 1502 } 1503 1504 /* 1505 * Accelerometer device 1506 */ 1507 static acpi_handle gsensor_handle; 1508 1509 static int acer_gsensor_init(void) 1510 { 1511 acpi_status status; 1512 struct acpi_buffer output; 1513 union acpi_object out_obj; 1514 1515 output.length = sizeof(out_obj); 1516 output.pointer = &out_obj; 1517 status = acpi_evaluate_object(gsensor_handle, "_INI", NULL, &output); 1518 if (ACPI_FAILURE(status)) 1519 return -1; 1520 1521 return 0; 1522 } 1523 1524 static int acer_gsensor_open(struct input_dev *input) 1525 { 1526 return acer_gsensor_init(); 1527 } 1528 1529 static int acer_gsensor_event(void) 1530 { 1531 acpi_status status; 1532 struct acpi_buffer output; 1533 union acpi_object out_obj[5]; 1534 1535 if (!has_cap(ACER_CAP_ACCEL)) 1536 return -1; 1537 1538 output.length = sizeof(out_obj); 1539 output.pointer = out_obj; 1540 1541 status = acpi_evaluate_object(gsensor_handle, "RDVL", NULL, &output); 1542 if (ACPI_FAILURE(status)) 1543 return -1; 1544 1545 if (out_obj->package.count != 4) 1546 return -1; 1547 1548 input_report_abs(acer_wmi_accel_dev, ABS_X, 1549 (s16)out_obj->package.elements[0].integer.value); 1550 input_report_abs(acer_wmi_accel_dev, ABS_Y, 1551 (s16)out_obj->package.elements[1].integer.value); 1552 input_report_abs(acer_wmi_accel_dev, ABS_Z, 1553 (s16)out_obj->package.elements[2].integer.value); 1554 input_sync(acer_wmi_accel_dev); 1555 return 0; 1556 } 1557 1558 /* 1559 * Rfkill devices 1560 */ 1561 static void acer_rfkill_update(struct work_struct *ignored); 1562 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); 1563 static void acer_rfkill_update(struct work_struct *ignored) 1564 { 1565 u32 state; 1566 acpi_status status; 1567 1568 if (has_cap(ACER_CAP_WIRELESS)) { 1569 status = get_u32(&state, ACER_CAP_WIRELESS); 1570 if (ACPI_SUCCESS(status)) { 1571 if (quirks->wireless == 3) 1572 rfkill_set_hw_state(wireless_rfkill, !state); 1573 else 1574 rfkill_set_sw_state(wireless_rfkill, !state); 1575 } 1576 } 1577 1578 if (has_cap(ACER_CAP_BLUETOOTH)) { 1579 status = get_u32(&state, ACER_CAP_BLUETOOTH); 1580 if (ACPI_SUCCESS(status)) 1581 rfkill_set_sw_state(bluetooth_rfkill, !state); 1582 } 1583 1584 if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { 1585 status = get_u32(&state, ACER_WMID3_GDS_THREEG); 1586 if (ACPI_SUCCESS(status)) 1587 rfkill_set_sw_state(threeg_rfkill, !state); 1588 } 1589 1590 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 1591 } 1592 1593 static int acer_rfkill_set(void *data, bool blocked) 1594 { 1595 acpi_status status; 1596 u32 cap = (unsigned long)data; 1597 1598 if (rfkill_inited) { 1599 status = set_u32(!blocked, cap); 1600 if (ACPI_FAILURE(status)) 1601 return -ENODEV; 1602 } 1603 1604 return 0; 1605 } 1606 1607 static const struct rfkill_ops acer_rfkill_ops = { 1608 .set_block = acer_rfkill_set, 1609 }; 1610 1611 static struct rfkill *acer_rfkill_register(struct device *dev, 1612 enum rfkill_type type, 1613 char *name, u32 cap) 1614 { 1615 int err; 1616 struct rfkill *rfkill_dev; 1617 u32 state; 1618 acpi_status status; 1619 1620 rfkill_dev = rfkill_alloc(name, dev, type, 1621 &acer_rfkill_ops, 1622 (void *)(unsigned long)cap); 1623 if (!rfkill_dev) 1624 return ERR_PTR(-ENOMEM); 1625 1626 status = get_u32(&state, cap); 1627 1628 err = rfkill_register(rfkill_dev); 1629 if (err) { 1630 rfkill_destroy(rfkill_dev); 1631 return ERR_PTR(err); 1632 } 1633 1634 if (ACPI_SUCCESS(status)) 1635 rfkill_set_sw_state(rfkill_dev, !state); 1636 1637 return rfkill_dev; 1638 } 1639 1640 static int acer_rfkill_init(struct device *dev) 1641 { 1642 int err; 1643 1644 if (has_cap(ACER_CAP_WIRELESS)) { 1645 wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, 1646 "acer-wireless", ACER_CAP_WIRELESS); 1647 if (IS_ERR(wireless_rfkill)) { 1648 err = PTR_ERR(wireless_rfkill); 1649 goto error_wireless; 1650 } 1651 } 1652 1653 if (has_cap(ACER_CAP_BLUETOOTH)) { 1654 bluetooth_rfkill = acer_rfkill_register(dev, 1655 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1656 ACER_CAP_BLUETOOTH); 1657 if (IS_ERR(bluetooth_rfkill)) { 1658 err = PTR_ERR(bluetooth_rfkill); 1659 goto error_bluetooth; 1660 } 1661 } 1662 1663 if (has_cap(ACER_CAP_THREEG)) { 1664 threeg_rfkill = acer_rfkill_register(dev, 1665 RFKILL_TYPE_WWAN, "acer-threeg", 1666 ACER_CAP_THREEG); 1667 if (IS_ERR(threeg_rfkill)) { 1668 err = PTR_ERR(threeg_rfkill); 1669 goto error_threeg; 1670 } 1671 } 1672 1673 rfkill_inited = true; 1674 1675 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 1676 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 1677 schedule_delayed_work(&acer_rfkill_work, 1678 round_jiffies_relative(HZ)); 1679 1680 return 0; 1681 1682 error_threeg: 1683 if (has_cap(ACER_CAP_BLUETOOTH)) { 1684 rfkill_unregister(bluetooth_rfkill); 1685 rfkill_destroy(bluetooth_rfkill); 1686 } 1687 error_bluetooth: 1688 if (has_cap(ACER_CAP_WIRELESS)) { 1689 rfkill_unregister(wireless_rfkill); 1690 rfkill_destroy(wireless_rfkill); 1691 } 1692 error_wireless: 1693 return err; 1694 } 1695 1696 static void acer_rfkill_exit(void) 1697 { 1698 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 1699 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 1700 cancel_delayed_work_sync(&acer_rfkill_work); 1701 1702 if (has_cap(ACER_CAP_WIRELESS)) { 1703 rfkill_unregister(wireless_rfkill); 1704 rfkill_destroy(wireless_rfkill); 1705 } 1706 1707 if (has_cap(ACER_CAP_BLUETOOTH)) { 1708 rfkill_unregister(bluetooth_rfkill); 1709 rfkill_destroy(bluetooth_rfkill); 1710 } 1711 1712 if (has_cap(ACER_CAP_THREEG)) { 1713 rfkill_unregister(threeg_rfkill); 1714 rfkill_destroy(threeg_rfkill); 1715 } 1716 return; 1717 } 1718 1719 static void acer_wmi_notify(u32 value, void *context) 1720 { 1721 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 1722 union acpi_object *obj; 1723 struct event_return_value return_value; 1724 acpi_status status; 1725 u16 device_state; 1726 const struct key_entry *key; 1727 u32 scancode; 1728 1729 status = wmi_get_event_data(value, &response); 1730 if (status != AE_OK) { 1731 pr_warn("bad event status 0x%x\n", status); 1732 return; 1733 } 1734 1735 obj = (union acpi_object *)response.pointer; 1736 1737 if (!obj) 1738 return; 1739 if (obj->type != ACPI_TYPE_BUFFER) { 1740 pr_warn("Unknown response received %d\n", obj->type); 1741 kfree(obj); 1742 return; 1743 } 1744 if (obj->buffer.length != 8) { 1745 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1746 kfree(obj); 1747 return; 1748 } 1749 1750 return_value = *((struct event_return_value *)obj->buffer.pointer); 1751 kfree(obj); 1752 1753 switch (return_value.function) { 1754 case WMID_HOTKEY_EVENT: 1755 device_state = return_value.device_state; 1756 pr_debug("device state: 0x%x\n", device_state); 1757 1758 key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev, 1759 return_value.key_num); 1760 if (!key) { 1761 pr_warn("Unknown key number - 0x%x\n", 1762 return_value.key_num); 1763 } else { 1764 scancode = return_value.key_num; 1765 switch (key->keycode) { 1766 case KEY_WLAN: 1767 case KEY_BLUETOOTH: 1768 if (has_cap(ACER_CAP_WIRELESS)) 1769 rfkill_set_sw_state(wireless_rfkill, 1770 !(device_state & ACER_WMID3_GDS_WIRELESS)); 1771 if (has_cap(ACER_CAP_THREEG)) 1772 rfkill_set_sw_state(threeg_rfkill, 1773 !(device_state & ACER_WMID3_GDS_THREEG)); 1774 if (has_cap(ACER_CAP_BLUETOOTH)) 1775 rfkill_set_sw_state(bluetooth_rfkill, 1776 !(device_state & ACER_WMID3_GDS_BLUETOOTH)); 1777 break; 1778 case KEY_TOUCHPAD_TOGGLE: 1779 scancode = (device_state & ACER_WMID3_GDS_TOUCHPAD) ? 1780 KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF; 1781 } 1782 sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); 1783 } 1784 break; 1785 case WMID_ACCEL_EVENT: 1786 acer_gsensor_event(); 1787 break; 1788 default: 1789 pr_warn("Unknown function number - %d - %d\n", 1790 return_value.function, return_value.key_num); 1791 break; 1792 } 1793 } 1794 1795 static acpi_status __init 1796 wmid3_set_function_mode(struct func_input_params *params, 1797 struct func_return_value *return_value) 1798 { 1799 acpi_status status; 1800 union acpi_object *obj; 1801 1802 struct acpi_buffer input = { sizeof(struct func_input_params), params }; 1803 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1804 1805 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output); 1806 if (ACPI_FAILURE(status)) 1807 return status; 1808 1809 obj = output.pointer; 1810 1811 if (!obj) 1812 return AE_ERROR; 1813 else if (obj->type != ACPI_TYPE_BUFFER) { 1814 kfree(obj); 1815 return AE_ERROR; 1816 } 1817 if (obj->buffer.length != 4) { 1818 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1819 kfree(obj); 1820 return AE_ERROR; 1821 } 1822 1823 *return_value = *((struct func_return_value *)obj->buffer.pointer); 1824 kfree(obj); 1825 1826 return status; 1827 } 1828 1829 static int __init acer_wmi_enable_ec_raw(void) 1830 { 1831 struct func_return_value return_value; 1832 acpi_status status; 1833 struct func_input_params params = { 1834 .function_num = 0x1, 1835 .commun_devices = 0xFFFF, 1836 .devices = 0xFFFF, 1837 .app_status = 0x00, /* Launch Manager Deactive */ 1838 .app_mask = 0x01, 1839 }; 1840 1841 status = wmid3_set_function_mode(¶ms, &return_value); 1842 1843 if (return_value.error_code || return_value.ec_return_value) 1844 pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n", 1845 return_value.error_code, 1846 return_value.ec_return_value); 1847 else 1848 pr_info("Enabled EC raw mode\n"); 1849 1850 return status; 1851 } 1852 1853 static int __init acer_wmi_enable_lm(void) 1854 { 1855 struct func_return_value return_value; 1856 acpi_status status; 1857 struct func_input_params params = { 1858 .function_num = 0x1, 1859 .commun_devices = 0xFFFF, 1860 .devices = 0xFFFF, 1861 .app_status = 0x01, /* Launch Manager Active */ 1862 .app_mask = 0x01, 1863 }; 1864 1865 status = wmid3_set_function_mode(¶ms, &return_value); 1866 1867 if (return_value.error_code || return_value.ec_return_value) 1868 pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n", 1869 return_value.error_code, 1870 return_value.ec_return_value); 1871 1872 return status; 1873 } 1874 1875 static int __init acer_wmi_enable_rf_button(void) 1876 { 1877 struct func_return_value return_value; 1878 acpi_status status; 1879 struct func_input_params params = { 1880 .function_num = 0x1, 1881 .commun_devices = 0xFFFF, 1882 .devices = 0xFFFF, 1883 .app_status = 0x10, /* RF Button Active */ 1884 .app_mask = 0x10, 1885 }; 1886 1887 status = wmid3_set_function_mode(¶ms, &return_value); 1888 1889 if (return_value.error_code || return_value.ec_return_value) 1890 pr_warn("Enabling RF Button failed: 0x%x - 0x%x\n", 1891 return_value.error_code, 1892 return_value.ec_return_value); 1893 1894 return status; 1895 } 1896 1897 #define ACER_WMID_ACCEL_HID "BST0001" 1898 1899 static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level, 1900 void *ctx, void **retval) 1901 { 1902 struct acpi_device *dev; 1903 1904 if (!strcmp(ctx, "SENR")) { 1905 if (acpi_bus_get_device(ah, &dev)) 1906 return AE_OK; 1907 if (strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev))) 1908 return AE_OK; 1909 } else 1910 return AE_OK; 1911 1912 *(acpi_handle *)retval = ah; 1913 1914 return AE_CTRL_TERMINATE; 1915 } 1916 1917 static int __init acer_wmi_get_handle(const char *name, const char *prop, 1918 acpi_handle *ah) 1919 { 1920 acpi_status status; 1921 acpi_handle handle; 1922 1923 BUG_ON(!name || !ah); 1924 1925 handle = NULL; 1926 status = acpi_get_devices(prop, acer_wmi_get_handle_cb, 1927 (void *)name, &handle); 1928 if (ACPI_SUCCESS(status) && handle) { 1929 *ah = handle; 1930 return 0; 1931 } else { 1932 return -ENODEV; 1933 } 1934 } 1935 1936 static int __init acer_wmi_accel_setup(void) 1937 { 1938 int err; 1939 1940 err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle); 1941 if (err) 1942 return err; 1943 1944 interface->capability |= ACER_CAP_ACCEL; 1945 1946 acer_wmi_accel_dev = input_allocate_device(); 1947 if (!acer_wmi_accel_dev) 1948 return -ENOMEM; 1949 1950 acer_wmi_accel_dev->open = acer_gsensor_open; 1951 1952 acer_wmi_accel_dev->name = "Acer BMA150 accelerometer"; 1953 acer_wmi_accel_dev->phys = "wmi/input1"; 1954 acer_wmi_accel_dev->id.bustype = BUS_HOST; 1955 acer_wmi_accel_dev->evbit[0] = BIT_MASK(EV_ABS); 1956 input_set_abs_params(acer_wmi_accel_dev, ABS_X, -16384, 16384, 0, 0); 1957 input_set_abs_params(acer_wmi_accel_dev, ABS_Y, -16384, 16384, 0, 0); 1958 input_set_abs_params(acer_wmi_accel_dev, ABS_Z, -16384, 16384, 0, 0); 1959 1960 err = input_register_device(acer_wmi_accel_dev); 1961 if (err) 1962 goto err_free_dev; 1963 1964 return 0; 1965 1966 err_free_dev: 1967 input_free_device(acer_wmi_accel_dev); 1968 return err; 1969 } 1970 1971 static void acer_wmi_accel_destroy(void) 1972 { 1973 input_unregister_device(acer_wmi_accel_dev); 1974 } 1975 1976 static int __init acer_wmi_input_setup(void) 1977 { 1978 acpi_status status; 1979 int err; 1980 1981 acer_wmi_input_dev = input_allocate_device(); 1982 if (!acer_wmi_input_dev) 1983 return -ENOMEM; 1984 1985 acer_wmi_input_dev->name = "Acer WMI hotkeys"; 1986 acer_wmi_input_dev->phys = "wmi/input0"; 1987 acer_wmi_input_dev->id.bustype = BUS_HOST; 1988 1989 err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL); 1990 if (err) 1991 goto err_free_dev; 1992 1993 status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, 1994 acer_wmi_notify, NULL); 1995 if (ACPI_FAILURE(status)) { 1996 err = -EIO; 1997 goto err_free_dev; 1998 } 1999 2000 err = input_register_device(acer_wmi_input_dev); 2001 if (err) 2002 goto err_uninstall_notifier; 2003 2004 return 0; 2005 2006 err_uninstall_notifier: 2007 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 2008 err_free_dev: 2009 input_free_device(acer_wmi_input_dev); 2010 return err; 2011 } 2012 2013 static void acer_wmi_input_destroy(void) 2014 { 2015 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 2016 input_unregister_device(acer_wmi_input_dev); 2017 } 2018 2019 /* 2020 * debugfs functions 2021 */ 2022 static u32 get_wmid_devices(void) 2023 { 2024 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 2025 union acpi_object *obj; 2026 acpi_status status; 2027 u32 devices = 0; 2028 2029 status = wmi_query_block(WMID_GUID2, 0, &out); 2030 if (ACPI_FAILURE(status)) 2031 return 0; 2032 2033 obj = (union acpi_object *) out.pointer; 2034 if (obj) { 2035 if (obj->type == ACPI_TYPE_BUFFER && 2036 (obj->buffer.length == sizeof(u32) || 2037 obj->buffer.length == sizeof(u64))) { 2038 devices = *((u32 *) obj->buffer.pointer); 2039 } else if (obj->type == ACPI_TYPE_INTEGER) { 2040 devices = (u32) obj->integer.value; 2041 } 2042 } 2043 2044 kfree(out.pointer); 2045 return devices; 2046 } 2047 2048 /* 2049 * Platform device 2050 */ 2051 static int acer_platform_probe(struct platform_device *device) 2052 { 2053 int err; 2054 2055 if (has_cap(ACER_CAP_MAILLED)) { 2056 err = acer_led_init(&device->dev); 2057 if (err) 2058 goto error_mailled; 2059 } 2060 2061 if (has_cap(ACER_CAP_BRIGHTNESS)) { 2062 err = acer_backlight_init(&device->dev); 2063 if (err) 2064 goto error_brightness; 2065 } 2066 2067 err = acer_rfkill_init(&device->dev); 2068 if (err) 2069 goto error_rfkill; 2070 2071 return err; 2072 2073 error_rfkill: 2074 if (has_cap(ACER_CAP_BRIGHTNESS)) 2075 acer_backlight_exit(); 2076 error_brightness: 2077 if (has_cap(ACER_CAP_MAILLED)) 2078 acer_led_exit(); 2079 error_mailled: 2080 return err; 2081 } 2082 2083 static int acer_platform_remove(struct platform_device *device) 2084 { 2085 if (has_cap(ACER_CAP_MAILLED)) 2086 acer_led_exit(); 2087 if (has_cap(ACER_CAP_BRIGHTNESS)) 2088 acer_backlight_exit(); 2089 2090 acer_rfkill_exit(); 2091 return 0; 2092 } 2093 2094 #ifdef CONFIG_PM_SLEEP 2095 static int acer_suspend(struct device *dev) 2096 { 2097 u32 value; 2098 struct acer_data *data = &interface->data; 2099 2100 if (!data) 2101 return -ENOMEM; 2102 2103 if (has_cap(ACER_CAP_MAILLED)) { 2104 get_u32(&value, ACER_CAP_MAILLED); 2105 set_u32(LED_OFF, ACER_CAP_MAILLED); 2106 data->mailled = value; 2107 } 2108 2109 if (has_cap(ACER_CAP_BRIGHTNESS)) { 2110 get_u32(&value, ACER_CAP_BRIGHTNESS); 2111 data->brightness = value; 2112 } 2113 2114 return 0; 2115 } 2116 2117 static int acer_resume(struct device *dev) 2118 { 2119 struct acer_data *data = &interface->data; 2120 2121 if (!data) 2122 return -ENOMEM; 2123 2124 if (has_cap(ACER_CAP_MAILLED)) 2125 set_u32(data->mailled, ACER_CAP_MAILLED); 2126 2127 if (has_cap(ACER_CAP_BRIGHTNESS)) 2128 set_u32(data->brightness, ACER_CAP_BRIGHTNESS); 2129 2130 if (has_cap(ACER_CAP_ACCEL)) 2131 acer_gsensor_init(); 2132 2133 return 0; 2134 } 2135 #else 2136 #define acer_suspend NULL 2137 #define acer_resume NULL 2138 #endif 2139 2140 static SIMPLE_DEV_PM_OPS(acer_pm, acer_suspend, acer_resume); 2141 2142 static void acer_platform_shutdown(struct platform_device *device) 2143 { 2144 struct acer_data *data = &interface->data; 2145 2146 if (!data) 2147 return; 2148 2149 if (has_cap(ACER_CAP_MAILLED)) 2150 set_u32(LED_OFF, ACER_CAP_MAILLED); 2151 } 2152 2153 static struct platform_driver acer_platform_driver = { 2154 .driver = { 2155 .name = "acer-wmi", 2156 .pm = &acer_pm, 2157 }, 2158 .probe = acer_platform_probe, 2159 .remove = acer_platform_remove, 2160 .shutdown = acer_platform_shutdown, 2161 }; 2162 2163 static struct platform_device *acer_platform_device; 2164 2165 static void remove_debugfs(void) 2166 { 2167 debugfs_remove(interface->debug.devices); 2168 debugfs_remove(interface->debug.root); 2169 } 2170 2171 static int __init create_debugfs(void) 2172 { 2173 interface->debug.root = debugfs_create_dir("acer-wmi", NULL); 2174 if (!interface->debug.root) { 2175 pr_err("Failed to create debugfs directory"); 2176 return -ENOMEM; 2177 } 2178 2179 interface->debug.devices = debugfs_create_u32("devices", S_IRUGO, 2180 interface->debug.root, 2181 &interface->debug.wmid_devices); 2182 if (!interface->debug.devices) 2183 goto error_debugfs; 2184 2185 return 0; 2186 2187 error_debugfs: 2188 remove_debugfs(); 2189 return -ENOMEM; 2190 } 2191 2192 static int __init acer_wmi_init(void) 2193 { 2194 int err; 2195 2196 pr_info("Acer Laptop ACPI-WMI Extras\n"); 2197 2198 if (dmi_check_system(acer_blacklist)) { 2199 pr_info("Blacklisted hardware detected - not loading\n"); 2200 return -ENODEV; 2201 } 2202 2203 find_quirks(); 2204 2205 /* 2206 * The AMW0_GUID1 wmi is not only found on Acer family but also other 2207 * machines like Lenovo, Fujitsu and Medion. In the past days, 2208 * acer-wmi driver handled those non-Acer machines by quirks list. 2209 * But actually acer-wmi driver was loaded on any machines that have 2210 * AMW0_GUID1. This behavior is strange because those machines should 2211 * be supported by appropriate wmi drivers. e.g. fujitsu-laptop, 2212 * ideapad-laptop. So, here checks the machine that has AMW0_GUID1 2213 * should be in Acer/Gateway/Packard Bell white list, or it's already 2214 * in the past quirk list. 2215 */ 2216 if (wmi_has_guid(AMW0_GUID1) && 2217 !dmi_check_system(amw0_whitelist) && 2218 quirks == &quirk_unknown) { 2219 pr_err("Unsupported machine has AMW0_GUID1, unable to load\n"); 2220 return -ENODEV; 2221 } 2222 2223 /* 2224 * Detect which ACPI-WMI interface we're using. 2225 */ 2226 if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 2227 interface = &AMW0_V2_interface; 2228 2229 if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 2230 interface = &wmid_interface; 2231 2232 if (wmi_has_guid(WMID_GUID3)) 2233 interface = &wmid_v2_interface; 2234 2235 if (interface) 2236 dmi_walk(type_aa_dmi_decode, NULL); 2237 2238 if (wmi_has_guid(WMID_GUID2) && interface) { 2239 if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) { 2240 pr_err("Unable to detect available WMID devices\n"); 2241 return -ENODEV; 2242 } 2243 /* WMID always provides brightness methods */ 2244 interface->capability |= ACER_CAP_BRIGHTNESS; 2245 } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { 2246 pr_err("No WMID device detection method found\n"); 2247 return -ENODEV; 2248 } 2249 2250 if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) { 2251 interface = &AMW0_interface; 2252 2253 if (ACPI_FAILURE(AMW0_set_capabilities())) { 2254 pr_err("Unable to detect available AMW0 devices\n"); 2255 return -ENODEV; 2256 } 2257 } 2258 2259 if (wmi_has_guid(AMW0_GUID1)) 2260 AMW0_find_mailled(); 2261 2262 if (!interface) { 2263 pr_err("No or unsupported WMI interface, unable to load\n"); 2264 return -ENODEV; 2265 } 2266 2267 set_quirks(); 2268 2269 if (dmi_check_system(video_vendor_dmi_table)) 2270 acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); 2271 2272 if (acpi_video_get_backlight_type() != acpi_backlight_vendor) 2273 interface->capability &= ~ACER_CAP_BRIGHTNESS; 2274 2275 if (wmi_has_guid(WMID_GUID3)) { 2276 if (ACPI_FAILURE(acer_wmi_enable_rf_button())) 2277 pr_warn("Cannot enable RF Button Driver\n"); 2278 2279 if (ec_raw_mode) { 2280 if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) { 2281 pr_err("Cannot enable EC raw mode\n"); 2282 return -ENODEV; 2283 } 2284 } else if (ACPI_FAILURE(acer_wmi_enable_lm())) { 2285 pr_err("Cannot enable Launch Manager mode\n"); 2286 return -ENODEV; 2287 } 2288 } else if (ec_raw_mode) { 2289 pr_info("No WMID EC raw mode enable method\n"); 2290 } 2291 2292 if (wmi_has_guid(ACERWMID_EVENT_GUID)) { 2293 err = acer_wmi_input_setup(); 2294 if (err) 2295 return err; 2296 err = acer_wmi_accel_setup(); 2297 if (err && err != -ENODEV) 2298 pr_warn("Cannot enable accelerometer\n"); 2299 } 2300 2301 err = platform_driver_register(&acer_platform_driver); 2302 if (err) { 2303 pr_err("Unable to register platform driver\n"); 2304 goto error_platform_register; 2305 } 2306 2307 acer_platform_device = platform_device_alloc("acer-wmi", -1); 2308 if (!acer_platform_device) { 2309 err = -ENOMEM; 2310 goto error_device_alloc; 2311 } 2312 2313 err = platform_device_add(acer_platform_device); 2314 if (err) 2315 goto error_device_add; 2316 2317 if (wmi_has_guid(WMID_GUID2)) { 2318 interface->debug.wmid_devices = get_wmid_devices(); 2319 err = create_debugfs(); 2320 if (err) 2321 goto error_create_debugfs; 2322 } 2323 2324 /* Override any initial settings with values from the commandline */ 2325 acer_commandline_init(); 2326 2327 return 0; 2328 2329 error_create_debugfs: 2330 platform_device_del(acer_platform_device); 2331 error_device_add: 2332 platform_device_put(acer_platform_device); 2333 error_device_alloc: 2334 platform_driver_unregister(&acer_platform_driver); 2335 error_platform_register: 2336 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 2337 acer_wmi_input_destroy(); 2338 if (has_cap(ACER_CAP_ACCEL)) 2339 acer_wmi_accel_destroy(); 2340 2341 return err; 2342 } 2343 2344 static void __exit acer_wmi_exit(void) 2345 { 2346 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 2347 acer_wmi_input_destroy(); 2348 2349 if (has_cap(ACER_CAP_ACCEL)) 2350 acer_wmi_accel_destroy(); 2351 2352 remove_debugfs(); 2353 platform_device_unregister(acer_platform_device); 2354 platform_driver_unregister(&acer_platform_driver); 2355 2356 pr_info("Acer Laptop WMI Extras unloaded\n"); 2357 return; 2358 } 2359 2360 module_init(acer_wmi_init); 2361 module_exit(acer_wmi_exit); 2362