diff options
| author | João Paulo Rechi Vita <jprvita@gmail.com> | 2017-02-20 14:50:22 -0500 |
|---|---|---|
| committer | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2017-02-26 10:01:48 -0500 |
| commit | 71050ae7bf83e4d71a859257d11adc5de517073e (patch) | |
| tree | 2483e8e647537b83b915d60e3da9abf2ca2f24e1 | |
| parent | 5802d0bc3fe9f598f0ff3f5fd7fd8c5c935a1b5d (diff) | |
platform/x86: asus-wmi: Detect quirk_no_rfkill from the DSDT
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>
| -rw-r--r-- | drivers/platform/x86/asus-wmi.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 43cb680adbb4..8499d3ae4257 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
| @@ -159,6 +159,8 @@ MODULE_LICENSE("GPL"); | |||
| 159 | #define USB_INTEL_XUSB2PR 0xD0 | 159 | #define USB_INTEL_XUSB2PR 0xD0 |
| 160 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 | 160 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 |
| 161 | 161 | ||
| 162 | static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; | ||
| 163 | |||
| 162 | struct bios_args { | 164 | struct bios_args { |
| 163 | u32 arg0; | 165 | u32 arg0; |
| 164 | u32 arg1; | 166 | u32 arg1; |
| @@ -2051,6 +2053,16 @@ static int asus_wmi_fan_init(struct asus_wmi *asus) | |||
| 2051 | return 0; | 2053 | return 0; |
| 2052 | } | 2054 | } |
| 2053 | 2055 | ||
| 2056 | static bool ashs_present(void) | ||
| 2057 | { | ||
| 2058 | int i = 0; | ||
| 2059 | while (ashs_ids[i]) { | ||
| 2060 | if (acpi_dev_found(ashs_ids[i++])) | ||
| 2061 | return true; | ||
| 2062 | } | ||
| 2063 | return false; | ||
| 2064 | } | ||
| 2065 | |||
| 2054 | /* | 2066 | /* |
| 2055 | * WMI Driver | 2067 | * WMI Driver |
| 2056 | */ | 2068 | */ |
| @@ -2095,6 +2107,13 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
| 2095 | if (err) | 2107 | if (err) |
| 2096 | goto fail_leds; | 2108 | goto fail_leds; |
| 2097 | 2109 | ||
| 2110 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); | ||
| 2111 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
| 2112 | asus->driver->wlan_ctrl_by_user = 1; | ||
| 2113 | |||
| 2114 | if (asus->driver->wlan_ctrl_by_user && ashs_present()) | ||
| 2115 | asus->driver->quirks->no_rfkill = 1; | ||
| 2116 | |||
| 2098 | if (!asus->driver->quirks->no_rfkill) { | 2117 | if (!asus->driver->quirks->no_rfkill) { |
| 2099 | err = asus_wmi_rfkill_init(asus); | 2118 | err = asus_wmi_rfkill_init(asus); |
| 2100 | if (err) | 2119 | if (err) |
| @@ -2134,10 +2153,6 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
| 2134 | if (err) | 2153 | if (err) |
| 2135 | goto fail_debugfs; | 2154 | goto fail_debugfs; |
| 2136 | 2155 | ||
| 2137 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); | ||
| 2138 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
| 2139 | asus->driver->wlan_ctrl_by_user = 1; | ||
| 2140 | |||
| 2141 | return 0; | 2156 | return 0; |
| 2142 | 2157 | ||
| 2143 | fail_debugfs: | 2158 | fail_debugfs: |
