[patch] add INPUT key reporting to thinkpad_acpi

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Attached patch adds input keyboard reporting to the thinkpad_acpi
driver.

This works for me using evtest /dev/input/event7, although the events do
not get to X for some reason. KEY_POWER does get to X but not KEY_FN_F1,
so I assume X is filtering the keys at some stage.

This removes ugly userspace uevent schemes and allows us to assign the
correct keys using keymaps.

Comments please.

Richard Hughes.

--- origin/thinkpad_acpi.h	2007-05-16 16:03:53.000000000 +0100
+++ thinkpad_acpi.h	2007-05-16 22:59:41.000000000 +0100
@@ -31,6 +31,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/input.h>
 
 #include <linux/proc_fs.h>
 #include <linux/sysfs.h>
@@ -197,6 +198,7 @@ struct ibm_struct {
 	int (*read) (char *);
 	int (*write) (char *);
 	void (*exit) (void);
+	struct input_dev *input;
 
 	struct list_head all_drivers;
 
@@ -206,6 +208,7 @@ struct ibm_struct {
 		u8 acpi_driver_registered:1;
 		u8 acpi_notify_installed:1;
 		u8 proc_created:1;
+		u8 using_input:1;
 		u8 init_called:1;
 		u8 experimental:1;
 	} flags;
--- origin/thinkpad_acpi.c	2007-05-16 16:03:51.000000000 +0100
+++ thinkpad_acpi.c	2007-05-16 23:03:58.000000000 +0100
@@ -808,6 +808,53 @@ static struct attribute *hotkey_mask_att
 	&dev_attr_hotkey_bios_mask.attr,
 };
 
+static int __init hotkey_init_input(struct ibm_init_struct *iibm)
+{
+	int error;
+	struct input_dev *input;
+
+	dbg_printk(TPACPI_DBG_INIT, "Trying to allocate input device\n");
+	input = input_allocate_device();
+	if (!input) {
+		printk(IBM_ERR "could not allocate input device\n");
+		error = -ENOMEM;
+		goto err_no_mem;
+	}
+
+	/* we need this later to emit and deallocate */
+	iibm->data->input = input;
+	iibm->data->flags.using_input = 1;
+
+	/* create one 'keyboard' virtual input device for all the acpi events */
+	input->name = "ThinkPad Extra Buttons";
+	input->phys = "thinkpad/input0";
+	input->id.bustype = BUS_HOST;
+	input->id.product = 0x0001;
+	input->evbit[0] = BIT(EV_KEY);
+	set_bit(KEY_FN_F1, input->keybit);
+	set_bit(KEY_FN_F2, input->keybit);
+	set_bit(KEY_FN_F3, input->keybit);
+	set_bit(KEY_FN_F4, input->keybit);
+	set_bit(KEY_FN_F5, input->keybit);
+	set_bit(KEY_FN_F6, input->keybit);
+	set_bit(KEY_FN_F7, input->keybit);
+	set_bit(KEY_FN_F8, input->keybit);
+	set_bit(KEY_FN_F9, input->keybit);
+	set_bit(KEY_FN_F10, input->keybit);
+	set_bit(KEY_FN_F11, input->keybit);
+	set_bit(KEY_FN_F12, input->keybit);
+
+	error = input_register_device(input);
+	if (error)
+		goto err_free_input;
+	return 0;
+
+err_free_input:
+	input_free_device(input);
+err_no_mem:
+	return error;
+}
+
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
 	int res;
@@ -824,6 +871,10 @@ static int __init hotkey_init(struct ibm
 		str_supported(tp_features.hotkey));
 
 	if (tp_features.hotkey) {
+
+		/* we should use INPUT rather than random acpi events */
+		hotkey_init_input (iibm);
+
 		hotkey_dev_attributes = create_attr_set(4,
 						TPACPI_HOTKEY_SYSFS_GROUP);
 		if (!hotkey_dev_attributes)
@@ -879,10 +930,63 @@ static void hotkey_exit(void)
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
 	int hkey;
+	int keycode;
 
-	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
+	if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
 		acpi_bus_generate_event(ibm->acpi->device, event, hkey);
-	else {
+
+		switch (hkey) {
+		case 4097:
+			keycode = KEY_FN_F1;
+			break;
+		case 4098:
+			keycode = KEY_FN_F2;
+			break;
+		case 4099:
+			keycode = KEY_FN_F3;
+			break;
+		case 4100:
+			keycode = KEY_FN_F4;
+			break;
+		case 4101:
+			keycode = KEY_FN_F5;
+			break;
+		case 4102:
+			keycode = KEY_FN_F6;
+			break;
+		case 4103:
+			keycode = KEY_FN_F7;
+			break;
+		case 4104:
+			keycode = KEY_FN_F8;
+			break;
+		case 4105:
+			keycode = KEY_FN_F9;
+			break;
+		case 4106:
+			keycode = KEY_FN_F10;
+			break;
+		case 4107:
+			keycode = KEY_FN_F11;
+			break;
+		case 4108:
+			keycode = KEY_FN_F12;
+			break;
+		case 4112:
+			keycode = KEY_F13; /* really we want KEY_FN_HOME */
+			break;
+		default:
+			keycode = KEY_UNKNOWN;
+		}
+
+		dbg_printk(TPACPI_DBG_ALL, "mapped hkey %i to keycode %i\n", hkey, keycode);
+		if (keycode != KEY_UNKNOWN) {
+			input_report_key(ibm->input, keycode, 1);
+			input_sync(ibm->input);
+			input_report_key(ibm->input, keycode, 0);
+		}
+
+	} else {
 		printk(IBM_ERR "unknown hotkey event %d\n", event);
 		acpi_bus_generate_event(ibm->acpi->device, event, 0);
 	}
@@ -4013,6 +4117,15 @@ static void ibm_exit(struct ibm_struct *
 		ibm->flags.acpi_driver_registered = 0;
 	}
 
+	if (ibm->flags.using_input) {
+		dbg_printk(TPACPI_DBG_EXIT,
+			"%s: input_free_device\n", ibm->name);
+		BUG_ON(!ibm->input);
+		input_free_device(ibm->input);
+		ibm->input = NULL;
+		ibm->flags.using_input = FALSE;
+	}
+
 	if (ibm->flags.init_called && ibm->exit) {
 		ibm->exit();
 		ibm->flags.init_called = 0;
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
ibm-acpi-devel mailing list
ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel

[Index of Archives]     [Linux ACPI]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Photo]     [Yosemite Photos]     [Yosemite Advice]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux