* [PATCH 1/4] Add acer wmi hotkey events support
@ 2010-10-30 16:36 Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 2/4] Enabled Acer Launch Manager mode Lee, Chun-Yi
2010-10-31 14:04 ` [PATCH 1/4] Add acer wmi hotkey events support Dmitry Torokhov
0 siblings, 2 replies; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-10-30 16:36 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-input, carlos, corentin.chary, dmitry.torokhov, tiwai,
trenn, mjg59, jbenc, Lee, Chun-Yi
Add acer wmi hotkey event support. Install a wmi notify handler to
transfer wmi event key to key code, then send out keycode through acer
wmi input device to userland.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
---
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/acer-wmi.c | 139 +++++++++++++++++++++++++++++++++++++++
2 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index cff7cc2..c242fdd 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -23,7 +23,9 @@ config ACER_WMI
depends on BACKLIGHT_CLASS_DEVICE
depends on SERIO_I8042
depends on RFKILL || RFKILL = n
+ depends on INPUT
select ACPI_WMI
+ select INPUT_SPARSEKMAP
---help---
This is a driver for newer Acer (and Wistron) laptops. It adds
wireless radio and bluetooth control, and on some laptops,
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 2badee2..930df56 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -37,6 +37,8 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <acpi/acpi_drivers.h>
@@ -48,6 +50,7 @@ MODULE_LICENSE("GPL");
#define ACER_ERR KERN_ERR ACER_LOGPREFIX
#define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
#define ACER_INFO KERN_INFO ACER_LOGPREFIX
+#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX
/*
* Magic Number
@@ -83,8 +86,39 @@ MODULE_LICENSE("GPL");
#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
+/*
+ * Acer ACPI event GUIDs
+ */
+#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
+
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
+MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
+
+enum acer_wmi_event_ids {
+ WMID_HOTKEY_EVENT = 0x1,
+};
+
+static const struct key_entry acer_wmi_keymap[] = {
+ {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
+ {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
+ {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
+ {KE_KEY, 0x22, {KEY_PROG2} }, /* Aracade */
+ {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
+ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
+ {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
+ {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */
+ {KE_END, 0}
+};
+
+static struct input_dev *acer_wmi_input_dev;
+
+struct event_return_value {
+ u8 function;
+ u8 key_num;
+ u16 device_state;
+ u32 reserved;
+} __attribute__((packed));
/*
* Interface capability flags
@@ -1085,6 +1119,99 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
+static void acer_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ struct event_return_value return_value;
+ acpi_status status;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ printk(ACER_WARNING "bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (!obj)
+ return;
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ printk(ACER_WARNING "Unknown response received %d\n",
+ obj->type);
+ kfree(obj);
+ return;
+ }
+ if (obj->buffer.length != 8) {
+ printk(ACER_WARNING "Unknown buffer length %d\n",
+ obj->buffer.length);
+ kfree(obj);
+ return;
+ }
+
+ return_value = *((struct event_return_value *)obj->buffer.pointer);
+ kfree(obj);
+
+ switch (return_value.function) {
+ case WMID_HOTKEY_EVENT:
+ if (!sparse_keymap_report_event(acer_wmi_input_dev,
+ return_value.key_num, 1, true))
+ printk(ACER_WARNING "Unknown key number - 0x%x\n",
+ return_value.key_num);
+ break;
+ default:
+ printk(ACER_WARNING "Unknown function number - %d - %d\n",
+ return_value.function, return_value.key_num);
+ break;
+ }
+}
+
+static int __init acer_wmi_input_setup(void)
+{
+ acpi_status status;
+ int err;
+
+ acer_wmi_input_dev = input_allocate_device();
+ if (!acer_wmi_input_dev)
+ return -ENOMEM;
+
+ acer_wmi_input_dev->name = "Acer WMI hotkeys";
+ acer_wmi_input_dev->phys = "wmi/input0";
+ acer_wmi_input_dev->id.bustype = BUS_HOST;
+
+ err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
+ acer_wmi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ err = -EIO;
+ goto err_free_keymap;
+ }
+
+ err = input_register_device(acer_wmi_input_dev);
+ if (err)
+ goto err_uninstall_notifier;
+
+ return 0;
+
+err_uninstall_notifier:
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+err_free_keymap:
+ sparse_keymap_free(acer_wmi_input_dev);
+err_free_dev:
+ input_free_device(acer_wmi_input_dev);
+ return err;
+}
+
+static void acer_wmi_input_destroy(void)
+{
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+ sparse_keymap_free(acer_wmi_input_dev);
+ input_unregister_device(acer_wmi_input_dev);
+}
+
/*
* debugfs functions
*/
@@ -1327,6 +1454,12 @@ static int __init acer_wmi_init(void)
"generic video driver\n");
}
+ if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
+ err = acer_wmi_input_setup();
+ if (err)
+ return err;
+ }
+
err = platform_driver_register(&acer_platform_driver);
if (err) {
printk(ACER_ERR "Unable to register platform driver.\n");
@@ -1368,11 +1501,17 @@ error_device_add:
error_device_alloc:
platform_driver_unregister(&acer_platform_driver);
error_platform_register:
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
return err;
}
static void __exit acer_wmi_exit(void)
{
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
remove_sysfs(acer_platform_device);
remove_debugfs();
platform_device_unregister(acer_platform_device);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/4] Enabled Acer Launch Manager mode
2010-10-30 16:36 [PATCH 1/4] Add acer wmi hotkey events support Lee, Chun-Yi
@ 2010-10-30 16:36 ` Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 3/4] Add 3G rfkill sysfs file Lee, Chun-Yi
2010-10-31 14:04 ` [PATCH 1/4] Add acer wmi hotkey events support Dmitry Torokhov
1 sibling, 1 reply; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-10-30 16:36 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-input, carlos, corentin.chary, dmitry.torokhov, tiwai,
trenn, mjg59, jbenc, Lee, Chun-Yi
Enabled Acer Launch Manager mode to disable the EC raw behavior for
communication devices when WMID3 method available. And, we also add a
ec_raw_mode kernel module option for enable The EC raw behavior mode
when anyone what reset it back.
When Acer Launch Manager mode enabled, EC will stop to touch any
communication devices' RF state or power state that causes conflict
with rfkill_input or any userland daemon to charge the rfkill rules.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
---
drivers/platform/x86/acer-wmi.c | 113 +++++++++++++++++++++++++++++++++++++++
1 files changed, 113 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 930df56..0b870d3 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -85,6 +85,7 @@ MODULE_LICENSE("GPL");
#define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C"
#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
+#define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
/*
* Acer ACPI event GUIDs
@@ -120,6 +121,20 @@ struct event_return_value {
u32 reserved;
} __attribute__((packed));
+struct lm_input_params {
+ u8 function_num; /* Function Number */
+ u16 commun_devices; /* Communication type devices default status */
+ u16 devices; /* Other type devices default status */
+ u8 lm_status; /* Launch Manager Status */
+ u16 reserved;
+} __attribute__((packed));
+
+struct lm_return_value {
+ u8 error_code; /* Error Code */
+ u8 ec_return_value; /* EC Return Value */
+ u16 reserved;
+} __attribute__((packed));
+
/*
* Interface capability flags
*/
@@ -150,15 +165,18 @@ static int mailled = -1;
static int brightness = -1;
static int threeg = -1;
static int force_series;
+static bool ec_raw_mode;
module_param(mailled, int, 0444);
module_param(brightness, int, 0444);
module_param(threeg, int, 0444);
module_param(force_series, int, 0444);
+module_param(ec_raw_mode, bool, 0444);
MODULE_PARM_DESC(mailled, "Set initial state of Mail LED");
MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness");
MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware");
MODULE_PARM_DESC(force_series, "Force a different laptop series");
+MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode");
struct acer_data {
int mailled;
@@ -1393,6 +1411,87 @@ error_debugfs:
return -ENOMEM;
}
+static acpi_status
+wmid3_set_lm_mode(struct lm_input_params *params,
+ struct lm_return_value *return_value)
+{
+ acpi_status status;
+ union acpi_object *obj;
+
+ struct acpi_buffer input = { sizeof(struct lm_input_params), params };
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ obj = output.pointer;
+
+ if (!obj)
+ return -EINVAL;
+ else if (obj->type != ACPI_TYPE_BUFFER) {
+ kfree(obj);
+ return -EINVAL;
+ }
+ if (obj->buffer.length != 4) {
+ printk(ACER_WARNING "Unknown buffer length %d\n",
+ obj->buffer.length);
+ kfree(obj);
+ return -EINVAL;
+ }
+
+ *return_value = *((struct lm_return_value *)obj->buffer.pointer);
+ kfree(obj);
+
+ return status;
+}
+
+static int acer_wmi_enable_ec_raw(void)
+{
+ struct lm_return_value return_value;
+ acpi_status status;
+ struct lm_input_params params = {
+ .function_num = 0x1,
+ .commun_devices = 0xFFFF,
+ .devices = 0xFFFF,
+ .lm_status = 0x00, /* Launch Manager Deactive */
+ };
+
+ status = wmid3_set_lm_mode(¶ms, &return_value);
+
+ if (return_value.error_code || return_value.ec_return_value)
+ printk(ACER_WARNING "Enabling EC raw mode failed: "
+ "0x%x - 0x%x\n", return_value.error_code,
+ return_value.ec_return_value);
+ else
+ printk(ACER_INFO "Enabled EC raw mode");
+
+ return status;
+}
+
+static int acer_wmi_enable_lm(void)
+{
+ struct lm_return_value return_value;
+ acpi_status status;
+ struct lm_input_params params = {
+ .function_num = 0x1,
+ .commun_devices = 0x0041, /* WiFi on, 3G on, BT off */
+ .devices = 0xFFFF,
+ .lm_status = 0x41, /* Launch Manager Active */
+ };
+
+ status = wmid3_set_lm_mode(¶ms, &return_value);
+
+ if (return_value.error_code || return_value.ec_return_value)
+ printk(ACER_WARNING "Enabling Launch Manager failed: "
+ "0x%x - 0x%x\n", return_value.error_code,
+ return_value.ec_return_value);
+ else
+ printk(ACER_INFO "Enabled Launch Manager");
+
+ return status;
+}
+
static int __init acer_wmi_init(void)
{
int err;
@@ -1454,6 +1553,20 @@ static int __init acer_wmi_init(void)
"generic video driver\n");
}
+ if (wmi_has_guid(WMID_GUID3)) {
+ if (ec_raw_mode) {
+ if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
+ printk(ACER_ERR "Cannot enable EC raw mode\n");
+ return -ENODEV;
+ }
+ } else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
+ printk(ACER_ERR "Cannot enable Launch Manager mode\n");
+ return -ENODEV;
+ }
+ } else if (!wmi_has_guid(WMID_GUID3) && ec_raw_mode) {
+ printk(ACER_INFO "No WMID EC raw mode enable method\n");
+ }
+
if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
err = acer_wmi_input_setup();
if (err)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/4] Add 3G rfkill sysfs file
2010-10-30 16:36 ` [PATCH 2/4] Enabled Acer Launch Manager mode Lee, Chun-Yi
@ 2010-10-30 16:36 ` Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 4/4] Detect the WiFi/Bluetooth/3G devices available Lee, Chun-Yi
0 siblings, 1 reply; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-10-30 16:36 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-input, carlos, corentin.chary, dmitry.torokhov, tiwai,
trenn, mjg59, jbenc, Lee, Chun-Yi
Add 3G rfkill sysfs file for provide userland to control 3G device
on/off by using WMI method.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
---
drivers/platform/x86/acer-wmi.c | 99 ++++++++++++++++++++++++++++++++++++++-
1 files changed, 98 insertions(+), 1 deletions(-)
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 0b870d3..9656464 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -136,6 +136,24 @@ struct lm_return_value {
} __attribute__((packed));
/*
+ * GUID3 Get Device Status device flags
+ */
+#define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
+
+struct wmid3_gds_input_param { /* Get Device Status input parameter */
+ u8 function_num; /* Function Number */
+ u8 hotkey_number; /* Hotkey Number */
+ u16 devices; /* Get Device */
+} __attribute__((packed));
+
+struct wmid3_gds_return_value { /* Get Device Status return value*/
+ u8 error_code; /* Error Code */
+ u8 ec_return_value; /* EC Return Value */
+ u16 devices; /* Current Device Status */
+ u32 reserved;
+} __attribute__((packed));
+
+/*
* Interface capability flags
*/
#define ACER_CAP_MAILLED (1<<0)
@@ -192,6 +210,7 @@ struct acer_debug {
static struct rfkill *wireless_rfkill;
static struct rfkill *bluetooth_rfkill;
+static struct rfkill *threeg_rfkill;
/* Each low-level interface must define at least some of the following */
struct wmi_interface {
@@ -1000,6 +1019,54 @@ static void acer_backlight_exit(void)
backlight_device_unregister(acer_backlight_device);
}
+static acpi_status wmid3_get_device_status(u32 *value, u16 device)
+{
+ struct wmid3_gds_return_value return_value;
+ acpi_status status;
+ union acpi_object *obj;
+ struct wmid3_gds_input_param params = {
+ .function_num = 0x1,
+ .hotkey_number = 0x01,
+ .devices = device,
+ };
+ struct acpi_buffer input = {
+ sizeof(struct wmid3_gds_input_param),
+ ¶ms
+ };
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+
+ status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ obj = output.pointer;
+
+ if (!obj)
+ return -EINVAL;
+ else if (obj->type != ACPI_TYPE_BUFFER) {
+ kfree(obj);
+ return -EINVAL;
+ }
+ if (obj->buffer.length != 8) {
+ printk(ACER_WARNING "Unknown buffer length %d\n",
+ obj->buffer.length);
+ kfree(obj);
+ return -EINVAL;
+ }
+
+ return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
+ kfree(obj);
+
+ if (return_value.error_code || return_value.ec_return_value)
+ printk(ACER_WARNING "Get Device Status failed: "
+ "0x%x - 0x%x\n", return_value.error_code,
+ return_value.ec_return_value);
+ else
+ *value = !!(return_value.devices & device);
+
+ return status;
+}
+
/*
* Rfkill devices
*/
@@ -1020,6 +1087,13 @@ static void acer_rfkill_update(struct work_struct *ignored)
rfkill_set_sw_state(bluetooth_rfkill, !state);
}
+ if (has_cap(ACER_CAP_THREEG) && wmi_has_guid(WMID_GUID3)) {
+ status = wmid3_get_device_status(&state,
+ ACER_WMID3_GDS_THREEG);
+ if (ACPI_SUCCESS(status))
+ rfkill_set_sw_state(threeg_rfkill, !state);
+ }
+
schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
}
@@ -1076,6 +1150,19 @@ static int acer_rfkill_init(struct device *dev)
}
}
+ if (has_cap(ACER_CAP_THREEG)) {
+ threeg_rfkill = acer_rfkill_register(dev,
+ RFKILL_TYPE_WWAN, "acer-threeg",
+ ACER_CAP_THREEG);
+ if (IS_ERR(threeg_rfkill)) {
+ rfkill_unregister(wireless_rfkill);
+ rfkill_destroy(wireless_rfkill);
+ rfkill_unregister(bluetooth_rfkill);
+ rfkill_destroy(bluetooth_rfkill);
+ return PTR_ERR(threeg_rfkill);
+ }
+ }
+
schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
return 0;
@@ -1092,6 +1179,11 @@ static void acer_rfkill_exit(void)
rfkill_unregister(bluetooth_rfkill);
rfkill_destroy(bluetooth_rfkill);
}
+
+ if (has_cap(ACER_CAP_THREEG)) {
+ rfkill_unregister(threeg_rfkill);
+ rfkill_destroy(threeg_rfkill);
+ }
return;
}
@@ -1102,7 +1194,12 @@ static ssize_t show_bool_threeg(struct device *dev,
struct device_attribute *attr, char *buf)
{
u32 result; \
- acpi_status status = get_u32(&result, ACER_CAP_THREEG);
+ acpi_status status;
+ if (wmi_has_guid(WMID_GUID3))
+ status = wmid3_get_device_status(&result,
+ ACER_WMID3_GDS_THREEG);
+ else
+ status = get_u32(&result, ACER_CAP_THREEG);
if (ACPI_SUCCESS(status))
return sprintf(buf, "%u\n", result);
return sprintf(buf, "Read error\n");
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/4] Detect the WiFi/Bluetooth/3G devices available
2010-10-30 16:36 ` [PATCH 3/4] Add 3G rfkill sysfs file Lee, Chun-Yi
@ 2010-10-30 16:36 ` Lee, Chun-Yi
0 siblings, 0 replies; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-10-30 16:36 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-input, carlos, corentin.chary, dmitry.torokhov, tiwai,
trenn, mjg59, jbenc, Lee, Chun-Yi
Check the Acer OEM-specific Type AA to detect the WiFi/Bluetooth/3G
devices available or not, and set the devices capability flag.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
---
drivers/platform/x86/acer-wmi.c | 50 ++++++++++++++++++++++++++++++++------
1 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 9656464..0247a70 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -39,6 +39,7 @@
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
+#include <linux/dmi.h>
#include <acpi/acpi_drivers.h>
@@ -138,7 +139,9 @@ struct lm_return_value {
/*
* GUID3 Get Device Status device flags
*/
-#define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
+#define ACER_WMID3_GDS_WIRELESS (1<<0) /* WiFi */
+#define ACER_WMID3_GDS_THREEG (1<<6) /* 3G */
+#define ACER_WMID3_GDS_BLUETOOTH (1<<11) /* BT */
struct wmid3_gds_input_param { /* Get Device Status input parameter */
u8 function_num; /* Function Number */
@@ -153,6 +156,15 @@ struct wmid3_gds_return_value { /* Get Device Status return value*/
u32 reserved;
} __attribute__((packed));
+#define ACER_DMI_DEV_TYPE_AA 170
+
+struct hotkey_function_type_aa {
+ u8 type;
+ u8 length;
+ u16 handle;
+ u16 commun_func_bitmap;
+} __attribute__((packed));
+
/*
* Interface capability flags
*/
@@ -184,6 +196,7 @@ static int brightness = -1;
static int threeg = -1;
static int force_series;
static bool ec_raw_mode;
+static struct hotkey_function_type_aa *type_aa;
module_param(mailled, int, 0444);
module_param(brightness, int, 0444);
@@ -824,6 +837,18 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface)
return WMI_execute_u32(method_id, (u32)value, NULL);
}
+static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy)
+{
+ /* We are looking for OEM-specific Type Aah */
+ if (header->type != ACER_DMI_DEV_TYPE_AA)
+ return;
+
+ type_aa = (struct hotkey_function_type_aa *) header;
+
+ printk(ACER_INFO "Function biti map for Communication Button: 0x%x\n",
+ type_aa->commun_func_bitmap);
+}
+
static acpi_status WMID_set_capabilities(void)
{
struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -844,16 +869,24 @@ static acpi_status WMID_set_capabilities(void)
return AE_ERROR;
}
- /* Not sure on the meaning of the relevant bits yet to detect these */
- interface->capability |= ACER_CAP_WIRELESS;
- interface->capability |= ACER_CAP_THREEG;
+ dmi_walk(type_aa_dmi_decode, NULL);
+ if (type_aa) {
+ if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
+ interface->capability |= ACER_CAP_WIRELESS;
+ if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_THREEG)
+ interface->capability |= ACER_CAP_THREEG;
+ if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH)
+ interface->capability |= ACER_CAP_BLUETOOTH;
+ } else {
+ interface->capability |= ACER_CAP_WIRELESS;
+ interface->capability |= ACER_CAP_THREEG;
+ if (devices & 0x10)
+ interface->capability |= ACER_CAP_BLUETOOTH;
+ }
/* WMID always provides brightness methods */
interface->capability |= ACER_CAP_BRIGHTNESS;
- if (devices & 0x10)
- interface->capability |= ACER_CAP_BLUETOOTH;
-
if (!(devices & 0x20))
max_brightness = 0x9;
@@ -932,7 +965,8 @@ static void __init acer_commandline_init(void)
* capability isn't available on the given interface
*/
set_u32(mailled, ACER_CAP_MAILLED);
- set_u32(threeg, ACER_CAP_THREEG);
+ if (!type_aa)
+ set_u32(threeg, ACER_CAP_THREEG);
set_u32(brightness, ACER_CAP_BRIGHTNESS);
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Add acer wmi hotkey events support
@ 2010-10-30 16:44 Joey Lee
0 siblings, 0 replies; 11+ messages in thread
From: Joey Lee @ 2010-10-30 16:44 UTC (permalink / raw)
To: platform-driver-x86
Cc: corentin.chary, dmitry.torokhov, Takashi Iwai, Thomas Renninger,
mjg59, carlos, jbenc, trenn, linux-input
Add CC. Thomas
於 日,2010-10-31 於 00:36 +0800,Lee, Chun-Yi 提到:
> Add acer wmi hotkey event support. Install a wmi notify handler to
> transfer wmi event key to key code, then send out keycode through acer
> wmi input device to userland.
>
> Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
> ---
> drivers/platform/x86/Kconfig | 2 +
> drivers/platform/x86/acer-wmi.c | 139 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 141 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index cff7cc2..c242fdd 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -23,7 +23,9 @@ config ACER_WMI
> depends on BACKLIGHT_CLASS_DEVICE
> depends on SERIO_I8042
> depends on RFKILL || RFKILL = n
> + depends on INPUT
> select ACPI_WMI
> + select INPUT_SPARSEKMAP
> ---help---
> This is a driver for newer Acer (and Wistron) laptops. It adds
> wireless radio and bluetooth control, and on some laptops,
> diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
> index 2badee2..930df56 100644
> --- a/drivers/platform/x86/acer-wmi.c
> +++ b/drivers/platform/x86/acer-wmi.c
> @@ -37,6 +37,8 @@
> #include <linux/workqueue.h>
> #include <linux/debugfs.h>
> #include <linux/slab.h>
> +#include <linux/input.h>
> +#include <linux/input/sparse-keymap.h>
>
> #include <acpi/acpi_drivers.h>
>
> @@ -48,6 +50,7 @@ MODULE_LICENSE("GPL");
> #define ACER_ERR KERN_ERR ACER_LOGPREFIX
> #define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
> #define ACER_INFO KERN_INFO ACER_LOGPREFIX
> +#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX
>
> /*
> * Magic Number
> @@ -83,8 +86,39 @@ MODULE_LICENSE("GPL");
> #define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
> #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
>
> +/*
> + * Acer ACPI event GUIDs
> + */
> +#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
> +
> MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
> MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
> +MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
> +
> +enum acer_wmi_event_ids {
> + WMID_HOTKEY_EVENT = 0x1,
> +};
> +
> +static const struct key_entry acer_wmi_keymap[] = {
> + {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
> + {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
> + {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
> + {KE_KEY, 0x22, {KEY_PROG2} }, /* Aracade */
> + {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
> + {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
> + {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
> + {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */
> + {KE_END, 0}
> +};
> +
> +static struct input_dev *acer_wmi_input_dev;
> +
> +struct event_return_value {
> + u8 function;
> + u8 key_num;
> + u16 device_state;
> + u32 reserved;
> +} __attribute__((packed));
>
> /*
> * Interface capability flags
> @@ -1085,6 +1119,99 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
>
> static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
>
> +static void acer_wmi_notify(u32 value, void *context)
> +{
> + struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
> + union acpi_object *obj;
> + struct event_return_value return_value;
> + acpi_status status;
> +
> + status = wmi_get_event_data(value, &response);
> + if (status != AE_OK) {
> + printk(ACER_WARNING "bad event status 0x%x\n", status);
> + return;
> + }
> +
> + obj = (union acpi_object *)response.pointer;
> +
> + if (!obj)
> + return;
> + if (obj->type != ACPI_TYPE_BUFFER) {
> + printk(ACER_WARNING "Unknown response received %d\n",
> + obj->type);
> + kfree(obj);
> + return;
> + }
> + if (obj->buffer.length != 8) {
> + printk(ACER_WARNING "Unknown buffer length %d\n",
> + obj->buffer.length);
> + kfree(obj);
> + return;
> + }
> +
> + return_value = *((struct event_return_value *)obj->buffer.pointer);
> + kfree(obj);
> +
> + switch (return_value.function) {
> + case WMID_HOTKEY_EVENT:
> + if (!sparse_keymap_report_event(acer_wmi_input_dev,
> + return_value.key_num, 1, true))
> + printk(ACER_WARNING "Unknown key number - 0x%x\n",
> + return_value.key_num);
> + break;
> + default:
> + printk(ACER_WARNING "Unknown function number - %d - %d\n",
> + return_value.function, return_value.key_num);
> + break;
> + }
> +}
> +
> +static int __init acer_wmi_input_setup(void)
> +{
> + acpi_status status;
> + int err;
> +
> + acer_wmi_input_dev = input_allocate_device();
> + if (!acer_wmi_input_dev)
> + return -ENOMEM;
> +
> + acer_wmi_input_dev->name = "Acer WMI hotkeys";
> + acer_wmi_input_dev->phys = "wmi/input0";
> + acer_wmi_input_dev->id.bustype = BUS_HOST;
> +
> + err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
> + if (err)
> + goto err_free_dev;
> +
> + status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
> + acer_wmi_notify, NULL);
> + if (ACPI_FAILURE(status)) {
> + err = -EIO;
> + goto err_free_keymap;
> + }
> +
> + err = input_register_device(acer_wmi_input_dev);
> + if (err)
> + goto err_uninstall_notifier;
> +
> + return 0;
> +
> +err_uninstall_notifier:
> + wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
> +err_free_keymap:
> + sparse_keymap_free(acer_wmi_input_dev);
> +err_free_dev:
> + input_free_device(acer_wmi_input_dev);
> + return err;
> +}
> +
> +static void acer_wmi_input_destroy(void)
> +{
> + wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
> + sparse_keymap_free(acer_wmi_input_dev);
> + input_unregister_device(acer_wmi_input_dev);
> +}
> +
> /*
> * debugfs functions
> */
> @@ -1327,6 +1454,12 @@ static int __init acer_wmi_init(void)
> "generic video driver\n");
> }
>
> + if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
> + err = acer_wmi_input_setup();
> + if (err)
> + return err;
> + }
> +
> err = platform_driver_register(&acer_platform_driver);
> if (err) {
> printk(ACER_ERR "Unable to register platform driver.\n");
> @@ -1368,11 +1501,17 @@ error_device_add:
> error_device_alloc:
> platform_driver_unregister(&acer_platform_driver);
> error_platform_register:
> + if (wmi_has_guid(ACERWMID_EVENT_GUID))
> + acer_wmi_input_destroy();
> +
> return err;
> }
>
> static void __exit acer_wmi_exit(void)
> {
> + if (wmi_has_guid(ACERWMID_EVENT_GUID))
> + acer_wmi_input_destroy();
> +
> remove_sysfs(acer_platform_device);
> remove_debugfs();
> platform_device_unregister(acer_platform_device);
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Add acer wmi hotkey events support
2010-10-30 16:36 [PATCH 1/4] Add acer wmi hotkey events support Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 2/4] Enabled Acer Launch Manager mode Lee, Chun-Yi
@ 2010-10-31 14:04 ` Dmitry Torokhov
1 sibling, 0 replies; 11+ messages in thread
From: Dmitry Torokhov @ 2010-10-31 14:04 UTC (permalink / raw)
To: Lee, Chun-Yi
Cc: platform-driver-x86, linux-input, carlos, corentin.chary, tiwai,
trenn, mjg59, jbenc, Lee, Chun-Yi
On Saturday, October 30, 2010 09:36:30 am Lee, Chun-Yi wrote:
> Add acer wmi hotkey event support. Install a wmi notify handler to
> transfer wmi event key to key code, then send out keycode through acer
> wmi input device to userland.
>
> Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
Looks good to me, thansk for making changes.
Acked-by: Dmitry Torokhov <dtor@mail.ru>
--
Dmitry
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] Add acer wmi hotkey events support
2010-11-24 17:39 [PATCH 0/4] Add new wmi support to acer-wmi driver Lee, Chun-Yi
@ 2010-11-24 17:39 ` Lee, Chun-Yi
2010-11-24 19:28 ` Carlos Corbacho
0 siblings, 1 reply; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-11-24 17:39 UTC (permalink / raw)
To: mjg59
Cc: corentin.chary, dmitry.torokhov, tiwai, carlos, jbenc, jdelvare,
trenn, linux-input, platform-driver-x86, Lee, Chun-Yi,
Corentin Chary
Add acer wmi hotkey event support. Install a wmi notify handler to
transfer wmi event key to key code, then send out keycode through acer
wmi input device to userland.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Acked-by: Thomas Renninger <trenn@suse.de>
Acked-by: Jiri Benc <jbenc@suse.cz>
Cc: Carlos Corbacho <carlos@strangeworlds.co.uk>
Cc: Corentin Chary <corentincj@iksaif.net>
---
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/acer-wmi.c | 139 +++++++++++++++++++++++++++++++++++++++
2 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index cff7cc2..c242fdd 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -23,7 +23,9 @@ config ACER_WMI
depends on BACKLIGHT_CLASS_DEVICE
depends on SERIO_I8042
depends on RFKILL || RFKILL = n
+ depends on INPUT
select ACPI_WMI
+ select INPUT_SPARSEKMAP
---help---
This is a driver for newer Acer (and Wistron) laptops. It adds
wireless radio and bluetooth control, and on some laptops,
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 2badee2..930df56 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -37,6 +37,8 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <acpi/acpi_drivers.h>
@@ -48,6 +50,7 @@ MODULE_LICENSE("GPL");
#define ACER_ERR KERN_ERR ACER_LOGPREFIX
#define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
#define ACER_INFO KERN_INFO ACER_LOGPREFIX
+#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX
/*
* Magic Number
@@ -83,8 +86,39 @@ MODULE_LICENSE("GPL");
#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
+/*
+ * Acer ACPI event GUIDs
+ */
+#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
+
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
+MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
+
+enum acer_wmi_event_ids {
+ WMID_HOTKEY_EVENT = 0x1,
+};
+
+static const struct key_entry acer_wmi_keymap[] = {
+ {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
+ {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
+ {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
+ {KE_KEY, 0x22, {KEY_PROG2} }, /* Aracade */
+ {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
+ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
+ {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
+ {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */
+ {KE_END, 0}
+};
+
+static struct input_dev *acer_wmi_input_dev;
+
+struct event_return_value {
+ u8 function;
+ u8 key_num;
+ u16 device_state;
+ u32 reserved;
+} __attribute__((packed));
/*
* Interface capability flags
@@ -1085,6 +1119,99 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
+static void acer_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ struct event_return_value return_value;
+ acpi_status status;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ printk(ACER_WARNING "bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (!obj)
+ return;
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ printk(ACER_WARNING "Unknown response received %d\n",
+ obj->type);
+ kfree(obj);
+ return;
+ }
+ if (obj->buffer.length != 8) {
+ printk(ACER_WARNING "Unknown buffer length %d\n",
+ obj->buffer.length);
+ kfree(obj);
+ return;
+ }
+
+ return_value = *((struct event_return_value *)obj->buffer.pointer);
+ kfree(obj);
+
+ switch (return_value.function) {
+ case WMID_HOTKEY_EVENT:
+ if (!sparse_keymap_report_event(acer_wmi_input_dev,
+ return_value.key_num, 1, true))
+ printk(ACER_WARNING "Unknown key number - 0x%x\n",
+ return_value.key_num);
+ break;
+ default:
+ printk(ACER_WARNING "Unknown function number - %d - %d\n",
+ return_value.function, return_value.key_num);
+ break;
+ }
+}
+
+static int __init acer_wmi_input_setup(void)
+{
+ acpi_status status;
+ int err;
+
+ acer_wmi_input_dev = input_allocate_device();
+ if (!acer_wmi_input_dev)
+ return -ENOMEM;
+
+ acer_wmi_input_dev->name = "Acer WMI hotkeys";
+ acer_wmi_input_dev->phys = "wmi/input0";
+ acer_wmi_input_dev->id.bustype = BUS_HOST;
+
+ err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
+ acer_wmi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ err = -EIO;
+ goto err_free_keymap;
+ }
+
+ err = input_register_device(acer_wmi_input_dev);
+ if (err)
+ goto err_uninstall_notifier;
+
+ return 0;
+
+err_uninstall_notifier:
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+err_free_keymap:
+ sparse_keymap_free(acer_wmi_input_dev);
+err_free_dev:
+ input_free_device(acer_wmi_input_dev);
+ return err;
+}
+
+static void acer_wmi_input_destroy(void)
+{
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+ sparse_keymap_free(acer_wmi_input_dev);
+ input_unregister_device(acer_wmi_input_dev);
+}
+
/*
* debugfs functions
*/
@@ -1327,6 +1454,12 @@ static int __init acer_wmi_init(void)
"generic video driver\n");
}
+ if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
+ err = acer_wmi_input_setup();
+ if (err)
+ return err;
+ }
+
err = platform_driver_register(&acer_platform_driver);
if (err) {
printk(ACER_ERR "Unable to register platform driver.\n");
@@ -1368,11 +1501,17 @@ error_device_add:
error_device_alloc:
platform_driver_unregister(&acer_platform_driver);
error_platform_register:
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
return err;
}
static void __exit acer_wmi_exit(void)
{
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
remove_sysfs(acer_platform_device);
remove_debugfs();
platform_device_unregister(acer_platform_device);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Add acer wmi hotkey events support
2010-11-24 17:39 ` [PATCH 1/4] Add acer wmi hotkey events support Lee, Chun-Yi
@ 2010-11-24 19:28 ` Carlos Corbacho
0 siblings, 0 replies; 11+ messages in thread
From: Carlos Corbacho @ 2010-11-24 19:28 UTC (permalink / raw)
To: Lee, Chun-Yi
Cc: mjg59, corentin.chary, dmitry.torokhov, tiwai, carlos, jbenc,
jdelvare, trenn, linux-input, platform-driver-x86, Lee, Chun-Yi,
Corentin Chary
On Wednesday 24 November 2010 17:39:36 Lee, Chun-Yi wrote:
> Add acer wmi hotkey event support. Install a wmi notify handler to
> transfer wmi event key to key code, then send out keycode through acer
> wmi input device to userland.
>
> Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
> Acked-by: Dmitry Torokhov <dtor@mail.ru>
> Acked-by: Thomas Renninger <trenn@suse.de>
> Acked-by: Jiri Benc <jbenc@suse.cz>
Please fix the typo. Otherwise:
Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
[..]
> +static const struct key_entry acer_wmi_keymap[] = {
> + {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
> + {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
> + {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
> + {KE_KEY, 0x22, {KEY_PROG2} }, /* Aracade */
s/Aracade/Arcade/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Add acer wmi hotkey events support
@ 2010-11-25 1:54 Joey Lee
0 siblings, 0 replies; 11+ messages in thread
From: Joey Lee @ 2010-11-25 1:54 UTC (permalink / raw)
To: carlos
Cc: corentin.chary, dmitry.torokhov, corentincj, Takashi Iwai, mjg59,
jbenc, jdelvare, trenn, linux-input, platform-driver-x86
Hi Carios,
First, Thank's for your review and take care. :-)
於 三,2010-11-24 於 19:28 +0000,Carlos Corbacho 提到:
> On Wednesday 24 November 2010 17:39:36 Lee, Chun-Yi wrote:
> > Add acer wmi hotkey event support. Install a wmi notify handler to
> > transfer wmi event key to key code, then send out keycode through acer
> > wmi input device to userland.
> >
> > Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
> > Acked-by: Dmitry Torokhov <dtor@mail.ru>
> > Acked-by: Thomas Renninger <trenn@suse.de>
> > Acked-by: Jiri Benc <jbenc@suse.cz>
>
> Please fix the typo. Otherwise:
>
> Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
>
> [..]
>
> > +static const struct key_entry acer_wmi_keymap[] = {
> > + {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
> > + {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
> > + {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
> > + {KE_KEY, 0x22, {KEY_PROG2} }, /* Aracade */
>
> s/Aracade/Arcade/
Fixed the typo issues, then I re-sand 1/4 patch.
Thank's a lot!
Joey Lee
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] Add acer wmi hotkey events support
@ 2010-11-25 1:56 Lee, Chun-Yi
0 siblings, 0 replies; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-11-25 1:56 UTC (permalink / raw)
To: carlos
Cc: mjg59, corentin.chary, dmitry.torokhov, tiwai, jbenc, jdelvare,
trenn, linux-input, platform-driver-x86, corentincj, Lee, Chun-Yi
Add acer wmi hotkey event support. Install a wmi notify handler to
transfer wmi event key to key code, then send out keycode through acer
wmi input device to userland.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Acked-by: Thomas Renninger <trenn@suse.de>
Acked-by: Jiri Benc <jbenc@suse.cz>
Cc: Carlos Corbacho <carlos@strangeworlds.co.uk>
Cc: Corentin Chary <corentincj@iksaif.net>
---
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/acer-wmi.c | 139 +++++++++++++++++++++++++++++++++++++++
2 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index cff7cc2..c242fdd 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -23,7 +23,9 @@ config ACER_WMI
depends on BACKLIGHT_CLASS_DEVICE
depends on SERIO_I8042
depends on RFKILL || RFKILL = n
+ depends on INPUT
select ACPI_WMI
+ select INPUT_SPARSEKMAP
---help---
This is a driver for newer Acer (and Wistron) laptops. It adds
wireless radio and bluetooth control, and on some laptops,
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 2badee2..930df56 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -37,6 +37,8 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <acpi/acpi_drivers.h>
@@ -48,6 +50,7 @@ MODULE_LICENSE("GPL");
#define ACER_ERR KERN_ERR ACER_LOGPREFIX
#define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
#define ACER_INFO KERN_INFO ACER_LOGPREFIX
+#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX
/*
* Magic Number
@@ -83,8 +86,39 @@ MODULE_LICENSE("GPL");
#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
+/*
+ * Acer ACPI event GUIDs
+ */
+#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
+
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
+MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
+
+enum acer_wmi_event_ids {
+ WMID_HOTKEY_EVENT = 0x1,
+};
+
+static const struct key_entry acer_wmi_keymap[] = {
+ {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
+ {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
+ {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
+ {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */
+ {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
+ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
+ {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
+ {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */
+ {KE_END, 0}
+};
+
+static struct input_dev *acer_wmi_input_dev;
+
+struct event_return_value {
+ u8 function;
+ u8 key_num;
+ u16 device_state;
+ u32 reserved;
+} __attribute__((packed));
/*
* Interface capability flags
@@ -1085,6 +1119,99 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
+static void acer_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ struct event_return_value return_value;
+ acpi_status status;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ printk(ACER_WARNING "bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (!obj)
+ return;
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ printk(ACER_WARNING "Unknown response received %d\n",
+ obj->type);
+ kfree(obj);
+ return;
+ }
+ if (obj->buffer.length != 8) {
+ printk(ACER_WARNING "Unknown buffer length %d\n",
+ obj->buffer.length);
+ kfree(obj);
+ return;
+ }
+
+ return_value = *((struct event_return_value *)obj->buffer.pointer);
+ kfree(obj);
+
+ switch (return_value.function) {
+ case WMID_HOTKEY_EVENT:
+ if (!sparse_keymap_report_event(acer_wmi_input_dev,
+ return_value.key_num, 1, true))
+ printk(ACER_WARNING "Unknown key number - 0x%x\n",
+ return_value.key_num);
+ break;
+ default:
+ printk(ACER_WARNING "Unknown function number - %d - %d\n",
+ return_value.function, return_value.key_num);
+ break;
+ }
+}
+
+static int __init acer_wmi_input_setup(void)
+{
+ acpi_status status;
+ int err;
+
+ acer_wmi_input_dev = input_allocate_device();
+ if (!acer_wmi_input_dev)
+ return -ENOMEM;
+
+ acer_wmi_input_dev->name = "Acer WMI hotkeys";
+ acer_wmi_input_dev->phys = "wmi/input0";
+ acer_wmi_input_dev->id.bustype = BUS_HOST;
+
+ err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
+ acer_wmi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ err = -EIO;
+ goto err_free_keymap;
+ }
+
+ err = input_register_device(acer_wmi_input_dev);
+ if (err)
+ goto err_uninstall_notifier;
+
+ return 0;
+
+err_uninstall_notifier:
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+err_free_keymap:
+ sparse_keymap_free(acer_wmi_input_dev);
+err_free_dev:
+ input_free_device(acer_wmi_input_dev);
+ return err;
+}
+
+static void acer_wmi_input_destroy(void)
+{
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+ sparse_keymap_free(acer_wmi_input_dev);
+ input_unregister_device(acer_wmi_input_dev);
+}
+
/*
* debugfs functions
*/
@@ -1327,6 +1454,12 @@ static int __init acer_wmi_init(void)
"generic video driver\n");
}
+ if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
+ err = acer_wmi_input_setup();
+ if (err)
+ return err;
+ }
+
err = platform_driver_register(&acer_platform_driver);
if (err) {
printk(ACER_ERR "Unable to register platform driver.\n");
@@ -1368,11 +1501,17 @@ error_device_add:
error_device_alloc:
platform_driver_unregister(&acer_platform_driver);
error_platform_register:
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
return err;
}
static void __exit acer_wmi_exit(void)
{
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
remove_sysfs(acer_platform_device);
remove_debugfs();
platform_device_unregister(acer_platform_device);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 1/4] Add acer wmi hotkey events support
2010-12-04 1:03 [PATCH 0/4] Add new wmi support to acer-wmi driver Lee, Chun-Yi
@ 2010-12-04 1:03 ` Lee, Chun-Yi
0 siblings, 0 replies; 11+ messages in thread
From: Lee, Chun-Yi @ 2010-12-04 1:03 UTC (permalink / raw)
To: mjg
Cc: carlos, corentin.chary, dmitry.torokhov, corentincj, tiwai, mjg59,
jbenc, jdelvare, trenn, platform-driver-x86, linux-input,
Lee, Chun-Yi
Add acer wmi hotkey event support. Install a wmi notify handler to
transfer wmi event key to key code, then send out keycode through acer
wmi input device to userland.
Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Acked-by: Thomas Renninger <trenn@suse.de>
Acked-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Carlos Corbacho <carlos@strangeworlds.co.uk>
Cc: Corentin Chary <corentincj@iksaif.net>
---
drivers/platform/x86/Kconfig | 2 +
drivers/platform/x86/acer-wmi.c | 139 +++++++++++++++++++++++++++++++++++++++
2 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index cff7cc2..c242fdd 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -23,7 +23,9 @@ config ACER_WMI
depends on BACKLIGHT_CLASS_DEVICE
depends on SERIO_I8042
depends on RFKILL || RFKILL = n
+ depends on INPUT
select ACPI_WMI
+ select INPUT_SPARSEKMAP
---help---
This is a driver for newer Acer (and Wistron) laptops. It adds
wireless radio and bluetooth control, and on some laptops,
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 2badee2..930df56 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -37,6 +37,8 @@
#include <linux/workqueue.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <acpi/acpi_drivers.h>
@@ -48,6 +50,7 @@ MODULE_LICENSE("GPL");
#define ACER_ERR KERN_ERR ACER_LOGPREFIX
#define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
#define ACER_INFO KERN_INFO ACER_LOGPREFIX
+#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX
/*
* Magic Number
@@ -83,8 +86,39 @@ MODULE_LICENSE("GPL");
#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
+/*
+ * Acer ACPI event GUIDs
+ */
+#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
+
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
+MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
+
+enum acer_wmi_event_ids {
+ WMID_HOTKEY_EVENT = 0x1,
+};
+
+static const struct key_entry acer_wmi_keymap[] = {
+ {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */
+ {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */
+ {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */
+ {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */
+ {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
+ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
+ {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
+ {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */
+ {KE_END, 0}
+};
+
+static struct input_dev *acer_wmi_input_dev;
+
+struct event_return_value {
+ u8 function;
+ u8 key_num;
+ u16 device_state;
+ u32 reserved;
+} __attribute__((packed));
/*
* Interface capability flags
@@ -1085,6 +1119,99 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(interface, S_IRUGO, show_interface, NULL);
+static void acer_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ struct event_return_value return_value;
+ acpi_status status;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ printk(ACER_WARNING "bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (!obj)
+ return;
+ if (obj->type != ACPI_TYPE_BUFFER) {
+ printk(ACER_WARNING "Unknown response received %d\n",
+ obj->type);
+ kfree(obj);
+ return;
+ }
+ if (obj->buffer.length != 8) {
+ printk(ACER_WARNING "Unknown buffer length %d\n",
+ obj->buffer.length);
+ kfree(obj);
+ return;
+ }
+
+ return_value = *((struct event_return_value *)obj->buffer.pointer);
+ kfree(obj);
+
+ switch (return_value.function) {
+ case WMID_HOTKEY_EVENT:
+ if (!sparse_keymap_report_event(acer_wmi_input_dev,
+ return_value.key_num, 1, true))
+ printk(ACER_WARNING "Unknown key number - 0x%x\n",
+ return_value.key_num);
+ break;
+ default:
+ printk(ACER_WARNING "Unknown function number - %d - %d\n",
+ return_value.function, return_value.key_num);
+ break;
+ }
+}
+
+static int __init acer_wmi_input_setup(void)
+{
+ acpi_status status;
+ int err;
+
+ acer_wmi_input_dev = input_allocate_device();
+ if (!acer_wmi_input_dev)
+ return -ENOMEM;
+
+ acer_wmi_input_dev->name = "Acer WMI hotkeys";
+ acer_wmi_input_dev->phys = "wmi/input0";
+ acer_wmi_input_dev->id.bustype = BUS_HOST;
+
+ err = sparse_keymap_setup(acer_wmi_input_dev, acer_wmi_keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
+ acer_wmi_notify, NULL);
+ if (ACPI_FAILURE(status)) {
+ err = -EIO;
+ goto err_free_keymap;
+ }
+
+ err = input_register_device(acer_wmi_input_dev);
+ if (err)
+ goto err_uninstall_notifier;
+
+ return 0;
+
+err_uninstall_notifier:
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+err_free_keymap:
+ sparse_keymap_free(acer_wmi_input_dev);
+err_free_dev:
+ input_free_device(acer_wmi_input_dev);
+ return err;
+}
+
+static void acer_wmi_input_destroy(void)
+{
+ wmi_remove_notify_handler(ACERWMID_EVENT_GUID);
+ sparse_keymap_free(acer_wmi_input_dev);
+ input_unregister_device(acer_wmi_input_dev);
+}
+
/*
* debugfs functions
*/
@@ -1327,6 +1454,12 @@ static int __init acer_wmi_init(void)
"generic video driver\n");
}
+ if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
+ err = acer_wmi_input_setup();
+ if (err)
+ return err;
+ }
+
err = platform_driver_register(&acer_platform_driver);
if (err) {
printk(ACER_ERR "Unable to register platform driver.\n");
@@ -1368,11 +1501,17 @@ error_device_add:
error_device_alloc:
platform_driver_unregister(&acer_platform_driver);
error_platform_register:
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
return err;
}
static void __exit acer_wmi_exit(void)
{
+ if (wmi_has_guid(ACERWMID_EVENT_GUID))
+ acer_wmi_input_destroy();
+
remove_sysfs(acer_platform_device);
remove_debugfs();
platform_device_unregister(acer_platform_device);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-12-04 1:03 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-30 16:36 [PATCH 1/4] Add acer wmi hotkey events support Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 2/4] Enabled Acer Launch Manager mode Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 3/4] Add 3G rfkill sysfs file Lee, Chun-Yi
2010-10-30 16:36 ` [PATCH 4/4] Detect the WiFi/Bluetooth/3G devices available Lee, Chun-Yi
2010-10-31 14:04 ` [PATCH 1/4] Add acer wmi hotkey events support Dmitry Torokhov
-- strict thread matches above, loose matches on Subject: below --
2010-10-30 16:44 Joey Lee
2010-11-24 17:39 [PATCH 0/4] Add new wmi support to acer-wmi driver Lee, Chun-Yi
2010-11-24 17:39 ` [PATCH 1/4] Add acer wmi hotkey events support Lee, Chun-Yi
2010-11-24 19:28 ` Carlos Corbacho
2010-11-25 1:54 Joey Lee
2010-11-25 1:56 Lee, Chun-Yi
2010-12-04 1:03 [PATCH 0/4] Add new wmi support to acer-wmi driver Lee, Chun-Yi
2010-12-04 1:03 ` [PATCH 1/4] Add acer wmi hotkey events support Lee, Chun-Yi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).