All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Lenovo IdeaPAD ACPI driver
@ 2010-08-10 22:52 David Woodhouse
  2010-08-11 12:59 ` Corentin Chary
  0 siblings, 1 reply; 8+ messages in thread
From: David Woodhouse @ 2010-08-10 22:52 UTC (permalink / raw)
  To: mjg59; +Cc: platform-driver-x86


Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
 drivers/platform/x86/Kconfig        |    7 +
 drivers/platform/x86/Makefile       |    1 +
 drivers/platform/x86/ideapad_acpi.c |  284 +++++++++++++++++++++++++++++++++++
 3 files changed, 292 insertions(+), 0 deletions(-)
 create mode 100644 drivers/platform/x86/ideapad_acpi.c

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 79baa63..044f430 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -219,6 +219,13 @@ config SONYPI_COMPAT
 	  ---help---
 	  Build the sonypi driver compatibility code into the sony-laptop driver.
 
+config IDEAPAD_ACPI
+	tristate "Lenovo IdeaPad ACPI Laptop Extras"
+	depends on ACPI
+	depends on RFKILL
+	help
+	  This is a driver for the rfkill switches on Lenovo IdeaPad netbooks.
+
 config THINKPAD_ACPI
 	tristate "ThinkPad ACPI Laptop Extras"
 	depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 4744c77..85fb2b84 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ACERHDF)		+= acerhdf.o
 obj-$(CONFIG_HP_WMI)		+= hp-wmi.o
 obj-$(CONFIG_TC1100_WMI)	+= tc1100-wmi.o
 obj-$(CONFIG_SONY_LAPTOP)	+= sony-laptop.o
+obj-$(CONFIG_IDEAPAD_ACPI)	+= ideapad_acpi.o
 obj-$(CONFIG_THINKPAD_ACPI)	+= thinkpad_acpi.o
 obj-$(CONFIG_FUJITSU_LAPTOP)	+= fujitsu-laptop.o
 obj-$(CONFIG_PANASONIC_LAPTOP)	+= panasonic-laptop.o
diff --git a/drivers/platform/x86/ideapad_acpi.c b/drivers/platform/x86/ideapad_acpi.c
new file mode 100644
index 0000000..26a29d4
--- /dev/null
+++ b/drivers/platform/x86/ideapad_acpi.c
@@ -0,0 +1,284 @@
+/*
+ *  ideapad_acpi.c - Lenovo IdeaPad ACPI Extras
+ *
+ *  Copyright © 2010 Intel Corporation
+ *  Copyright © 2010 David Woodhouse <dwmw2@infradead.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/rfkill.h>
+
+#define IDEAPAD_DEV_CAMERA	0
+#define IDEAPAD_DEV_WLAN	1
+#define IDEAPAD_DEV_BLUETOOTH	2
+#define IDEAPAD_DEV_3G		3
+#define IDEAPAD_DEV_KILLSW	4
+
+static struct rfkill *ideapad_rfkill[5];
+
+static const char *ideapad_rfk_names[] = {
+	"ideapad_camera", "ideapad_wlan", "ideapad_bluetooth", "ideapad_3g", "ideapad_rfkill"
+};
+static const int ideapad_rfk_types[] = {
+	0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_WWAN, RFKILL_TYPE_WLAN
+};
+
+static int ideapad_dev_exists(int device)
+{
+	acpi_status status;
+	union acpi_object in_param;
+	struct acpi_object_list input = { 1, &in_param };
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	in_param.type = ACPI_TYPE_INTEGER;
+	in_param.integer.value = device + 1;
+
+	status = acpi_evaluate_object(NULL, "\\_SB_.DECN", &input, &output);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_WARNING "IdeaPAD \\_SB_.DECN method failed %d. Is this an IdeaPAD?\n", status);
+		return -ENODEV;
+	}
+	if (out_obj.type != ACPI_TYPE_INTEGER) {
+		printk(KERN_WARNING "IdeaPAD \\_SB_.DECN method returned unexpected type\n");
+		return -ENODEV;
+	}
+	return out_obj.integer.value;
+}
+
+static int ideapad_dev_get_state(int device)
+{
+	acpi_status status;
+	union acpi_object in_param;
+	struct acpi_object_list input = { 1, &in_param };
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	in_param.type = ACPI_TYPE_INTEGER;
+	in_param.integer.value = device + 1;
+
+	status = acpi_evaluate_object(NULL, "\\_SB_.GECN", &input, &output);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_WARNING "IdeaPAD \\_SB_.GECN method failed %d\n", status);
+		return -ENODEV;
+	}
+	if (out_obj.type != ACPI_TYPE_INTEGER) {
+		printk(KERN_WARNING "IdeaPAD \\_SB_.GECN method returned unexpected type\n");
+		return -ENODEV;
+	}
+	return out_obj.integer.value;
+}
+
+static int ideapad_dev_set_state(int device, int state)
+{
+	acpi_status status;
+	union acpi_object in_params[2];
+	struct acpi_object_list input = { 2, in_params };
+
+	in_params[0].type = ACPI_TYPE_INTEGER;
+	in_params[0].integer.value = device + 1;
+	in_params[1].type = ACPI_TYPE_INTEGER;
+	in_params[1].integer.value = state;
+
+	status = acpi_evaluate_object(NULL, "\\_SB_.SECN", &input, NULL);
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_WARNING "IdeaPAD \\_SB_.SECN method failed %d\n", status);
+		return -ENODEV;
+	}
+	return 0;
+}
+static ssize_t show_ideapad_cam(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	int state = ideapad_dev_get_state(IDEAPAD_DEV_CAMERA);
+	if (state < 0)
+		return state;
+
+	return sprintf(buf, "%d\n", state);
+}
+
+static ssize_t store_ideapad_cam(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int ret, state;
+
+	if (!count)
+		return 0;
+	if (sscanf(buf, "%i", &state) != 1)
+		return -EINVAL;
+	ret = ideapad_dev_set_state(IDEAPAD_DEV_CAMERA, state);
+	if (ret < 0)
+		return ret;
+	return count;
+}
+
+static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam);
+
+static int ideapad_rfk_set(void *data, bool blocked)
+{
+	int device = (unsigned long)data;
+
+	if (device == IDEAPAD_DEV_KILLSW)
+		return -EINVAL;
+	return ideapad_dev_set_state(device, !blocked);
+}
+
+static struct rfkill_ops ideapad_rfk_ops = {
+	.set_block = ideapad_rfk_set,
+};
+
+static void ideapad_sync_rfk_state(void)
+{
+	int hw_blocked = !ideapad_dev_get_state(IDEAPAD_DEV_KILLSW);
+	int i;
+
+	rfkill_set_hw_state(ideapad_rfkill[IDEAPAD_DEV_KILLSW], hw_blocked);
+	for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
+		if (ideapad_rfkill[i])
+			rfkill_set_hw_state(ideapad_rfkill[i], hw_blocked);
+	if (hw_blocked)
+		return;
+
+	for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
+		if (ideapad_rfkill[i])
+			rfkill_set_sw_state(ideapad_rfkill[i], !ideapad_dev_get_state(i));
+}
+
+static int __init ideapad_register_rfkill(struct acpi_device *device, int dev)
+{
+	int ret;
+
+	ideapad_rfkill[dev] = rfkill_alloc(ideapad_rfk_names[dev], &device->dev,
+					   ideapad_rfk_types[dev], &ideapad_rfk_ops,
+					   (void *)(long)dev);
+	if (!ideapad_rfkill[dev])
+		return -ENOMEM;
+
+	ret = rfkill_register(ideapad_rfkill[dev]);
+	if (ret) {
+		rfkill_destroy(ideapad_rfkill[dev]);
+		return ret;
+	}
+	return 0;
+}
+
+static void __exit ideapad_unregister_rfkill(int dev)
+{
+	if (!ideapad_rfkill[dev])
+		return;
+
+	rfkill_unregister(ideapad_rfkill[dev]);
+	rfkill_destroy(ideapad_rfkill[dev]);
+}
+
+static const struct acpi_device_id ideapad_device_ids[] = {
+        { "VPC2004", 0},
+        { "", 0},
+};
+MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
+
+static int ideapad_acpi_add(struct acpi_device *device)
+{
+	int i;
+	int devs_present[5];
+
+	for (i = IDEAPAD_DEV_CAMERA; i < IDEAPAD_DEV_KILLSW; i++) {
+		devs_present[i] = ideapad_dev_exists(i);
+		if (devs_present[i] < 0)
+			return devs_present[i];
+	}
+
+	/* The hardware switch is always present */
+	devs_present[IDEAPAD_DEV_KILLSW] = 1;
+
+	if (devs_present[IDEAPAD_DEV_CAMERA]) {
+		int ret = device_create_file(&device->dev, &dev_attr_camera_power);
+		if (ret)
+			return ret;
+	}
+
+	for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) {
+		if (!devs_present[i])
+			continue;
+
+		ideapad_register_rfkill(device, i);
+	}
+	ideapad_sync_rfk_state();
+	return 0;
+}
+
+static int ideapad_acpi_remove(struct acpi_device *device, int type)
+{
+	int i;
+	device_remove_file(&device->dev, &dev_attr_camera_power);
+	for (i = 0; i < 5; i++)
+		ideapad_unregister_rfkill(i);
+	return 0;
+}
+
+static void ideapad_acpi_notify(struct acpi_device *device, u32 event)
+{
+	ideapad_sync_rfk_state();
+}
+
+static struct acpi_driver ideapad_acpi_driver = {
+	.name = "ideapad_acpi",
+	.class = "IdeaPad",
+	.ids = ideapad_device_ids,
+	.ops.add = ideapad_acpi_add,
+	.ops.remove = ideapad_acpi_remove,
+	.ops.notify = ideapad_acpi_notify,
+	.owner = THIS_MODULE,
+};
+
+
+static int __init ideapad_acpi_module_init(void)
+{
+	acpi_bus_register_driver(&ideapad_acpi_driver);
+
+	return 0;
+}
+
+
+static void ideapad_acpi_module_exit(void)
+{
+	acpi_bus_unregister_driver(&ideapad_acpi_driver);
+
+}
+/* Support only the S10-3 for now, until we verify other models */
+MODULE_ALIAS("dmi:bvnLENOVO*:pnS10-3:*");
+
+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
+MODULE_DESCRIPTION("IdeaPad ACPI Extras");
+MODULE_LICENSE("GPL");
+
+module_init(ideapad_acpi_module_init);
+module_exit(ideapad_acpi_module_exit);
-- 
1.7.2.1


-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-10 22:52 [PATCH] Lenovo IdeaPAD ACPI driver David Woodhouse
@ 2010-08-11 12:59 ` Corentin Chary
  2010-08-11 13:39   ` David Woodhouse
  0 siblings, 1 reply; 8+ messages in thread
From: Corentin Chary @ 2010-08-11 12:59 UTC (permalink / raw)
  To: David Woodhouse; +Cc: mjg59, platform-driver-x86

On Wed, Aug 11, 2010 at 12:52 AM, David Woodhouse <dwmw2@infradead.org> wrote:
>
> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
> ---
>  drivers/platform/x86/Kconfig        |    7 +
>  drivers/platform/x86/Makefile       |    1 +
>  drivers/platform/x86/ideapad_acpi.c |  284 +++++++++++++++++++++++++++++++++++
>  3 files changed, 292 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/platform/x86/ideapad_acpi.c
>
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index 79baa63..044f430 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -219,6 +219,13 @@ config SONYPI_COMPAT
>          ---help---
>          Build the sonypi driver compatibility code into the sony-laptop driver.
>
> +config IDEAPAD_ACPI
> +       tristate "Lenovo IdeaPad ACPI Laptop Extras"
> +       depends on ACPI
> +       depends on RFKILL
> +       help
> +         This is a driver for the rfkill switches on Lenovo IdeaPad netbooks.
> +

I'd suggest to name it ideapad-laptop (IDEAPAD_LAPTOP). We try to use
that name for laptop related drivers.
But ... new WMI drivers are named with the *-wmi suffix. So I'm not
really sure. Anyway, it's not really important.

>  config THINKPAD_ACPI
>        tristate "ThinkPad ACPI Laptop Extras"
>        depends on ACPI
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index 4744c77..85fb2b84 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_ACERHDF)         += acerhdf.o
>  obj-$(CONFIG_HP_WMI)           += hp-wmi.o
>  obj-$(CONFIG_TC1100_WMI)       += tc1100-wmi.o
>  obj-$(CONFIG_SONY_LAPTOP)      += sony-laptop.o
> +obj-$(CONFIG_IDEAPAD_ACPI)     += ideapad_acpi.o
>  obj-$(CONFIG_THINKPAD_ACPI)    += thinkpad_acpi.o
>  obj-$(CONFIG_FUJITSU_LAPTOP)   += fujitsu-laptop.o
>  obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o
> diff --git a/drivers/platform/x86/ideapad_acpi.c b/drivers/platform/x86/ideapad_acpi.c
> new file mode 100644
> index 0000000..26a29d4
> --- /dev/null
> +++ b/drivers/platform/x86/ideapad_acpi.c
> @@ -0,0 +1,284 @@
> +/*
> + *  ideapad_acpi.c - Lenovo IdeaPad ACPI Extras
> + *
> + *  Copyright © 2010 Intel Corporation
> + *  Copyright © 2010 David Woodhouse <dwmw2@infradead.org>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + *  02110-1301, USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/types.h>
> +#include <acpi/acpi_bus.h>
> +#include <acpi/acpi_drivers.h>
> +#include <linux/rfkill.h>
> +
> +#define IDEAPAD_DEV_CAMERA     0
> +#define IDEAPAD_DEV_WLAN       1
> +#define IDEAPAD_DEV_BLUETOOTH  2
> +#define IDEAPAD_DEV_3G         3
> +#define IDEAPAD_DEV_KILLSW     4

What's DEV_KILLSW ? a global kill switch ?

> +static struct rfkill *ideapad_rfkill[5];
> +
> +static const char *ideapad_rfk_names[] = {
> +       "ideapad_camera", "ideapad_wlan", "ideapad_bluetooth", "ideapad_3g", "ideapad_rfkill"
> +};

Hum, ideapad_camera inside rfkill stuff ?

> +static const int ideapad_rfk_types[] = {
> +       0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_WWAN, RFKILL_TYPE_WLAN
> +};
> +
> +static int ideapad_dev_exists(int device)
> +{
> +       acpi_status status;
> +       union acpi_object in_param;
> +       struct acpi_object_list input = { 1, &in_param };
> +       struct acpi_buffer output;
> +       union acpi_object out_obj;
> +
> +       output.length = sizeof(out_obj);
> +       output.pointer = &out_obj;
> +
> +       in_param.type = ACPI_TYPE_INTEGER;
> +       in_param.integer.value = device + 1;
> +
> +       status = acpi_evaluate_object(NULL, "\\_SB_.DECN", &input, &output);
> +       if (ACPI_FAILURE(status)) {
> +               printk(KERN_WARNING "IdeaPAD \\_SB_.DECN method failed %d. Is this an IdeaPAD?\n", status);
> +               return -ENODEV;
> +       }
> +       if (out_obj.type != ACPI_TYPE_INTEGER) {
> +               printk(KERN_WARNING "IdeaPAD \\_SB_.DECN method returned unexpected type\n");
> +               return -ENODEV;
> +       }
> +       return out_obj.integer.value;
> +}
> +
> +static int ideapad_dev_get_state(int device)
> +{
> +       acpi_status status;
> +       union acpi_object in_param;
> +       struct acpi_object_list input = { 1, &in_param };
> +       struct acpi_buffer output;
> +       union acpi_object out_obj;
> +
> +       output.length = sizeof(out_obj);
> +       output.pointer = &out_obj;
> +
> +       in_param.type = ACPI_TYPE_INTEGER;
> +       in_param.integer.value = device + 1;
> +
> +       status = acpi_evaluate_object(NULL, "\\_SB_.GECN", &input, &output);
> +       if (ACPI_FAILURE(status)) {
> +               printk(KERN_WARNING "IdeaPAD \\_SB_.GECN method failed %d\n", status);
> +               return -ENODEV;
> +       }
> +       if (out_obj.type != ACPI_TYPE_INTEGER) {
> +               printk(KERN_WARNING "IdeaPAD \\_SB_.GECN method returned unexpected type\n");
> +               return -ENODEV;
> +       }
> +       return out_obj.integer.value;
> +}
> +
> +static int ideapad_dev_set_state(int device, int state)
> +{
> +       acpi_status status;
> +       union acpi_object in_params[2];
> +       struct acpi_object_list input = { 2, in_params };
> +
> +       in_params[0].type = ACPI_TYPE_INTEGER;
> +       in_params[0].integer.value = device + 1;
> +       in_params[1].type = ACPI_TYPE_INTEGER;
> +       in_params[1].integer.value = state;
> +
> +       status = acpi_evaluate_object(NULL, "\\_SB_.SECN", &input, NULL);
> +       if (ACPI_FAILURE(status)) {
> +               printk(KERN_WARNING "IdeaPAD \\_SB_.SECN method failed %d\n", status);
> +               return -ENODEV;
> +       }
> +       return 0;
> +}
> +static ssize_t show_ideapad_cam(struct device *dev,
> +                               struct device_attribute *attr,
> +                               char *buf)
> +{
> +       int state = ideapad_dev_get_state(IDEAPAD_DEV_CAMERA);
> +       if (state < 0)
> +               return state;
> +
> +       return sprintf(buf, "%d\n", state);
> +}
> +
> +static ssize_t store_ideapad_cam(struct device *dev,
> +                                struct device_attribute *attr,
> +                                const char *buf, size_t count)
> +{
> +       int ret, state;
> +
> +       if (!count)
> +               return 0;
> +       if (sscanf(buf, "%i", &state) != 1)
> +               return -EINVAL;
> +       ret = ideapad_dev_set_state(IDEAPAD_DEV_CAMERA, state);

What does it do with values other than 1 and 0 ? maybe you could send
!!state instead

> +       if (ret < 0)
> +               return ret;
> +       return count;
> +}
> +
> +static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam);
> +
> +static int ideapad_rfk_set(void *data, bool blocked)
> +{
> +       int device = (unsigned long)data;
> +
> +       if (device == IDEAPAD_DEV_KILLSW)
> +               return -EINVAL;
> +       return ideapad_dev_set_state(device, !blocked);
> +}
> +
> +static struct rfkill_ops ideapad_rfk_ops = {
> +       .set_block = ideapad_rfk_set,
> +};
> +
> +static void ideapad_sync_rfk_state(void)
> +{
> +       int hw_blocked = !ideapad_dev_get_state(IDEAPAD_DEV_KILLSW);
> +       int i;
> +
> +       rfkill_set_hw_state(ideapad_rfkill[IDEAPAD_DEV_KILLSW], hw_blocked);
> +       for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
> +               if (ideapad_rfkill[i])
> +                       rfkill_set_hw_state(ideapad_rfkill[i], hw_blocked);
> +       if (hw_blocked)
> +               return;
> +
> +       for (i = IDEAPAD_DEV_WLAN; i < IDEAPAD_DEV_KILLSW; i++)
> +               if (ideapad_rfkill[i])
> +                       rfkill_set_sw_state(ideapad_rfkill[i], !ideapad_dev_get_state(i));
> +}
> +
> +static int __init ideapad_register_rfkill(struct acpi_device *device, int dev)
> +{
> +       int ret;
> +
> +       ideapad_rfkill[dev] = rfkill_alloc(ideapad_rfk_names[dev], &device->dev,
> +                                          ideapad_rfk_types[dev], &ideapad_rfk_ops,
> +                                          (void *)(long)dev);
> +       if (!ideapad_rfkill[dev])
> +               return -ENOMEM;
> +
> +       ret = rfkill_register(ideapad_rfkill[dev]);
> +       if (ret) {
> +               rfkill_destroy(ideapad_rfkill[dev]);
> +               return ret;
> +       }
> +       return 0;
> +}
> +
> +static void __exit ideapad_unregister_rfkill(int dev)
> +{
> +       if (!ideapad_rfkill[dev])
> +               return;
> +
> +       rfkill_unregister(ideapad_rfkill[dev]);
> +       rfkill_destroy(ideapad_rfkill[dev]);
> +}
> +
> +static const struct acpi_device_id ideapad_device_ids[] = {
> +        { "VPC2004", 0},
> +        { "", 0},
> +};
> +MODULE_DEVICE_TABLE(acpi, ideapad_device_ids);
> +
> +static int ideapad_acpi_add(struct acpi_device *device)
> +{
> +       int i;
> +       int devs_present[5];
> +
> +       for (i = IDEAPAD_DEV_CAMERA; i < IDEAPAD_DEV_KILLSW; i++) {
> +               devs_present[i] = ideapad_dev_exists(i);
> +               if (devs_present[i] < 0)
> +                       return devs_present[i];
> +       }
> +
> +       /* The hardware switch is always present */
> +       devs_present[IDEAPAD_DEV_KILLSW] = 1;
> +
> +       if (devs_present[IDEAPAD_DEV_CAMERA]) {
> +               int ret = device_create_file(&device->dev, &dev_attr_camera_power);
> +               if (ret)
> +                       return ret;
> +       }
> +
> +       for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) {
> +               if (!devs_present[i])
> +                       continue;
> +
> +               ideapad_register_rfkill(device, i);
> +       }
> +       ideapad_sync_rfk_state();
> +       return 0;
> +}
> +
> +static int ideapad_acpi_remove(struct acpi_device *device, int type)
> +{
> +       int i;
> +       device_remove_file(&device->dev, &dev_attr_camera_power);
> +       for (i = 0; i < 5; i++)
> +               ideapad_unregister_rfkill(i);
> +       return 0;
> +}
> +
> +static void ideapad_acpi_notify(struct acpi_device *device, u32 event)
> +{
> +       ideapad_sync_rfk_state();
> +}
> +
> +static struct acpi_driver ideapad_acpi_driver = {
> +       .name = "ideapad_acpi",
> +       .class = "IdeaPad",
> +       .ids = ideapad_device_ids,
> +       .ops.add = ideapad_acpi_add,
> +       .ops.remove = ideapad_acpi_remove,
> +       .ops.notify = ideapad_acpi_notify,
> +       .owner = THIS_MODULE,
> +};
> +
> +
> +static int __init ideapad_acpi_module_init(void)
> +{
> +       acpi_bus_register_driver(&ideapad_acpi_driver);
> +
> +       return 0;
> +}
> +
> +
> +static void ideapad_acpi_module_exit(void)
> +{
> +       acpi_bus_unregister_driver(&ideapad_acpi_driver);
> +
> +}
> +/* Support only the S10-3 for now, until we verify other models */
> +MODULE_ALIAS("dmi:bvnLENOVO*:pnS10-3:*");
> +
> +MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
> +MODULE_DESCRIPTION("IdeaPad ACPI Extras");
> +MODULE_LICENSE("GPL");
> +
> +module_init(ideapad_acpi_module_init);
> +module_exit(ideapad_acpi_module_exit);
> --
> 1.7.2.1
>

Also, it would be great not to use the "there will only be one of
these device" anti-pattern.
Of course, it will work, but I think it's better to get a clean,
fully-reentrant driver.

-- 
Corentin Chary
http://xf.iksaif.net

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-11 12:59 ` Corentin Chary
@ 2010-08-11 13:39   ` David Woodhouse
  2010-08-11 13:51     ` Corentin Chary
  0 siblings, 1 reply; 8+ messages in thread
From: David Woodhouse @ 2010-08-11 13:39 UTC (permalink / raw)
  To: Corentin Chary; +Cc: mjg59, platform-driver-x86

On Wed, 2010-08-11 at 14:59 +0200, Corentin Chary wrote:
> I'd suggest to name it ideapad-laptop (IDEAPAD_LAPTOP). We try to use
> that name for laptop related drivers.

OK.

> But ... new WMI drivers are named with the *-wmi suffix. So I'm not
> really sure. Anyway, it's not really important.

It doesn't do any WMI stuff... yet. I was looking at your discussion
from April and hoping you'd help make it work...

> What's DEV_KILLSW ? a global kill switch ?

Yes, that's a physical switch on the side of the laptop which
automatically kills all of wifi, bluetooth and 3g.

> > +static struct rfkill *ideapad_rfkill[5];
> > +
> > +static const char *ideapad_rfk_names[] = {
> > +       "ideapad_camera", "ideapad_wlan", "ideapad_bluetooth", "ideapad_3g", "ideapad_rfkill"
> > +};
> 
> Hum, ideapad_camera inside rfkill stuff ?

Element zero of the array doesn't get used. It was that or add a bunch
of '-1' in various places. I am entirely unconvinced which I like least.
It's the same for the types:

> > +static const int ideapad_rfk_types[] = {
> > +       0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_WWAN, RFKILL_TYPE_WLAN
> > +};
...
> > +static ssize_t store_ideapad_cam(struct device *dev,
> > +                                struct device_attribute *attr,
> > +                                const char *buf, size_t count)
> > +{
> > +       int ret, state;
> > +
> > +       if (!count)
> > +               return 0;
> > +       if (sscanf(buf, "%i", &state) != 1)
> > +               return -EINVAL;
> > +       ret = ideapad_dev_set_state(IDEAPAD_DEV_CAMERA, state);
> 
> What does it do with values other than 1 and 0 ? maybe you could send
> !!state instead

I could do. The ACPI code does so for itself anyway:

            If (Arg1)
            {
                Store (0x01, Local1)
            }
            Else
            {
                Store (0x00, Local1)
            }

> Also, it would be great not to use the "there will only be one of
> these device" anti-pattern.
> Of course, it will work, but I think it's better to get a clean,
> fully-reentrant driver.

Agreed. Will fix.

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-11 13:39   ` David Woodhouse
@ 2010-08-11 13:51     ` Corentin Chary
  2010-08-11 13:55       ` David Woodhouse
  2010-08-12  9:42       ` David Woodhouse
  0 siblings, 2 replies; 8+ messages in thread
From: Corentin Chary @ 2010-08-11 13:51 UTC (permalink / raw)
  To: David Woodhouse; +Cc: mjg59, platform-driver-x86

On Wed, Aug 11, 2010 at 3:39 PM, David Woodhouse <dwmw2@infradead.org> wrote:
> On Wed, 2010-08-11 at 14:59 +0200, Corentin Chary wrote:
>> I'd suggest to name it ideapad-laptop (IDEAPAD_LAPTOP). We try to use
>> that name for laptop related drivers.
>
> OK.
>
>> But ... new WMI drivers are named with the *-wmi suffix. So I'm not
>> really sure. Anyway, it's not really important.
>
> It doesn't do any WMI stuff... yet. I was looking at your discussion
> from April and hoping you'd help make it work...

I'd suggest you to read http://lwn.net/Articles/391230/  :)

>> What's DEV_KILLSW ? a global kill switch ?
>
> Yes, that's a physical switch on the side of the laptop which
> automatically kills all of wifi, bluetooth and 3g.
>
>> > +static struct rfkill *ideapad_rfkill[5];
>> > +
>> > +static const char *ideapad_rfk_names[] = {
>> > +       "ideapad_camera", "ideapad_wlan", "ideapad_bluetooth", "ideapad_3g", "ideapad_rfkill"
>> > +};
>>
>> Hum, ideapad_camera inside rfkill stuff ?
>
> Element zero of the array doesn't get used. It was that or add a bunch
> of '-1' in various places. I am entirely unconvinced which I like least.
> It's the same for the types:
>
>> > +static const int ideapad_rfk_types[] = {
>> > +       0, RFKILL_TYPE_WLAN, RFKILL_TYPE_BLUETOOTH, RFKILL_TYPE_WWAN, RFKILL_TYPE_WLAN
>> > +};
> ...
>> > +static ssize_t store_ideapad_cam(struct device *dev,
>> > +                                struct device_attribute *attr,
>> > +                                const char *buf, size_t count)
>> > +{
>> > +       int ret, state;
>> > +
>> > +       if (!count)
>> > +               return 0;
>> > +       if (sscanf(buf, "%i", &state) != 1)
>> > +               return -EINVAL;
>> > +       ret = ideapad_dev_set_state(IDEAPAD_DEV_CAMERA, state);
>>
>> What does it do with values other than 1 and 0 ? maybe you could send
>> !!state instead
>
> I could do. The ACPI code does so for itself anyway:
>
>            If (Arg1)
>            {
>                Store (0x01, Local1)
>            }
>            Else
>            {
>                Store (0x00, Local1)
>            }
>
>> Also, it would be great not to use the "there will only be one of
>> these device" anti-pattern.
>> Of course, it will work, but I think it's better to get a clean,
>> fully-reentrant driver.
>
> Agreed. Will fix.

Alan did a great work on that for eeepc-laptop, and the new eeepc-wmi
should be clean.
You can take a look a these.

And you should probably make it a platform driver (being the parent of
acpi, wmi, input, backlight, rfkill, etc..).

Is there a lot of thing hidden in ACPI / WMI on these models (like
hotkeys, backlight, light sensors)  ?

Thanks,

-- 
Corentin Chary
http://xf.iksaif.net

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-11 13:51     ` Corentin Chary
@ 2010-08-11 13:55       ` David Woodhouse
  2010-08-12  9:42       ` David Woodhouse
  1 sibling, 0 replies; 8+ messages in thread
From: David Woodhouse @ 2010-08-11 13:55 UTC (permalink / raw)
  To: Corentin Chary; +Cc: mjg59, platform-driver-x86

On Wed, 2010-08-11 at 15:51 +0200, Corentin Chary wrote:
> On Wed, Aug 11, 2010 at 3:39 PM, David Woodhouse <dwmw2@infradead.org> wrote:
> > On Wed, 2010-08-11 at 14:59 +0200, Corentin Chary wrote:
> >> I'd suggest to name it ideapad-laptop (IDEAPAD_LAPTOP). We try to use
> >> that name for laptop related drivers.
> >
> > OK.
> >
> >> But ... new WMI drivers are named with the *-wmi suffix. So I'm not
> >> really sure. Anyway, it's not really important.
> >
> > It doesn't do any WMI stuff... yet. I was looking at your discussion
> > from April and hoping you'd help make it work...
> 
> I'd suggest you to read http://lwn.net/Articles/391230/  :)

Ah, thanks. I'd seen Matthew's article on basic ACPI drivers, but hadn't
seen this one.

> And you should probably make it a platform driver (being the parent of
> acpi, wmi, input, backlight, rfkill, etc..).

I had faked a platform device to start with, but got rid of it as soon
as I had the acpi_device to use instead.

> Is there a lot of thing hidden in ACPI / WMI on these models (like
> hotkeys, backlight, light sensors)  ?

I think so, yes. My primary focus was the rfkill, which was breaking
wireless connectivity unless we have a way to turn it off -- but now I'm
here I may as well see what else I can do with it.

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-11 13:51     ` Corentin Chary
  2010-08-11 13:55       ` David Woodhouse
@ 2010-08-12  9:42       ` David Woodhouse
  2010-08-12 11:49         ` Corentin Chary
  1 sibling, 1 reply; 8+ messages in thread
From: David Woodhouse @ 2010-08-12  9:42 UTC (permalink / raw)
  To: Corentin Chary; +Cc: mjg59, platform-driver-x86

On Wed, 2010-08-11 at 15:51 +0200, Corentin Chary wrote:
> And you should probably make it a platform driver (being the parent of
> acpi, wmi, input, backlight, rfkill, etc..).
> 
> Is there a lot of thing hidden in ACPI / WMI on these models (like
> hotkeys, backlight, light sensors)  ?

I hooked up something (below) to dump the AE or IO WMI blocks each time
we get a notification on the VPC2004 device. Although the notification
happens when we press a key, nothing ever changes in either of them.

I *did* notice that we're actually getting proper keycodes for the
hotkeys though, so for now I've lost what little interest I already had
in doing anything with WMI. If anyone (Florian?) wants to do more, I'd
be happy to do some testing.

As I said, my main reason for looking at this was to implement the
rkfill support, without which some people can't get the wireless working
on these devices at all (without booting to Windows to unblock it). And
that much is working in git://git.infradead.org/~dwmw2/ideapad-2.6.git

diff --git a/drivers/platform/x86/ideapad-wmi.c b/drivers/platform/x86/ideapad-wmi.c
index 53046d1..5bdbd9c 100644
--- a/drivers/platform/x86/ideapad-wmi.c
+++ b/drivers/platform/x86/ideapad-wmi.c
@@ -28,6 +28,10 @@
 #include <acpi/acpi_drivers.h>
 #include <linux/rfkill.h>
 
+#define IDEAPAD_EVENT_GUID	"ABBC0F20-8EA1-11D1-00A0-C90629100000"
+#define IDEAPAD_IO_GUID		"ABBC0F40-8EA1-11D1-00A0-C90629100000"
+#define IDEAPAD_AE_GUID		"05901221-D566-11D1-B2F0-00A0C9062910"
+
 #define IDEAPAD_DEV_CAMERA	0
 #define IDEAPAD_DEV_WLAN	1
 #define IDEAPAD_DEV_BLUETOOTH	2
@@ -268,9 +272,44 @@ static int ideapad_acpi_remove(struct acpi_device *adevice, int type)
 	return 0;
 }
 
+static int oldlen;
+static unsigned char oldresponse[4096];
+
 static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
 {
+	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	acpi_status status;
+
 	ideapad_sync_rfk_state(adevice);
+
+	status = wmi_query_block(IDEAPAD_AE_GUID, 1, &response);
+	if (ACPI_FAILURE(status))
+		return;
+
+	obj = response.pointer;
+	if (obj && obj->type == ACPI_TYPE_BUFFER) {
+		int i;
+#if 1
+		for (i=0 ; i<obj->buffer.length; i++) {
+			if (!(i&0xf)) {
+				if (i)
+					printk("\n");
+				printk(KERN_INFO "%04x:", i);
+			}
+			printk(" %02x", ((unsigned char *)obj->buffer.pointer)[i]);
+		}
+		printk("\n");
+#endif
+		for (i=0 ; i < obj->buffer.length && i < oldlen; i++) {
+			if (oldresponse[i] != obj->buffer.pointer[i])
+				printk(KERN_INFO "Byte %04x: %02x->%02x\n",
+				       i, oldresponse[i], obj->buffer.pointer[i]);
+		}
+		oldlen = min(sizeof(oldresponse), obj->buffer.length);
+		memcpy(oldresponse, obj->buffer.pointer, oldlen);
+	}
+	kfree(obj);
 }
 
 static struct acpi_driver ideapad_acpi_driver = {


-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-12  9:42       ` David Woodhouse
@ 2010-08-12 11:49         ` Corentin Chary
  2010-08-12 12:24           ` David Woodhouse
  0 siblings, 1 reply; 8+ messages in thread
From: Corentin Chary @ 2010-08-12 11:49 UTC (permalink / raw)
  To: David Woodhouse; +Cc: mjg59, platform-driver-x86

On Thu, Aug 12, 2010 at 11:42 AM, David Woodhouse <dwmw2@infradead.org> wrote:
> On Wed, 2010-08-11 at 15:51 +0200, Corentin Chary wrote:
>> And you should probably make it a platform driver (being the parent of
>> acpi, wmi, input, backlight, rfkill, etc..).
>>
>> Is there a lot of thing hidden in ACPI / WMI on these models (like
>> hotkeys, backlight, light sensors)  ?
>
> I hooked up something (below) to dump the AE or IO WMI blocks each time
> we get a notification on the VPC2004 device. Although the notification
> happens when we press a key, nothing ever changes in either of them.

They is probably something interesting in the u32 event var.
To get wmi events, you need to use wmi_install_notify_handler.

For example, the hardware rfkill state may change due to some keypress,
and an event may be sent via acpi or wmi, but if you don't catch it, the rfkill
class won't be updated.

Could you send the output of acpidump ?

> I *did* notice that we're actually getting proper keycodes for the
> hotkeys though, so for now I've lost what little interest I already had
> in doing anything with WMI. If anyone (Florian?) wants to do more, I'd
> be happy to do some testing.

keycodes are sent from the keyboard input device for all specials keys
? (especially Fn+Fx keys) ?

Thanks,

-- 
Corentin Chary
http://xf.iksaif.net

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Lenovo IdeaPAD ACPI driver
  2010-08-12 11:49         ` Corentin Chary
@ 2010-08-12 12:24           ` David Woodhouse
  0 siblings, 0 replies; 8+ messages in thread
From: David Woodhouse @ 2010-08-12 12:24 UTC (permalink / raw)
  To: Corentin Chary; +Cc: mjg59, platform-driver-x86

On Thu, 2010-08-12 at 13:49 +0200, Corentin Chary wrote:
> On Thu, Aug 12, 2010 at 11:42 AM, David Woodhouse <dwmw2@infradead.org> wrote:
> > On Wed, 2010-08-11 at 15:51 +0200, Corentin Chary wrote:
> >> And you should probably make it a platform driver (being the parent of
> >> acpi, wmi, input, backlight, rfkill, etc..).
> >>
> >> Is there a lot of thing hidden in ACPI / WMI on these models (like
> >> hotkeys, backlight, light sensors)  ?
> >
> > I hooked up something (below) to dump the AE or IO WMI blocks each time
> > we get a notification on the VPC2004 device. Although the notification
> > happens when we press a key, nothing ever changes in either of them.
> 
> They is probably something interesting in the u32 event var.

It's always 0x80.

> To get wmi events, you need to use wmi_install_notify_handler.

I didn't bother hooking that up -- according to the discussion back in
April, the WMI is never triggered.

http://www.mail-archive.com/platform-driver-x86@vger.kernel.org/msg00034.html

> For example, the hardware rfkill state may change due to some keypress,
> and an event may be sent via acpi or wmi, but if you don't catch it, the rfkill
> class won't be updated.

The notify gets called then too, and we resync the rfkill state.

> Could you send the output of acpidump ?

Attached to http://bugs.meego.com/show_bug.cgi?id=4086 --
http://bugs.meego.com/attachment.cgi?id=1860

It's much the same as what you were looking at before on the S10-3t, as
far as I can tell.

> > I *did* notice that we're actually getting proper keycodes for the
> > hotkeys though, so for now I've lost what little interest I already had
> > in doing anything with WMI. If anyone (Florian?) wants to do more, I'd
> > be happy to do some testing.
> 
> keycodes are sent from the keyboard input device for all specials keys
> ? (especially Fn+Fx keys) ?

All but the external display hotkey.

The brightness up/down (Fn-up, Fn-down) don't do anything but they do
report:
[10608.863641] atkbd.c: Unknown key pressed (translated set 2, code 0xb9 on isa0060/serio0).
[10608.863655] atkbd.c: Use 'setkeycodes e039 <keycode>' to make it known.
[10609.002143] atkbd.c: Unknown key released (translated set 2, code 0xb9 on isa0060/serio0).
[10609.002157] atkbd.c: Use 'setkeycodes e039 <keycode>' to make it known.
[10609.225721] atkbd.c: Unknown key pressed (translated set 2, code 0xba on isa0060/serio0).
[10609.225735] atkbd.c: Use 'setkeycodes e03a <keycode>' to make it known.
[10609.332264] atkbd.c: Unknown key released (translated set 2, code 0xba on isa0060/serio0).
[10609.332278] atkbd.c: Use 'setkeycodes e03a <keycode>' to make it known.

The camera enable/disable (Fn-Esc) toggles the camera power (which is
also readable/writable through sysfs with my driver) and also reports:
[10633.222832] atkbd.c: Unknown key pressed (translated set 2, code 0xf1 on isa0060/serio0).
[10633.222846] atkbd.c: Use 'setkeycodes e071 <keycode>' to make it known.
[10633.329105] atkbd.c: Unknown key released (translated set 2, code 0xf1 on isa0060/serio0).
[10633.329119] atkbd.c: Use 'setkeycodes e071 <keycode>' to make it known.
[10633.451208] usb 1-8: USB disconnect, address 5

The sleep button (Fn-F1) just puts it to sleep; that'll be reported
through a separate ACPI event. I haven't investigated but I assume
that's working correctly.

The 'display off' button (Fn-F2) works and:
[10788.130877] atkbd.c: Unknown key pressed (translated set 2, code 0x83 on isa0060/serio0).
[10788.130891] atkbd.c: Use 'setkeycodes e003 <keycode>' to make it known.
[10788.269195] atkbd.c: Unknown key released (translated set 2, code 0x83 on isa0060/serio0).
[10788.269209] atkbd.c: Use 'setkeycodes e003 <keycode>' to make it known.

What I assume is the external display key (Fn-F3) seems to do nothing,
whether I have an external display connected or not. If I connect an
external display (even if it's powered off), X switches over to it
automatically. That's probably just X under MeeGo doing that though.

Fn-F4 has no special marking

The rfkill hotkey (Fn-F5) which under Windows just brings up the Lenovo
GUI tool, does nothing except:
[10835.095618] atkbd.c: Unknown key pressed (translated set 2, code 0x81 on isa0060/serio0).
[10835.095631] atkbd.c: Use 'setkeycodes e001 <keycode>' to make it known.
[10835.233979] atkbd.c: Unknown key released (translated set 2, code 0x81 on isa0060/serio0).
[10835.233994] atkbd.c: Use 'setkeycodes e001 <keycode>' to make it known.

What looks like a 'trackpad kill' (Fn-F6) just does:
[10910.931021] atkbd.c: Unknown key pressed (translated set 2, code 0xf2 on isa0060/serio0).
[10910.931036] atkbd.c: Use 'setkeycodes e072 <keycode>' to make it known.
[10911.048135] atkbd.c: Unknown key released (translated set 2, code 0xf2 on isa0060/serio0).
[10911.048148] atkbd.c: Use 'setkeycodes e072 <keycode>' to make it known.

The multimedia keys on Fn-F{7,8,9,10} seems to be generating 'known'
keycodes which don't cause a complaint, although they don't seem to show
up as anything useful in 'xev'.
[11135.784840] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11135374]
[11135.789916] drivers/input/serio/i8042.c: 22 <- i8042 (interrupt, 0, 1) [11135379]
[11135.901911] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11135491]
[11135.907035] drivers/input/serio/i8042.c: a2 <- i8042 (interrupt, 0, 1) [11135497]
[11135.949906] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11135539]
[11135.954976] drivers/input/serio/i8042.c: 24 <- i8042 (interrupt, 0, 1) [11135544]
[11136.125383] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11135715]
[11136.130516] drivers/input/serio/i8042.c: a4 <- i8042 (interrupt, 0, 1) [11135720]
[11136.395678] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11135985]
[11136.400910] drivers/input/serio/i8042.c: 10 <- i8042 (interrupt, 0, 1) [11135990]
[11136.523555] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11136113]
[11136.528676] drivers/input/serio/i8042.c: 90 <- i8042 (interrupt, 0, 1) [11136118]
[11136.864389] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11136454]
[11136.869477] drivers/input/serio/i8042.c: 19 <- i8042 (interrupt, 0, 1) [11136459]
[11136.944201] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11136534]
[11136.949322] drivers/input/serio/i8042.c: 99 <- i8042 (interrupt, 0, 1) [11136539]


If I press and hold the Fn key, after a while I get a stream of
[11231.859281] drivers/input/serio/i8042.c: e0 <- i8042 (interrupt, 0, 1) [11231449]
[11231.864363] drivers/input/serio/i8042.c: 63 <- i8042 (interrupt, 0, 1) [11231454]

-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse@intel.com                              Intel Corporation

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-08-12 12:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-10 22:52 [PATCH] Lenovo IdeaPAD ACPI driver David Woodhouse
2010-08-11 12:59 ` Corentin Chary
2010-08-11 13:39   ` David Woodhouse
2010-08-11 13:51     ` Corentin Chary
2010-08-11 13:55       ` David Woodhouse
2010-08-12  9:42       ` David Woodhouse
2010-08-12 11:49         ` Corentin Chary
2010-08-12 12:24           ` David Woodhouse

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.