lkml.org 
[lkml]   [2006]   [Apr]   [19]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateWed, 19 Apr 2006 20:53:58 +0100
FromMatthew Garrett <>
Subject[RFC] [PATCH] Make ACPI button driver an input device
Sleep and power buttons are logically part of the keyboard, and it makes 
for them to be exposed via an input device rather than an odd file in 
/proc. This patch adds a keycode for lid switches (are we running out of 
keycodes?) and allows the button driver to register an input device.

Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>

diff -ur drivers/acpi.bak/button.c drivers/acpi/button.c
--- drivers/acpi.bak/button.c	2006-04-03 04:22:10 +0100
+++ a/drivers/acpi/button.c	2006-04-19 20:36:05 +0100
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/input.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -102,6 +103,8 @@
 	.release = single_release,
 };
 
+static struct input_dev *input_dev;
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
@@ -260,6 +263,37 @@
                                 Driver Interface
    -------------------------------------------------------------------------- */
 
+static void acpi_button_report (struct acpi_button *button)
+{
+	int keycode = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_button_report");
+
+	switch(button->type) {
+	case ACPI_BUTTON_TYPE_POWER:
+	case ACPI_BUTTON_TYPE_POWERF:
+		keycode = KEY_POWER;
+		break;
+	case ACPI_BUTTON_TYPE_SLEEP:
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		keycode = KEY_SLEEP;
+		break;
+	case ACPI_BUTTON_TYPE_LID:
+		keycode = KEY_LID;
+		break;
+
+	}
+
+	if (keycode) {
+		input_report_key(input_dev, keycode, 1);
+		input_sync(input_dev);
+		input_report_key(input_dev, keycode, 0);
+		input_sync(input_dev);
+	}
+
+	return_VOID;
+}
+
 static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct acpi_button *button = (struct acpi_button *)data;
@@ -273,6 +307,7 @@
 	case ACPI_BUTTON_NOTIFY_STATUS:
 		acpi_bus_generate_event(button->device, event,
 					++button->pushed);
+		acpi_button_report(button);		
 		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -467,6 +502,26 @@
 		return_VALUE(-ENODEV);
 	}
 
+	input_dev = input_allocate_device();
+
+	if (input_dev) {
+		int error;
+
+		input_dev->name = "ACPI button driver";
+		input_dev->phys = "acpi/input0";
+		input_dev->id.bustype = BUS_HOST;
+		input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+		set_bit(KEY_SLEEP, input_dev->keybit);
+		set_bit(KEY_POWER, input_dev->keybit);
+		set_bit(KEY_LID, input_dev->keybit);
+
+		error = input_register_device(input_dev);
+		if (error) {
+			printk(KERN_ERR "Unable to register ACPI input device\n");
+			input_free_device(input_dev);
+		}
+	}
+
 	return_VALUE(0);
 }
 
@@ -484,6 +539,9 @@
 		remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
 
+	if (input_dev)
+		input_unregister_device(input_dev);
+
 	return_VOID;
 }
 
--- include/linux/input.h.bak	2006-04-19 20:47:58 +0100
+++ a/include/linux/input.h	2006-04-19 20:49:18 +0100
@@ -344,6 +344,7 @@
 #define KEY_FORWARDMAIL		233
 #define KEY_SAVE		234
 #define KEY_DOCUMENTS		235
+#define KEY_LID			237
 
 #define KEY_UNKNOWN		240

-- 
Matthew Garrett | mjg59@srcf.ucam.org
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2006-04-19 21:56    [from the cache]
©2003-2008