diff mbox

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

Message ID 1465851456-1421-3-git-send-email-jprvita@endlessm.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

João Paulo Rechi Vita June 13, 2016, 8:57 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 through the ASHS ACPI device. It also adds a match to
that quirk for the Asus X555UB, which is affected by this problem.

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 June 19, 2016, 7:13 a.m. UTC | #1
On Mon, Jun 13, 2016 at 10:57 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.

Have you tried check the values of SFUN for these laptops ? It's
supposed to have 1 bit per "feature"
maybe there is a bit that we could use to enable this quirk (this can
clearly be done after this whole series).

>
> 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 through the ASHS ACPI device. It also adds a match to
> that quirk for the Asus X555UB, which is affected by this problem.
>
> 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 091ca7a..90c8f41 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;
> @@ -306,6 +310,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 a26dca3..7c093a0 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -2069,9 +2069,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
>
diff mbox

Patch

diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 091ca7a..90c8f41 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;
@@ -306,6 +310,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 a26dca3..7c093a0 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -2069,9 +2069,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;