aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/asus-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/asus-laptop.c')
-rw-r--r--drivers/misc/asus-laptop.c48
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
275static void write_status(acpi_handle handle, int out, int mask, int invert) 275static 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
300ASUS_LED_HANDLER(mled, MLED_ON, 1); 306ASUS_LED_HANDLER(mled, MLED_ON);
301ASUS_LED_HANDLER(pled, PLED_ON, 0); 307ASUS_LED_HANDLER(pled, PLED_ON);
302ASUS_LED_HANDLER(rled, RLED_ON, 0); 308ASUS_LED_HANDLER(rled, RLED_ON);
303ASUS_LED_HANDLER(tled, TLED_ON, 0); 309ASUS_LED_HANDLER(tled, TLED_ON);
304 310
305static int get_lcd_state(void) 311static 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
460static ssize_t store_status(const char *buf, size_t count, 466static 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,
508static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, 514static 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;