platform/x86: Add Acer Wireless Radio Control driver
PATCH 1/1 platform/x86: Add Acer Wireless Radio Control driver
New Acer laptops in 2018 will have a separate ACPI device for notifications from the airplane mode hotkey. The device name in the DSDT is SMKB and its ACPI _HID is 10251229.
For these models, when the airplane mode hotkey (Fn+F3) pressed, a query 0x02 is started in the Embedded Controller, and all this query does is a notify SMKB with the value 0x80.
Scope (_SB.PCI0.LPCB.EC0)
{
(...)
Method (_Q02, 0, NotSerialized) // _Qxx: EC Query
{
HKEV (0x2, One)
Notify (SMKB, 0x80) // Status Change
}
}Based on code from asus-wireless
--- drivers/platform/x86/Kconfig | 14 ++++++ drivers/platform/x86/Makefile | 1 + drivers/platform/x86/acer-wireless.c | 86 ++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 drivers/platform/x86/acer-wireless.c
drivers/platform/x86/Kconfig +14 -0
@@ -36,6 +36,20 @@ config ACER_WMI If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M here. +config ACER_WIRELESS + tristate "Acer Wireless Radio Control Driver" + depends on ACPI + depends on INPUT + ---help--- + The Acer Wireless Radio Control handles the airplane mode hotkey + present on new Acer laptops. + + Say Y or M here if you have an Acer notebook with an airplane mode + hotkey. + + If you choose to compile this driver as a module the module will be + called acer-wireless. + config ACERHDF tristate "Acer Aspire One temperature and fan driver" depends on ACPI && THERMAL
drivers/platform/x86/Makefile +1 -0
@@ -19,6 +19,7 @@ obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o +obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o obj-$(CONFIG_ACERHDF) += acerhdf.o obj-$(CONFIG_HP_ACCEL) += hp_accel.o obj-$(CONFIG_HP_WIRELESS) += hp-wireless.o
drivers/platform/x86/acer-wireless.c new file +86 -0
86 lines not on this page · raw message
Signature · 1 line
2.11.0
Quoted 18 lines · Chris Chiu
New Acer laptops in 2018 will have a separate ACPI device for notifications from the airplane mode hotkey. The device name in the DSDT is SMKB and its ACPI
_HIDis 10251229.For these models, when the airplane mode hotkey (Fn+F3) pressed, a query
0x02is started in the Embedded Controller, and all this query does is a notify SMKB with the value0x80.Scope (_SB.PCI0.LPCB.EC0) { (...) Method (_Q02, 0, NotSerialized) // _Qxx: EC Query { HKEV (0x2, One) Notify (SMKB, 0x80) // Status Change } }
Quoted 1 line
Based on code from asus-wireless
Thanks for the patch! Overall looks good, comment below.
drivers/platform/x86/acer-wireless.c line 13
Quoted 4 lines
drivers/platform/x86/acer-wireless.c new file +3
-0+#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h>
Either from that, not both.
drivers/platform/x86/acer-wireless.c line 17
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +4
-0+#include <linux/types.h> +#include <linux/acpi.h> +#include <linux/input.h> +#include <linux/pci_ids.h>
Why do you need this one?
Okay, you are using Vendor ID from there.
Besides above, please keep them in alphabetical order.
drivers/platform/x86/acer-wireless.c line 21
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +4
-0+ +struct acer_wireless_data { +struct input_dev *idev; +struct acpi_device *adev;
Do you need this one?
I suppose whenever you need struct device out of it you may find it via input->parent. Right?
drivers/platform/x86/acer-wireless.c line 24
Quoted 3 lines
drivers/platform/x86/acer-wireless.c new file +3
-0+}; + +static const struct acpi_device_id device_ids[] = {
acer_wireless_acpi_ids
drivers/platform/x86/acer-wireless.c line 34
Quoted 11 lines
drivers/platform/x86/acer-wireless.c new file +10
-0+ {"10251229", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE (acpi, device_ids); + +static void acer_wireless_notify (struct acpi_device *adev,u32 event) +{ +struct acer_wireless_data *data =acpi_driver_data (adev); + +dev_dbg (&adev->dev,"event=%#x\n" , event);
This makes sense after the check, otherwise you will get two messages in a row.
Quoted 6 lines
drivers/platform/x86/acer-wireless.c new file +5
-0+if (event !=0x80 ) { +dev_notice (&adev->dev,"Unknown SMKB event: %#x\n" , event); +return ; + } +input_report_key (data->idev,KEY_RFKILL ,1 );
drivers/platform/x86/acer-wireless.c line 60
Quoted 10 lines
drivers/platform/x86/acer-wireless.c new file +8
-0+input_report_key (data->idev,KEY_RFKILL ,0 ); + data->idev =devm_input_allocate_device (&adev->dev); +if (!data->idev) +return -ENOMEM ; + data->idev->name ="Acer Wireless Radio Control" ; + data->idev->phys ="acer-wireless/input0" ; + data->idev->id.bustype =BUS_HOST ; + data->idev->id.vendor =PCI_VENDOR_ID_AI ;
Where is product ID?
I suppose you can use ACPI ID (which is basically PCI one in ACPI table) and split it.
u32 id = simple_strtoul(...ACPI ID..., 16);
vendor = id >> 16;
product = id & 0xffff;
Or just hard code product ID for now.
drivers/platform/x86/acer-wireless.c line 71
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +5
-0+static int acer_wireless_remove (struct acpi_device *adev) +{ +return 0 ; +} +
No need UI suppose.
Quoted 1 line
+MODULE_LICENSE("GPL");
GPL v2 ?
Signature · 2 lines
With Best Regards, Andy Shevchenko
Quoted 46 lines · Andy Shevchenko
Quoted 18 lines · Chris Chiu
New Acer laptops in 2018 will have a separate ACPI device for notifications from the airplane mode hotkey. The device name in the DSDT is SMKB and its ACPI
_HIDis 10251229.For these models, when the airplane mode hotkey (Fn+F3) pressed, a query
0x02is started in the Embedded Controller, and all this query does is a notify SMKB with the value0x80.Scope (_SB.PCI0.LPCB.EC0) { (...) Method (_Q02, 0, NotSerialized) // _Qxx: EC Query { HKEV (0x2, One) Notify (SMKB, 0x80) // Status Change } }Quoted 1 line
Based on code from asus-wireless
Thanks for the patch! Overall looks good, comment below.
drivers/platform/x86/acer-wireless.c line 13
Quoted 4 lines
drivers/platform/x86/acer-wireless.c new file +3
-0+#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> Either from that, not both.
drivers/platform/x86/acer-wireless.c line 17
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +4
-0+#include <linux/types.h> +#include <linux/acpi.h> +#include <linux/input.h> +#include <linux/pci_ids.h> Why do you need this one?
Okay, you are using Vendor ID from there.Besides above, please keep them in alphabetical order.
Quoted 3 lines
drivers/platform/x86/acer-wireless.c new file +3
-0+ +struct acer_wireless_data { +struct input_dev *idev;
Quoted 6 lines
Quoted 1 line
+ struct
acpi_device*adev;Do you need this one?
I suppose whenever you need struct device out of it you may find it viainput->parent. Right?
But I think it would make life easier to have the following line in .notify callback
struct acer_wireless_data * data = acpi_driver_data(adev);
I can get its parent acer_wireless_data and point to input_dev easier.
Quoted 42 lines
drivers/platform/x86/acer-wireless.c line 24
Quoted 3 lines
drivers/platform/x86/acer-wireless.c new file +3
-0+}; + +static const struct acpi_device_id device_ids[] = {
acer_wireless_acpi_idsdrivers/platform/x86/acer-wireless.c line 34
Quoted 11 lines
drivers/platform/x86/acer-wireless.c new file +10
-0+ {"10251229", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE (acpi, device_ids); + +static void acer_wireless_notify (struct acpi_device *adev,u32 event) +{ +struct acer_wireless_data *data =acpi_driver_data (adev); + +dev_dbg (&adev->dev,"event=%#x\n" , event);This makes sense after the check, otherwise you will get two messages in a row.
Quoted 6 lines
drivers/platform/x86/acer-wireless.c new file +5
-0+if (event !=0x80 ) { +dev_notice (&adev->dev,"Unknown SMKB event: %#x\n" , event); +return ; + } +input_report_key (data->idev,KEY_RFKILL ,1 );drivers/platform/x86/acer-wireless.c line 60
Quoted 10 lines
drivers/platform/x86/acer-wireless.c new file +8
-0+input_report_key (data->idev,KEY_RFKILL ,0 ); + data->idev =devm_input_allocate_device (&adev->dev); +if (!data->idev) +return -ENOMEM ; + data->idev->name ="Acer Wireless Radio Control" ; + data->idev->phys ="acer-wireless/input0" ; + data->idev->id.bustype =BUS_HOST ; + data->idev->id.vendor =PCI_VENDOR_ID_AI ;Where is product ID?
I suppose you can use ACPI ID (which is basically PCI one in ACPI table) and split it.
Quoted 7 lines
u32 id =
simple_strtoul(...ACPI ID..., 16);vendor = id >> 16;
product = id &0xffff;Or just hard code product ID for now.
Thanks. I will hard code the product ID for now with data->idev->id.vendor = 0x1229;
Quoted 8 lines
drivers/platform/x86/acer-wireless.c line 71
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +5
-0+static int acer_wireless_remove (struct acpi_device *adev) +{ +return 0 ; +} +No need UI suppose.
You mean remove this acer_wireless_remove which does nothing? Will do.
Quoted 7 lines
Quoted 1 line
+MODULE_LICENSE("GPL");
GPL v2 ?
--
With Best Regards,
Andy Shevchenko
Quoted 15 lines · Chris Chiu
Quoted 6 lines · Andy Shevchenko
Quoted 3 lines · Chris Chiu
drivers/platform/x86/acer-wireless.c new file +3
-0+ +struct acer_wireless_data { +struct input_dev *idev;Quoted 6 lines
Quoted 1 line
+ struct
acpi_device*adev;Do you need this one?
I suppose whenever you need struct device out of it you may find it viainput->parent. Right?
Quoted 5 lines
But I think it would make life easier to have the following line in .notify callback
structacer_wireless_data* data =acpi_driver_data(adev);I can get its parent
acer_wireless_dataand point toinput_deveasier.
Yes, though if I'm not mistaken, you may get rid completely of your custom container and use struct input_dev for accessing that via to_acpi_device(idev->dev.parent).
It would be less code, less data structures, cleaner view. Right?
Quoted 10 lines
Quoted 8 lines
drivers/platform/x86/acer-wireless.c line 71
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +5
-0+static int acer_wireless_remove (struct acpi_device *adev) +{ +return 0 ; +} +No need UI suppose.
You mean remove this
acer_wireless_removewhich does nothing? Will do.
Correct.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Quoted 38 lines · Andy Shevchenko
Quoted 15 lines · Chris Chiu
Quoted 6 lines · Andy Shevchenko
Quoted 3 lines · Chris Chiu
drivers/platform/x86/acer-wireless.c new file +3
-0+ +struct acer_wireless_data { +struct input_dev *idev;Quoted 6 lines
Quoted 1 line
+ struct
acpi_device*adev;Do you need this one?
I suppose whenever you need struct device out of it you may find it viainput->parent. Right?Quoted 5 lines
But I think it would make life easier to have the following line in .notify callback
structacer_wireless_data* data =acpi_driver_data(adev);I can get its parent
acer_wireless_dataand point toinput_deveasier.Yes, though if I'm not mistaken, you may get rid completely of your custom container and use struct
input_devfor accessing that viato_acpi_device(idev->dev.parent).It would be less code, less data structures, cleaner view. Right?
Quoted 9 lines
Quoted 8 lines
drivers/platform/x86/acer-wireless.c line 71
Quoted 5 lines
drivers/platform/x86/acer-wireless.c new file +5
-0+static int acer_wireless_remove (struct acpi_device *adev) +{ +return 0 ; +} +No need UI suppose.
Quoted 7 lines
Quoted 1 line
You mean remove this
acer_wireless_removewhich does nothing? Will do.Correct.
--
With Best Regards,
Andy Shevchenko
I think I get your point. Will soon have a v2 patch later.