diff options
Diffstat (limited to 'drivers/misc/asus-laptop.c')
-rw-r--r-- | drivers/misc/asus-laptop.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index dcab778a91c5..3ba579899ac7 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -272,19 +272,25 @@ static int read_status(int mask) | |||
272 | return (hotk->status & mask) ? 1 : 0; | 272 | return (hotk->status & mask) ? 1 : 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | static void write_status(acpi_handle handle, int out, int mask, int invert) | 275 | static void write_status(acpi_handle handle, int out, int mask) |
276 | { | 276 | { |
277 | hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask); | 277 | hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask); |
278 | 278 | ||
279 | if (invert) /* invert target value */ | 279 | switch (mask) { |
280 | case MLED_ON: | ||
280 | out = !out & 0x1; | 281 | out = !out & 0x1; |
282 | break; | ||
283 | default: | ||
284 | out &= 0x1; | ||
285 | break; | ||
286 | } | ||
281 | 287 | ||
282 | if (handle && !write_acpi_int(handle, NULL, out, NULL)) | 288 | if (handle && !write_acpi_int(handle, NULL, out, NULL)) |
283 | printk(ASUS_WARNING " write failed\n"); | 289 | printk(ASUS_WARNING " write failed %x\n", mask); |
284 | } | 290 | } |
285 | 291 | ||
286 | /* /sys/class/led handlers */ | 292 | /* /sys/class/led handlers */ |
287 | #define ASUS_LED_HANDLER(object, mask, invert) \ | 293 | #define ASUS_LED_HANDLER(object, mask) \ |
288 | static void object##_led_set(struct led_classdev *led_cdev, \ | 294 | static void object##_led_set(struct led_classdev *led_cdev, \ |
289 | enum led_brightness value) \ | 295 | enum led_brightness value) \ |
290 | { \ | 296 | { \ |
@@ -294,13 +300,13 @@ static void write_status(acpi_handle handle, int out, int mask, int invert) | |||
294 | static void object##_led_update(struct work_struct *ignored) \ | 300 | static void object##_led_update(struct work_struct *ignored) \ |
295 | { \ | 301 | { \ |
296 | int value = object##_led_wk; \ | 302 | int value = object##_led_wk; \ |
297 | write_status(object##_set_handle, value, (mask), (invert)); \ | 303 | write_status(object##_set_handle, value, (mask)); \ |
298 | } | 304 | } |
299 | 305 | ||
300 | ASUS_LED_HANDLER(mled, MLED_ON, 1); | 306 | ASUS_LED_HANDLER(mled, MLED_ON); |
301 | ASUS_LED_HANDLER(pled, PLED_ON, 0); | 307 | ASUS_LED_HANDLER(pled, PLED_ON); |
302 | ASUS_LED_HANDLER(rled, RLED_ON, 0); | 308 | ASUS_LED_HANDLER(rled, RLED_ON); |
303 | ASUS_LED_HANDLER(tled, TLED_ON, 0); | 309 | ASUS_LED_HANDLER(tled, TLED_ON); |
304 | 310 | ||
305 | static int get_lcd_state(void) | 311 | static int get_lcd_state(void) |
306 | { | 312 | { |
@@ -325,7 +331,7 @@ static int set_lcd_state(int value) | |||
325 | printk(ASUS_WARNING "Error switching LCD\n"); | 331 | printk(ASUS_WARNING "Error switching LCD\n"); |
326 | } | 332 | } |
327 | 333 | ||
328 | write_status(NULL, lcd, LCD_ON, 0); | 334 | write_status(NULL, lcd, LCD_ON); |
329 | return 0; | 335 | return 0; |
330 | } | 336 | } |
331 | 337 | ||
@@ -458,7 +464,7 @@ static int parse_arg(const char *buf, unsigned long count, int *val) | |||
458 | } | 464 | } |
459 | 465 | ||
460 | static ssize_t store_status(const char *buf, size_t count, | 466 | static ssize_t store_status(const char *buf, size_t count, |
461 | acpi_handle handle, int mask, int invert) | 467 | acpi_handle handle, int mask) |
462 | { | 468 | { |
463 | int rv, value; | 469 | int rv, value; |
464 | int out = 0; | 470 | int out = 0; |
@@ -467,7 +473,7 @@ static ssize_t store_status(const char *buf, size_t count, | |||
467 | if (rv > 0) | 473 | if (rv > 0) |
468 | out = value ? 1 : 0; | 474 | out = value ? 1 : 0; |
469 | 475 | ||
470 | write_status(handle, out, mask, invert); | 476 | write_status(handle, out, mask); |
471 | 477 | ||
472 | return rv; | 478 | return rv; |
473 | } | 479 | } |
@@ -508,7 +514,7 @@ static ssize_t show_wlan(struct device *dev, | |||
508 | static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, | 514 | static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, |
509 | const char *buf, size_t count) | 515 | const char *buf, size_t count) |
510 | { | 516 | { |
511 | return store_status(buf, count, wl_switch_handle, WL_ON, 0); | 517 | return store_status(buf, count, wl_switch_handle, WL_ON); |
512 | } | 518 | } |
513 | 519 | ||
514 | /* | 520 | /* |
@@ -524,7 +530,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
524 | struct device_attribute *attr, const char *buf, | 530 | struct device_attribute *attr, const char *buf, |
525 | size_t count) | 531 | size_t count) |
526 | { | 532 | { |
527 | return store_status(buf, count, bt_switch_handle, BT_ON, 0); | 533 | return store_status(buf, count, bt_switch_handle, BT_ON); |
528 | } | 534 | } |
529 | 535 | ||
530 | /* | 536 | /* |
@@ -652,10 +658,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
652 | * switched | 658 | * switched |
653 | */ | 659 | */ |
654 | if (event == ATKD_LCD_ON) { | 660 | if (event == ATKD_LCD_ON) { |
655 | write_status(NULL, 1, LCD_ON, 0); | 661 | write_status(NULL, 1, LCD_ON); |
656 | lcd_blank(FB_BLANK_UNBLANK); | 662 | lcd_blank(FB_BLANK_UNBLANK); |
657 | } else if (event == ATKD_LCD_OFF) { | 663 | } else if (event == ATKD_LCD_OFF) { |
658 | write_status(NULL, 0, LCD_ON, 0); | 664 | write_status(NULL, 0, LCD_ON); |
659 | lcd_blank(FB_BLANK_POWERDOWN); | 665 | lcd_blank(FB_BLANK_POWERDOWN); |
660 | } | 666 | } |
661 | 667 | ||
@@ -928,11 +934,15 @@ static int asus_hotk_add(struct acpi_device *device) | |||
928 | asus_hotk_found = 1; | 934 | asus_hotk_found = 1; |
929 | 935 | ||
930 | /* WLED and BLED are on by default */ | 936 | /* WLED and BLED are on by default */ |
931 | write_status(bt_switch_handle, 1, BT_ON, 0); | 937 | write_status(bt_switch_handle, 1, BT_ON); |
932 | write_status(wl_switch_handle, 1, WL_ON, 0); | 938 | write_status(wl_switch_handle, 1, WL_ON); |
939 | |||
940 | /* If the h/w switch is off, we need to check the real status */ | ||
941 | write_status(NULL, read_status(BT_ON), BT_ON); | ||
942 | write_status(NULL, read_status(WL_ON), WL_ON); | ||
933 | 943 | ||
934 | /* LCD Backlight is on by default */ | 944 | /* LCD Backlight is on by default */ |
935 | write_status(NULL, 1, LCD_ON, 0); | 945 | write_status(NULL, 1, LCD_ON); |
936 | 946 | ||
937 | /* LED display is off by default */ | 947 | /* LED display is off by default */ |
938 | hotk->ledd_status = 0xFFF; | 948 | hotk->ledd_status = 0xFFF; |