Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1421317 > unrolled thread
| Started by | "João Paulo Rechi Vita" <jprvita@gmail.com> |
|---|---|
| First post | 2016-06-13 23:00 +0200 |
| Last post | 2016-06-19 09:20 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH 0/7] asus-wireless: LED control "João Paulo Rechi Vita" <jprvita@gmail.com> - 2016-06-13 23:00 +0200
[PATCH 4/7] asus-wmi: Add quirk_no_rfkill for the Asus U303LB "João Paulo Rechi Vita" <jprvita@gmail.com> - 2016-06-13 23:00 +0200
[PATCH 1/7] asus-wireless: Toggle airplane mode LED "João Paulo Rechi Vita" <jprvita@gmail.com> - 2016-06-13 23:10 +0200
Re: [PATCH 0/7] asus-wireless: LED control Corentin Chary <corentin.chary@gmail.com> - 2016-06-19 09:20 +0200
| From | "João Paulo Rechi Vita" <jprvita@gmail.com> |
|---|---|
| Date | 2016-06-13 23:00 +0200 |
| Subject | [PATCH 0/7] asus-wireless: LED control |
| Message-ID | <rJH7H-2Zc-3@gated-at.bofh.it> |
This series adds support for controlling the airplane-mode indicator LED present in some Asus laptops. It also creates a quirk in asus-wmi so it does not create RFKill devices for platforms that use asus-wireless and where there is a competition for the LED control (see "asus-wmi: Create quirk for airplane_mode LED" for more details). João Paulo Rechi Vita (7): asus-wireless: Toggle airplane mode LED asus-wmi: Create quirk for airplane_mode LED asus-wmi: Add quirk_no_rfkill for the Asus N552VW asus-wmi: Add quirk_no_rfkill for the Asus U303LB asus-wmi: Add quirk_no_rfkill for the Asus Z550MA asus-wmi: Add quirk_no_rfkill_wapf4 for the Asus X456UF asus-wmi: Add quirk_no_rfkill_wapf4 for the Asus X456UA drivers/platform/x86/Kconfig | 2 + drivers/platform/x86/asus-nb-wmi.c | 49 ++++++++++++++++++- drivers/platform/x86/asus-wireless.c | 91 +++++++++++++++++++++++++++++++++++- drivers/platform/x86/asus-wmi.c | 8 ++-- drivers/platform/x86/asus-wmi.h | 1 + 5 files changed, 145 insertions(+), 6 deletions(-) -- 2.5.0
[toc] | [next] | [standalone]
| From | "João Paulo Rechi Vita" <jprvita@gmail.com> |
|---|---|
| Date | 2016-06-13 23:00 +0200 |
| Subject | [PATCH 4/7] asus-wmi: Add quirk_no_rfkill for the Asus U303LB |
| Message-ID | <rJH7J-2Zc-51@gated-at.bofh.it> |
| In reply to | #1421317 |
The Asus U303LB has an airplane-mode indicator LED and the WMI WLAN user
bit set, so asus-wmi uses ASUS_WMI_DEVID_WLAN_LED (0x00010002) to store
the wlan state, which has a side-effect of driving the airplane mode
indicator LED in an inverted fashion. quirk_no_rfkill prevents asus-wmi
from registering RFKill switches at all for this laptop and allows
asus-wireless to drive the LED through the ASHS ACPI device.
Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com>
Reported-by: Mousou Yuu <guogaishiwo@gmail.com>
---
drivers/platform/x86/asus-nb-wmi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 31fcde1..efae467 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -328,6 +328,15 @@ static const struct dmi_system_id asus_quirks[] = {
},
.driver_data = &quirk_no_rfkill,
},
+ {
+ .callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. U303LB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "U303LB"),
+ },
+ .driver_data = &quirk_no_rfkill,
+ },
{},
};
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | "João Paulo Rechi Vita" <jprvita@gmail.com> |
|---|---|
| Date | 2016-06-13 23:10 +0200 |
| Subject | [PATCH 1/7] asus-wireless: Toggle airplane mode LED |
| Message-ID | <rJHho-3ij-37@gated-at.bofh.it> |
| In reply to | #1421317 |
In the ASHS device we have the HSWC method, which calls either OWGD or
OWGS, depending on its parameter:
Device (ASHS)
{
Name (_HID, "ATK4002") // _HID: Hardware ID
Method (HSWC, 1, Serialized)
{
If ((Arg0 < 0x02))
{
OWGD (Arg0)
Return (One)
}
If ((Arg0 == 0x02))
{
Local0 = OWGS ()
If (Local0)
{
Return (0x05)
}
Else
{
Return (0x04)
}
}
If ((Arg0 == 0x03))
{
Return (0xFF)
}
If ((Arg0 == 0x04))
{
OWGD (Zero)
Return (One)
}
If ((Arg0 == 0x05))
{
OWGD (One)
Return (One)
}
If ((Arg0 == 0x80))
{
Return (One)
}
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
If ((MSOS () >= OSW8))
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
}
On the Asus laptops that does not have an airplane mode LED, OWGD has an
empty implementation and OWGS simply returns 0. On the ones that have an
airplane mode LED these methods have the following implementation:
Method (OWGD, 1, Serialized)
{
SGPL (0x0203000F, Arg0)
SGPL (0x0203000F, Arg0)
}
Method (OWGS, 0, Serialized)
{
Store (RGPL (0x0203000F), Local0)
Return (Local0)
}
Where OWGD(1) sets the airplane mode LED ON, OWGD(0) set it off, and
OWGS() returns its state.
This commit exposes the airplane mode indicator LED to userspace under
the name asus-wireless::airplane, so it can be driven according to
userspace's policy.
Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com>
---
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/asus-wireless.c | 91 +++++++++++++++++++++++++++++++++++-
2 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index c06bb85..e9d0144 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -604,6 +604,8 @@ config ASUS_WIRELESS
tristate "Asus Wireless Radio Control Driver"
depends on ACPI
depends on INPUT
+ select NEW_LEDS
+ select LEDS_CLASS
---help---
The Asus Wireless Radio Control handles the airplane mode hotkey
present on some Asus laptops.
diff --git a/drivers/platform/x86/asus-wireless.c b/drivers/platform/x86/asus-wireless.c
index 9ec721e..d617dfd 100644
--- a/drivers/platform/x86/asus-wireless.c
+++ b/drivers/platform/x86/asus-wireless.c
@@ -15,11 +15,78 @@
#include <linux/acpi.h>
#include <linux/input.h>
#include <linux/pci_ids.h>
+#include <linux/leds.h>
+
+#define ASUS_WIRELESS_LED_STATUS 0x2
+#define ASUS_WIRELESS_LED_OFF 0x4
+#define ASUS_WIRELESS_LED_ON 0x5
struct asus_wireless_data {
struct input_dev *idev;
+ struct acpi_device *adev;
+ struct workqueue_struct *wq;
+ struct work_struct led_work;
+ struct led_classdev led;
+ int led_state;
};
+static u64 asus_wireless_method(acpi_handle handle, const char *method,
+ int param)
+{
+ union acpi_object obj;
+ struct acpi_object_list p;
+ acpi_status s;
+ u64 ret;
+
+ acpi_handle_debug(handle, "Evaluating method %s, parameter %#x\n",
+ method, param);
+ obj.type = ACPI_TYPE_INTEGER;
+ obj.integer.value = param;
+ p.count = 1;
+ p.pointer = &obj;
+
+ s = acpi_evaluate_integer(handle, (acpi_string) method, &p, &ret);
+ if (ACPI_FAILURE(s))
+ acpi_handle_err(handle,
+ "Failed to eval method %s, param %#x (%d)\n",
+ method, param, s);
+ acpi_handle_debug(handle, "%s returned %#x\n", method, (uint) ret);
+ return ret;
+}
+
+static enum led_brightness led_state_get(struct led_classdev *led)
+{
+ struct asus_wireless_data *data;
+ int s;
+
+ data = container_of(led, struct asus_wireless_data, led);
+ s = asus_wireless_method(acpi_device_handle(data->adev), "HSWC",
+ ASUS_WIRELESS_LED_STATUS);
+ if (s == ASUS_WIRELESS_LED_ON)
+ return LED_FULL;
+ return LED_OFF;
+}
+
+static void led_state_update(struct work_struct *work)
+{
+ struct asus_wireless_data *data;
+
+ data = container_of(work, struct asus_wireless_data, led_work);
+ asus_wireless_method(acpi_device_handle(data->adev), "HSWC",
+ data->led_state);
+}
+
+static void led_state_set(struct led_classdev *led,
+ enum led_brightness value)
+{
+ struct asus_wireless_data *data;
+
+ data = container_of(led, struct asus_wireless_data, led);
+ data->led_state = value == LED_OFF ? ASUS_WIRELESS_LED_OFF :
+ ASUS_WIRELESS_LED_ON;
+ queue_work(data->wq, &data->led_work);
+}
+
static void asus_wireless_notify(struct acpi_device *adev, u32 event)
{
struct asus_wireless_data *data = acpi_driver_data(adev);
@@ -37,6 +104,7 @@ static void asus_wireless_notify(struct acpi_device *adev, u32 event)
static int asus_wireless_add(struct acpi_device *adev)
{
struct asus_wireless_data *data;
+ int err;
data = devm_kzalloc(&adev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -52,11 +120,32 @@ static int asus_wireless_add(struct acpi_device *adev)
data->idev->id.vendor = PCI_VENDOR_ID_ASUSTEK;
set_bit(EV_KEY, data->idev->evbit);
set_bit(KEY_RFKILL, data->idev->keybit);
- return input_register_device(data->idev);
+ err = input_register_device(data->idev);
+ if (err)
+ return err;
+
+ data->adev = adev;
+ data->wq = create_singlethread_workqueue("asus_wireless_workqueue");
+ if (!data->wq)
+ return -ENOMEM;
+ INIT_WORK(&data->led_work, led_state_update);
+ data->led.name = "asus-wireless::airplane";
+ data->led.brightness_set = led_state_set;
+ data->led.brightness_get = led_state_get;
+ data->led.flags = LED_CORE_SUSPENDRESUME;
+ data->led.max_brightness = 1;
+ err = devm_led_classdev_register(&adev->dev, &data->led);
+ if (err)
+ destroy_workqueue(data->wq);
+ return err;
}
static int asus_wireless_remove(struct acpi_device *adev)
{
+ struct asus_wireless_data *data = acpi_driver_data(adev);
+
+ if (data->wq)
+ destroy_workqueue(data->wq);
return 0;
}
--
2.5.0
[toc] | [prev] | [next] | [standalone]
| From | Corentin Chary <corentin.chary@gmail.com> |
|---|---|
| Date | 2016-06-19 09:20 +0200 |
| Message-ID | <rLFbr-7ts-9@gated-at.bofh.it> |
| In reply to | #1421317 |
On Mon, Jun 13, 2016 at 10:57 PM, João Paulo Rechi Vita <jprvita@gmail.com> wrote: > This series adds support for controlling the airplane-mode indicator LED > present in some Asus laptops. It also creates a quirk in asus-wmi so it does not > create RFKill devices for platforms that use asus-wireless and where there is a > competition for the LED control (see "asus-wmi: Create quirk for airplane_mode > LED" for more details). > > João Paulo Rechi Vita (7): > asus-wireless: Toggle airplane mode LED > asus-wmi: Create quirk for airplane_mode LED > asus-wmi: Add quirk_no_rfkill for the Asus N552VW > asus-wmi: Add quirk_no_rfkill for the Asus U303LB > asus-wmi: Add quirk_no_rfkill for the Asus Z550MA > asus-wmi: Add quirk_no_rfkill_wapf4 for the Asus X456UF > asus-wmi: Add quirk_no_rfkill_wapf4 for the Asus X456UA > > drivers/platform/x86/Kconfig | 2 + > drivers/platform/x86/asus-nb-wmi.c | 49 ++++++++++++++++++- > drivers/platform/x86/asus-wireless.c | 91 +++++++++++++++++++++++++++++++++++- > drivers/platform/x86/asus-wmi.c | 8 ++-- > drivers/platform/x86/asus-wmi.h | 1 + > 5 files changed, 145 insertions(+), 6 deletions(-) > > -- > 2.5.0 > Looks good to me. I hope that we can get rid of all these quirks in the near future. Reviewed-by: Corentin Chary <corentin.chary@gmail.com> -- Corentin Chary http://xf.iksaif.net
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web