Re: [PATCH 1/2] asus-wmi: record wlan status while controlling by user app

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Dear Corentin,

>From ASUS, for old machines, they use 0x00010012 to turn on/off the wlan led
but now use 0x00010002
So, 0x00010012 is reused to store the wlan status nowadays if wlan is
controlled by user.

Best regards,
AceLan Kao.

2012/7/23 AceLan Kao <acelan.kao@xxxxxxxxxxxxx>:
> Dear Corentin,
>
> 2012/7/23 Corentin Chary <corentincj@xxxxxxxxxx>:
>> On Mon, Jul 23, 2012 at 5:27 AM, AceLan Kao <acelan.kao@xxxxxxxxxxxxx> wrote:
>>> Dear Corentin,
>>>
>>> 2012/7/20 Corentin Chary <corentincj@xxxxxxxxxx>:
>>>> On Fri, Jul 20, 2012 at 5:26 AM, AceLan Kao <acelan.kao@xxxxxxxxxxxxx> wrote:
>>>>> 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
>>>>
>>>> Will it handle the LED too, or do you have to call 0x00010012 ?
>>> In this case, we don't have to worry about the LED, BIOS will pull
>>> up/down the LED pin
>>> after receiving the enable/disable wireless command through WMI.
>>>
>>>>
>>>>> (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.
>>>>
>>>> That means WMIMethod(DSTS, 0x00010011, 0) will do nothing ? Or will it
>>>> control both the led and the device ?
>>> Yes, WMIMethod(DSTS, 0x00010011, 0) will do nothing if we try to
>>> enable/disable it.
>>> It won't turn on/off the wifi nor the LED.
>>> But, we still can read the status of wireless through this command, but
>>> need to use 0x00010012 to set wifi status.
>>>
>>>> How can you then call WMIMethod(DSTS, 0x00010012, 0/1) since nobody
>>>> switched wlan on or off ?
>>>> If you just want a way to control the led, expose it under
>>>> /sys/class/leds, and remove wlan from /sys/class/rfkill if it doesn't
>>>> work.
>>> ASUS' BIOS engineer told us that it's a way to change the status of
>>> wifi(read from id 0x00010011)
>>> by writing the value to 0x00010012, and ms windows application do that as well.
>>> It's a poor design by ASUS' BIOS, they really surprise me while telling me that.
>>>
>>> But, the advantage of doing this is the value stored in the 0x00010012
>>> (should be read from id 0x00010011) will be preserved to next reboot.
>>> So that we can track the status of wifi.
>>> And once we can get the correct wifi state, we then can block/unblock
>>> wifi while boot up.
>>> And it will have the same behavior as the one controlled by BIOS.
>>
>> So, in this case, 0x00010012 controls:
>> - The LED
>> - The LED *and* the WLAN device
>> - The WLAN device
>> - Nothing, it just stores a value
>>
>> Just to be sure to understand ... Be sure to add a comment when using
>> 0x00010012 to tell exactly what it does.
> From what I have heard, it should be 4 (stores a value but should be
> read from 0x00010011, instead of from 0x00010012)
> But I also raise this question to our PM and he will help us to
> clarify this from ASUS tomorrow.
>
>>
>>>>
>>>>> (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 <acelan.kao@xxxxxxxxxxxxx>
>>>>> ---
>>>>>  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
>>>>
>>>> What's the difference between this one and ASUS_WMI_DEVID_WIRELESS_LED ?
>>>> What is really  0x00010002 ?
>>> That's another weird part, that's the name defined in the ASUS WMI spec.
>>> Please see the attached pic.
>>> 0x00010002 is the read one which can control the wireless LED,
>>> I don't know why there is another one exists in the spec.
>>>
>>>>>  #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;
>>>>
>>>> Don't use a static variable, add a field into struct asus_wmi instead.
>>> got it.
>>>
>>>>
>>>>>         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);
>>>>
>>>> Maybe you could read that on startup instead of using lazy loading ?
>>>> Read the state of the wlan device, and set a flag "led should be controlled"
>>> ok
>>>
>>>>
>>>>> +               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)
>>>>
>>>> While this patch work, I'll prefer an approach using a led class and a
>>>> led trigger. The led trigger would be set by default, but the user
>>>> would also be able to switch the trigger to another one, or to control
>>>> the led using /sys/class/leds/
>>> I think the problem is not so seriously, we just need to record the wifi status
>>> if the wifi device is controlled by application.
>>> And the solution is to store the status in 0x00010012.
>>> So that rfkill could work as expected.
>>>
>>> Best regards,
>>> AceLan Kao.
>>>
>>> --
>>> Chia-Lin Kao(AceLan)
>>> http://blog.acelan.idv.tw/
>>> E-Mail: acelan.kaoATcanonical.com (s/AT/@/)
>>
>>
>>
>> --
>> Corentin Chary
>> http://xf.iksaif.net
>> --
>> To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>
> --
> Chia-Lin Kao(AceLan)
> http://blog.acelan.idv.tw/
> E-Mail: acelan.kaoATcanonical.com (s/AT/@/)



-- 
Chia-Lin Kao(AceLan)
http://blog.acelan.idv.tw/
E-Mail: acelan.kaoATcanonical.com (s/AT/@/)
--
To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux