diff options
author | Len Brown <len.brown@intel.com> | 2007-04-28 22:18:21 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-04-28 22:18:21 -0400 |
commit | eaf60d6924759eb2a249c0b568533a90c238061b (patch) | |
tree | 08f625eb473247fdbbb2651166d26ffe7f3c6434 | |
parent | de46c33745f5e2ad594c72f2cf5f490861b16ce1 (diff) | |
parent | 8ec555c2c4c6c33759a1dbb13fa8f3b14fc77e10 (diff) |
Pull asus into release branch
-rw-r--r-- | drivers/misc/asus-laptop.c | 151 |
1 files changed, 95 insertions, 56 deletions
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index 4b232124a1ab..65c32a95e121 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor | 5 | * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor |
6 | * Copyright (C) 2006 Corentin Chary | 6 | * Copyright (C) 2006-2007 Corentin Chary |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -48,7 +48,7 @@ | |||
48 | #include <acpi/acpi_bus.h> | 48 | #include <acpi/acpi_bus.h> |
49 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
50 | 50 | ||
51 | #define ASUS_LAPTOP_VERSION "0.40" | 51 | #define ASUS_LAPTOP_VERSION "0.41" |
52 | 52 | ||
53 | #define ASUS_HOTK_NAME "Asus Laptop Support" | 53 | #define ASUS_HOTK_NAME "Asus Laptop Support" |
54 | #define ASUS_HOTK_CLASS "hotkey" | 54 | #define ASUS_HOTK_CLASS "hotkey" |
@@ -81,7 +81,8 @@ | |||
81 | #define TLED_ON 0x08 //touchpad LED | 81 | #define TLED_ON 0x08 //touchpad LED |
82 | #define RLED_ON 0x10 //Record LED | 82 | #define RLED_ON 0x10 //Record LED |
83 | #define PLED_ON 0x20 //Phone LED | 83 | #define PLED_ON 0x20 //Phone LED |
84 | #define LCD_ON 0x40 //LCD backlight | 84 | #define GLED_ON 0x40 //Gaming LED |
85 | #define LCD_ON 0x80 //LCD backlight | ||
85 | 86 | ||
86 | #define ASUS_LOG ASUS_HOTK_FILE ": " | 87 | #define ASUS_LOG ASUS_HOTK_FILE ": " |
87 | #define ASUS_ERR KERN_ERR ASUS_LOG | 88 | #define ASUS_ERR KERN_ERR ASUS_LOG |
@@ -94,6 +95,19 @@ MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Corentin Chary"); | |||
94 | MODULE_DESCRIPTION(ASUS_HOTK_NAME); | 95 | MODULE_DESCRIPTION(ASUS_HOTK_NAME); |
95 | MODULE_LICENSE("GPL"); | 96 | MODULE_LICENSE("GPL"); |
96 | 97 | ||
98 | /* WAPF defines the behavior of the Fn+Fx wlan key | ||
99 | * The significance of values is yet to be found, but | ||
100 | * most of the time: | ||
101 | * 0x0 will do nothing | ||
102 | * 0x1 will allow to control the device with Fn+Fx key. | ||
103 | * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key | ||
104 | * 0x5 like 0x1 or 0x4 | ||
105 | * So, if something doesn't work as you want, just try other values =) | ||
106 | */ | ||
107 | static uint wapf = 1; | ||
108 | module_param(wapf, uint, 0644); | ||
109 | MODULE_PARM_DESC(wapf, "WAPF value"); | ||
110 | |||
97 | #define ASUS_HANDLE(object, paths...) \ | 111 | #define ASUS_HANDLE(object, paths...) \ |
98 | static acpi_handle object##_handle = NULL; \ | 112 | static acpi_handle object##_handle = NULL; \ |
99 | static char *object##_paths[] = { paths } | 113 | static char *object##_paths[] = { paths } |
@@ -103,6 +117,7 @@ ASUS_HANDLE(mled_set, ASUS_HOTK_PREFIX "MLED"); | |||
103 | ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED"); | 117 | ASUS_HANDLE(tled_set, ASUS_HOTK_PREFIX "TLED"); |
104 | ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */ | 118 | ASUS_HANDLE(rled_set, ASUS_HOTK_PREFIX "RLED"); /* W1JC */ |
105 | ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */ | 119 | ASUS_HANDLE(pled_set, ASUS_HOTK_PREFIX "PLED"); /* A7J */ |
120 | ASUS_HANDLE(gled_set, ASUS_HOTK_PREFIX "GLED"); /* G1, G2 (probably) */ | ||
106 | 121 | ||
107 | /* LEDD */ | 122 | /* LEDD */ |
108 | ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM"); | 123 | ASUS_HANDLE(ledd_set, ASUS_HOTK_PREFIX "SLCM"); |
@@ -221,6 +236,7 @@ ASUS_LED(mled, "mail"); | |||
221 | ASUS_LED(tled, "touchpad"); | 236 | ASUS_LED(tled, "touchpad"); |
222 | ASUS_LED(rled, "record"); | 237 | ASUS_LED(rled, "record"); |
223 | ASUS_LED(pled, "phone"); | 238 | ASUS_LED(pled, "phone"); |
239 | ASUS_LED(gled, "gaming"); | ||
224 | 240 | ||
225 | /* | 241 | /* |
226 | * This function evaluates an ACPI method, given an int as parameter, the | 242 | * This function evaluates an ACPI method, given an int as parameter, the |
@@ -245,32 +261,19 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val, | |||
245 | return (status == AE_OK); | 261 | return (status == AE_OK); |
246 | } | 262 | } |
247 | 263 | ||
248 | static int read_acpi_int(acpi_handle handle, const char *method, int *val, | ||
249 | struct acpi_object_list *params) | ||
250 | { | ||
251 | struct acpi_buffer output; | ||
252 | union acpi_object out_obj; | ||
253 | acpi_status status; | ||
254 | |||
255 | output.length = sizeof(out_obj); | ||
256 | output.pointer = &out_obj; | ||
257 | |||
258 | status = acpi_evaluate_object(handle, (char *)method, params, &output); | ||
259 | *val = out_obj.integer.value; | ||
260 | return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); | ||
261 | } | ||
262 | |||
263 | static int read_wireless_status(int mask) | 264 | static int read_wireless_status(int mask) |
264 | { | 265 | { |
265 | int status; | 266 | ulong status; |
267 | acpi_status rv = AE_OK; | ||
266 | 268 | ||
267 | if (!wireless_status_handle) | 269 | if (!wireless_status_handle) |
268 | return (hotk->status & mask) ? 1 : 0; | 270 | return (hotk->status & mask) ? 1 : 0; |
269 | 271 | ||
270 | if (read_acpi_int(wireless_status_handle, NULL, &status, NULL)) { | 272 | rv = acpi_evaluate_integer(wireless_status_handle, NULL, NULL, &status); |
271 | return (status & mask) ? 1 : 0; | 273 | if (ACPI_FAILURE(rv)) |
272 | } else | ||
273 | printk(ASUS_WARNING "Error reading Wireless status\n"); | 274 | printk(ASUS_WARNING "Error reading Wireless status\n"); |
275 | else | ||
276 | return (status & mask) ? 1 : 0; | ||
274 | 277 | ||
275 | return (hotk->status & mask) ? 1 : 0; | 278 | return (hotk->status & mask) ? 1 : 0; |
276 | } | 279 | } |
@@ -285,19 +288,28 @@ static int read_status(int mask) | |||
285 | return (hotk->status & mask) ? 1 : 0; | 288 | return (hotk->status & mask) ? 1 : 0; |
286 | } | 289 | } |
287 | 290 | ||
288 | static void write_status(acpi_handle handle, int out, int mask, int invert) | 291 | static void write_status(acpi_handle handle, int out, int mask) |
289 | { | 292 | { |
290 | hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask); | 293 | hotk->status = (out) ? (hotk->status | mask) : (hotk->status & ~mask); |
291 | 294 | ||
292 | if (invert) /* invert target value */ | 295 | switch (mask) { |
296 | case MLED_ON: | ||
293 | out = !out & 0x1; | 297 | out = !out & 0x1; |
298 | break; | ||
299 | case GLED_ON: | ||
300 | out = (out & 0x1) + 1; | ||
301 | break; | ||
302 | default: | ||
303 | out &= 0x1; | ||
304 | break; | ||
305 | } | ||
294 | 306 | ||
295 | if (handle && !write_acpi_int(handle, NULL, out, NULL)) | 307 | if (handle && !write_acpi_int(handle, NULL, out, NULL)) |
296 | printk(ASUS_WARNING " write failed\n"); | 308 | printk(ASUS_WARNING " write failed %x\n", mask); |
297 | } | 309 | } |
298 | 310 | ||
299 | /* /sys/class/led handlers */ | 311 | /* /sys/class/led handlers */ |
300 | #define ASUS_LED_HANDLER(object, mask, invert) \ | 312 | #define ASUS_LED_HANDLER(object, mask) \ |
301 | static void object##_led_set(struct led_classdev *led_cdev, \ | 313 | static void object##_led_set(struct led_classdev *led_cdev, \ |
302 | enum led_brightness value) \ | 314 | enum led_brightness value) \ |
303 | { \ | 315 | { \ |
@@ -307,13 +319,14 @@ static void write_status(acpi_handle handle, int out, int mask, int invert) | |||
307 | static void object##_led_update(struct work_struct *ignored) \ | 319 | static void object##_led_update(struct work_struct *ignored) \ |
308 | { \ | 320 | { \ |
309 | int value = object##_led_wk; \ | 321 | int value = object##_led_wk; \ |
310 | write_status(object##_set_handle, value, (mask), (invert)); \ | 322 | write_status(object##_set_handle, value, (mask)); \ |
311 | } | 323 | } |
312 | 324 | ||
313 | ASUS_LED_HANDLER(mled, MLED_ON, 1); | 325 | ASUS_LED_HANDLER(mled, MLED_ON); |
314 | ASUS_LED_HANDLER(pled, PLED_ON, 0); | 326 | ASUS_LED_HANDLER(pled, PLED_ON); |
315 | ASUS_LED_HANDLER(rled, RLED_ON, 0); | 327 | ASUS_LED_HANDLER(rled, RLED_ON); |
316 | ASUS_LED_HANDLER(tled, TLED_ON, 0); | 328 | ASUS_LED_HANDLER(tled, TLED_ON); |
329 | ASUS_LED_HANDLER(gled, GLED_ON); | ||
317 | 330 | ||
318 | static int get_lcd_state(void) | 331 | static int get_lcd_state(void) |
319 | { | 332 | { |
@@ -338,7 +351,7 @@ static int set_lcd_state(int value) | |||
338 | printk(ASUS_WARNING "Error switching LCD\n"); | 351 | printk(ASUS_WARNING "Error switching LCD\n"); |
339 | } | 352 | } |
340 | 353 | ||
341 | write_status(NULL, lcd, LCD_ON, 0); | 354 | write_status(NULL, lcd, LCD_ON); |
342 | return 0; | 355 | return 0; |
343 | } | 356 | } |
344 | 357 | ||
@@ -354,9 +367,11 @@ static void lcd_blank(int blank) | |||
354 | 367 | ||
355 | static int read_brightness(struct backlight_device *bd) | 368 | static int read_brightness(struct backlight_device *bd) |
356 | { | 369 | { |
357 | int value; | 370 | ulong value; |
371 | acpi_status rv = AE_OK; | ||
358 | 372 | ||
359 | if (!read_acpi_int(brightness_get_handle, NULL, &value, NULL)) | 373 | rv = acpi_evaluate_integer(brightness_get_handle, NULL, NULL, &value); |
374 | if (ACPI_FAILURE(rv)) | ||
360 | printk(ASUS_WARNING "Error reading brightness\n"); | 375 | printk(ASUS_WARNING "Error reading brightness\n"); |
361 | 376 | ||
362 | return value; | 377 | return value; |
@@ -403,8 +418,10 @@ static ssize_t show_infos(struct device *dev, | |||
403 | struct device_attribute *attr, char *page) | 418 | struct device_attribute *attr, char *page) |
404 | { | 419 | { |
405 | int len = 0; | 420 | int len = 0; |
406 | int temp; | 421 | ulong temp; |
407 | char buf[16]; //enough for all info | 422 | char buf[16]; //enough for all info |
423 | acpi_status rv = AE_OK; | ||
424 | |||
408 | /* | 425 | /* |
409 | * We use the easy way, we don't care of off and count, so we don't set eof | 426 | * We use the easy way, we don't care of off and count, so we don't set eof |
410 | * to 1 | 427 | * to 1 |
@@ -418,9 +435,10 @@ static ssize_t show_infos(struct device *dev, | |||
418 | * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. | 435 | * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card. |
419 | * The significance of others is yet to be found. | 436 | * The significance of others is yet to be found. |
420 | */ | 437 | */ |
421 | if (read_acpi_int(hotk->handle, "SFUN", &temp, NULL)) | 438 | rv = acpi_evaluate_integer(hotk->handle, "SFUN", NULL, &temp); |
422 | len += | 439 | if (!ACPI_FAILURE(rv)) |
423 | sprintf(page + len, "SFUN value : 0x%04x\n", temp); | 440 | len += sprintf(page + len, "SFUN value : 0x%04x\n", |
441 | (uint) temp); | ||
424 | /* | 442 | /* |
425 | * Another value for userspace: the ASYM method returns 0x02 for | 443 | * Another value for userspace: the ASYM method returns 0x02 for |
426 | * battery low and 0x04 for battery critical, its readings tend to be | 444 | * battery low and 0x04 for battery critical, its readings tend to be |
@@ -428,9 +446,10 @@ static ssize_t show_infos(struct device *dev, | |||
428 | * Note: since not all the laptops provide this method, errors are | 446 | * Note: since not all the laptops provide this method, errors are |
429 | * silently ignored. | 447 | * silently ignored. |
430 | */ | 448 | */ |
431 | if (read_acpi_int(hotk->handle, "ASYM", &temp, NULL)) | 449 | rv = acpi_evaluate_integer(hotk->handle, "ASYM", NULL, &temp); |
432 | len += | 450 | if (!ACPI_FAILURE(rv)) |
433 | sprintf(page + len, "ASYM value : 0x%04x\n", temp); | 451 | len += sprintf(page + len, "ASYM value : 0x%04x\n", |
452 | (uint) temp); | ||
434 | if (asus_info) { | 453 | if (asus_info) { |
435 | snprintf(buf, 16, "%d", asus_info->length); | 454 | snprintf(buf, 16, "%d", asus_info->length); |
436 | len += sprintf(page + len, "DSDT length : %s\n", buf); | 455 | len += sprintf(page + len, "DSDT length : %s\n", buf); |
@@ -465,7 +484,7 @@ static int parse_arg(const char *buf, unsigned long count, int *val) | |||
465 | } | 484 | } |
466 | 485 | ||
467 | static ssize_t store_status(const char *buf, size_t count, | 486 | static ssize_t store_status(const char *buf, size_t count, |
468 | acpi_handle handle, int mask, int invert) | 487 | acpi_handle handle, int mask) |
469 | { | 488 | { |
470 | int rv, value; | 489 | int rv, value; |
471 | int out = 0; | 490 | int out = 0; |
@@ -474,7 +493,7 @@ static ssize_t store_status(const char *buf, size_t count, | |||
474 | if (rv > 0) | 493 | if (rv > 0) |
475 | out = value ? 1 : 0; | 494 | out = value ? 1 : 0; |
476 | 495 | ||
477 | write_status(handle, out, mask, invert); | 496 | write_status(handle, out, mask); |
478 | 497 | ||
479 | return rv; | 498 | return rv; |
480 | } | 499 | } |
@@ -515,7 +534,7 @@ static ssize_t show_wlan(struct device *dev, | |||
515 | static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, | 534 | static ssize_t store_wlan(struct device *dev, struct device_attribute *attr, |
516 | const char *buf, size_t count) | 535 | const char *buf, size_t count) |
517 | { | 536 | { |
518 | return store_status(buf, count, wl_switch_handle, WL_ON, 0); | 537 | return store_status(buf, count, wl_switch_handle, WL_ON); |
519 | } | 538 | } |
520 | 539 | ||
521 | /* | 540 | /* |
@@ -531,7 +550,7 @@ static ssize_t store_bluetooth(struct device *dev, | |||
531 | struct device_attribute *attr, const char *buf, | 550 | struct device_attribute *attr, const char *buf, |
532 | size_t count) | 551 | size_t count) |
533 | { | 552 | { |
534 | return store_status(buf, count, bt_switch_handle, BT_ON, 0); | 553 | return store_status(buf, count, bt_switch_handle, BT_ON); |
535 | } | 554 | } |
536 | 555 | ||
537 | /* | 556 | /* |
@@ -547,12 +566,15 @@ static void set_display(int value) | |||
547 | 566 | ||
548 | static int read_display(void) | 567 | static int read_display(void) |
549 | { | 568 | { |
550 | int value = 0; | 569 | ulong value = 0; |
570 | acpi_status rv = AE_OK; | ||
551 | 571 | ||
552 | /* In most of the case, we know how to set the display, but sometime | 572 | /* In most of the case, we know how to set the display, but sometime |
553 | we can't read it */ | 573 | we can't read it */ |
554 | if (display_get_handle) { | 574 | if (display_get_handle) { |
555 | if (!read_acpi_int(display_get_handle, NULL, &value, NULL)) | 575 | rv = acpi_evaluate_integer(display_get_handle, NULL, |
576 | NULL, &value); | ||
577 | if (ACPI_FAILURE(rv)) | ||
556 | printk(ASUS_WARNING "Error reading display status\n"); | 578 | printk(ASUS_WARNING "Error reading display status\n"); |
557 | } | 579 | } |
558 | 580 | ||
@@ -656,10 +678,10 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | |||
656 | * switched | 678 | * switched |
657 | */ | 679 | */ |
658 | if (event == ATKD_LCD_ON) { | 680 | if (event == ATKD_LCD_ON) { |
659 | write_status(NULL, 1, LCD_ON, 0); | 681 | write_status(NULL, 1, LCD_ON); |
660 | lcd_blank(FB_BLANK_UNBLANK); | 682 | lcd_blank(FB_BLANK_UNBLANK); |
661 | } else if (event == ATKD_LCD_OFF) { | 683 | } else if (event == ATKD_LCD_OFF) { |
662 | write_status(NULL, 0, LCD_ON, 0); | 684 | write_status(NULL, 0, LCD_ON); |
663 | lcd_blank(FB_BLANK_POWERDOWN); | 685 | lcd_blank(FB_BLANK_POWERDOWN); |
664 | } | 686 | } |
665 | 687 | ||
@@ -771,7 +793,7 @@ static int asus_hotk_get_info(void) | |||
771 | { | 793 | { |
772 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 794 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
773 | union acpi_object *model = NULL; | 795 | union acpi_object *model = NULL; |
774 | int bsts_result, hwrs_result; | 796 | ulong bsts_result, hwrs_result; |
775 | char *string = NULL; | 797 | char *string = NULL; |
776 | acpi_status status; | 798 | acpi_status status; |
777 | 799 | ||
@@ -794,11 +816,16 @@ static int asus_hotk_get_info(void) | |||
794 | } | 816 | } |
795 | 817 | ||
796 | /* This needs to be called for some laptops to init properly */ | 818 | /* This needs to be called for some laptops to init properly */ |
797 | if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result, NULL)) | 819 | status = |
820 | acpi_evaluate_integer(hotk->handle, "BSTS", NULL, &bsts_result); | ||
821 | if (ACPI_FAILURE(status)) | ||
798 | printk(ASUS_WARNING "Error calling BSTS\n"); | 822 | printk(ASUS_WARNING "Error calling BSTS\n"); |
799 | else if (bsts_result) | 823 | else if (bsts_result) |
800 | printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n", | 824 | printk(ASUS_NOTICE "BSTS called, 0x%02x returned\n", |
801 | bsts_result); | 825 | (uint) bsts_result); |
826 | |||
827 | /* This too ... */ | ||
828 | write_acpi_int(hotk->handle, "CWAP", wapf, NULL); | ||
802 | 829 | ||
803 | /* | 830 | /* |
804 | * Try to match the object returned by INIT to the specific model. | 831 | * Try to match the object returned by INIT to the specific model. |
@@ -831,6 +858,7 @@ static int asus_hotk_get_info(void) | |||
831 | ASUS_HANDLE_INIT(tled_set); | 858 | ASUS_HANDLE_INIT(tled_set); |
832 | ASUS_HANDLE_INIT(rled_set); | 859 | ASUS_HANDLE_INIT(rled_set); |
833 | ASUS_HANDLE_INIT(pled_set); | 860 | ASUS_HANDLE_INIT(pled_set); |
861 | ASUS_HANDLE_INIT(gled_set); | ||
834 | 862 | ||
835 | ASUS_HANDLE_INIT(ledd_set); | 863 | ASUS_HANDLE_INIT(ledd_set); |
836 | 864 | ||
@@ -840,7 +868,9 @@ static int asus_hotk_get_info(void) | |||
840 | * The significance of others is yet to be found. | 868 | * The significance of others is yet to be found. |
841 | * If we don't find the method, we assume the device are present. | 869 | * If we don't find the method, we assume the device are present. |
842 | */ | 870 | */ |
843 | if (!read_acpi_int(hotk->handle, "HRWS", &hwrs_result, NULL)) | 871 | status = |
872 | acpi_evaluate_integer(hotk->handle, "HRWS", NULL, &hwrs_result); | ||
873 | if (ACPI_FAILURE(status)) | ||
844 | hwrs_result = WL_HWRS | BT_HWRS; | 874 | hwrs_result = WL_HWRS | BT_HWRS; |
845 | 875 | ||
846 | if (hwrs_result & WL_HWRS) | 876 | if (hwrs_result & WL_HWRS) |
@@ -928,11 +958,15 @@ static int asus_hotk_add(struct acpi_device *device) | |||
928 | asus_hotk_found = 1; | 958 | asus_hotk_found = 1; |
929 | 959 | ||
930 | /* WLED and BLED are on by default */ | 960 | /* WLED and BLED are on by default */ |
931 | write_status(bt_switch_handle, 1, BT_ON, 0); | 961 | write_status(bt_switch_handle, 1, BT_ON); |
932 | write_status(wl_switch_handle, 1, WL_ON, 0); | 962 | write_status(wl_switch_handle, 1, WL_ON); |
963 | |||
964 | /* If the h/w switch is off, we need to check the real status */ | ||
965 | write_status(NULL, read_status(BT_ON), BT_ON); | ||
966 | write_status(NULL, read_status(WL_ON), WL_ON); | ||
933 | 967 | ||
934 | /* LCD Backlight is on by default */ | 968 | /* LCD Backlight is on by default */ |
935 | write_status(NULL, 1, LCD_ON, 0); | 969 | write_status(NULL, 1, LCD_ON); |
936 | 970 | ||
937 | /* LED display is off by default */ | 971 | /* LED display is off by default */ |
938 | hotk->ledd_status = 0xFFF; | 972 | hotk->ledd_status = 0xFFF; |
@@ -991,6 +1025,7 @@ static void asus_led_exit(void) | |||
991 | ASUS_LED_UNREGISTER(tled); | 1025 | ASUS_LED_UNREGISTER(tled); |
992 | ASUS_LED_UNREGISTER(pled); | 1026 | ASUS_LED_UNREGISTER(pled); |
993 | ASUS_LED_UNREGISTER(rled); | 1027 | ASUS_LED_UNREGISTER(rled); |
1028 | ASUS_LED_UNREGISTER(gled); | ||
994 | 1029 | ||
995 | destroy_workqueue(led_workqueue); | 1030 | destroy_workqueue(led_workqueue); |
996 | } | 1031 | } |
@@ -1062,6 +1097,10 @@ static int asus_led_init(struct device *dev) | |||
1062 | if (rv) | 1097 | if (rv) |
1063 | return rv; | 1098 | return rv; |
1064 | 1099 | ||
1100 | rv = ASUS_LED_REGISTER(gled, dev); | ||
1101 | if (rv) | ||
1102 | return rv; | ||
1103 | |||
1065 | led_workqueue = create_singlethread_workqueue("led_workqueue"); | 1104 | led_workqueue = create_singlethread_workqueue("led_workqueue"); |
1066 | if (!led_workqueue) | 1105 | if (!led_workqueue) |
1067 | return -ENOMEM; | 1106 | return -ENOMEM; |