| From 717aff9ea9d3895907f80d69703ea515fcd6d489 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= <jprvita@gmail.com> |
| Date: Mon, 20 Feb 2017 14:50:22 -0500 |
| Subject: [PATCH] platform/x86: asus-wmi: Detect quirk_no_rfkill from the DSDT |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit 71050ae7bf83e4d71a859257d11adc5de517073e upstream. |
| |
| 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 skips registering RFKill switches at all for these laptops, |
| to allow the asus-wireless driver to drive the airplane mode LED |
| correctly through the ASHS ACPI device. Relying on the presence of ASHS |
| and ASUS_WMI_DSTS_USER_BIT avoids adding DMI-based quirks for at least |
| 21 different laptops. |
| |
| Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com> |
| Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c |
| index 8cd689a4e3b8..f081008a19e1 100644 |
| --- a/drivers/platform/x86/asus-wmi.c |
| +++ b/drivers/platform/x86/asus-wmi.c |
| @@ -159,6 +159,8 @@ MODULE_LICENSE("GPL"); |
| #define USB_INTEL_XUSB2PR 0xD0 |
| #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 |
| |
| +static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; |
| + |
| struct bios_args { |
| u32 arg0; |
| u32 arg1; |
| @@ -2051,6 +2053,16 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) |
| return 0; |
| } |
| |
| +static bool ashs_present(void) |
| +{ |
| + int i = 0; |
| + while (ashs_ids[i]) { |
| + if (acpi_dev_found(ashs_ids[i++])) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| /* |
| * WMI Driver |
| */ |
| @@ -2095,6 +2107,13 @@ static int asus_wmi_add(struct platform_device *pdev) |
| if (err) |
| goto fail_leds; |
| |
| + asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); |
| + if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) |
| + asus->driver->wlan_ctrl_by_user = 1; |
| + |
| + if (asus->driver->wlan_ctrl_by_user && ashs_present()) |
| + asus->driver->quirks->no_rfkill = 1; |
| + |
| if (!asus->driver->quirks->no_rfkill) { |
| err = asus_wmi_rfkill_init(asus); |
| if (err) |
| @@ -2131,10 +2150,6 @@ static int asus_wmi_add(struct platform_device *pdev) |
| if (err) |
| goto fail_debugfs; |
| |
| - asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); |
| - if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) |
| - asus->driver->wlan_ctrl_by_user = 1; |
| - |
| return 0; |
| |
| fail_debugfs: |
| -- |
| 2.12.0 |
| |