Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
[~shefty/rdma-dev.git] / drivers / platform / x86 / asus-wmi.c
index 9929246895deb386a75dd08b00722f0424257595..77aadde5281c97ae423e35f5255c7e9b63d36b70 100644 (file)
@@ -411,7 +411,7 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
 
        if (retval >= 0) {
                if (level)
-                       *level = retval & 0x80 ? retval & 0x7F : 0;
+                       *level = retval & 0x7F;
                if (env)
                        *env = (retval >> 8) & 0x7F;
                retval = 0;
@@ -784,7 +784,8 @@ static int asus_new_rfkill(struct asus_wmi *asus,
        arfkill->dev_id = dev_id;
        arfkill->asus = asus;
 
-       if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless)
+       if (dev_id == ASUS_WMI_DEVID_WLAN &&
+           asus->driver->quirks->hotplug_wireless)
                *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
                                       &asus_rfkill_wlan_ops, arfkill);
        else
@@ -895,7 +896,7 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus)
        if (result && result != -ENODEV)
                goto exit;
 
-       if (!asus->driver->hotplug_wireless)
+       if (!asus->driver->quirks->hotplug_wireless)
                goto exit;
 
        result = asus_setup_pci_hotplug(asus);
@@ -1075,7 +1076,12 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus)
  */
 static int read_backlight_power(struct asus_wmi *asus)
 {
-       int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT);
+       int ret;
+       if (asus->driver->quirks->store_backlight_power)
+               ret = !asus->driver->panel_power;
+       else
+               ret = asus_wmi_get_devstate_simple(asus,
+                                                  ASUS_WMI_DEVID_BACKLIGHT);
 
        if (ret < 0)
                return ret;
@@ -1116,26 +1122,51 @@ static int read_brightness(struct backlight_device *bd)
        return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
 }
 
-static int update_bl_status(struct backlight_device *bd)
+static u32 get_scalar_command(struct backlight_device *bd)
 {
        struct asus_wmi *asus = bl_get_data(bd);
-       u32 ctrl_param;
-       int power, err;
+       u32 ctrl_param = 0;
 
-       ctrl_param = bd->props.brightness;
+       if ((asus->driver->brightness < bd->props.brightness) ||
+           bd->props.brightness == bd->props.max_brightness)
+               ctrl_param = 0x00008001;
+       else if ((asus->driver->brightness > bd->props.brightness) ||
+                bd->props.brightness == 0)
+               ctrl_param = 0x00008000;
 
-       err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
-                                   ctrl_param, NULL);
+       asus->driver->brightness = bd->props.brightness;
 
-       if (err < 0)
-               return err;
+       return ctrl_param;
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+       struct asus_wmi *asus = bl_get_data(bd);
+       u32 ctrl_param;
+       int power, err = 0;
 
        power = read_backlight_power(asus);
        if (power != -ENODEV && bd->props.power != power) {
                ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
                err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
                                            ctrl_param, NULL);
+               if (asus->driver->quirks->store_backlight_power)
+                       asus->driver->panel_power = bd->props.power;
+
+               /* When using scalar brightness, updating the brightness
+                * will mess with the backlight power */
+               if (asus->driver->quirks->scalar_panel_brightness)
+                       return err;
        }
+
+       if (asus->driver->quirks->scalar_panel_brightness)
+               ctrl_param = get_scalar_command(bd);
+       else
+               ctrl_param = bd->props.brightness;
+
+       err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
+                                   ctrl_param, NULL);
+
        return err;
 }
 
@@ -1196,10 +1227,15 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus)
 
        asus->backlight_device = bd;
 
+       if (asus->driver->quirks->store_backlight_power)
+               asus->driver->panel_power = power;
+
        bd->props.brightness = read_brightness(bd);
        bd->props.power = power;
        backlight_update_status(bd);
 
+       asus->driver->brightness = bd->props.brightness;
+
        return 0;
 }
 
@@ -1441,9 +1477,9 @@ static int asus_wmi_platform_init(struct asus_wmi *asus)
 
        /* CWAP allow to define the behavior of the Fn+F2 key,
         * this method doesn't seems to be present on Eee PCs */
-       if (asus->driver->wapf >= 0)
+       if (asus->driver->quirks->wapf >= 0)
                asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP,
-                                     asus->driver->wapf, NULL);
+                                     asus->driver->quirks->wapf, NULL);
 
        return asus_wmi_sysfs_init(asus->platform_device);
 }
@@ -1622,8 +1658,8 @@ static int asus_wmi_add(struct platform_device *pdev)
        wdrv->platform_device = pdev;
        platform_set_drvdata(asus->platform_device, asus);
 
-       if (wdrv->quirks)
-               wdrv->quirks(asus->driver);
+       if (wdrv->detect_quirks)
+               wdrv->detect_quirks(asus->driver);
 
        err = asus_wmi_platform_init(asus);
        if (err)