diff options
| -rw-r--r-- | drivers/platform/x86/asus-laptop.c | 240 |
1 files changed, 129 insertions, 111 deletions
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index ae4f80886577..671fad96c275 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
| @@ -115,27 +115,27 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " | |||
| 115 | static char *object##_paths[] = { paths } | 115 | static char *object##_paths[] = { paths } |
| 116 | 116 | ||
| 117 | /* LED */ | 117 | /* LED */ |
| 118 | ASUS_HANDLE(mled_set, ASUS_LAPTOP_PREFIX "MLED"); | 118 | #define METHOD_MLED "MLED" |
| 119 | ASUS_HANDLE(tled_set, ASUS_LAPTOP_PREFIX "TLED"); | 119 | #define METHOD_TLED "TLED" |
| 120 | ASUS_HANDLE(rled_set, ASUS_LAPTOP_PREFIX "RLED"); /* W1JC */ | 120 | #define METHOD_RLED "RLED" /* W1JC */ |
| 121 | ASUS_HANDLE(pled_set, ASUS_LAPTOP_PREFIX "PLED"); /* A7J */ | 121 | #define METHOD_PLED "PLED" /* A7J */ |
| 122 | ASUS_HANDLE(gled_set, ASUS_LAPTOP_PREFIX "GLED"); /* G1, G2 (probably) */ | 122 | #define METHOD_GLED "GLED" /* G1, G2 (probably) */ |
| 123 | 123 | ||
| 124 | /* LEDD */ | 124 | /* LEDD */ |
| 125 | ASUS_HANDLE(ledd_set, ASUS_LAPTOP_PREFIX "SLCM"); | 125 | #define METHOD_LEDD "SLCM" |
| 126 | 126 | ||
| 127 | /* | 127 | /* |
| 128 | * Bluetooth and WLAN | 128 | * Bluetooth and WLAN |
| 129 | * WLED and BLED are not handled like other XLED, because in some dsdt | 129 | * WLED and BLED are not handled like other XLED, because in some dsdt |
| 130 | * they also control the WLAN/Bluetooth device. | 130 | * they also control the WLAN/Bluetooth device. |
| 131 | */ | 131 | */ |
| 132 | ASUS_HANDLE(wl_switch, ASUS_LAPTOP_PREFIX "WLED"); | 132 | #define METHOD_WLAN "WLED" |
| 133 | ASUS_HANDLE(bt_switch, ASUS_LAPTOP_PREFIX "BLED"); | 133 | #define METHOD_BLUETOOTH "BLED" |
| 134 | ASUS_HANDLE(wireless_status, ASUS_LAPTOP_PREFIX "RSTS"); /* All new models */ | 134 | #define METHOD_WL_STATUS "RSTS" |
| 135 | 135 | ||
| 136 | /* Brightness */ | 136 | /* Brightness */ |
| 137 | ASUS_HANDLE(brightness_set, ASUS_LAPTOP_PREFIX "SPLV"); | 137 | #define METHOD_BRIGHTNESS_SET "SPLV" |
| 138 | ASUS_HANDLE(brightness_get, ASUS_LAPTOP_PREFIX "GPLV"); | 138 | #define METHOD_BRIGHTNESS_GET "GPLV" |
| 139 | 139 | ||
| 140 | /* Backlight */ | 140 | /* Backlight */ |
| 141 | ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ | 141 | ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ |
| @@ -148,7 +148,7 @@ ASUS_HANDLE(lcd_switch, "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */ | |||
| 148 | "\\Q10"); /* A2x, L2D, L3D, M2E */ | 148 | "\\Q10"); /* A2x, L2D, L3D, M2E */ |
| 149 | 149 | ||
| 150 | /* Display */ | 150 | /* Display */ |
| 151 | ASUS_HANDLE(display_set, ASUS_LAPTOP_PREFIX "SDSP"); | 151 | #define METHOD_SWITCH_DISPLAY "SDSP" |
| 152 | ASUS_HANDLE(display_get, | 152 | ASUS_HANDLE(display_get, |
| 153 | /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */ | 153 | /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */ |
| 154 | "\\_SB.PCI0.P0P1.VGA.GETD", | 154 | "\\_SB.PCI0.P0P1.VGA.GETD", |
| @@ -173,18 +173,18 @@ ASUS_HANDLE(display_get, | |||
| 173 | /* A3F A6F A3N A3L M6N W3N W6A */ | 173 | /* A3F A6F A3N A3L M6N W3N W6A */ |
| 174 | "\\SSTE"); | 174 | "\\SSTE"); |
| 175 | 175 | ||
| 176 | ASUS_HANDLE(ls_switch, ASUS_LAPTOP_PREFIX "ALSC"); /* Z71A Z71V */ | 176 | #define METHOD_ALS_CONTROL "ALSC" /* Z71A Z71V */ |
| 177 | ASUS_HANDLE(ls_level, ASUS_LAPTOP_PREFIX "ALSL"); /* Z71A Z71V */ | 177 | #define METHOD_ALS_LEVEL "ALSL" /* Z71A Z71V */ |
| 178 | 178 | ||
| 179 | /* GPS */ | 179 | /* GPS */ |
| 180 | /* R2H use different handle for GPS on/off */ | 180 | /* R2H use different handle for GPS on/off */ |
| 181 | ASUS_HANDLE(gps_on, ASUS_LAPTOP_PREFIX "SDON"); /* R2H */ | 181 | #define METHOD_GPS_ON "SDON" |
| 182 | ASUS_HANDLE(gps_off, ASUS_LAPTOP_PREFIX "SDOF"); /* R2H */ | 182 | #define METHOD_GPS_OFF "SDOF" |
| 183 | ASUS_HANDLE(gps_status, ASUS_LAPTOP_PREFIX "GPST"); | 183 | #define METHOD_GPS_STATUS "GPST" |
| 184 | 184 | ||
| 185 | /* Keyboard light */ | 185 | /* Keyboard light */ |
| 186 | ASUS_HANDLE(kled_set, ASUS_LAPTOP_PREFIX "SLKB"); | 186 | #define METHOD_KBD_LIGHT_SET "SLKB" |
| 187 | ASUS_HANDLE(kled_get, ASUS_LAPTOP_PREFIX "GLKB"); | 187 | #define METHOD_KBD_LIGHT_GET "GLKB" |
| 188 | 188 | ||
| 189 | /* | 189 | /* |
| 190 | * Define a specific led structure to keep the main structure clean | 190 | * Define a specific led structure to keep the main structure clean |
| @@ -323,18 +323,44 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val) | |||
| 323 | return write_acpi_int_ret(handle, method, val, NULL); | 323 | return write_acpi_int_ret(handle, method, val, NULL); |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | static int acpi_check_handle(acpi_handle handle, const char *method, | ||
| 327 | acpi_handle *ret) | ||
| 328 | { | ||
| 329 | acpi_status status; | ||
| 330 | |||
| 331 | if (method == NULL) | ||
| 332 | return -ENODEV; | ||
| 333 | |||
| 334 | if (ret) | ||
| 335 | status = acpi_get_handle(handle, (char *)method, | ||
| 336 | ret); | ||
| 337 | else { | ||
| 338 | acpi_handle dummy; | ||
| 339 | |||
| 340 | status = acpi_get_handle(handle, (char *)method, | ||
| 341 | &dummy); | ||
| 342 | } | ||
| 343 | |||
| 344 | if (status != AE_OK) { | ||
| 345 | if (ret) | ||
| 346 | pr_warning("Error finding %s\n", method); | ||
| 347 | return -ENODEV; | ||
| 348 | } | ||
| 349 | return 0; | ||
| 350 | } | ||
| 351 | |||
| 326 | /* Generic LED function */ | 352 | /* Generic LED function */ |
| 327 | static void asus_led_set(struct asus_laptop *asus, acpi_handle handle, | 353 | static void asus_led_set(struct asus_laptop *asus, char *method, |
| 328 | int value) | 354 | int value) |
| 329 | { | 355 | { |
| 330 | if (handle == mled_set_handle) | 356 | if (!strcmp(method, METHOD_MLED)) |
| 331 | value = !value; | 357 | value = !value; |
| 332 | else if (handle == gled_set_handle) | 358 | else if (!strcmp(method, METHOD_GLED)) |
| 333 | value = !value + 1; | 359 | value = !value + 1; |
| 334 | else | 360 | else |
| 335 | value = !!value; | 361 | value = !!value; |
| 336 | 362 | ||
| 337 | write_acpi_int(handle, NULL, value); | 363 | write_acpi_int(asus->handle, method, value); |
| 338 | } | 364 | } |
| 339 | 365 | ||
| 340 | /* | 366 | /* |
| @@ -361,7 +387,7 @@ ASUS_LED(gled, "gaming", 1); | |||
| 361 | ASUS_LED(kled, "kbd_backlight", 3); | 387 | ASUS_LED(kled, "kbd_backlight", 3); |
| 362 | 388 | ||
| 363 | /* /sys/class/led handlers */ | 389 | /* /sys/class/led handlers */ |
| 364 | #define ASUS_LED_HANDLER(object, mask) \ | 390 | #define ASUS_LED_HANDLER(object, method) \ |
| 365 | static void object##_led_set(struct led_classdev *led_cdev, \ | 391 | static void object##_led_set(struct led_classdev *led_cdev, \ |
| 366 | enum led_brightness value) \ | 392 | enum led_brightness value) \ |
| 367 | { \ | 393 | { \ |
| @@ -377,7 +403,7 @@ ASUS_LED(kled, "kbd_backlight", 3); | |||
| 377 | struct asus_laptop *asus = work_to_asus(work, object); \ | 403 | struct asus_laptop *asus = work_to_asus(work, object); \ |
| 378 | \ | 404 | \ |
| 379 | int value = asus->leds.object##_wk; \ | 405 | int value = asus->leds.object##_wk; \ |
| 380 | asus_led_set(asus, object##_set_handle, value); \ | 406 | asus_led_set(asus, method, value); \ |
| 381 | } \ | 407 | } \ |
| 382 | static enum led_brightness object##_led_get( \ | 408 | static enum led_brightness object##_led_get( \ |
| 383 | struct led_classdev *led_cdev) \ | 409 | struct led_classdev *led_cdev) \ |
| @@ -385,16 +411,16 @@ ASUS_LED(kled, "kbd_backlight", 3); | |||
| 385 | return led_cdev->brightness; \ | 411 | return led_cdev->brightness; \ |
| 386 | } | 412 | } |
| 387 | 413 | ||
| 388 | ASUS_LED_HANDLER(mled, MLED_ON); | 414 | ASUS_LED_HANDLER(mled, METHOD_MLED); |
| 389 | ASUS_LED_HANDLER(pled, PLED_ON); | 415 | ASUS_LED_HANDLER(pled, METHOD_PLED); |
| 390 | ASUS_LED_HANDLER(rled, RLED_ON); | 416 | ASUS_LED_HANDLER(rled, METHOD_RLED); |
| 391 | ASUS_LED_HANDLER(tled, TLED_ON); | 417 | ASUS_LED_HANDLER(tled, METHOD_TLED); |
| 392 | ASUS_LED_HANDLER(gled, GLED_ON); | 418 | ASUS_LED_HANDLER(gled, METHOD_GLED); |
| 393 | 419 | ||
| 394 | /* | 420 | /* |
| 395 | * Keyboard backlight (also a LED) | 421 | * Keyboard backlight (also a LED) |
| 396 | */ | 422 | */ |
| 397 | static int asus_kled_lvl(void) | 423 | static int asus_kled_lvl(struct asus_laptop *asus) |
| 398 | { | 424 | { |
| 399 | unsigned long long kblv; | 425 | unsigned long long kblv; |
| 400 | struct acpi_object_list params; | 426 | struct acpi_object_list params; |
| @@ -406,7 +432,8 @@ static int asus_kled_lvl(void) | |||
| 406 | in_obj.type = ACPI_TYPE_INTEGER; | 432 | in_obj.type = ACPI_TYPE_INTEGER; |
| 407 | in_obj.integer.value = 2; | 433 | in_obj.integer.value = 2; |
| 408 | 434 | ||
| 409 | rv = acpi_evaluate_integer(kled_get_handle, NULL, ¶ms, &kblv); | 435 | rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET, |
| 436 | ¶ms, &kblv); | ||
| 410 | if (ACPI_FAILURE(rv)) { | 437 | if (ACPI_FAILURE(rv)) { |
| 411 | pr_warning("Error reading kled level\n"); | 438 | pr_warning("Error reading kled level\n"); |
| 412 | return -ENODEV; | 439 | return -ENODEV; |
| @@ -421,7 +448,7 @@ static int asus_kled_set(struct asus_laptop *asus, int kblv) | |||
| 421 | else | 448 | else |
| 422 | kblv = 0; | 449 | kblv = 0; |
| 423 | 450 | ||
| 424 | if (write_acpi_int(kled_set_handle, NULL, kblv)) { | 451 | if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) { |
| 425 | pr_warning("Keyboard LED display write failed\n"); | 452 | pr_warning("Keyboard LED display write failed\n"); |
| 426 | return -EINVAL; | 453 | return -EINVAL; |
| 427 | } | 454 | } |
| @@ -446,7 +473,9 @@ static void kled_led_update(struct work_struct *work) | |||
| 446 | 473 | ||
| 447 | static enum led_brightness kled_led_get(struct led_classdev *led_cdev) | 474 | static enum led_brightness kled_led_get(struct led_classdev *led_cdev) |
| 448 | { | 475 | { |
| 449 | return asus_kled_lvl(); | 476 | struct asus_laptop *asus = led_to_asus(led_cdev, kled); |
| 477 | |||
| 478 | return asus_kled_lvl(asus); | ||
| 450 | } | 479 | } |
| 451 | 480 | ||
| 452 | #define ASUS_LED_UNREGISTER(object) \ | 481 | #define ASUS_LED_UNREGISTER(object) \ |
| @@ -468,10 +497,11 @@ static void asus_led_exit(struct asus_laptop *asus) | |||
| 468 | } | 497 | } |
| 469 | 498 | ||
| 470 | /* Ugly macro, need to fix that later */ | 499 | /* Ugly macro, need to fix that later */ |
| 471 | #define ASUS_LED_REGISTER(asus, object, _name, max) \ | 500 | #define ASUS_LED_REGISTER(asus, object, _name, max, method) \ |
| 472 | do { \ | 501 | do { \ |
| 473 | struct led_classdev *ldev = &asus->leds.object; \ | 502 | struct led_classdev *ldev = &asus->leds.object; \ |
| 474 | if (!object##_set_handle) \ | 503 | \ |
| 504 | if (method && acpi_check_handle(asus->handle, method, NULL)) \ | ||
| 475 | break ; \ | 505 | break ; \ |
| 476 | \ | 506 | \ |
| 477 | INIT_WORK(&asus->leds.object##_work, object##_led_update); \ | 507 | INIT_WORK(&asus->leds.object##_work, object##_led_update); \ |
| @@ -497,13 +527,14 @@ static int asus_led_init(struct asus_laptop *asus) | |||
| 497 | if (!asus->leds.workqueue) | 527 | if (!asus->leds.workqueue) |
| 498 | return -ENOMEM; | 528 | return -ENOMEM; |
| 499 | 529 | ||
| 500 | ASUS_LED_REGISTER(asus, mled, "mail", 1); | 530 | ASUS_LED_REGISTER(asus, mled, "mail", 1, METHOD_MLED); |
| 501 | ASUS_LED_REGISTER(asus, tled, "touchpad", 1); | 531 | ASUS_LED_REGISTER(asus, tled, "touchpad", 1, METHOD_TLED); |
| 502 | ASUS_LED_REGISTER(asus, rled, "record", 1); | 532 | ASUS_LED_REGISTER(asus, rled, "record", 1, METHOD_RLED); |
| 503 | ASUS_LED_REGISTER(asus, pled, "phone", 1); | 533 | ASUS_LED_REGISTER(asus, pled, "phone", 1, METHOD_PLED); |
| 504 | ASUS_LED_REGISTER(asus, gled, "gaming", 1); | 534 | ASUS_LED_REGISTER(asus, gled, "gaming", 1, METHOD_GLED); |
| 505 | if (kled_set_handle && kled_get_handle) | 535 | if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL) && |
| 506 | ASUS_LED_REGISTER(asus, kled, "kbd_backlight", 3); | 536 | !acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_GET, NULL)) |
| 537 | ASUS_LED_REGISTER(asus, kled, "kbd_backlight", 3, NULL); | ||
| 507 | error: | 538 | error: |
| 508 | if (rv) | 539 | if (rv) |
| 509 | asus_led_exit(asus); | 540 | asus_led_exit(asus); |
| @@ -557,10 +588,12 @@ static void lcd_blank(struct asus_laptop *asus, int blank) | |||
| 557 | 588 | ||
| 558 | static int asus_read_brightness(struct backlight_device *bd) | 589 | static int asus_read_brightness(struct backlight_device *bd) |
| 559 | { | 590 | { |
| 591 | struct asus_laptop *asus = bl_get_data(bd); | ||
| 560 | unsigned long long value; | 592 | unsigned long long value; |
| 561 | acpi_status rv = AE_OK; | 593 | acpi_status rv = AE_OK; |
| 562 | 594 | ||
| 563 | rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value); | 595 | rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET, |
| 596 | NULL, &value); | ||
| 564 | if (ACPI_FAILURE(rv)) | 597 | if (ACPI_FAILURE(rv)) |
| 565 | pr_warning("Error reading brightness\n"); | 598 | pr_warning("Error reading brightness\n"); |
| 566 | 599 | ||
| @@ -569,7 +602,9 @@ static int asus_read_brightness(struct backlight_device *bd) | |||
| 569 | 602 | ||
| 570 | static int asus_set_brightness(struct backlight_device *bd, int value) | 603 | static int asus_set_brightness(struct backlight_device *bd, int value) |
| 571 | { | 604 | { |
| 572 | if (write_acpi_int(brightness_set_handle, NULL, value)) { | 605 | struct asus_laptop *asus = bl_get_data(bd); |
| 606 | |||
| 607 | if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) { | ||
| 573 | pr_warning("Error changing brightness\n"); | 608 | pr_warning("Error changing brightness\n"); |
| 574 | return -EIO; | 609 | return -EIO; |
| 575 | } | 610 | } |
| @@ -600,7 +635,9 @@ static int asus_backlight_init(struct asus_laptop *asus) | |||
| 600 | struct backlight_device *bd; | 635 | struct backlight_device *bd; |
| 601 | struct device *dev = &asus->platform_device->dev; | 636 | struct device *dev = &asus->platform_device->dev; |
| 602 | 637 | ||
| 603 | if (brightness_set_handle && lcd_switch_handle) { | 638 | if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) && |
| 639 | !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) && | ||
| 640 | lcd_switch_handle) { | ||
| 604 | bd = backlight_device_register(ASUS_LAPTOP_FILE, dev, | 641 | bd = backlight_device_register(ASUS_LAPTOP_FILE, dev, |
| 605 | asus, &asusbl_ops); | 642 | asus, &asusbl_ops); |
| 606 | if (IS_ERR(bd)) { | 643 | if (IS_ERR(bd)) { |
| @@ -612,8 +649,8 @@ static int asus_backlight_init(struct asus_laptop *asus) | |||
| 612 | asus->backlight_device = bd; | 649 | asus->backlight_device = bd; |
| 613 | 650 | ||
| 614 | bd->props.max_brightness = 15; | 651 | bd->props.max_brightness = 15; |
| 615 | bd->props.brightness = asus_read_brightness(NULL); | ||
| 616 | bd->props.power = FB_BLANK_UNBLANK; | 652 | bd->props.power = FB_BLANK_UNBLANK; |
| 653 | bd->props.brightness = asus_read_brightness(bd); | ||
| 617 | backlight_update_status(bd); | 654 | backlight_update_status(bd); |
| 618 | } | 655 | } |
| 619 | return 0; | 656 | return 0; |
| @@ -716,7 +753,7 @@ static int parse_arg(const char *buf, unsigned long count, int *val) | |||
| 716 | 753 | ||
| 717 | static ssize_t sysfs_acpi_set(struct asus_laptop *asus, | 754 | static ssize_t sysfs_acpi_set(struct asus_laptop *asus, |
| 718 | const char *buf, size_t count, | 755 | const char *buf, size_t count, |
| 719 | acpi_handle handle) | 756 | const char *method) |
| 720 | { | 757 | { |
| 721 | int rv, value; | 758 | int rv, value; |
| 722 | int out = 0; | 759 | int out = 0; |
| @@ -725,7 +762,7 @@ static ssize_t sysfs_acpi_set(struct asus_laptop *asus, | |||
| 725 | if (rv > 0) | 762 | if (rv > 0) |
| 726 | out = value ? 1 : 0; | 763 | out = value ? 1 : 0; |
| 727 | 764 | ||
| 728 | if (write_acpi_int(handle, NULL, value)) | 765 | if (write_acpi_int(asus->handle, method, value)) |
| 729 | return -ENODEV; | 766 | return -ENODEV; |
| 730 | return rv; | 767 | return rv; |
| 731 | } | 768 | } |
| @@ -749,7 +786,7 @@ static ssize_t store_ledd(struct device *dev, struct device_attribute *attr, | |||
| 749 | 786 | ||
| 750 | rv = parse_arg(buf, count, &value); | 787 | rv = parse_arg(buf, count, &value); |
| 751 | if (rv > 0) { | 788 | if (rv > 0) { |
| 752 | if (write_acpi_int(ledd_set_handle, NULL, value)) | 789 | if (write_acpi_int(asus->handle, METHOD_LEDD, value)) |
| 753 | pr_warning("LED display write failed\n"); | 790 | pr_warning("LED display write failed\n"); |
| 754 | else | 791 | else |
| 755 | asus->ledd_status = (u32) value; | 792 | asus->ledd_status = (u32) value; |
| @@ -768,7 +805,8 @@ static int asus_wireless_status(struct asus_laptop *asus, int mask) | |||
| 768 | if (!asus->have_rsts) | 805 | if (!asus->have_rsts) |
| 769 | return (asus->wireless_status & mask) ? 1 : 0; | 806 | return (asus->wireless_status & mask) ? 1 : 0; |
| 770 | 807 | ||
| 771 | rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status); | 808 | rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS, |
| 809 | NULL, &status); | ||
| 772 | if (ACPI_FAILURE(rv)) { | 810 | if (ACPI_FAILURE(rv)) { |
| 773 | pr_warning("Error reading Wireless status\n"); | 811 | pr_warning("Error reading Wireless status\n"); |
| 774 | return -EINVAL; | 812 | return -EINVAL; |
| @@ -792,7 +830,7 @@ static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, | |||
| 792 | { | 830 | { |
| 793 | struct asus_laptop *asus = dev_get_drvdata(dev); | 831 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 794 | 832 | ||
| 795 | return sysfs_acpi_set(asus, buf, count, wl_switch_handle); | 833 | return sysfs_acpi_set(asus, buf, count, METHOD_WLAN); |
| 796 | } | 834 | } |
| 797 | 835 | ||
| 798 | /* | 836 | /* |
| @@ -812,7 +850,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
| 812 | { | 850 | { |
| 813 | struct asus_laptop *asus = dev_get_drvdata(dev); | 851 | struct asus_laptop *asus = dev_get_drvdata(dev); |
| 814 | 852 | ||
| 815 | return sysfs_acpi_set(asus, buf, count, bt_switch_handle); | 853 | return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH); |
| 816 | } | 854 | } |
| 817 | 855 | ||
| 818 | /* | 856 | /* |
| @@ -821,7 +859,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
| 821 | static void asus_set_display(struct asus_laptop *asus, int value) | 859 | static void asus_set_display(struct asus_laptop *asus, int value) |
| 822 | { | 860 | { |
| 823 | /* no sanity check needed for now */ | 861 | /* no sanity check needed for now */ |
| 824 | if (write_acpi_int(display_set_handle, NULL, value)) | 862 | if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value)) |
| 825 | pr_warning("Error setting display\n"); | 863 | pr_warning("Error setting display\n"); |
| 826 | return; | 864 | return; |
| 827 | } | 865 | } |
| @@ -883,7 +921,7 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | |||
| 883 | */ | 921 | */ |
| 884 | static void asus_als_switch(struct asus_laptop *asus, int value) | 922 | static void asus_als_switch(struct asus_laptop *asus, int value) |
| 885 | { | 923 | { |
| 886 | if (write_acpi_int(ls_switch_handle, NULL, value)) | 924 | if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value)) |
| 887 | pr_warning("Error setting light sensor switch\n"); | 925 | pr_warning("Error setting light sensor switch\n"); |
| 888 | asus->light_switch = value; | 926 | asus->light_switch = value; |
| 889 | } | 927 | } |
| @@ -911,7 +949,7 @@ static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, | |||
| 911 | 949 | ||
| 912 | static void asus_als_level(struct asus_laptop *asus, int value) | 950 | static void asus_als_level(struct asus_laptop *asus, int value) |
| 913 | { | 951 | { |
| 914 | if (write_acpi_int(ls_level_handle, NULL, value)) | 952 | if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value)) |
| 915 | pr_warning("Error setting light sensor level\n"); | 953 | pr_warning("Error setting light sensor level\n"); |
| 916 | asus->light_level = value; | 954 | asus->light_level = value; |
| 917 | } | 955 | } |
| @@ -949,7 +987,8 @@ static int asus_gps_status(struct asus_laptop *asus) | |||
| 949 | unsigned long long status; | 987 | unsigned long long status; |
| 950 | acpi_status rv = AE_OK; | 988 | acpi_status rv = AE_OK; |
| 951 | 989 | ||
| 952 | rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status); | 990 | rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS, |
| 991 | NULL, &status); | ||
| 953 | if (ACPI_FAILURE(rv)) { | 992 | if (ACPI_FAILURE(rv)) { |
| 954 | pr_warning("Error reading GPS status\n"); | 993 | pr_warning("Error reading GPS status\n"); |
| 955 | return -ENODEV; | 994 | return -ENODEV; |
| @@ -959,9 +998,9 @@ static int asus_gps_status(struct asus_laptop *asus) | |||
| 959 | 998 | ||
| 960 | static int asus_gps_switch(struct asus_laptop *asus, int status) | 999 | static int asus_gps_switch(struct asus_laptop *asus, int status) |
| 961 | { | 1000 | { |
| 962 | acpi_handle handle = status ? gps_on_handle : gps_off_handle; | 1001 | const char *meth = status ? METHOD_GPS_ON : METHOD_GPS_OFF; |
| 963 | 1002 | ||
| 964 | if (write_acpi_int(handle, NULL, 0x02)) | 1003 | if (write_acpi_int(asus->handle, meth, 0x02)) |
| 965 | return -ENODEV; | 1004 | return -ENODEV; |
| 966 | return 0; | 1005 | return 0; |
| 967 | } | 1006 | } |
| @@ -1224,27 +1263,33 @@ static void asus_laptop_add_fs(struct asus_laptop *asus) | |||
| 1224 | { | 1263 | { |
| 1225 | ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); | 1264 | ASUS_SET_DEVICE_ATTR(infos, 0444, show_infos, NULL); |
| 1226 | 1265 | ||
| 1227 | if (wl_switch_handle) | 1266 | if (!acpi_check_handle(asus->handle, METHOD_WLAN, NULL)) |
| 1228 | ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan); | 1267 | ASUS_SET_DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan); |
| 1229 | 1268 | ||
| 1230 | if (bt_switch_handle) | 1269 | if (!acpi_check_handle(asus->handle, METHOD_BLUETOOTH, NULL)) |
| 1231 | ASUS_SET_DEVICE_ATTR(bluetooth, 0644, | 1270 | ASUS_SET_DEVICE_ATTR(bluetooth, 0644, |
| 1232 | show_bluetooth, store_bluetooth); | 1271 | show_bluetooth, store_bluetooth); |
| 1233 | 1272 | ||
| 1234 | if (display_set_handle && display_get_handle) | 1273 | if (!acpi_check_handle(asus->handle, METHOD_SWITCH_DISPLAY, NULL)) { |
| 1235 | ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, store_disp); | 1274 | if (display_get_handle) |
| 1236 | else if (display_set_handle) | 1275 | ASUS_SET_DEVICE_ATTR(display, 0644, show_disp, |
| 1237 | ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp); | 1276 | store_disp); |
| 1277 | else | ||
| 1278 | ASUS_SET_DEVICE_ATTR(display, 0200, NULL, store_disp); | ||
| 1279 | } | ||
| 1238 | 1280 | ||
| 1239 | if (ledd_set_handle) | 1281 | if (!acpi_check_handle(asus->handle, METHOD_LEDD, NULL)) |
| 1240 | ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd); | 1282 | ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd); |
| 1241 | 1283 | ||
| 1242 | if (ls_switch_handle && ls_level_handle) { | 1284 | if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) && |
| 1285 | !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) { | ||
| 1243 | ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); | 1286 | ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); |
| 1244 | ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); | 1287 | ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); |
| 1245 | } | 1288 | } |
| 1246 | 1289 | ||
| 1247 | if (gps_status_handle && gps_on_handle && gps_off_handle) | 1290 | if (!acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) && |
| 1291 | !acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) && | ||
| 1292 | !acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL)) | ||
| 1248 | ASUS_SET_DEVICE_ATTR(gps, 0644, show_gps, store_gps); | 1293 | ASUS_SET_DEVICE_ATTR(gps, 0644, show_gps, store_gps); |
| 1249 | } | 1294 | } |
| 1250 | 1295 | ||
| @@ -1337,55 +1382,23 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
| 1337 | if (*string) | 1382 | if (*string) |
| 1338 | pr_notice(" %s model detected\n", string); | 1383 | pr_notice(" %s model detected\n", string); |
| 1339 | 1384 | ||
| 1340 | ASUS_HANDLE_INIT(mled_set); | ||
| 1341 | ASUS_HANDLE_INIT(tled_set); | ||
| 1342 | ASUS_HANDLE_INIT(rled_set); | ||
| 1343 | ASUS_HANDLE_INIT(pled_set); | ||
| 1344 | ASUS_HANDLE_INIT(gled_set); | ||
| 1345 | |||
| 1346 | ASUS_HANDLE_INIT(ledd_set); | ||
| 1347 | |||
| 1348 | ASUS_HANDLE_INIT(kled_set); | ||
| 1349 | ASUS_HANDLE_INIT(kled_get); | ||
| 1350 | |||
| 1351 | /* | 1385 | /* |
| 1352 | * The HWRS method return informations about the hardware. | 1386 | * The HWRS method return informations about the hardware. |
| 1353 | * 0x80 bit is for WLAN, 0x100 for Bluetooth. | 1387 | * 0x80 bit is for WLAN, 0x100 for Bluetooth. |
| 1354 | * The significance of others is yet to be found. | 1388 | * The significance of others is yet to be found. |
| 1355 | * If we don't find the method, we assume the device are present. | ||
| 1356 | */ | 1389 | */ |
| 1357 | status = | 1390 | status = |
| 1358 | acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); | 1391 | acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); |
| 1359 | if (ACPI_FAILURE(status)) | 1392 | if (!ACPI_FAILURE(status)) |
| 1360 | hwrs_result = WL_HWRS | BT_HWRS; | 1393 | pr_notice(" HRWS returned %x", (int)hwrs_result); |
| 1361 | 1394 | ||
| 1362 | if (hwrs_result & WL_HWRS) | 1395 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) |
| 1363 | ASUS_HANDLE_INIT(wl_switch); | ||
| 1364 | if (hwrs_result & BT_HWRS) | ||
| 1365 | ASUS_HANDLE_INIT(bt_switch); | ||
| 1366 | |||
| 1367 | if (!ASUS_HANDLE_INIT(wireless_status)) | ||
| 1368 | asus->have_rsts = true; | 1396 | asus->have_rsts = true; |
| 1369 | 1397 | ||
| 1370 | ASUS_HANDLE_INIT(brightness_set); | 1398 | /* Scheduled for removal */ |
| 1371 | ASUS_HANDLE_INIT(brightness_get); | ||
| 1372 | |||
| 1373 | ASUS_HANDLE_INIT(lcd_switch); | 1399 | ASUS_HANDLE_INIT(lcd_switch); |
| 1374 | |||
| 1375 | ASUS_HANDLE_INIT(display_set); | ||
| 1376 | ASUS_HANDLE_INIT(display_get); | 1400 | ASUS_HANDLE_INIT(display_get); |
| 1377 | 1401 | ||
| 1378 | /* | ||
| 1379 | * There is a lot of models with "ALSL", but a few get | ||
| 1380 | * a real light sens, so we need to check it. | ||
| 1381 | */ | ||
| 1382 | if (!ASUS_HANDLE_INIT(ls_switch)) | ||
| 1383 | ASUS_HANDLE_INIT(ls_level); | ||
| 1384 | |||
| 1385 | ASUS_HANDLE_INIT(gps_on); | ||
| 1386 | ASUS_HANDLE_INIT(gps_off); | ||
| 1387 | ASUS_HANDLE_INIT(gps_status); | ||
| 1388 | |||
| 1389 | kfree(model); | 1402 | kfree(model); |
| 1390 | 1403 | ||
| 1391 | return AE_OK; | 1404 | return AE_OK; |
| @@ -1413,12 +1426,14 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) | |||
| 1413 | 1426 | ||
| 1414 | /* WLED and BLED are on by default */ | 1427 | /* WLED and BLED are on by default */ |
| 1415 | if (bluetooth_status >= 0) | 1428 | if (bluetooth_status >= 0) |
| 1416 | write_acpi_int(bt_switch_handle, NULL, !!bluetooth_status); | 1429 | write_acpi_int(asus->handle, METHOD_BLUETOOTH, |
| 1430 | !!bluetooth_status); | ||
| 1417 | if (wireless_status >= 0) | 1431 | if (wireless_status >= 0) |
| 1418 | write_acpi_int(wl_switch_handle, NULL, !!wireless_status); | 1432 | write_acpi_int(asus->handle, METHOD_WLAN, |
| 1433 | !!wireless_status); | ||
| 1419 | 1434 | ||
| 1420 | /* Keyboard Backlight is on by default */ | 1435 | /* Keyboard Backlight is on by default */ |
| 1421 | if (kled_set_handle) | 1436 | if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL)) |
| 1422 | asus_kled_set(asus, 1); | 1437 | asus_kled_set(asus, 1); |
| 1423 | 1438 | ||
| 1424 | /* LED display is off by default */ | 1439 | /* LED display is off by default */ |
| @@ -1428,14 +1443,17 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) | |||
| 1428 | asus->light_switch = 0; /* Default to light sensor disabled */ | 1443 | asus->light_switch = 0; /* Default to light sensor disabled */ |
| 1429 | asus->light_level = 5; /* level 5 for sensor sensitivity */ | 1444 | asus->light_level = 5; /* level 5 for sensor sensitivity */ |
| 1430 | 1445 | ||
| 1431 | if (ls_switch_handle) | 1446 | if (!acpi_check_handle(asus->handle, METHOD_ALS_CONTROL, NULL) && |
| 1447 | !acpi_check_handle(asus->handle, METHOD_ALS_LEVEL, NULL)) { | ||
| 1432 | asus_als_switch(asus, asus->light_switch); | 1448 | asus_als_switch(asus, asus->light_switch); |
| 1433 | |||
| 1434 | if (ls_level_handle) | ||
| 1435 | asus_als_level(asus, asus->light_level); | 1449 | asus_als_level(asus, asus->light_level); |
| 1450 | } | ||
| 1436 | 1451 | ||
| 1437 | /* GPS is on by default */ | 1452 | /* GPS is on by default */ |
| 1438 | asus_gps_switch(asus, 1); | 1453 | if (!acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) && |
| 1454 | !acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) && | ||
| 1455 | !acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL)) | ||
| 1456 | asus_gps_switch(asus, 1); | ||
| 1439 | return result; | 1457 | return result; |
| 1440 | } | 1458 | } |
| 1441 | 1459 | ||
