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