aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorCorentin Chary <corentincj@iksaif.net>2010-01-25 17:29:24 -0500
committerCorentin Chary <corentincj@iksaif.net>2010-02-28 13:35:13 -0500
commit18e1311ee71a67497a33521be61ddf6562fa22c0 (patch)
tree1d14c250e2461bda6d0472496272c5f7ced58457 /drivers/platform
parent47ee0e99524a7ee0185e3c38423cc17cc1318ddc (diff)
asus-laptop: add gps rfkill
The rfkill subsystem will enable gps by default. Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig1
-rw-r--r--drivers/platform/x86/asus-laptop.c65
2 files changed, 59 insertions, 7 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 7f5a222c2325..527abf1b5bd1 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -59,6 +59,7 @@ config ASUS_LAPTOP
59 select NEW_LEDS 59 select NEW_LEDS
60 select BACKLIGHT_CLASS_DEVICE 60 select BACKLIGHT_CLASS_DEVICE
61 depends on INPUT 61 depends on INPUT
62 depends on RFKILL || RFKILL = n
62 select INPUT_SPARSEKMAP 63 select INPUT_SPARSEKMAP
63 ---help--- 64 ---help---
64 This is the new Linux driver for Asus laptops. It may also support some 65 This is the new Linux driver for Asus laptops. It may also support some
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 1d61094d3b5f..e1df92a22de9 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -50,6 +50,7 @@
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
51#include <linux/input.h> 51#include <linux/input.h>
52#include <linux/input/sparse-keymap.h> 52#include <linux/input/sparse-keymap.h>
53#include <linux/rfkill.h>
53 54
54#define ASUS_LAPTOP_VERSION "0.42" 55#define ASUS_LAPTOP_VERSION "0.42"
55 56
@@ -238,6 +239,8 @@ struct asus_laptop {
238 bool have_rsts; 239 bool have_rsts;
239 int lcd_state; 240 int lcd_state;
240 241
242 struct rfkill *gps_rfkill;
243
241 acpi_handle handle; /* the handle of the hotk device */ 244 acpi_handle handle; /* the handle of the hotk device */
242 u32 ledd_status; /* status of the LED display */ 245 u32 ledd_status; /* status of the LED display */
243 u8 light_level; /* light sensor level */ 246 u8 light_level; /* light sensor level */
@@ -1006,7 +1009,6 @@ static ssize_t store_lslvl(struct device *dev, struct device_attribute *attr,
1006 1009
1007/* 1010/*
1008 * GPS 1011 * GPS
1009 * TODO: use rfkill
1010 */ 1012 */
1011static int asus_gps_status(struct asus_laptop *asus) 1013static int asus_gps_status(struct asus_laptop *asus)
1012{ 1014{
@@ -1052,10 +1054,58 @@ static ssize_t store_gps(struct device *dev, struct device_attribute *attr,
1052 ret = asus_gps_switch(asus, !!value); 1054 ret = asus_gps_switch(asus, !!value);
1053 if (ret) 1055 if (ret)
1054 return ret; 1056 return ret;
1057 rfkill_set_sw_state(asus->gps_rfkill, !value);
1055 return rv; 1058 return rv;
1056} 1059}
1057 1060
1058/* 1061/*
1062 * rfkill
1063 */
1064static int asus_gps_rfkill_set(void *data, bool blocked)
1065{
1066 acpi_handle handle = data;
1067
1068 return asus_gps_switch(handle, !blocked);
1069}
1070
1071static const struct rfkill_ops asus_gps_rfkill_ops = {
1072 .set_block = asus_gps_rfkill_set,
1073};
1074
1075static void asus_rfkill_exit(struct asus_laptop *asus)
1076{
1077 if (asus->gps_rfkill) {
1078 rfkill_unregister(asus->gps_rfkill);
1079 rfkill_destroy(asus->gps_rfkill);
1080 asus->gps_rfkill = NULL;
1081 }
1082}
1083
1084static int asus_rfkill_init(struct asus_laptop *asus)
1085{
1086 int result;
1087
1088 if (acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) ||
1089 acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) ||
1090 acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL))
1091 return 0;
1092
1093 asus->gps_rfkill = rfkill_alloc("asus-gps", &asus->platform_device->dev,
1094 RFKILL_TYPE_GPS,
1095 &asus_gps_rfkill_ops, NULL);
1096 if (!asus->gps_rfkill)
1097 return -EINVAL;
1098
1099 result = rfkill_register(asus->gps_rfkill);
1100 if (result) {
1101 rfkill_destroy(asus->gps_rfkill);
1102 asus->gps_rfkill = NULL;
1103 }
1104
1105 return result;
1106}
1107
1108/*
1059 * Input device (i.e. hotkeys) 1109 * Input device (i.e. hotkeys)
1060 */ 1110 */
1061static void asus_input_notify(struct asus_laptop *asus, int event) 1111static void asus_input_notify(struct asus_laptop *asus, int event)
@@ -1416,12 +1466,6 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
1416 asus_als_level(asus, asus->light_level); 1466 asus_als_level(asus, asus->light_level);
1417 } 1467 }
1418 1468
1419 /* GPS is on by default */
1420 if (!acpi_check_handle(asus->handle, METHOD_GPS_ON, NULL) &&
1421 !acpi_check_handle(asus->handle, METHOD_GPS_OFF, NULL) &&
1422 !acpi_check_handle(asus->handle, METHOD_GPS_STATUS, NULL))
1423 asus_gps_switch(asus, 1);
1424
1425 asus->lcd_state = 1; /* LCD should be on when the module load */ 1469 asus->lcd_state = 1; /* LCD should be on when the module load */
1426 return result; 1470 return result;
1427} 1471}
@@ -1469,9 +1513,15 @@ static int __devinit asus_acpi_add(struct acpi_device *device)
1469 if (result) 1513 if (result)
1470 goto fail_led; 1514 goto fail_led;
1471 1515
1516 result = asus_rfkill_init(asus);
1517 if (result)
1518 goto fail_rfkill;
1519
1472 asus_device_present = true; 1520 asus_device_present = true;
1473 return 0; 1521 return 0;
1474 1522
1523fail_rfkill:
1524 asus_led_exit(asus);
1475fail_led: 1525fail_led:
1476 asus_input_exit(asus); 1526 asus_input_exit(asus);
1477fail_input: 1527fail_input:
@@ -1490,6 +1540,7 @@ static int asus_acpi_remove(struct acpi_device *device, int type)
1490 struct asus_laptop *asus = acpi_driver_data(device); 1540 struct asus_laptop *asus = acpi_driver_data(device);
1491 1541
1492 asus_backlight_exit(asus); 1542 asus_backlight_exit(asus);
1543 asus_rfkill_exit(asus);
1493 asus_led_exit(asus); 1544 asus_led_exit(asus);
1494 asus_input_exit(asus); 1545 asus_input_exit(asus);
1495 asus_platform_exit(asus); 1546 asus_platform_exit(asus);