Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier...
[cascardo/linux.git] / drivers / platform / x86 / asus-laptop.c
index 5a6f7d7..c53b3ff 100644 (file)
@@ -29,7 +29,7 @@
  *  John Belmonte  - ACPI code for Toshiba laptop was a good starting point.
  *  Eric Burghard  - LED display support for W1N
  *  Josh Green     - Light Sens support
- *  Thomas Tuttle  - His first patch for led support was very helpfull
+ *  Thomas Tuttle  - His first patch for led support was very helpful
  *  Sam Lin        - GPS support
  */
 
@@ -50,6 +50,7 @@
 #include <linux/input/sparse-keymap.h>
 #include <linux/rfkill.h>
 #include <linux/slab.h>
+#include <linux/dmi.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
@@ -157,46 +158,9 @@ MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot "
 #define METHOD_BRIGHTNESS_SET  "SPLV"
 #define METHOD_BRIGHTNESS_GET  "GPLV"
 
-/* Backlight */
-static acpi_handle lcd_switch_handle;
-static char *lcd_switch_paths[] = {
-  "\\_SB.PCI0.SBRG.EC0._Q10",  /* All new models */
-  "\\_SB.PCI0.ISA.EC0._Q10",   /* A1x */
-  "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
-  "\\_SB.PCI0.PX40.EC0.Q10",   /* M1A */
-  "\\_SB.PCI0.LPCB.EC0._Q10",  /* P30 */
-  "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
-  "\\_SB.PCI0.PX40.Q10",       /* S1x */
-  "\\Q10"};            /* A2x, L2D, L3D, M2E */
-
 /* Display */
 #define METHOD_SWITCH_DISPLAY  "SDSP"
 
-static acpi_handle display_get_handle;
-static char *display_get_paths[] = {
-  /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */
-  "\\_SB.PCI0.P0P1.VGA.GETD",
-  /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */
-  "\\_SB.PCI0.P0P2.VGA.GETD",
-  /* A6V A6Q */
-  "\\_SB.PCI0.P0P3.VGA.GETD",
-  /* A6T, A6M */
-  "\\_SB.PCI0.P0PA.VGA.GETD",
-  /* L3C */
-  "\\_SB.PCI0.PCI1.VGAC.NMAP",
-  /* Z96F */
-  "\\_SB.PCI0.VGA.GETD",
-  /* A2D */
-  "\\ACTD",
-  /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */
-  "\\ADVG",
-  /* P30 */
-  "\\DNXT",
-  /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */
-  "\\INFB",
-  /* A3F A6F A3N A3L M6N W3N W6A */
-  "\\SSTE"};
-
 #define METHOD_ALS_CONTROL     "ALSC" /* Z71A Z71V */
 #define METHOD_ALS_LEVEL       "ALSL" /* Z71A Z71V */
 
@@ -246,7 +210,6 @@ struct asus_laptop {
 
        int wireless_status;
        bool have_rsts;
-       int lcd_state;
 
        struct rfkill *gps_rfkill;
 
@@ -559,48 +522,6 @@ error:
 /*
  * Backlight device
  */
-static int asus_lcd_status(struct asus_laptop *asus)
-{
-       return asus->lcd_state;
-}
-
-static int asus_lcd_set(struct asus_laptop *asus, int value)
-{
-       int lcd = 0;
-       acpi_status status = 0;
-
-       lcd = !!value;
-
-       if (lcd == asus_lcd_status(asus))
-               return 0;
-
-       if (!lcd_switch_handle)
-               return -ENODEV;
-
-       status = acpi_evaluate_object(lcd_switch_handle,
-                                     NULL, NULL, NULL);
-
-       if (ACPI_FAILURE(status)) {
-               pr_warning("Error switching LCD\n");
-               return -ENODEV;
-       }
-
-       asus->lcd_state = lcd;
-       return 0;
-}
-
-static void lcd_blank(struct asus_laptop *asus, int blank)
-{
-       struct backlight_device *bd = asus->backlight_device;
-
-       asus->lcd_state = (blank == FB_BLANK_UNBLANK);
-
-       if (bd) {
-               bd->props.power = blank;
-               backlight_update_status(bd);
-       }
-}
-
 static int asus_read_brightness(struct backlight_device *bd)
 {
        struct asus_laptop *asus = bl_get_data(bd);
@@ -628,16 +549,9 @@ static int asus_set_brightness(struct backlight_device *bd, int value)
 
 static int update_bl_status(struct backlight_device *bd)
 {
-       struct asus_laptop *asus = bl_get_data(bd);
-       int rv;
        int value = bd->props.brightness;
 
-       rv = asus_set_brightness(bd, value);
-       if (rv)
-               return rv;
-
-       value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0;
-       return asus_lcd_set(asus, value);
+       return asus_set_brightness(bd, value);
 }
 
 static const struct backlight_ops asusbl_ops = {
@@ -661,8 +575,7 @@ static int asus_backlight_init(struct asus_laptop *asus)
        struct backlight_properties props;
 
        if (acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) ||
-           acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) ||
-           !lcd_switch_handle)
+           acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL))
                return 0;
 
        memset(&props, 0, sizeof(struct backlight_properties));
@@ -971,41 +884,6 @@ static void asus_set_display(struct asus_laptop *asus, int value)
        return;
 }
 
-static int read_display(struct asus_laptop *asus)
-{
-       unsigned long long value = 0;
-       acpi_status rv = AE_OK;
-
-       /*
-        * In most of the case, we know how to set the display, but sometime
-        * we can't read it
-        */
-       if (display_get_handle) {
-               rv = acpi_evaluate_integer(display_get_handle, NULL,
-                                          NULL, &value);
-               if (ACPI_FAILURE(rv))
-                       pr_warning("Error reading display status\n");
-       }
-
-       value &= 0x0F; /* needed for some models, shouldn't hurt others */
-
-       return value;
-}
-
-/*
- * Now, *this* one could be more user-friendly, but so far, no-one has
- * complained. The significance of bits is the same as in store_disp()
- */
-static ssize_t show_disp(struct device *dev,
-                        struct device_attribute *attr, char *buf)
-{
-       struct asus_laptop *asus = dev_get_drvdata(dev);
-
-       if (!display_get_handle)
-               return -ENODEV;
-       return sprintf(buf, "%d\n", read_display(asus));
-}
-
 /*
  * Experimental support for display switching. As of now: 1 should activate
  * the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI.
@@ -1247,15 +1125,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event)
        struct asus_laptop *asus = acpi_driver_data(device);
        u16 count;
 
-       /*
-        * We need to tell the backlight device when the backlight power is
-        * switched
-        */
-       if (event == ATKD_LCD_ON)
-               lcd_blank(asus, FB_BLANK_UNBLANK);
-       else if (event == ATKD_LCD_OFF)
-               lcd_blank(asus, FB_BLANK_POWERDOWN);
-
        /* TODO Find a better way to handle events count. */
        count = asus->event_count[event % 128]++;
        acpi_bus_generate_proc_event(asus->device, event, count);
@@ -1282,7 +1151,7 @@ static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR,
                   show_bluetooth, store_bluetooth);
 static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
 static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
-static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
+static DEVICE_ATTR(display, S_IWUSR, NULL, store_disp);
 static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
 static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
 static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw);
@@ -1393,26 +1262,6 @@ static struct platform_driver platform_driver = {
        }
 };
 
-static int asus_handle_init(char *name, acpi_handle * handle,
-                           char **paths, int num_paths)
-{
-       int i;
-       acpi_status status;
-
-       for (i = 0; i < num_paths; i++) {
-               status = acpi_get_handle(NULL, paths[i], handle);
-               if (ACPI_SUCCESS(status))
-                       return 0;
-       }
-
-       *handle = NULL;
-       return -ENODEV;
-}
-
-#define ASUS_HANDLE_INIT(object)                                       \
-       asus_handle_init(#object, &object##_handle, object##_paths,     \
-                        ARRAY_SIZE(object##_paths))
-
 /*
  * This function is used to initialize the context with right values. In this
  * method, we can make all the detection we want, and modify the asus_laptop
@@ -1498,10 +1347,6 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
        if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL))
                asus->have_rsts = true;
 
-       /* Scheduled for removal */
-       ASUS_HANDLE_INIT(lcd_switch);
-       ASUS_HANDLE_INIT(display_get);
-
        kfree(model);
 
        return AE_OK;
@@ -1553,10 +1398,23 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
                asus_als_level(asus, asus->light_level);
        }
 
-       asus->lcd_state = 1; /* LCD should be on when the module load */
        return result;
 }
 
+static void __devinit asus_dmi_check(void)
+{
+       const char *model;
+
+       model = dmi_get_system_info(DMI_PRODUCT_NAME);
+       if (!model)
+               return;
+
+       /* On L1400B WLED control the sound card, don't mess with it ... */
+       if (strncmp(model, "L1400B", 6) == 0) {
+               wlan_status = -1;
+       }
+}
+
 static bool asus_device_present;
 
 static int __devinit asus_acpi_add(struct acpi_device *device)
@@ -1575,6 +1433,8 @@ static int __devinit asus_acpi_add(struct acpi_device *device)
        device->driver_data = asus;
        asus->device = device;
 
+       asus_dmi_check();
+
        result = asus_acpi_init(asus);
        if (result)
                goto fail_platform;