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,

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/@/)
--
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