linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] Add acer wmi hotkey events support
@ 2010-10-18  4:53 Joey Lee
  2010-10-18  8:12 ` Dmitry Torokhov
  0 siblings, 1 reply; 14+ messages in thread
From: Joey Lee @ 2010-10-18  4:53 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: corentin.chary, Takashi Iwai, Thomas Renninger, mjg59, carlos,
	jbenc, linux-input, platform-driver-x86

Hi Dmitry, 

於 三,2010-10-13 於 11:24 -0700,Dmitry Torokhov 提到:
> Hi Joey,
> 
> On Wed, Oct 13, 2010 at 11:47:40AM +0800, Lee, Chun-Yi wrote:
>  +
> > +	status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
> > +						acer_wmi_notify, NULL);
> > +	if (ACPI_FAILURE(status)) {
> > +		err = -EIO;
> > +		goto err_unregister_input;
> > +	}
> > +
> > +	return 0;
> > +
> > +err_unregister_input:
> > +	input_unregister_device(acer_wmi_input_dev);
> > +err_free_keymap:
> > +	sparse_keymap_free(acer_wmi_input_dev);
> > +err_free_dev:
> > +	input_free_device(acer_wmi_input_dev);
> 
> If wmi_install_notify_handler() fails you'll end up doing
> input_unregister_device() + input_free_device() which is forbidden. To
> avoid this issue register the device after installing the handler. As
> long as input device is properly allocated (by calling
> input_allocate_device) it is safe to use it to send events (although
> they will not go anywhere).
> 
> BTW, I think it is high time we allocate a dedicated key for touchpad
> on/off....
> 

Thank's for your review.
I changed the error handler priority:

>From 9e31867c348a1f2119d16ddbcf9cf0b7de111cf9 Mon Sep 17 00:00:00 2001
From: Lee, Chun-Yi <jlee@novell.com>
Date: Mon, 18 Oct 2010 12:12:49 +0800
Subject: [PATCH 1/3] Add acer wmi hotkey events support

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



--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Add acer wmi hotkey events support
@ 2010-10-19  9:43 Joey Lee
  2010-10-19 15:53 ` Dmitry Torokhov
  0 siblings, 1 reply; 14+ messages in thread
From: Joey Lee @ 2010-10-19  9:43 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: corentin.chary, Takashi Iwai, Thomas Renninger, mjg59, carlos,
	jbenc, linux-input, platform-driver-x86

Hi Dmity, 

於 一,2010-10-18 於 01:12 -0700,Dmitry Torokhov 提到:
> On Sun, Oct 17, 2010 at 10:53:04PM -0600, Joey Lee wrote:
> > Hi Dmitry, 
> > 
> > 於 三,2010-10-13 於 11:24 -0700,Dmitry Torokhov 提到:
> > > Hi Joey,
> > > 
> > > On Wed, Oct 13, 2010 at 11:47:40AM +0800, Lee, Chun-Yi wrote:
> > >  +
> > > > +	status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
> > > > +						acer_wmi_notify, NULL);
> > > > +	if (ACPI_FAILURE(status)) {
> > > > +		err = -EIO;
> > > > +		goto err_unregister_input;
> > > > +	}
> > > > +
> > > > +	return 0;
> > > > +
> > > > +err_unregister_input:
> > > > +	input_unregister_device(acer_wmi_input_dev);
> > > > +err_free_keymap:
> > > > +	sparse_keymap_free(acer_wmi_input_dev);
> > > > +err_free_dev:
> > > > +	input_free_device(acer_wmi_input_dev);
> > > 
> > > If wmi_install_notify_handler() fails you'll end up doing
> > > input_unregister_device() + input_free_device() which is forbidden. To
> > > avoid this issue register the device after installing the handler. As
> > > long as input device is properly allocated (by calling
> > > input_allocate_device) it is safe to use it to send events (although
> > > they will not go anywhere).
> > > 
> > > BTW, I think it is high time we allocate a dedicated key for touchpad
> > > on/off....
> > > 
> > 
> > Thank's for your review.
> > I changed the error handler priority:
> > 
> > >From 9e31867c348a1f2119d16ddbcf9cf0b7de111cf9 Mon Sep 17 00:00:00 2001
> > From: Lee, Chun-Yi <jlee@novell.com>
> > Date: Mon, 18 Oct 2010 12:12:49 +0800
> > Subject: [PATCH 1/3] Add acer wmi hotkey events support
> > 
> > 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, thank you for making changes.
> 

You are welcome, and also thank's for your kindly review my patches.

> >  
> > @@ -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
> >  
> 
> As a separate change could you please move the driver to using pr_err()
> and friends?
> 

Got it, will generate patch to using pr_err().

> >  /*
> >   * 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 */
> 
> We need to standardize this. Some people use F13/F14, here we have
> F22...
> 

Currently, evdev is mapping the F22 to XF86TouchpadToggle:

http://cgit.freedesktop.org/xkeyboard-config/commit/?id=1d05eda8dfc706d6450cab5883120e0d5e1100c


Thank's
Joey Lee

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Add acer wmi hotkey events support
@ 2010-10-19  9:35 Joey Lee
  0 siblings, 0 replies; 14+ messages in thread
From: Joey Lee @ 2010-10-19  9:35 UTC (permalink / raw)
  To: dmitry.torokhov
  Cc: corentin.chary, Stefan Dirsch, Takashi Iwai, Thomas Renninger,
	mjg59, carlos, jbenc, linux-input, platform-driver-x86

Hi Dmitry, 

於 一,2010-10-18 於 01:25 -0700,Dmitry Torokhov 提到:
> On Mon, Oct 18, 2010 at 10:19:37AM +0200, Corentin Chary wrote:
> > On Mon, Oct 18, 2010 at 10:12 AM, Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> > > On Sun, Oct 17, 2010 at 10:53:04PM -0600, Joey Lee wrote:
> > >> +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 */
> > >
> > > We need to standardize this. Some people use F13/F14, here we have
> > > F22...
> > >
> > 
> > The good thing with F* keys, is that they are already mapped in X/Qt/SDL/etc..
> > 
> > But if we do, we could add KEY_TOUCHPADTOGGLE 0x1b8
> > Then bind it to XF86XK_TouchpadToggle (what's the right way to do that
> > ? keymaps ?)
> > 
> 
> I wonder who the main consumers of such events will be... X applications
> or daemons that listen turn this into some DBUS signal...
> 

As I know,
X-input will transfer the keycode to x-keycode (XF22), then mapping the
x-keycode to x-symbol (XF86XK_TouchpadToggle).
Then some daemon or userland applications can grab it.

Thank's
Joey Lee

^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Add acer wmi hotkey events support
@ 2010-10-19  9:31 Joey Lee
  0 siblings, 0 replies; 14+ messages in thread
From: Joey Lee @ 2010-10-19  9:31 UTC (permalink / raw)
  To: tiwai
  Cc: corentin.chary, dmitry.torokhov, Thomas Renninger, mjg59, carlos,
	jbenc, linux-input, platform-driver-x86

Hi all, 

於 一,2010-10-18 於 11:26 +0200,Takashi Iwai 提到:
> At Mon, 18 Oct 2010 10:47:31 +0200,
> Corentin Chary wrote:
> > 
> > On Mon, Oct 18, 2010 at 10:25 AM, Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> > > On Mon, Oct 18, 2010 at 10:19:37AM +0200, Corentin Chary wrote:
> > >> On Mon, Oct 18, 2010 at 10:12 AM, Dmitry Torokhov
> > >> <dmitry.torokhov@gmail.com> wrote:
> > >> > On Sun, Oct 17, 2010 at 10:53:04PM -0600, Joey Lee wrote:
> > >> >> +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 */
> > >> >
> > >> > We need to standardize this. Some people use F13/F14, here we have
> > >> > F22...
> > >> >
> > >>
> > >> The good thing with F* keys, is that they are already mapped in X/Qt/SDL/etc..
> > >>
> > >> But if we do, we could add KEY_TOUCHPADTOGGLE 0x1b8
> > >> Then bind it to XF86XK_TouchpadToggle (what's the right way to do that
> > >> ? keymaps ?)
> > >>
> > >
> > > I wonder who the main consumers of such events will be... X applications
> > > or daemons that listen turn this into some DBUS signal...
> > 
> > I guess xbindkeys and tools like qsynaptics should be able to consume
> > such events.
> > HAL also handled some touchpads things, but now that it is deprecated, who is in
> > charge of doing that ?
> 
> There seems no standardization forseen, but which daemon (as of local
> user) is used depends on the desktop environment.  For example, it's
> gnome-settings-daemon for GNOME.
> 

Yes, g-s-d have a plugin to show up touchpad OSD when touchpad toggled.

And, in xkeyboard-config
currently, F22 mapped to XF86TouchpadToggle:

http://cgit.freedesktop.org/xkeyboard-config/commit/?id=1d05eda8dfc706d6450cab5883120e0d5e1100c0


diff --git a/symbols/inet b/symbols/inet
index 7300e76..f6cd6ac 100644
--- a/symbols/inet
+++ b/symbols/inet
@@ -119,6 +119,7 @@ xkb_symbols "evdev" {

key <HNGL> { [ Hangul ] };
key <HJCV> { [ Hangul_Hanja ] };
+ key <FK22> { [ XF86TouchpadToggle ] };

// key <I120> { [ ] }; // KEY_MACRO 
key <I126> { [ plusminus ] };


Thank's
Joey Lee

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH 1/3] Add acer wmi hotkey events support
@ 2010-10-13  3:47 Lee, Chun-Yi
  2010-10-13 18:24 ` Dmitry Torokhov
  0 siblings, 1 reply; 14+ messages in thread
From: Lee, Chun-Yi @ 2010-10-13  3:47 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: mjg59, carlos, linux-input, dmitry.torokhov, tiwai, trenn, jbenc,
	corentin.chary, 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..32285f4 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;
+
+	err = input_register_device(acer_wmi_input_dev);
+	if (err)
+		goto err_free_keymap;
+
+	status = wmi_install_notify_handler(ACERWMID_EVENT_GUID,
+						acer_wmi_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		err = -EIO;
+		goto err_unregister_input;
+	}
+
+	return 0;
+
+err_unregister_input:
+	input_unregister_device(acer_wmi_input_dev);
+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] 14+ messages in thread

end of thread, other threads:[~2010-10-19 15:53 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-18  4:53 [PATCH 1/3] Add acer wmi hotkey events support Joey Lee
2010-10-18  8:12 ` Dmitry Torokhov
2010-10-18  8:19   ` Corentin Chary
2010-10-18  8:25     ` Dmitry Torokhov
2010-10-18  8:47       ` Corentin Chary
2010-10-18  9:26         ` Takashi Iwai
2010-10-18  9:23     ` Matthew Garrett
2010-10-18 23:48       ` Dmitry Torokhov
  -- strict thread matches above, loose matches on Subject: below --
2010-10-19  9:43 Joey Lee
2010-10-19 15:53 ` Dmitry Torokhov
2010-10-19  9:35 Joey Lee
2010-10-19  9:31 Joey Lee
2010-10-13  3:47 Lee, Chun-Yi
2010-10-13 18:24 ` Dmitry Torokhov

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).