diff mbox

[2/5] asus-wmi: Create quirk for airplane_mode LED

Message ID 1454951123-27470-3-git-send-email-jprvita@endlessm.com (mailing list archive)
State Deferred, archived
Headers show

Commit Message

João Paulo Rechi Vita Feb. 8, 2016, 5:05 p.m. UTC
Some Asus laptops that have an "airplane mode" indicator LED, also have
the WMI WLAN user bit set, and the following bits in their DSDT:

Scope (_SB)
{
  (...)
  Device (ATKD)
  {
    (...)
    Method (WMNB, 3, Serialized)
    {
      (...)
      If (LEqual (IIA0, 0x00010002))
      {
        OWGD (IIA1)
        Return (One)
      }
    }
  }
}

So when asus-wmi uses ASUS_WMI_DEVID_WLAN_LED (0x00010002) to store the
wlan state, it drives the airplane mode indicator LED (through the call
to OWGD) in an inverted fashion: the LED is ON when airplane mode is OFF
(since wlan is ON), and vice-versa.

This commit creates a quirk to not register a RFKill switch at all for
these laptops, to allow the asus-wireless driver to drive the airplane
mode LED correctly. It also adds a match to that quirk for the Asus
X555UB.

Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com>
---
 drivers/platform/x86/asus-nb-wmi.c | 13 +++++++++++++
 drivers/platform/x86/asus-wmi.c    |  8 +++++---
 drivers/platform/x86/asus-wmi.h    |  1 +
 3 files changed, 19 insertions(+), 3 deletions(-)

Comments

Corentin Chary May 25, 2016, 7:13 a.m. UTC | #1
On Mon, Feb 8, 2016 at 6:05 PM, João Paulo Rechi Vita <jprvita@gmail.com> wrote:
> Some Asus laptops that have an "airplane mode" indicator LED, also have
> the WMI WLAN user bit set, and the following bits in their DSDT:
>
> Scope (_SB)
> {
>   (...)
>   Device (ATKD)
>   {
>     (...)
>     Method (WMNB, 3, Serialized)
>     {
>       (...)
>       If (LEqual (IIA0, 0x00010002))
>       {
>         OWGD (IIA1)
>         Return (One)
>       }
>     }
>   }
> }
>
> So when asus-wmi uses ASUS_WMI_DEVID_WLAN_LED (0x00010002) to store the
> wlan state, it drives the airplane mode indicator LED (through the call
> to OWGD) in an inverted fashion: the LED is ON when airplane mode is OFF
> (since wlan is ON), and vice-versa.
>
> This commit creates a quirk to not register a RFKill switch at all for
> these laptops, to allow the asus-wireless driver to drive the airplane
> mode LED correctly. It also adds a match to that quirk for the Asus
> X555UB.

This is really something that should get merged, multiple users are
affected by this. I do not own any of these laptops, but would there
be a way to detect this behavior instead of having static quircks ?

> Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com>
> ---
>  drivers/platform/x86/asus-nb-wmi.c | 13 +++++++++++++
>  drivers/platform/x86/asus-wmi.c    |  8 +++++---
>  drivers/platform/x86/asus-wmi.h    |  1 +
>  3 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
> index 131fee2..cfee863 100644
> --- a/drivers/platform/x86/asus-nb-wmi.c
> +++ b/drivers/platform/x86/asus-nb-wmi.c
> @@ -78,6 +78,10 @@ static struct quirk_entry quirk_asus_x200ca = {
>         .wapf = 2,
>  };
>
> +static struct quirk_entry quirk_no_rfkill = {
> +       .no_rfkill = true,
> +};
> +
>  static int dmi_matched(const struct dmi_system_id *dmi)
>  {
>         quirks = dmi->driver_data;
> @@ -297,6 +301,15 @@ static const struct dmi_system_id asus_quirks[] = {
>                 },
>                 .driver_data = &quirk_asus_x200ca,
>         },
> +       {
> +               .callback = dmi_matched,
> +               .ident = "ASUSTeK COMPUTER INC. X555UB",
> +               .matches = {
> +                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
> +                       DMI_MATCH(DMI_PRODUCT_NAME, "X555UB"),
> +               },
> +               .driver_data = &quirk_no_rfkill,
> +       },
>         {},
>  };
>
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index a96630d..370fa347 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -2064,9 +2064,11 @@ static int asus_wmi_add(struct platform_device *pdev)
>         if (err)
>                 goto fail_leds;
>
> -       err = asus_wmi_rfkill_init(asus);
> -       if (err)
> -               goto fail_rfkill;
> +       if (!asus->driver->quirks->no_rfkill) {
> +               err = asus_wmi_rfkill_init(asus);
> +               if (err)
> +                       goto fail_rfkill;
> +       }
>
>         /* Some Asus desktop boards export an acpi-video backlight interface,
>            stop this from showing up */
> diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
> index 4da4c8b..5de1df5 100644
> --- a/drivers/platform/x86/asus-wmi.h
> +++ b/drivers/platform/x86/asus-wmi.h
> @@ -38,6 +38,7 @@ struct key_entry;
>  struct asus_wmi;
>
>  struct quirk_entry {
> +       bool no_rfkill;
>         bool hotplug_wireless;
>         bool scalar_panel_brightness;
>         bool store_backlight_power;
> --
> 2.5.0
>
João Paulo Rechi Vita May 25, 2016, 4:20 p.m. UTC | #2
On 25 May 2016 at 03:13, Corentin Chary <corentin.chary@gmail.com> wrote:
> On Mon, Feb 8, 2016 at 6:05 PM, João Paulo Rechi Vita <jprvita@gmail.com> wrote:
>> Some Asus laptops that have an "airplane mode" indicator LED, also have
>> the WMI WLAN user bit set, and the following bits in their DSDT:
>>
>> Scope (_SB)
>> {
>>   (...)
>>   Device (ATKD)
>>   {
>>     (...)
>>     Method (WMNB, 3, Serialized)
>>     {
>>       (...)
>>       If (LEqual (IIA0, 0x00010002))
>>       {
>>         OWGD (IIA1)
>>         Return (One)
>>       }
>>     }
>>   }
>> }
>>
>> So when asus-wmi uses ASUS_WMI_DEVID_WLAN_LED (0x00010002) to store the
>> wlan state, it drives the airplane mode indicator LED (through the call
>> to OWGD) in an inverted fashion: the LED is ON when airplane mode is OFF
>> (since wlan is ON), and vice-versa.
>>
>> This commit creates a quirk to not register a RFKill switch at all for
>> these laptops, to allow the asus-wireless driver to drive the airplane
>> mode LED correctly. It also adds a match to that quirk for the Asus
>> X555UB.
>
> This is really something that should get merged, multiple users are
> affected by this. I do not own any of these laptops, but would there
> be a way to detect this behavior instead of having static quircks ?
>

I could not come up with a way to detect this, but I can probably
gather most (if not all) of the DSDTs if want to have a look at them.
In any case, I must say the asus-wireless patches that actually drive
the LED are still blocked on a couple of rfkill patches that implement
a new airplane-mode led trigger, which I'm trying to have merged for
the past two kernel releases. I can send a new series with only the
asus-wmi patches if you want to have them merged first, but in this
case the LED will not work (I imagine it will be always OFF) instead
of working in an inverted fashion. Just let me know!

Regards,

--
João Paulo Rechi Vita
http://about.me/jprvita
--
To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Darren Hart May 25, 2016, 9:24 p.m. UTC | #3
On Wed, May 25, 2016 at 09:13:23AM +0200, Corentin Chary wrote:
> On Mon, Feb 8, 2016 at 6:05 PM, João Paulo Rechi Vita <jprvita@gmail.com> wrote:
> > Some Asus laptops that have an "airplane mode" indicator LED, also have
> > the WMI WLAN user bit set, and the following bits in their DSDT:
> >
> > Scope (_SB)
> > {
> >   (...)
> >   Device (ATKD)
> >   {
> >     (...)
> >     Method (WMNB, 3, Serialized)
> >     {
> >       (...)
> >       If (LEqual (IIA0, 0x00010002))
> >       {
> >         OWGD (IIA1)
> >         Return (One)
> >       }
> >     }
> >   }
> > }
> >
> > So when asus-wmi uses ASUS_WMI_DEVID_WLAN_LED (0x00010002) to store the
> > wlan state, it drives the airplane mode indicator LED (through the call
> > to OWGD) in an inverted fashion: the LED is ON when airplane mode is OFF
> > (since wlan is ON), and vice-versa.
> >
> > This commit creates a quirk to not register a RFKill switch at all for
> > these laptops, to allow the asus-wireless driver to drive the airplane
> > mode LED correctly. It also adds a match to that quirk for the Asus
> > X555UB.
> 
> This is really something that should get merged, multiple users are
> affected by this. I do not own any of these laptops, but would there
> be a way to detect this behavior instead of having static quircks ?

I believe this is all still blocked on the underlying RFKILL support. João,
correct me if I'm mistaken.
João Paulo Rechi Vita June 13, 2016, 9:02 p.m. UTC | #4
On 25 May 2016 at 17:24, Darren Hart <dvhart@infradead.org> wrote:
>

(...)

> I believe this is all still blocked on the underlying RFKILL support. João,
> correct me if I'm mistaken.
>

That was true at the time of this message, but the RFKill
infrastructure that I was planning to use here is not going to be
merged. So the new plan is now to simply expose the LED to userspace
under a meaningful name ("asus-wireless::airplane") and have the
userspace people look for LEDs with this suffix and drive then
accordingly.

I have just sent an updated patchset.

--
João Paulo Rechi Vita
http://about.me/jprvita
--
To unsubscribe from this list: send the line "unsubscribe platform-driver-x86" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 131fee2..cfee863 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -78,6 +78,10 @@  static struct quirk_entry quirk_asus_x200ca = {
 	.wapf = 2,
 };
 
+static struct quirk_entry quirk_no_rfkill = {
+	.no_rfkill = true,
+};
+
 static int dmi_matched(const struct dmi_system_id *dmi)
 {
 	quirks = dmi->driver_data;
@@ -297,6 +301,15 @@  static const struct dmi_system_id asus_quirks[] = {
 		},
 		.driver_data = &quirk_asus_x200ca,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. X555UB",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X555UB"),
+		},
+		.driver_data = &quirk_no_rfkill,
+	},
 	{},
 };
 
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index a96630d..370fa347 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -2064,9 +2064,11 @@  static int asus_wmi_add(struct platform_device *pdev)
 	if (err)
 		goto fail_leds;
 
-	err = asus_wmi_rfkill_init(asus);
-	if (err)
-		goto fail_rfkill;
+	if (!asus->driver->quirks->no_rfkill) {
+		err = asus_wmi_rfkill_init(asus);
+		if (err)
+			goto fail_rfkill;
+	}
 
 	/* Some Asus desktop boards export an acpi-video backlight interface,
 	   stop this from showing up */
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 4da4c8b..5de1df5 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -38,6 +38,7 @@  struct key_entry;
 struct asus_wmi;
 
 struct quirk_entry {
+	bool no_rfkill;
 	bool hotplug_wireless;
 	bool scalar_panel_brightness;
 	bool store_backlight_power;