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 45 #include <acpi/acpi_drivers.h> 46 47 MODULE_AUTHOR("Carlos Corbacho"); 48 MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); 49 MODULE_LICENSE("GPL"); 50 51 /* 52 * Magic Number 53 * Meaning is unknown - this number is required for writing to ACPI for AMW0 54 * (it's also used in acerhk when directly accessing the BIOS) 55 */ 56 #define ACER_AMW0_WRITE 0x9610 57 58 /* 59 * Bit masks for the AMW0 interface 60 */ 61 #define ACER_AMW0_WIRELESS_MASK 0x35 62 #define ACER_AMW0_BLUETOOTH_MASK 0x34 63 #define ACER_AMW0_MAILLED_MASK 0x31 64 65 /* 66 * Method IDs for WMID interface 67 */ 68 #define ACER_WMID_GET_WIRELESS_METHODID 1 69 #define ACER_WMID_GET_BLUETOOTH_METHODID 2 70 #define ACER_WMID_GET_BRIGHTNESS_METHODID 3 71 #define ACER_WMID_SET_WIRELESS_METHODID 4 72 #define ACER_WMID_SET_BLUETOOTH_METHODID 5 73 #define ACER_WMID_SET_BRIGHTNESS_METHODID 6 74 #define ACER_WMID_GET_THREEG_METHODID 10 75 #define ACER_WMID_SET_THREEG_METHODID 11 76 77 /* 78 * Acer ACPI method GUIDs 79 */ 80 #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" 81 #define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C" 82 #define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3" 83 #define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A" 84 #define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531" 85 86 /* 87 * Acer ACPI event GUIDs 88 */ 89 #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" 90 91 MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); 92 MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"); 93 MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); 94 95 enum acer_wmi_event_ids { 96 WMID_HOTKEY_EVENT = 0x1, 97 }; 98 99 static const struct key_entry acer_wmi_keymap[] = { 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_IGNORE, 0x41, {KEY_MUTE} }, 109 {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, 110 {KE_IGNORE, 0x43, {KEY_NEXTSONG} }, 111 {KE_IGNORE, 0x44, {KEY_PLAYPAUSE} }, 112 {KE_IGNORE, 0x45, {KEY_STOP} }, 113 {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, 114 {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, 115 {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} }, 116 {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, 117 {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, 118 {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ 119 {KE_IGNORE, 0x81, {KEY_SLEEP} }, 120 {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */ 121 {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, 122 {KE_END, 0} 123 }; 124 125 static struct input_dev *acer_wmi_input_dev; 126 127 struct event_return_value { 128 u8 function; 129 u8 key_num; 130 u16 device_state; 131 u32 reserved; 132 } __attribute__((packed)); 133 134 /* 135 * GUID3 Get Device Status device flags 136 */ 137 #define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */ 138 #define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */ 139 #define ACER_WMID3_GDS_WIMAX (1<<7) /* WiMAX */ 140 #define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */ 141 142 struct lm_input_params { 143 u8 function_num; /* Function Number */ 144 u16 commun_devices; /* Communication type devices default status */ 145 u16 devices; /* Other type devices default status */ 146 u8 lm_status; /* Launch Manager Status */ 147 u16 reserved; 148 } __attribute__((packed)); 149 150 struct lm_return_value { 151 u8 error_code; /* Error Code */ 152 u8 ec_return_value; /* EC Return Value */ 153 u16 reserved; 154 } __attribute__((packed)); 155 156 struct wmid3_gds_input_param { /* Get Device Status input parameter */ 157 u8 function_num; /* Function Number */ 158 u8 hotkey_number; /* Hotkey Number */ 159 u16 devices; /* Get Device */ 160 } __attribute__((packed)); 161 162 struct wmid3_gds_return_value { /* Get Device Status return value*/ 163 u8 error_code; /* Error Code */ 164 u8 ec_return_value; /* EC Return Value */ 165 u16 devices; /* Current Device Status */ 166 u32 reserved; 167 } __attribute__((packed)); 168 169 struct hotkey_function_type_aa { 170 u8 type; 171 u8 length; 172 u16 handle; 173 u16 commun_func_bitmap; 174 } __attribute__((packed)); 175 176 /* 177 * Interface capability flags 178 */ 179 #define ACER_CAP_MAILLED (1<<0) 180 #define ACER_CAP_WIRELESS (1<<1) 181 #define ACER_CAP_BLUETOOTH (1<<2) 182 #define ACER_CAP_BRIGHTNESS (1<<3) 183 #define ACER_CAP_THREEG (1<<4) 184 #define ACER_CAP_ANY (0xFFFFFFFF) 185 186 /* 187 * Interface type flags 188 */ 189 enum interface_flags { 190 ACER_AMW0, 191 ACER_AMW0_V2, 192 ACER_WMID, 193 ACER_WMID_v2, 194 }; 195 196 #define ACER_DEFAULT_WIRELESS 0 197 #define ACER_DEFAULT_BLUETOOTH 0 198 #define ACER_DEFAULT_MAILLED 0 199 #define ACER_DEFAULT_THREEG 0 200 201 static int max_brightness = 0xF; 202 203 static int mailled = -1; 204 static int brightness = -1; 205 static int threeg = -1; 206 static int force_series; 207 static bool ec_raw_mode; 208 static bool has_type_aa; 209 static u16 commun_func_bitmap; 210 211 module_param(mailled, int, 0444); 212 module_param(brightness, int, 0444); 213 module_param(threeg, int, 0444); 214 module_param(force_series, int, 0444); 215 module_param(ec_raw_mode, bool, 0444); 216 MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); 217 MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); 218 MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); 219 MODULE_PARM_DESC(force_series, "Force a different laptop series"); 220 MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); 221 222 struct acer_data { 223 int mailled; 224 int threeg; 225 int brightness; 226 }; 227 228 struct acer_debug { 229 struct dentry *root; 230 struct dentry *devices; 231 u32 wmid_devices; 232 }; 233 234 static struct rfkill *wireless_rfkill; 235 static struct rfkill *bluetooth_rfkill; 236 static struct rfkill *threeg_rfkill; 237 static bool rfkill_inited; 238 239 /* Each low-level interface must define at least some of the following */ 240 struct wmi_interface { 241 /* The WMI device type */ 242 u32 type; 243 244 /* The capabilities this interface provides */ 245 u32 capability; 246 247 /* Private data for the current interface */ 248 struct acer_data data; 249 250 /* debugfs entries associated with this interface */ 251 struct acer_debug debug; 252 }; 253 254 /* The static interface pointer, points to the currently detected interface */ 255 static struct wmi_interface *interface; 256 257 /* 258 * Embedded Controller quirks 259 * Some laptops require us to directly access the EC to either enable or query 260 * features that are not available through WMI. 261 */ 262 263 struct quirk_entry { 264 u8 wireless; 265 u8 mailled; 266 s8 brightness; 267 u8 bluetooth; 268 }; 269 270 static struct quirk_entry *quirks; 271 272 static void set_quirks(void) 273 { 274 if (!interface) 275 return; 276 277 if (quirks->mailled) 278 interface->capability |= ACER_CAP_MAILLED; 279 280 if (quirks->brightness) 281 interface->capability |= ACER_CAP_BRIGHTNESS; 282 } 283 284 static int dmi_matched(const struct dmi_system_id *dmi) 285 { 286 quirks = dmi->driver_data; 287 return 1; 288 } 289 290 static struct quirk_entry quirk_unknown = { 291 }; 292 293 static struct quirk_entry quirk_acer_aspire_1520 = { 294 .brightness = -1, 295 }; 296 297 static struct quirk_entry quirk_acer_travelmate_2490 = { 298 .mailled = 1, 299 }; 300 301 /* This AMW0 laptop has no bluetooth */ 302 static struct quirk_entry quirk_medion_md_98300 = { 303 .wireless = 1, 304 }; 305 306 static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { 307 .wireless = 2, 308 }; 309 310 static struct quirk_entry quirk_lenovo_ideapad_s205 = { 311 .wireless = 3, 312 }; 313 314 /* The Aspire One has a dummy ACPI-WMI interface - disable it */ 315 static struct dmi_system_id __devinitdata acer_blacklist[] = { 316 { 317 .ident = "Acer Aspire One (SSD)", 318 .matches = { 319 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 320 DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), 321 }, 322 }, 323 { 324 .ident = "Acer Aspire One (HDD)", 325 .matches = { 326 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 327 DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), 328 }, 329 }, 330 {} 331 }; 332 333 static struct dmi_system_id acer_quirks[] = { 334 { 335 .callback = dmi_matched, 336 .ident = "Acer Aspire 1360", 337 .matches = { 338 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 339 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), 340 }, 341 .driver_data = &quirk_acer_aspire_1520, 342 }, 343 { 344 .callback = dmi_matched, 345 .ident = "Acer Aspire 1520", 346 .matches = { 347 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 348 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"), 349 }, 350 .driver_data = &quirk_acer_aspire_1520, 351 }, 352 { 353 .callback = dmi_matched, 354 .ident = "Acer Aspire 3100", 355 .matches = { 356 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 357 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"), 358 }, 359 .driver_data = &quirk_acer_travelmate_2490, 360 }, 361 { 362 .callback = dmi_matched, 363 .ident = "Acer Aspire 3610", 364 .matches = { 365 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 366 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"), 367 }, 368 .driver_data = &quirk_acer_travelmate_2490, 369 }, 370 { 371 .callback = dmi_matched, 372 .ident = "Acer Aspire 5100", 373 .matches = { 374 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 375 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), 376 }, 377 .driver_data = &quirk_acer_travelmate_2490, 378 }, 379 { 380 .callback = dmi_matched, 381 .ident = "Acer Aspire 5610", 382 .matches = { 383 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 384 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), 385 }, 386 .driver_data = &quirk_acer_travelmate_2490, 387 }, 388 { 389 .callback = dmi_matched, 390 .ident = "Acer Aspire 5630", 391 .matches = { 392 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 393 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), 394 }, 395 .driver_data = &quirk_acer_travelmate_2490, 396 }, 397 { 398 .callback = dmi_matched, 399 .ident = "Acer Aspire 5650", 400 .matches = { 401 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 402 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), 403 }, 404 .driver_data = &quirk_acer_travelmate_2490, 405 }, 406 { 407 .callback = dmi_matched, 408 .ident = "Acer Aspire 5680", 409 .matches = { 410 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 411 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), 412 }, 413 .driver_data = &quirk_acer_travelmate_2490, 414 }, 415 { 416 .callback = dmi_matched, 417 .ident = "Acer Aspire 9110", 418 .matches = { 419 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 420 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), 421 }, 422 .driver_data = &quirk_acer_travelmate_2490, 423 }, 424 { 425 .callback = dmi_matched, 426 .ident = "Acer TravelMate 2490", 427 .matches = { 428 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 429 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), 430 }, 431 .driver_data = &quirk_acer_travelmate_2490, 432 }, 433 { 434 .callback = dmi_matched, 435 .ident = "Acer TravelMate 4200", 436 .matches = { 437 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 438 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4200"), 439 }, 440 .driver_data = &quirk_acer_travelmate_2490, 441 }, 442 { 443 .callback = dmi_matched, 444 .ident = "Fujitsu Siemens Amilo Li 1718", 445 .matches = { 446 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), 447 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"), 448 }, 449 .driver_data = &quirk_fujitsu_amilo_li_1718, 450 }, 451 { 452 .callback = dmi_matched, 453 .ident = "Medion MD 98300", 454 .matches = { 455 DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), 456 DMI_MATCH(DMI_PRODUCT_NAME, "WAM2030"), 457 }, 458 .driver_data = &quirk_medion_md_98300, 459 }, 460 { 461 .callback = dmi_matched, 462 .ident = "Lenovo Ideapad S205", 463 .matches = { 464 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 465 DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"), 466 }, 467 .driver_data = &quirk_lenovo_ideapad_s205, 468 }, 469 { 470 .callback = dmi_matched, 471 .ident = "Lenovo 3000 N200", 472 .matches = { 473 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 474 DMI_MATCH(DMI_PRODUCT_NAME, "0687A31"), 475 }, 476 .driver_data = &quirk_fujitsu_amilo_li_1718, 477 }, 478 {} 479 }; 480 481 /* Find which quirks are needed for a particular vendor/ model pair */ 482 static void find_quirks(void) 483 { 484 if (!force_series) { 485 dmi_check_system(acer_quirks); 486 } else if (force_series == 2490) { 487 quirks = &quirk_acer_travelmate_2490; 488 } 489 490 if (quirks == NULL) 491 quirks = &quirk_unknown; 492 493 set_quirks(); 494 } 495 496 /* 497 * General interface convenience methods 498 */ 499 500 static bool has_cap(u32 cap) 501 { 502 if ((interface->capability & cap) != 0) 503 return 1; 504 505 return 0; 506 } 507 508 /* 509 * AMW0 (V1) interface 510 */ 511 struct wmab_args { 512 u32 eax; 513 u32 ebx; 514 u32 ecx; 515 u32 edx; 516 }; 517 518 struct wmab_ret { 519 u32 eax; 520 u32 ebx; 521 u32 ecx; 522 u32 edx; 523 u32 eex; 524 }; 525 526 static acpi_status wmab_execute(struct wmab_args *regbuf, 527 struct acpi_buffer *result) 528 { 529 struct acpi_buffer input; 530 acpi_status status; 531 input.length = sizeof(struct wmab_args); 532 input.pointer = (u8 *)regbuf; 533 534 status = wmi_evaluate_method(AMW0_GUID1, 1, 1, &input, result); 535 536 return status; 537 } 538 539 static acpi_status AMW0_get_u32(u32 *value, u32 cap, 540 struct wmi_interface *iface) 541 { 542 int err; 543 u8 result; 544 545 switch (cap) { 546 case ACER_CAP_MAILLED: 547 switch (quirks->mailled) { 548 default: 549 err = ec_read(0xA, &result); 550 if (err) 551 return AE_ERROR; 552 *value = (result >> 7) & 0x1; 553 return AE_OK; 554 } 555 break; 556 case ACER_CAP_WIRELESS: 557 switch (quirks->wireless) { 558 case 1: 559 err = ec_read(0x7B, &result); 560 if (err) 561 return AE_ERROR; 562 *value = result & 0x1; 563 return AE_OK; 564 case 2: 565 err = ec_read(0x71, &result); 566 if (err) 567 return AE_ERROR; 568 *value = result & 0x1; 569 return AE_OK; 570 case 3: 571 err = ec_read(0x78, &result); 572 if (err) 573 return AE_ERROR; 574 *value = result & 0x1; 575 return AE_OK; 576 default: 577 err = ec_read(0xA, &result); 578 if (err) 579 return AE_ERROR; 580 *value = (result >> 2) & 0x1; 581 return AE_OK; 582 } 583 break; 584 case ACER_CAP_BLUETOOTH: 585 switch (quirks->bluetooth) { 586 default: 587 err = ec_read(0xA, &result); 588 if (err) 589 return AE_ERROR; 590 *value = (result >> 4) & 0x1; 591 return AE_OK; 592 } 593 break; 594 case ACER_CAP_BRIGHTNESS: 595 switch (quirks->brightness) { 596 default: 597 err = ec_read(0x83, &result); 598 if (err) 599 return AE_ERROR; 600 *value = result; 601 return AE_OK; 602 } 603 break; 604 default: 605 return AE_ERROR; 606 } 607 return AE_OK; 608 } 609 610 static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface) 611 { 612 struct wmab_args args; 613 614 args.eax = ACER_AMW0_WRITE; 615 args.ebx = value ? (1<<8) : 0; 616 args.ecx = args.edx = 0; 617 618 switch (cap) { 619 case ACER_CAP_MAILLED: 620 if (value > 1) 621 return AE_BAD_PARAMETER; 622 args.ebx |= ACER_AMW0_MAILLED_MASK; 623 break; 624 case ACER_CAP_WIRELESS: 625 if (value > 1) 626 return AE_BAD_PARAMETER; 627 args.ebx |= ACER_AMW0_WIRELESS_MASK; 628 break; 629 case ACER_CAP_BLUETOOTH: 630 if (value > 1) 631 return AE_BAD_PARAMETER; 632 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 633 break; 634 case ACER_CAP_BRIGHTNESS: 635 if (value > max_brightness) 636 return AE_BAD_PARAMETER; 637 switch (quirks->brightness) { 638 default: 639 return ec_write(0x83, value); 640 break; 641 } 642 default: 643 return AE_ERROR; 644 } 645 646 /* Actually do the set */ 647 return wmab_execute(&args, NULL); 648 } 649 650 static acpi_status AMW0_find_mailled(void) 651 { 652 struct wmab_args args; 653 struct wmab_ret ret; 654 acpi_status status = AE_OK; 655 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 656 union acpi_object *obj; 657 658 args.eax = 0x86; 659 args.ebx = args.ecx = args.edx = 0; 660 661 status = wmab_execute(&args, &out); 662 if (ACPI_FAILURE(status)) 663 return status; 664 665 obj = (union acpi_object *) out.pointer; 666 if (obj && obj->type == ACPI_TYPE_BUFFER && 667 obj->buffer.length == sizeof(struct wmab_ret)) { 668 ret = *((struct wmab_ret *) obj->buffer.pointer); 669 } else { 670 kfree(out.pointer); 671 return AE_ERROR; 672 } 673 674 if (ret.eex & 0x1) 675 interface->capability |= ACER_CAP_MAILLED; 676 677 kfree(out.pointer); 678 679 return AE_OK; 680 } 681 682 static acpi_status AMW0_set_capabilities(void) 683 { 684 struct wmab_args args; 685 struct wmab_ret ret; 686 acpi_status status; 687 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 688 union acpi_object *obj; 689 690 /* 691 * On laptops with this strange GUID (non Acer), normal probing doesn't 692 * work. 693 */ 694 if (wmi_has_guid(AMW0_GUID2)) { 695 interface->capability |= ACER_CAP_WIRELESS; 696 return AE_OK; 697 } 698 699 args.eax = ACER_AMW0_WRITE; 700 args.ecx = args.edx = 0; 701 702 args.ebx = 0xa2 << 8; 703 args.ebx |= ACER_AMW0_WIRELESS_MASK; 704 705 status = wmab_execute(&args, &out); 706 if (ACPI_FAILURE(status)) 707 return status; 708 709 obj = out.pointer; 710 if (obj && obj->type == ACPI_TYPE_BUFFER && 711 obj->buffer.length == sizeof(struct wmab_ret)) { 712 ret = *((struct wmab_ret *) obj->buffer.pointer); 713 } else { 714 status = AE_ERROR; 715 goto out; 716 } 717 718 if (ret.eax & 0x1) 719 interface->capability |= ACER_CAP_WIRELESS; 720 721 args.ebx = 2 << 8; 722 args.ebx |= ACER_AMW0_BLUETOOTH_MASK; 723 724 /* 725 * It's ok to use existing buffer for next wmab_execute call. 726 * But we need to kfree(out.pointer) if next wmab_execute fail. 727 */ 728 status = wmab_execute(&args, &out); 729 if (ACPI_FAILURE(status)) 730 goto out; 731 732 obj = (union acpi_object *) out.pointer; 733 if (obj && obj->type == ACPI_TYPE_BUFFER 734 && obj->buffer.length == sizeof(struct wmab_ret)) { 735 ret = *((struct wmab_ret *) obj->buffer.pointer); 736 } else { 737 status = AE_ERROR; 738 goto out; 739 } 740 741 if (ret.eax & 0x1) 742 interface->capability |= ACER_CAP_BLUETOOTH; 743 744 /* 745 * This appears to be safe to enable, since all Wistron based laptops 746 * appear to use the same EC register for brightness, even if they 747 * differ for wireless, etc 748 */ 749 if (quirks->brightness >= 0) 750 interface->capability |= ACER_CAP_BRIGHTNESS; 751 752 status = AE_OK; 753 out: 754 kfree(out.pointer); 755 return status; 756 } 757 758 static struct wmi_interface AMW0_interface = { 759 .type = ACER_AMW0, 760 }; 761 762 static struct wmi_interface AMW0_V2_interface = { 763 .type = ACER_AMW0_V2, 764 }; 765 766 /* 767 * New interface (The WMID interface) 768 */ 769 static acpi_status 770 WMI_execute_u32(u32 method_id, u32 in, u32 *out) 771 { 772 struct acpi_buffer input = { (acpi_size) sizeof(u32), (void *)(&in) }; 773 struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL }; 774 union acpi_object *obj; 775 u32 tmp; 776 acpi_status status; 777 778 status = wmi_evaluate_method(WMID_GUID1, 1, method_id, &input, &result); 779 780 if (ACPI_FAILURE(status)) 781 return status; 782 783 obj = (union acpi_object *) result.pointer; 784 if (obj && obj->type == ACPI_TYPE_BUFFER && 785 (obj->buffer.length == sizeof(u32) || 786 obj->buffer.length == sizeof(u64))) { 787 tmp = *((u32 *) obj->buffer.pointer); 788 } else if (obj->type == ACPI_TYPE_INTEGER) { 789 tmp = (u32) obj->integer.value; 790 } else { 791 tmp = 0; 792 } 793 794 if (out) 795 *out = tmp; 796 797 kfree(result.pointer); 798 799 return status; 800 } 801 802 static acpi_status WMID_get_u32(u32 *value, u32 cap, 803 struct wmi_interface *iface) 804 { 805 acpi_status status; 806 u8 tmp; 807 u32 result, method_id = 0; 808 809 switch (cap) { 810 case ACER_CAP_WIRELESS: 811 method_id = ACER_WMID_GET_WIRELESS_METHODID; 812 break; 813 case ACER_CAP_BLUETOOTH: 814 method_id = ACER_WMID_GET_BLUETOOTH_METHODID; 815 break; 816 case ACER_CAP_BRIGHTNESS: 817 method_id = ACER_WMID_GET_BRIGHTNESS_METHODID; 818 break; 819 case ACER_CAP_THREEG: 820 method_id = ACER_WMID_GET_THREEG_METHODID; 821 break; 822 case ACER_CAP_MAILLED: 823 if (quirks->mailled == 1) { 824 ec_read(0x9f, &tmp); 825 *value = tmp & 0x1; 826 return 0; 827 } 828 default: 829 return AE_ERROR; 830 } 831 status = WMI_execute_u32(method_id, 0, &result); 832 833 if (ACPI_SUCCESS(status)) 834 *value = (u8)result; 835 836 return status; 837 } 838 839 static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) 840 { 841 u32 method_id = 0; 842 char param; 843 844 switch (cap) { 845 case ACER_CAP_BRIGHTNESS: 846 if (value > max_brightness) 847 return AE_BAD_PARAMETER; 848 method_id = ACER_WMID_SET_BRIGHTNESS_METHODID; 849 break; 850 case ACER_CAP_WIRELESS: 851 if (value > 1) 852 return AE_BAD_PARAMETER; 853 method_id = ACER_WMID_SET_WIRELESS_METHODID; 854 break; 855 case ACER_CAP_BLUETOOTH: 856 if (value > 1) 857 return AE_BAD_PARAMETER; 858 method_id = ACER_WMID_SET_BLUETOOTH_METHODID; 859 break; 860 case ACER_CAP_THREEG: 861 if (value > 1) 862 return AE_BAD_PARAMETER; 863 method_id = ACER_WMID_SET_THREEG_METHODID; 864 break; 865 case ACER_CAP_MAILLED: 866 if (value > 1) 867 return AE_BAD_PARAMETER; 868 if (quirks->mailled == 1) { 869 param = value ? 0x92 : 0x93; 870 i8042_lock_chip(); 871 i8042_command(¶m, 0x1059); 872 i8042_unlock_chip(); 873 return 0; 874 } 875 break; 876 default: 877 return AE_ERROR; 878 } 879 return WMI_execute_u32(method_id, (u32)value, NULL); 880 } 881 882 static acpi_status wmid3_get_device_status(u32 *value, u16 device) 883 { 884 struct wmid3_gds_return_value return_value; 885 acpi_status status; 886 union acpi_object *obj; 887 struct wmid3_gds_input_param params = { 888 .function_num = 0x1, 889 .hotkey_number = 0x01, 890 .devices = device, 891 }; 892 struct acpi_buffer input = { 893 sizeof(struct wmid3_gds_input_param), 894 ¶ms 895 }; 896 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 897 898 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); 899 if (ACPI_FAILURE(status)) 900 return status; 901 902 obj = output.pointer; 903 904 if (!obj) 905 return AE_ERROR; 906 else if (obj->type != ACPI_TYPE_BUFFER) { 907 kfree(obj); 908 return AE_ERROR; 909 } 910 if (obj->buffer.length != 8) { 911 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 912 kfree(obj); 913 return AE_ERROR; 914 } 915 916 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 917 kfree(obj); 918 919 if (return_value.error_code || return_value.ec_return_value) 920 pr_warn("Get 0x%x Device Status failed: 0x%x - 0x%x\n", 921 device, 922 return_value.error_code, 923 return_value.ec_return_value); 924 else 925 *value = !!(return_value.devices & device); 926 927 return status; 928 } 929 930 static acpi_status wmid_v2_get_u32(u32 *value, u32 cap) 931 { 932 u16 device; 933 934 switch (cap) { 935 case ACER_CAP_WIRELESS: 936 device = ACER_WMID3_GDS_WIRELESS; 937 break; 938 case ACER_CAP_BLUETOOTH: 939 device = ACER_WMID3_GDS_BLUETOOTH; 940 break; 941 case ACER_CAP_THREEG: 942 device = ACER_WMID3_GDS_THREEG; 943 break; 944 default: 945 return AE_ERROR; 946 } 947 return wmid3_get_device_status(value, device); 948 } 949 950 static acpi_status wmid3_set_device_status(u32 value, u16 device) 951 { 952 struct wmid3_gds_return_value return_value; 953 acpi_status status; 954 union acpi_object *obj; 955 u16 devices; 956 struct wmid3_gds_input_param params = { 957 .function_num = 0x1, 958 .hotkey_number = 0x01, 959 .devices = commun_func_bitmap, 960 }; 961 struct acpi_buffer input = { 962 sizeof(struct wmid3_gds_input_param), 963 ¶ms 964 }; 965 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 966 struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL }; 967 968 status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output); 969 if (ACPI_FAILURE(status)) 970 return status; 971 972 obj = output.pointer; 973 974 if (!obj) 975 return AE_ERROR; 976 else if (obj->type != ACPI_TYPE_BUFFER) { 977 kfree(obj); 978 return AE_ERROR; 979 } 980 if (obj->buffer.length != 8) { 981 pr_warning("Unknown buffer length %d\n", obj->buffer.length); 982 kfree(obj); 983 return AE_ERROR; 984 } 985 986 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 987 kfree(obj); 988 989 if (return_value.error_code || return_value.ec_return_value) { 990 pr_warning("Get Current Device Status failed: " 991 "0x%x - 0x%x\n", return_value.error_code, 992 return_value.ec_return_value); 993 return status; 994 } 995 996 devices = return_value.devices; 997 params.function_num = 0x2; 998 params.hotkey_number = 0x01; 999 params.devices = (value) ? (devices | device) : (devices & ~device); 1000 1001 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2); 1002 if (ACPI_FAILURE(status)) 1003 return status; 1004 1005 obj = output2.pointer; 1006 1007 if (!obj) 1008 return AE_ERROR; 1009 else if (obj->type != ACPI_TYPE_BUFFER) { 1010 kfree(obj); 1011 return AE_ERROR; 1012 } 1013 if (obj->buffer.length != 4) { 1014 pr_warning("Unknown buffer length %d\n", obj->buffer.length); 1015 kfree(obj); 1016 return AE_ERROR; 1017 } 1018 1019 return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer); 1020 kfree(obj); 1021 1022 if (return_value.error_code || return_value.ec_return_value) 1023 pr_warning("Set Device Status failed: " 1024 "0x%x - 0x%x\n", return_value.error_code, 1025 return_value.ec_return_value); 1026 1027 return status; 1028 } 1029 1030 static acpi_status wmid_v2_set_u32(u32 value, u32 cap) 1031 { 1032 u16 device; 1033 1034 switch (cap) { 1035 case ACER_CAP_WIRELESS: 1036 device = ACER_WMID3_GDS_WIRELESS; 1037 break; 1038 case ACER_CAP_BLUETOOTH: 1039 device = ACER_WMID3_GDS_BLUETOOTH; 1040 break; 1041 case ACER_CAP_THREEG: 1042 device = ACER_WMID3_GDS_THREEG; 1043 break; 1044 default: 1045 return AE_ERROR; 1046 } 1047 return wmid3_set_device_status(value, device); 1048 } 1049 1050 static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy) 1051 { 1052 struct hotkey_function_type_aa *type_aa; 1053 1054 /* We are looking for OEM-specific Type AAh */ 1055 if (header->type != 0xAA) 1056 return; 1057 1058 has_type_aa = true; 1059 type_aa = (struct hotkey_function_type_aa *) header; 1060 1061 pr_info("Function bitmap for Communication Button: 0x%x\n", 1062 type_aa->commun_func_bitmap); 1063 commun_func_bitmap = type_aa->commun_func_bitmap; 1064 1065 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS) 1066 interface->capability |= ACER_CAP_WIRELESS; 1067 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG) 1068 interface->capability |= ACER_CAP_THREEG; 1069 if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) 1070 interface->capability |= ACER_CAP_BLUETOOTH; 1071 } 1072 1073 static acpi_status WMID_set_capabilities(void) 1074 { 1075 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1076 union acpi_object *obj; 1077 acpi_status status; 1078 u32 devices; 1079 1080 status = wmi_query_block(WMID_GUID2, 1, &out); 1081 if (ACPI_FAILURE(status)) 1082 return status; 1083 1084 obj = (union acpi_object *) out.pointer; 1085 if (obj && obj->type == ACPI_TYPE_BUFFER && 1086 (obj->buffer.length == sizeof(u32) || 1087 obj->buffer.length == sizeof(u64))) { 1088 devices = *((u32 *) obj->buffer.pointer); 1089 } else if (obj->type == ACPI_TYPE_INTEGER) { 1090 devices = (u32) obj->integer.value; 1091 } else { 1092 kfree(out.pointer); 1093 return AE_ERROR; 1094 } 1095 1096 pr_info("Function bitmap for Communication Device: 0x%x\n", devices); 1097 if (devices & 0x07) 1098 interface->capability |= ACER_CAP_WIRELESS; 1099 if (devices & 0x40) 1100 interface->capability |= ACER_CAP_THREEG; 1101 if (devices & 0x10) 1102 interface->capability |= ACER_CAP_BLUETOOTH; 1103 1104 if (!(devices & 0x20)) 1105 max_brightness = 0x9; 1106 1107 kfree(out.pointer); 1108 return status; 1109 } 1110 1111 static struct wmi_interface wmid_interface = { 1112 .type = ACER_WMID, 1113 }; 1114 1115 static struct wmi_interface wmid_v2_interface = { 1116 .type = ACER_WMID_v2, 1117 }; 1118 1119 /* 1120 * Generic Device (interface-independent) 1121 */ 1122 1123 static acpi_status get_u32(u32 *value, u32 cap) 1124 { 1125 acpi_status status = AE_ERROR; 1126 1127 switch (interface->type) { 1128 case ACER_AMW0: 1129 status = AMW0_get_u32(value, cap, interface); 1130 break; 1131 case ACER_AMW0_V2: 1132 if (cap == ACER_CAP_MAILLED) { 1133 status = AMW0_get_u32(value, cap, interface); 1134 break; 1135 } 1136 case ACER_WMID: 1137 status = WMID_get_u32(value, cap, interface); 1138 break; 1139 case ACER_WMID_v2: 1140 if (cap & (ACER_CAP_WIRELESS | 1141 ACER_CAP_BLUETOOTH | 1142 ACER_CAP_THREEG)) 1143 status = wmid_v2_get_u32(value, cap); 1144 else if (wmi_has_guid(WMID_GUID2)) 1145 status = WMID_get_u32(value, cap, interface); 1146 break; 1147 } 1148 1149 return status; 1150 } 1151 1152 static acpi_status set_u32(u32 value, u32 cap) 1153 { 1154 acpi_status status; 1155 1156 if (interface->capability & cap) { 1157 switch (interface->type) { 1158 case ACER_AMW0: 1159 return AMW0_set_u32(value, cap, interface); 1160 case ACER_AMW0_V2: 1161 if (cap == ACER_CAP_MAILLED) 1162 return AMW0_set_u32(value, cap, interface); 1163 1164 /* 1165 * On some models, some WMID methods don't toggle 1166 * properly. For those cases, we want to run the AMW0 1167 * method afterwards to be certain we've really toggled 1168 * the device state. 1169 */ 1170 if (cap == ACER_CAP_WIRELESS || 1171 cap == ACER_CAP_BLUETOOTH) { 1172 status = WMID_set_u32(value, cap, interface); 1173 if (ACPI_FAILURE(status)) 1174 return status; 1175 1176 return AMW0_set_u32(value, cap, interface); 1177 } 1178 case ACER_WMID: 1179 return WMID_set_u32(value, cap, interface); 1180 case ACER_WMID_v2: 1181 if (cap & (ACER_CAP_WIRELESS | 1182 ACER_CAP_BLUETOOTH | 1183 ACER_CAP_THREEG)) 1184 return wmid_v2_set_u32(value, cap); 1185 else if (wmi_has_guid(WMID_GUID2)) 1186 return WMID_set_u32(value, cap, interface); 1187 default: 1188 return AE_BAD_PARAMETER; 1189 } 1190 } 1191 return AE_BAD_PARAMETER; 1192 } 1193 1194 static void __init acer_commandline_init(void) 1195 { 1196 /* 1197 * These will all fail silently if the value given is invalid, or the 1198 * capability isn't available on the given interface 1199 */ 1200 if (mailled >= 0) 1201 set_u32(mailled, ACER_CAP_MAILLED); 1202 if (!has_type_aa && threeg >= 0) 1203 set_u32(threeg, ACER_CAP_THREEG); 1204 if (brightness >= 0) 1205 set_u32(brightness, ACER_CAP_BRIGHTNESS); 1206 } 1207 1208 /* 1209 * LED device (Mail LED only, no other LEDs known yet) 1210 */ 1211 static void mail_led_set(struct led_classdev *led_cdev, 1212 enum led_brightness value) 1213 { 1214 set_u32(value, ACER_CAP_MAILLED); 1215 } 1216 1217 static struct led_classdev mail_led = { 1218 .name = "acer-wmi::mail", 1219 .brightness_set = mail_led_set, 1220 }; 1221 1222 static int __devinit acer_led_init(struct device *dev) 1223 { 1224 return led_classdev_register(dev, &mail_led); 1225 } 1226 1227 static void acer_led_exit(void) 1228 { 1229 set_u32(LED_OFF, ACER_CAP_MAILLED); 1230 led_classdev_unregister(&mail_led); 1231 } 1232 1233 /* 1234 * Backlight device 1235 */ 1236 static struct backlight_device *acer_backlight_device; 1237 1238 static int read_brightness(struct backlight_device *bd) 1239 { 1240 u32 value; 1241 get_u32(&value, ACER_CAP_BRIGHTNESS); 1242 return value; 1243 } 1244 1245 static int update_bl_status(struct backlight_device *bd) 1246 { 1247 int intensity = bd->props.brightness; 1248 1249 if (bd->props.power != FB_BLANK_UNBLANK) 1250 intensity = 0; 1251 if (bd->props.fb_blank != FB_BLANK_UNBLANK) 1252 intensity = 0; 1253 1254 set_u32(intensity, ACER_CAP_BRIGHTNESS); 1255 1256 return 0; 1257 } 1258 1259 static const struct backlight_ops acer_bl_ops = { 1260 .get_brightness = read_brightness, 1261 .update_status = update_bl_status, 1262 }; 1263 1264 static int __devinit acer_backlight_init(struct device *dev) 1265 { 1266 struct backlight_properties props; 1267 struct backlight_device *bd; 1268 1269 memset(&props, 0, sizeof(struct backlight_properties)); 1270 props.type = BACKLIGHT_PLATFORM; 1271 props.max_brightness = max_brightness; 1272 bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops, 1273 &props); 1274 if (IS_ERR(bd)) { 1275 pr_err("Could not register Acer backlight device\n"); 1276 acer_backlight_device = NULL; 1277 return PTR_ERR(bd); 1278 } 1279 1280 acer_backlight_device = bd; 1281 1282 bd->props.power = FB_BLANK_UNBLANK; 1283 bd->props.brightness = read_brightness(bd); 1284 backlight_update_status(bd); 1285 return 0; 1286 } 1287 1288 static void acer_backlight_exit(void) 1289 { 1290 backlight_device_unregister(acer_backlight_device); 1291 } 1292 1293 /* 1294 * Rfkill devices 1295 */ 1296 static void acer_rfkill_update(struct work_struct *ignored); 1297 static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); 1298 static void acer_rfkill_update(struct work_struct *ignored) 1299 { 1300 u32 state; 1301 acpi_status status; 1302 1303 if (has_cap(ACER_CAP_WIRELESS)) { 1304 status = get_u32(&state, ACER_CAP_WIRELESS); 1305 if (ACPI_SUCCESS(status)) { 1306 if (quirks->wireless == 3) 1307 rfkill_set_hw_state(wireless_rfkill, !state); 1308 else 1309 rfkill_set_sw_state(wireless_rfkill, !state); 1310 } 1311 } 1312 1313 if (has_cap(ACER_CAP_BLUETOOTH)) { 1314 status = get_u32(&state, ACER_CAP_BLUETOOTH); 1315 if (ACPI_SUCCESS(status)) 1316 rfkill_set_sw_state(bluetooth_rfkill, !state); 1317 } 1318 1319 if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) { 1320 status = get_u32(&state, ACER_WMID3_GDS_THREEG); 1321 if (ACPI_SUCCESS(status)) 1322 rfkill_set_sw_state(threeg_rfkill, !state); 1323 } 1324 1325 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 1326 } 1327 1328 static int acer_rfkill_set(void *data, bool blocked) 1329 { 1330 acpi_status status; 1331 u32 cap = (unsigned long)data; 1332 1333 if (rfkill_inited) { 1334 status = set_u32(!blocked, cap); 1335 if (ACPI_FAILURE(status)) 1336 return -ENODEV; 1337 } 1338 1339 return 0; 1340 } 1341 1342 static const struct rfkill_ops acer_rfkill_ops = { 1343 .set_block = acer_rfkill_set, 1344 }; 1345 1346 static struct rfkill *acer_rfkill_register(struct device *dev, 1347 enum rfkill_type type, 1348 char *name, u32 cap) 1349 { 1350 int err; 1351 struct rfkill *rfkill_dev; 1352 u32 state; 1353 acpi_status status; 1354 1355 rfkill_dev = rfkill_alloc(name, dev, type, 1356 &acer_rfkill_ops, 1357 (void *)(unsigned long)cap); 1358 if (!rfkill_dev) 1359 return ERR_PTR(-ENOMEM); 1360 1361 status = get_u32(&state, cap); 1362 1363 err = rfkill_register(rfkill_dev); 1364 if (err) { 1365 rfkill_destroy(rfkill_dev); 1366 return ERR_PTR(err); 1367 } 1368 1369 if (ACPI_SUCCESS(status)) 1370 rfkill_set_sw_state(rfkill_dev, !state); 1371 1372 return rfkill_dev; 1373 } 1374 1375 static int acer_rfkill_init(struct device *dev) 1376 { 1377 int err; 1378 1379 if (has_cap(ACER_CAP_WIRELESS)) { 1380 wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, 1381 "acer-wireless", ACER_CAP_WIRELESS); 1382 if (IS_ERR(wireless_rfkill)) { 1383 err = PTR_ERR(wireless_rfkill); 1384 goto error_wireless; 1385 } 1386 } 1387 1388 if (has_cap(ACER_CAP_BLUETOOTH)) { 1389 bluetooth_rfkill = acer_rfkill_register(dev, 1390 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1391 ACER_CAP_BLUETOOTH); 1392 if (IS_ERR(bluetooth_rfkill)) { 1393 err = PTR_ERR(bluetooth_rfkill); 1394 goto error_bluetooth; 1395 } 1396 } 1397 1398 if (has_cap(ACER_CAP_THREEG)) { 1399 threeg_rfkill = acer_rfkill_register(dev, 1400 RFKILL_TYPE_WWAN, "acer-threeg", 1401 ACER_CAP_THREEG); 1402 if (IS_ERR(threeg_rfkill)) { 1403 err = PTR_ERR(threeg_rfkill); 1404 goto error_threeg; 1405 } 1406 } 1407 1408 rfkill_inited = true; 1409 1410 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 1411 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 1412 schedule_delayed_work(&acer_rfkill_work, 1413 round_jiffies_relative(HZ)); 1414 1415 return 0; 1416 1417 error_threeg: 1418 if (has_cap(ACER_CAP_BLUETOOTH)) { 1419 rfkill_unregister(bluetooth_rfkill); 1420 rfkill_destroy(bluetooth_rfkill); 1421 } 1422 error_bluetooth: 1423 if (has_cap(ACER_CAP_WIRELESS)) { 1424 rfkill_unregister(wireless_rfkill); 1425 rfkill_destroy(wireless_rfkill); 1426 } 1427 error_wireless: 1428 return err; 1429 } 1430 1431 static void acer_rfkill_exit(void) 1432 { 1433 if ((ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID)) && 1434 has_cap(ACER_CAP_WIRELESS | ACER_CAP_BLUETOOTH | ACER_CAP_THREEG)) 1435 cancel_delayed_work_sync(&acer_rfkill_work); 1436 1437 if (has_cap(ACER_CAP_WIRELESS)) { 1438 rfkill_unregister(wireless_rfkill); 1439 rfkill_destroy(wireless_rfkill); 1440 } 1441 1442 if (has_cap(ACER_CAP_BLUETOOTH)) { 1443 rfkill_unregister(bluetooth_rfkill); 1444 rfkill_destroy(bluetooth_rfkill); 1445 } 1446 1447 if (has_cap(ACER_CAP_THREEG)) { 1448 rfkill_unregister(threeg_rfkill); 1449 rfkill_destroy(threeg_rfkill); 1450 } 1451 return; 1452 } 1453 1454 /* 1455 * sysfs interface 1456 */ 1457 static ssize_t show_bool_threeg(struct device *dev, 1458 struct device_attribute *attr, char *buf) 1459 { 1460 u32 result; \ 1461 acpi_status status; 1462 1463 pr_info("This threeg sysfs will be removed in 2012" 1464 " - used by: %s\n", current->comm); 1465 status = get_u32(&result, ACER_CAP_THREEG); 1466 if (ACPI_SUCCESS(status)) 1467 return sprintf(buf, "%u\n", result); 1468 return sprintf(buf, "Read error\n"); 1469 } 1470 1471 static ssize_t set_bool_threeg(struct device *dev, 1472 struct device_attribute *attr, const char *buf, size_t count) 1473 { 1474 u32 tmp = simple_strtoul(buf, NULL, 10); 1475 acpi_status status = set_u32(tmp, ACER_CAP_THREEG); 1476 pr_info("This threeg sysfs will be removed in 2012" 1477 " - used by: %s\n", current->comm); 1478 if (ACPI_FAILURE(status)) 1479 return -EINVAL; 1480 return count; 1481 } 1482 static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg, 1483 set_bool_threeg); 1484 1485 static ssize_t show_interface(struct device *dev, struct device_attribute *attr, 1486 char *buf) 1487 { 1488 pr_info("This interface sysfs will be removed in 2012" 1489 " - used by: %s\n", current->comm); 1490 switch (interface->type) { 1491 case ACER_AMW0: 1492 return sprintf(buf, "AMW0\n"); 1493 case ACER_AMW0_V2: 1494 return sprintf(buf, "AMW0 v2\n"); 1495 case ACER_WMID: 1496 return sprintf(buf, "WMID\n"); 1497 case ACER_WMID_v2: 1498 return sprintf(buf, "WMID v2\n"); 1499 default: 1500 return sprintf(buf, "Error!\n"); 1501 } 1502 } 1503 1504 static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL); 1505 1506 static void acer_wmi_notify(u32 value, void *context) 1507 { 1508 struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; 1509 union acpi_object *obj; 1510 struct event_return_value return_value; 1511 acpi_status status; 1512 u16 device_state; 1513 const struct key_entry *key; 1514 1515 status = wmi_get_event_data(value, &response); 1516 if (status != AE_OK) { 1517 pr_warn("bad event status 0x%x\n", status); 1518 return; 1519 } 1520 1521 obj = (union acpi_object *)response.pointer; 1522 1523 if (!obj) 1524 return; 1525 if (obj->type != ACPI_TYPE_BUFFER) { 1526 pr_warn("Unknown response received %d\n", obj->type); 1527 kfree(obj); 1528 return; 1529 } 1530 if (obj->buffer.length != 8) { 1531 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1532 kfree(obj); 1533 return; 1534 } 1535 1536 return_value = *((struct event_return_value *)obj->buffer.pointer); 1537 kfree(obj); 1538 1539 switch (return_value.function) { 1540 case WMID_HOTKEY_EVENT: 1541 device_state = return_value.device_state; 1542 pr_debug("device state: 0x%x\n", device_state); 1543 1544 key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev, 1545 return_value.key_num); 1546 if (!key) { 1547 pr_warn("Unknown key number - 0x%x\n", 1548 return_value.key_num); 1549 } else { 1550 switch (key->keycode) { 1551 case KEY_WLAN: 1552 case KEY_BLUETOOTH: 1553 if (has_cap(ACER_CAP_WIRELESS)) 1554 rfkill_set_sw_state(wireless_rfkill, 1555 !(device_state & ACER_WMID3_GDS_WIRELESS)); 1556 if (has_cap(ACER_CAP_THREEG)) 1557 rfkill_set_sw_state(threeg_rfkill, 1558 !(device_state & ACER_WMID3_GDS_THREEG)); 1559 if (has_cap(ACER_CAP_BLUETOOTH)) 1560 rfkill_set_sw_state(bluetooth_rfkill, 1561 !(device_state & ACER_WMID3_GDS_BLUETOOTH)); 1562 break; 1563 } 1564 sparse_keymap_report_entry(acer_wmi_input_dev, key, 1565 1, true); 1566 } 1567 break; 1568 default: 1569 pr_warn("Unknown function number - %d - %d\n", 1570 return_value.function, return_value.key_num); 1571 break; 1572 } 1573 } 1574 1575 static acpi_status 1576 wmid3_set_lm_mode(struct lm_input_params *params, 1577 struct lm_return_value *return_value) 1578 { 1579 acpi_status status; 1580 union acpi_object *obj; 1581 1582 struct acpi_buffer input = { sizeof(struct lm_input_params), params }; 1583 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 1584 1585 status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output); 1586 if (ACPI_FAILURE(status)) 1587 return status; 1588 1589 obj = output.pointer; 1590 1591 if (!obj) 1592 return AE_ERROR; 1593 else if (obj->type != ACPI_TYPE_BUFFER) { 1594 kfree(obj); 1595 return AE_ERROR; 1596 } 1597 if (obj->buffer.length != 4) { 1598 pr_warn("Unknown buffer length %d\n", obj->buffer.length); 1599 kfree(obj); 1600 return AE_ERROR; 1601 } 1602 1603 *return_value = *((struct lm_return_value *)obj->buffer.pointer); 1604 kfree(obj); 1605 1606 return status; 1607 } 1608 1609 static int acer_wmi_enable_ec_raw(void) 1610 { 1611 struct lm_return_value return_value; 1612 acpi_status status; 1613 struct lm_input_params params = { 1614 .function_num = 0x1, 1615 .commun_devices = 0xFFFF, 1616 .devices = 0xFFFF, 1617 .lm_status = 0x00, /* Launch Manager Deactive */ 1618 }; 1619 1620 status = wmid3_set_lm_mode(¶ms, &return_value); 1621 1622 if (return_value.error_code || return_value.ec_return_value) 1623 pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n", 1624 return_value.error_code, 1625 return_value.ec_return_value); 1626 else 1627 pr_info("Enabled EC raw mode\n"); 1628 1629 return status; 1630 } 1631 1632 static int acer_wmi_enable_lm(void) 1633 { 1634 struct lm_return_value return_value; 1635 acpi_status status; 1636 struct lm_input_params params = { 1637 .function_num = 0x1, 1638 .commun_devices = 0xFFFF, 1639 .devices = 0xFFFF, 1640 .lm_status = 0x01, /* Launch Manager Active */ 1641 }; 1642 1643 status = wmid3_set_lm_mode(¶ms, &return_value); 1644 1645 if (return_value.error_code || return_value.ec_return_value) 1646 pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n", 1647 return_value.error_code, 1648 return_value.ec_return_value); 1649 1650 return status; 1651 } 1652 1653 static int __init acer_wmi_input_setup(void) 1654 { 1655 acpi_status status; 1656 int err; 1657 1658 acer_wmi_input_dev = input_allocate_device(); 1659 if (!acer_wmi_input_dev) 1660 return -ENOMEM; 1661 1662 acer_wmi_input_dev->name = "Acer WMI hotkeys"; 1663 acer_wmi_input_dev->phys = "wmi/input0"; 1664 acer_wmi_input_dev->id.bustype = BUS_HOST; 1665 1666 err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL); 1667 if (err) 1668 goto err_free_dev; 1669 1670 status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, 1671 acer_wmi_notify, NULL); 1672 if (ACPI_FAILURE(status)) { 1673 err = -EIO; 1674 goto err_free_keymap; 1675 } 1676 1677 err = input_register_device(acer_wmi_input_dev); 1678 if (err) 1679 goto err_uninstall_notifier; 1680 1681 return 0; 1682 1683 err_uninstall_notifier: 1684 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 1685 err_free_keymap: 1686 sparse_keymap_free(acer_wmi_input_dev); 1687 err_free_dev: 1688 input_free_device(acer_wmi_input_dev); 1689 return err; 1690 } 1691 1692 static void acer_wmi_input_destroy(void) 1693 { 1694 wmi_remove_notify_handler(ACERWMID_EVENT_GUID); 1695 sparse_keymap_free(acer_wmi_input_dev); 1696 input_unregister_device(acer_wmi_input_dev); 1697 } 1698 1699 /* 1700 * debugfs functions 1701 */ 1702 static u32 get_wmid_devices(void) 1703 { 1704 struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL}; 1705 union acpi_object *obj; 1706 acpi_status status; 1707 u32 devices = 0; 1708 1709 status = wmi_query_block(WMID_GUID2, 1, &out); 1710 if (ACPI_FAILURE(status)) 1711 return 0; 1712 1713 obj = (union acpi_object *) out.pointer; 1714 if (obj && obj->type == ACPI_TYPE_BUFFER && 1715 (obj->buffer.length == sizeof(u32) || 1716 obj->buffer.length == sizeof(u64))) { 1717 devices = *((u32 *) obj->buffer.pointer); 1718 } else if (obj->type == ACPI_TYPE_INTEGER) { 1719 devices = (u32) obj->integer.value; 1720 } 1721 1722 kfree(out.pointer); 1723 return devices; 1724 } 1725 1726 /* 1727 * Platform device 1728 */ 1729 static int __devinit acer_platform_probe(struct platform_device *device) 1730 { 1731 int err; 1732 1733 if (has_cap(ACER_CAP_MAILLED)) { 1734 err = acer_led_init(&device->dev); 1735 if (err) 1736 goto error_mailled; 1737 } 1738 1739 if (has_cap(ACER_CAP_BRIGHTNESS)) { 1740 err = acer_backlight_init(&device->dev); 1741 if (err) 1742 goto error_brightness; 1743 } 1744 1745 err = acer_rfkill_init(&device->dev); 1746 if (err) 1747 goto error_rfkill; 1748 1749 return err; 1750 1751 error_rfkill: 1752 if (has_cap(ACER_CAP_BRIGHTNESS)) 1753 acer_backlight_exit(); 1754 error_brightness: 1755 if (has_cap(ACER_CAP_MAILLED)) 1756 acer_led_exit(); 1757 error_mailled: 1758 return err; 1759 } 1760 1761 static int acer_platform_remove(struct platform_device *device) 1762 { 1763 if (has_cap(ACER_CAP_MAILLED)) 1764 acer_led_exit(); 1765 if (has_cap(ACER_CAP_BRIGHTNESS)) 1766 acer_backlight_exit(); 1767 1768 acer_rfkill_exit(); 1769 return 0; 1770 } 1771 1772 static int acer_platform_suspend(struct platform_device *dev, 1773 pm_message_t state) 1774 { 1775 u32 value; 1776 struct acer_data *data = &interface->data; 1777 1778 if (!data) 1779 return -ENOMEM; 1780 1781 if (has_cap(ACER_CAP_MAILLED)) { 1782 get_u32(&value, ACER_CAP_MAILLED); 1783 set_u32(LED_OFF, ACER_CAP_MAILLED); 1784 data->mailled = value; 1785 } 1786 1787 if (has_cap(ACER_CAP_BRIGHTNESS)) { 1788 get_u32(&value, ACER_CAP_BRIGHTNESS); 1789 data->brightness = value; 1790 } 1791 1792 return 0; 1793 } 1794 1795 static int acer_platform_resume(struct platform_device *device) 1796 { 1797 struct acer_data *data = &interface->data; 1798 1799 if (!data) 1800 return -ENOMEM; 1801 1802 if (has_cap(ACER_CAP_MAILLED)) 1803 set_u32(data->mailled, ACER_CAP_MAILLED); 1804 1805 if (has_cap(ACER_CAP_BRIGHTNESS)) 1806 set_u32(data->brightness, ACER_CAP_BRIGHTNESS); 1807 1808 return 0; 1809 } 1810 1811 static void acer_platform_shutdown(struct platform_device *device) 1812 { 1813 struct acer_data *data = &interface->data; 1814 1815 if (!data) 1816 return; 1817 1818 if (has_cap(ACER_CAP_MAILLED)) 1819 set_u32(LED_OFF, ACER_CAP_MAILLED); 1820 } 1821 1822 static struct platform_driver acer_platform_driver = { 1823 .driver = { 1824 .name = "acer-wmi", 1825 .owner = THIS_MODULE, 1826 }, 1827 .probe = acer_platform_probe, 1828 .remove = acer_platform_remove, 1829 .suspend = acer_platform_suspend, 1830 .resume = acer_platform_resume, 1831 .shutdown = acer_platform_shutdown, 1832 }; 1833 1834 static struct platform_device *acer_platform_device; 1835 1836 static int remove_sysfs(struct platform_device *device) 1837 { 1838 if (has_cap(ACER_CAP_THREEG)) 1839 device_remove_file(&device->dev, &dev_attr_threeg); 1840 1841 device_remove_file(&device->dev, &dev_attr_interface); 1842 1843 return 0; 1844 } 1845 1846 static int create_sysfs(void) 1847 { 1848 int retval = -ENOMEM; 1849 1850 if (has_cap(ACER_CAP_THREEG)) { 1851 retval = device_create_file(&acer_platform_device->dev, 1852 &dev_attr_threeg); 1853 if (retval) 1854 goto error_sysfs; 1855 } 1856 1857 retval = device_create_file(&acer_platform_device->dev, 1858 &dev_attr_interface); 1859 if (retval) 1860 goto error_sysfs; 1861 1862 return 0; 1863 1864 error_sysfs: 1865 remove_sysfs(acer_platform_device); 1866 return retval; 1867 } 1868 1869 static void remove_debugfs(void) 1870 { 1871 debugfs_remove(interface->debug.devices); 1872 debugfs_remove(interface->debug.root); 1873 } 1874 1875 static int create_debugfs(void) 1876 { 1877 interface->debug.root = debugfs_create_dir("acer-wmi", NULL); 1878 if (!interface->debug.root) { 1879 pr_err("Failed to create debugfs directory"); 1880 return -ENOMEM; 1881 } 1882 1883 interface->debug.devices = debugfs_create_u32("devices", S_IRUGO, 1884 interface->debug.root, 1885 &interface->debug.wmid_devices); 1886 if (!interface->debug.devices) 1887 goto error_debugfs; 1888 1889 return 0; 1890 1891 error_debugfs: 1892 remove_debugfs(); 1893 return -ENOMEM; 1894 } 1895 1896 static int __init acer_wmi_init(void) 1897 { 1898 int err; 1899 1900 pr_info("Acer Laptop ACPI-WMI Extras\n"); 1901 1902 if (dmi_check_system(acer_blacklist)) { 1903 pr_info("Blacklisted hardware detected - not loading\n"); 1904 return -ENODEV; 1905 } 1906 1907 find_quirks(); 1908 1909 /* 1910 * Detect which ACPI-WMI interface we're using. 1911 */ 1912 if (wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 1913 interface = &AMW0_V2_interface; 1914 1915 if (!wmi_has_guid(AMW0_GUID1) && wmi_has_guid(WMID_GUID1)) 1916 interface = &wmid_interface; 1917 1918 if (wmi_has_guid(WMID_GUID3)) 1919 interface = &wmid_v2_interface; 1920 1921 if (interface) 1922 dmi_walk(type_aa_dmi_decode, NULL); 1923 1924 if (wmi_has_guid(WMID_GUID2) && interface) { 1925 if (!has_type_aa && ACPI_FAILURE(WMID_set_capabilities())) { 1926 pr_err("Unable to detect available WMID devices\n"); 1927 return -ENODEV; 1928 } 1929 /* WMID always provides brightness methods */ 1930 interface->capability |= ACER_CAP_BRIGHTNESS; 1931 } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { 1932 pr_err("No WMID device detection method found\n"); 1933 return -ENODEV; 1934 } 1935 1936 if (wmi_has_guid(AMW0_GUID1) && !wmi_has_guid(WMID_GUID1)) { 1937 interface = &AMW0_interface; 1938 1939 if (ACPI_FAILURE(AMW0_set_capabilities())) { 1940 pr_err("Unable to detect available AMW0 devices\n"); 1941 return -ENODEV; 1942 } 1943 } 1944 1945 if (wmi_has_guid(AMW0_GUID1)) 1946 AMW0_find_mailled(); 1947 1948 if (!interface) { 1949 pr_err("No or unsupported WMI interface, unable to load\n"); 1950 return -ENODEV; 1951 } 1952 1953 set_quirks(); 1954 1955 if (acpi_video_backlight_support()) { 1956 interface->capability &= ~ACER_CAP_BRIGHTNESS; 1957 pr_info("Brightness must be controlled by " 1958 "generic video driver\n"); 1959 } 1960 1961 if (wmi_has_guid(WMID_GUID3)) { 1962 if (ec_raw_mode) { 1963 if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) { 1964 pr_err("Cannot enable EC raw mode\n"); 1965 return -ENODEV; 1966 } 1967 } else if (ACPI_FAILURE(acer_wmi_enable_lm())) { 1968 pr_err("Cannot enable Launch Manager mode\n"); 1969 return -ENODEV; 1970 } 1971 } else if (ec_raw_mode) { 1972 pr_info("No WMID EC raw mode enable method\n"); 1973 } 1974 1975 if (wmi_has_guid(ACERWMID_EVENT_GUID)) { 1976 err = acer_wmi_input_setup(); 1977 if (err) 1978 return err; 1979 } 1980 1981 err = platform_driver_register(&acer_platform_driver); 1982 if (err) { 1983 pr_err("Unable to register platform driver.\n"); 1984 goto error_platform_register; 1985 } 1986 1987 acer_platform_device = platform_device_alloc("acer-wmi", -1); 1988 if (!acer_platform_device) { 1989 err = -ENOMEM; 1990 goto error_device_alloc; 1991 } 1992 1993 err = platform_device_add(acer_platform_device); 1994 if (err) 1995 goto error_device_add; 1996 1997 err = create_sysfs(); 1998 if (err) 1999 goto error_create_sys; 2000 2001 if (wmi_has_guid(WMID_GUID2)) { 2002 interface->debug.wmid_devices = get_wmid_devices(); 2003 err = create_debugfs(); 2004 if (err) 2005 goto error_create_debugfs; 2006 } 2007 2008 /* Override any initial settings with values from the commandline */ 2009 acer_commandline_init(); 2010 2011 return 0; 2012 2013 error_create_debugfs: 2014 remove_sysfs(acer_platform_device); 2015 error_create_sys: 2016 platform_device_del(acer_platform_device); 2017 error_device_add: 2018 platform_device_put(acer_platform_device); 2019 error_device_alloc: 2020 platform_driver_unregister(&acer_platform_driver); 2021 error_platform_register: 2022 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 2023 acer_wmi_input_destroy(); 2024 2025 return err; 2026 } 2027 2028 static void __exit acer_wmi_exit(void) 2029 { 2030 if (wmi_has_guid(ACERWMID_EVENT_GUID)) 2031 acer_wmi_input_destroy(); 2032 2033 remove_sysfs(acer_platform_device); 2034 remove_debugfs(); 2035 platform_device_unregister(acer_platform_device); 2036 platform_driver_unregister(&acer_platform_driver); 2037 2038 pr_info("Acer Laptop WMI Extras unloaded\n"); 2039 return; 2040 } 2041 2042 module_init(acer_wmi_init); 2043 module_exit(acer_wmi_exit); 2044