diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/asus-laptop.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index dfec565ffa82..f1bab721ff55 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -30,7 +30,7 @@ | |||
30 | * Eric Burghard - LED display support for W1N | 30 | * Eric Burghard - LED display support for W1N |
31 | * Josh Green - Light Sens support | 31 | * Josh Green - Light Sens support |
32 | * Thomas Tuttle - His first patch for led support was very helpfull | 32 | * Thomas Tuttle - His first patch for led support was very helpfull |
33 | * | 33 | * Sam Lin - GPS support |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #include <linux/autoconf.h> | 36 | #include <linux/autoconf.h> |
@@ -83,6 +83,7 @@ | |||
83 | #define PLED_ON 0x20 //Phone LED | 83 | #define PLED_ON 0x20 //Phone LED |
84 | #define GLED_ON 0x40 //Gaming LED | 84 | #define GLED_ON 0x40 //Gaming LED |
85 | #define LCD_ON 0x80 //LCD backlight | 85 | #define LCD_ON 0x80 //LCD backlight |
86 | #define GPS_ON 0x100 //GPS | ||
86 | 87 | ||
87 | #define ASUS_LOG ASUS_HOTK_FILE ": " | 88 | #define ASUS_LOG ASUS_HOTK_FILE ": " |
88 | #define ASUS_ERR KERN_ERR ASUS_LOG | 89 | #define ASUS_ERR KERN_ERR ASUS_LOG |
@@ -162,6 +163,12 @@ ASUS_HANDLE(display_get, "\\_SB.PCI0.P0P1.VGA.GETD", /* A6B, A6K A6R A7D F3JM L | |||
162 | ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ | 163 | ASUS_HANDLE(ls_switch, ASUS_HOTK_PREFIX "ALSC"); /* Z71A Z71V */ |
163 | ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ | 164 | ASUS_HANDLE(ls_level, ASUS_HOTK_PREFIX "ALSL"); /* Z71A Z71V */ |
164 | 165 | ||
166 | /* GPS */ | ||
167 | /* R2H use different handle for GPS on/off */ | ||
168 | ASUS_HANDLE(gps_on, ASUS_HOTK_PREFIX "SDON"); /* R2H */ | ||
169 | ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF"); /* R2H */ | ||
170 | ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST"); | ||
171 | |||
165 | /* | 172 | /* |
166 | * This is the main structure, we can use it to store anything interesting | 173 | * This is the main structure, we can use it to store anything interesting |
167 | * about the hotk device | 174 | * about the hotk device |
@@ -278,12 +285,27 @@ static int read_wireless_status(int mask) | |||
278 | return (hotk->status & mask) ? 1 : 0; | 285 | return (hotk->status & mask) ? 1 : 0; |
279 | } | 286 | } |
280 | 287 | ||
288 | static int read_gps_status(void) { | ||
289 | ulong status; | ||
290 | acpi_status rv = AE_OK; | ||
291 | |||
292 | rv = acpi_evaluate_integer(gps_status_handle, NULL, NULL, &status); | ||
293 | if (ACPI_FAILURE(rv)) | ||
294 | printk(ASUS_WARNING "Error reading GPS status\n"); | ||
295 | else | ||
296 | return status ? 1 : 0; | ||
297 | |||
298 | return (hotk->status & GPS_ON) ? 1 : 0; | ||
299 | } | ||
300 | |||
281 | /* Generic LED functions */ | 301 | /* Generic LED functions */ |
282 | static int read_status(int mask) | 302 | static int read_status(int mask) |
283 | { | 303 | { |
284 | /* There is a special method for both wireless devices */ | 304 | /* There is a special method for both wireless devices */ |
285 | if (mask == BT_ON || mask == WL_ON) | 305 | if (mask == BT_ON || mask == WL_ON) |
286 | return read_wireless_status(mask); | 306 | return read_wireless_status(mask); |
307 | else if(mask == GPS_ON) | ||
308 | return read_gps_status(); | ||
287 | 309 | ||
288 | return (hotk->status & mask) ? 1 : 0; | 310 | return (hotk->status & mask) ? 1 : 0; |
289 | } | 311 | } |
@@ -299,6 +321,10 @@ static void write_status(acpi_handle handle, int out, int mask) | |||
299 | case GLED_ON: | 321 | case GLED_ON: |
300 | out = (out & 0x1) + 1; | 322 | out = (out & 0x1) + 1; |
301 | break; | 323 | break; |
324 | case GPS_ON: | ||
325 | handle = (out) ? gps_on_handle : gps_off_handle; | ||
326 | out = 0x02; | ||
327 | break; | ||
302 | default: | 328 | default: |
303 | out &= 0x1; | 329 | out &= 0x1; |
304 | break; | 330 | break; |
@@ -667,6 +693,21 @@ static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr, | |||
667 | return rv; | 693 | return rv; |
668 | } | 694 | } |
669 | 695 | ||
696 | /* | ||
697 | * GPS | ||
698 | */ | ||
699 | static ssize_t show_gps(struct device *dev, | ||
700 | struct device_attribute *attr, char *buf) | ||
701 | { | ||
702 | return sprintf(buf, "%d\n", read_status(GPS_ON)); | ||
703 | } | ||
704 | |||
705 | static ssize_t store_gps(struct device *dev, struct device_attribute *attr, | ||
706 | const char *buf, size_t count) | ||
707 | { | ||
708 | return store_status(buf, count, NULL, GPS_ON); | ||
709 | } | ||
710 | |||
670 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) | 711 | static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) |
671 | { | 712 | { |
672 | /* TODO Find a better way to handle events count. */ | 713 | /* TODO Find a better way to handle events count. */ |
@@ -715,6 +756,7 @@ static ASUS_CREATE_DEVICE_ATTR(display); | |||
715 | static ASUS_CREATE_DEVICE_ATTR(ledd); | 756 | static ASUS_CREATE_DEVICE_ATTR(ledd); |
716 | static ASUS_CREATE_DEVICE_ATTR(ls_switch); | 757 | static ASUS_CREATE_DEVICE_ATTR(ls_switch); |
717 | static ASUS_CREATE_DEVICE_ATTR(ls_level); | 758 | static ASUS_CREATE_DEVICE_ATTR(ls_level); |
759 | static ASUS_CREATE_DEVICE_ATTR(gps); | ||
718 | 760 | ||
719 | static struct attribute *asuspf_attributes[] = { | 761 | static struct attribute *asuspf_attributes[] = { |
720 | &dev_attr_infos.attr, | 762 | &dev_attr_infos.attr, |
@@ -724,6 +766,7 @@ static struct attribute *asuspf_attributes[] = { | |||
724 | &dev_attr_ledd.attr, | 766 | &dev_attr_ledd.attr, |
725 | &dev_attr_ls_switch.attr, | 767 | &dev_attr_ls_switch.attr, |
726 | &dev_attr_ls_level.attr, | 768 | &dev_attr_ls_level.attr, |
769 | &dev_attr_gps.attr, | ||
727 | NULL | 770 | NULL |
728 | }; | 771 | }; |
729 | 772 | ||
@@ -763,6 +806,9 @@ static void asus_hotk_add_fs(void) | |||
763 | ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); | 806 | ASUS_SET_DEVICE_ATTR(ls_level, 0644, show_lslvl, store_lslvl); |
764 | ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); | 807 | ASUS_SET_DEVICE_ATTR(ls_switch, 0644, show_lssw, store_lssw); |
765 | } | 808 | } |
809 | |||
810 | if(gps_status_handle && gps_on_handle && gps_off_handle) | ||
811 | ASUS_SET_DEVICE_ATTR(gps, 0644, show_gps, store_gps); | ||
766 | } | 812 | } |
767 | 813 | ||
768 | static int asus_handle_init(char *name, acpi_handle * handle, | 814 | static int asus_handle_init(char *name, acpi_handle * handle, |
@@ -893,6 +939,10 @@ static int asus_hotk_get_info(void) | |||
893 | if (ASUS_HANDLE_INIT(ls_switch)) | 939 | if (ASUS_HANDLE_INIT(ls_switch)) |
894 | ASUS_HANDLE_INIT(ls_level); | 940 | ASUS_HANDLE_INIT(ls_level); |
895 | 941 | ||
942 | ASUS_HANDLE_INIT(gps_on); | ||
943 | ASUS_HANDLE_INIT(gps_off); | ||
944 | ASUS_HANDLE_INIT(gps_status); | ||
945 | |||
896 | kfree(model); | 946 | kfree(model); |
897 | 947 | ||
898 | return AE_OK; | 948 | return AE_OK; |
@@ -981,6 +1031,9 @@ static int asus_hotk_add(struct acpi_device *device) | |||
981 | if (ls_level_handle) | 1031 | if (ls_level_handle) |
982 | set_light_sens_level(hotk->light_level); | 1032 | set_light_sens_level(hotk->light_level); |
983 | 1033 | ||
1034 | /* GPS is on by default */ | ||
1035 | write_status(NULL, 1, GPS_ON); | ||
1036 | |||
984 | end: | 1037 | end: |
985 | if (result) { | 1038 | if (result) { |
986 | kfree(hotk->name); | 1039 | kfree(hotk->name); |