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); |