diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/misc/asus-laptop.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index bd963c6365c8..6f72cd529556 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
| @@ -145,6 +145,9 @@ ASUS_HANDLE(display_get, | |||
| 145 | "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ | 145 | "\\INFB", /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */ |
| 146 | "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */ | 146 | "\\SSTE"); /* A3F A6F A3N A3L M6N W3N W6A */ |
| 147 | 147 | ||
| 148 | ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ | ||
| 149 | ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ | ||
| 150 | |||
| 148 | /* | 151 | /* |
| 149 | * This is the main structure, we can use it to store anything interesting | 152 | * This is the main structure, we can use it to store anything interesting |
| 150 | * about the hotk device | 153 | * about the hotk device |
| @@ -155,6 +158,8 @@ struct asus_hotk { | |||
| 155 | acpi_handle handle; //the handle of the hotk device | 158 | acpi_handle handle; //the handle of the hotk device |
| 156 | char status; //status of the hotk, for LEDs, ... | 159 | char status; //status of the hotk, for LEDs, ... |
| 157 | u32 ledd_status; //status of the LED display | 160 | u32 ledd_status; //status of the LED display |
| 161 | u8 light_level; //light sensor level | ||
| 162 | u8 light_switch; //light sensor switch value | ||
| 158 | u16 event_count[128]; //count for each event TODO make this better | 163 | u16 event_count[128]; //count for each event TODO make this better |
| 159 | }; | 164 | }; |
| 160 | 165 | ||
| @@ -590,6 +595,62 @@ static ssize_t store_disp(struct device *dev, struct device_attribute *attr, | |||
| 590 | return rv; | 595 | return rv; |
| 591 | } | 596 | } |
| 592 | 597 | ||
| 598 | /* | ||
| 599 | * Light Sens | ||
| 600 | */ | ||
| 601 | static void set_light_sens_switch(int value) | ||
| 602 | { | ||
| 603 | if (!write_acpi_int(ls_switch_handle, NULL, value, NULL)) | ||
| 604 | printk(ASUS_WARNING "Error setting light sensor switch\n"); | ||
| 605 | hotk->light_switch = value; | ||
| 606 | } | ||
| 607 | |||
| 608 | static ssize_t show_lssw(struct device *dev, | ||
| 609 | struct device_attribute *attr, char *buf) | ||
| 610 | { | ||
| 611 | return sprintf(buf, "%d\n", hotk->light_switch); | ||
| 612 | } | ||
| 613 | |||
| 614 | static ssize_t store_lssw(struct device *dev, struct device_attribute *attr, | ||
| 615 | const char *buf, size_t count) | ||
| 616 | { | ||
| 617 | int rv, value; | ||
| 618 | |||
| 619 | rv = parse_arg(buf, count, &value); | ||
| 620 | if (rv > 0) | ||
| 621 | set_light_sens_switch(value ? 1 : 0); | ||
| 622 | |||
| 623 | return rv; | ||
| 624 | } | ||
| 625 | |||
| 626 | static void set_light_sens_level(int value) | ||
| 627 | { | ||
| 628 | if (!write_acpi_int(ls_level_handle, NULL, value, NULL)) | ||
| 629 | printk(ASUS_WARNING "Error setting light sensor level\n"); | ||
| 630 | hotk->light_level = value; | ||
| 631 | } | ||
| 632 | |||
| 633 | static ssize_t show_lslvl(struct device *dev, | ||
| 634 | struct device_attribute *attr, char *buf) | ||
| 635 | { | ||
| 636 | return sprintf(buf, "%d\n", hotk->light_level); | ||
| 637 | } | ||
| 638 | |||
| 639 | static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, | ||
| 640 | const char *buf, size_t count) | ||
| 641 | { | ||
| 642 | int rv, value; | ||
| 643 | |||
| 644 | rv = parse_arg(buf, count, &value); | ||
| 645 | if (rv > 0) { | ||
| 646 | value = (0 < value) ? ((15 < value) ? 15 : value) : 0; | ||
| 647 | /* 0 <= value <= 15 */ | ||
| 648 | set_light_sens_level(value); | ||
| 649 | } | ||
| 650 | |||
| 651 | return rv; | ||
| 652 | } | ||
| 653 | |||
| 593 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | 654 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) |
| 594 | { | 655 | { |
| 595 | /* TODO Find a better way to handle events count. */ | 656 | /* TODO Find a better way to handle events count. */ |
| @@ -636,6 +697,8 @@ static ASUS_CREATE_DEVICE_ATTR(wlan); | |||
| 636 | static ASUS_CREATE_DEVICE_ATTR(bluetooth); | 697 | static ASUS_CREATE_DEVICE_ATTR(bluetooth); |
| 637 | static ASUS_CREATE_DEVICE_ATTR(display); | 698 | static ASUS_CREATE_DEVICE_ATTR(display); |
| 638 | static ASUS_CREATE_DEVICE_ATTR(ledd); | 699 | static ASUS_CREATE_DEVICE_ATTR(ledd); |
| 700 | static ASUS_CREATE_DEVICE_ATTR(ls_switch); | ||
| 701 | static ASUS_CREATE_DEVICE_ATTR(ls_level); | ||
| 639 | 702 | ||
| 640 | static struct attribute *asuspf_attributes[] = { | 703 | static struct attribute *asuspf_attributes[] = { |
| 641 | &dev_attr_infos.attr, | 704 | &dev_attr_infos.attr, |
| @@ -643,6 +706,8 @@ static struct attribute *asuspf_attributes[] = { | |||
| 643 | &dev_attr_bluetooth.attr, | 706 | &dev_attr_bluetooth.attr, |
| 644 | &dev_attr_display.attr, | 707 | &dev_attr_display.attr, |
| 645 | &dev_attr_ledd.attr, | 708 | &dev_attr_ledd.attr, |
| 709 | &dev_attr_ls_switch.attr, | ||
| 710 | &dev_attr_ls_level.attr, | ||
| 646 | NULL | 711 | NULL |
| 647 | }; | 712 | }; |
| 648 | 713 | ||
| @@ -679,6 +744,10 @@ static void asus_hotk_add_fs(void) | |||
| 679 | if (ledd_set_handle) | 744 | if (ledd_set_handle) |
| 680 | ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd); | 745 | ASUS_SET_DEVICE_ATTR(ledd, 0644, show_ledd, store_ledd); |
| 681 | 746 | ||
| 747 | if (ls_switch_handle && ls_level_handle) { | ||
| 748 | ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); | ||
| 749 | ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); | ||
| 750 | } | ||
| 682 | } | 751 | } |
| 683 | 752 | ||
| 684 | static int asus_handle_init(char *name, acpi_handle *handle, | 753 | static int asus_handle_init(char *name, acpi_handle *handle, |
| @@ -800,6 +869,11 @@ static int asus_hotk_get_info(void) | |||
| 800 | ASUS_HANDLE_INIT(display_set); | 869 | ASUS_HANDLE_INIT(display_set); |
| 801 | ASUS_HANDLE_INIT(display_get); | 870 | ASUS_HANDLE_INIT(display_get); |
| 802 | 871 | ||
| 872 | /* There is a lot of models with "ALSL", but a few get | ||
| 873 | a real light sens, so we need to check it. */ | ||
| 874 | if(ASUS_HANDLE_INIT(ls_switch)) | ||
| 875 | ASUS_HANDLE_INIT(ls_level); | ||
| 876 | |||
| 803 | kfree(model); | 877 | kfree(model); |
| 804 | 878 | ||
| 805 | return AE_OK; | 879 | return AE_OK; |
| @@ -874,6 +948,16 @@ static int asus_hotk_add(struct acpi_device *device) | |||
| 874 | /* LED display is off by default */ | 948 | /* LED display is off by default */ |
| 875 | hotk->ledd_status = 0xFFF; | 949 | hotk->ledd_status = 0xFFF; |
| 876 | 950 | ||
| 951 | /* Set initial values of light sensor and level */ | ||
| 952 | hotk->light_switch = 1; /* Default to light sensor disabled */ | ||
| 953 | hotk->light_level = 0; /* level 5 for sensor sensitivity */ | ||
| 954 | |||
| 955 | if (ls_switch_handle) | ||
| 956 | set_light_sens_switch(hotk->light_switch); | ||
| 957 | |||
| 958 | if (ls_level_handle) | ||
| 959 | set_light_sens_level(hotk->light_level); | ||
| 960 | |||
| 877 | end: | 961 | end: |
| 878 | if (result) { | 962 | if (result) { |
| 879 | kfree(hotk->name); | 963 | kfree(hotk->name); |
