If the user bit is set, that mean BIOS can't set and record the wlan
status, it will report the value read from id ASUS_WMI_DEVID_WLAN_LED
while we query the wlan status by id ASUS_WMI_DEVID_WLAN through WMI.
So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED
while setting the wlan status through WMI.
This is also the behavior that windows app will do.

Quote from ASUS application engineer
===
When you call WMIMethod(DSTS, 0x00010011) to get WLAN status, it may return

(1) 0x00050001 (On)
(2) 0x00050000 (Off)
(3) 0x00030001 (On)
(4) 0x00030000 (Off)
(5) 0x00000002 (Unknown)

(1), (2) means that the model has hardware GPIO for WLAN, you can call
WMIMethod(DEVS, 0x00010011, 1 or 0) to turn WLAN on/off.
(3), (4) means that the model doesn’t have hardware GPIO, you need to use
API or driver library to turn WLAN on/off, and call
WMIMethod(DEVS, 0x00010012, 1 or 0) to set WLAN LED status.
After you set WLAN LED status, you can see the WLAN status is changed with
WMIMethod(DSTS, 0x00010011). Because the status is recorded lastly
(ex: Windows), you can use it for synchronization.
(5) means that the model doesn’t have WLAN device.

WLAN is the ONLY special case with upper rule.

For other device, like Bluetooth, you just need use
WMIMethod(DSTS, 0x00010013) to get, and WMIMethod(DEVS, 0x00010013, 1 or 0)
to set.
===

Signed-off-by: AceLan Kao <[email protected]>
---
 drivers/platform/x86/asus-wmi.c |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 556cbb4..638facf 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -98,6 +98,7 @@ MODULE_LICENSE("GPL");
 #define ASUS_WMI_DEVID_WIRELESS_LED    0x00010002
 #define ASUS_WMI_DEVID_CWAP            0x00010003
 #define ASUS_WMI_DEVID_WLAN            0x00010011
+#define ASUS_WMI_DEVID_WLAN_LED                0x00010012
 #define ASUS_WMI_DEVID_BLUETOOTH       0x00010013
 #define ASUS_WMI_DEVID_GPS             0x00010015
 #define ASUS_WMI_DEVID_WIMAX           0x00010017
@@ -723,10 +724,34 @@ error_workqueue:
  */
 static int asus_rfkill_set(void *data, bool blocked)
 {
+       static u32 wlan_status = 0xffffffff;
        struct asus_rfkill *priv = data;
        u32 ctrl_param = !blocked;
+       u32 dev_id = priv->dev_id;
+       int result;
 
-       return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL);
+       /*
+        * If the user bit is set, BIOS can't set and record the wlan status,
+        * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED
+        * while we query the wlan status through WMI.
+        * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED
+        * while setting the wlan status through WMI.
+        * This is also the behavior that windows app will do.
+        */
+       if (dev_id == ASUS_WMI_DEVID_WLAN) {
+               if (wlan_status == 0xffffffff)
+                       asus_wmi_get_devstate(priv->asus,
+                                             ASUS_WMI_DEVID_WLAN,
+                                             &wlan_status);
+
+               if (wlan_status &
+                  (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT))
+                       dev_id = ASUS_WMI_DEVID_WLAN_LED;
+       }
+
+       result = asus_wmi_set_devstate(dev_id, ctrl_param, NULL);
+
+       return result;
 }
 
 static void asus_rfkill_query(struct rfkill *rfkill, void *data)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" 
in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to