[PATCH] Add support for OQO 01+ multimedia keys

From: Jamie Lentin <hidden>
Date: 2009-04-30 21:42:03
Subsystem: input (keyboard, mouse, joystick, touchscreen) drivers, the rest · Maintainers: Dmitry Torokhov, Linus Torvalds

OQO 01+ multimedia keys produce 6x on press, e0 6x upon release. As a
result, Linux thinks that another key has been pressed (or is repeating), 
when it is actually a release of the same key.  Remap e0 6x to a release 
of 6x.

Signed-off-by: Jamie Lentin <redacted>
---

Comments welcome---I'm rather aware that I'm adding a fair chunk of extra
code for 3 keys on a fairly obscure device and that my C is rusty to say
the least, but I thought I'd give it a go anyway.  If there are major
objections to this, my fallback plan is to make both 6x and e0 6x
auto-release, which may in fact be preferred.  If I've missed something
really obvious please point it out :)

  drivers/input/keyboard/atkbd.c |   41 +++++++++++++++++++++++++++++++++++++++-
  1 files changed, 40 insertions(+), 1 deletions(-)
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 444dec0..ecf9e9d 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -227,10 +227,12 @@ struct atkbd {
  };

  /*
- * System-specific ketymap fixup routine
+ * System-specific keymap fixup routine
   */
  static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
  static void *atkbd_platform_fixup_data;
+static unsigned int (*atkbd_platform_fixup_function)(struct atkbd *,
+				unsigned int);

  static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
  				ssize_t (*handler)(struct atkbd *, char *));
@@ -431,6 +433,12 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,

  	code = atkbd_compat_scancode(atkbd, code);

+	/*
+	 * Perform platform-specific fixups
+	 */
+	if (unlikely(atkbd_platform_fixup_function))
+		code = atkbd_platform_fixup_function(atkbd, code);
+
  	if (atkbd->emul && --atkbd->emul)
  		goto out;
@@ -895,6 +903,21 @@ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = {
  };

  /*
+ * OQO 01+ multimedia keys (64--66), say e0 6x when they mean f0 6x, i.e. upon
+ * release. Remap e4--e6 (from compat_scancode) to a release of 64--66.
+ */
+static unsigned int atkbd_oqo_01plus_remap_release_keys(struct atkbd *atkbd,
+				unsigned int code)
+{
+	if (code == 0xe4 || code == 0xe5 || code == 0xe6) {
+		atkbd->release = 1;
+		code &= 0x7f;
+	}
+
+	return code;
+}
+
+/*
   * atkbd_set_keycode_table() initializes keyboard's keycode table
   * according to the selected scancode set
   */
@@ -1478,6 +1501,13 @@ static int __init atkbd_setup_forced_release(const struct dmi_system_id *id)
  	return 0;
  }

+static int __init atkbd_setup_inline_fix(const struct dmi_system_id *id)
+{
+	atkbd_platform_fixup_function = id->driver_data;
+
+	return 0;
+}
+
  static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
  	{
  		.ident = "Dell Laptop",
@@ -1560,6 +1590,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
  		.callback = atkbd_setup_forced_release,
  		.driver_data = atkbd_amilo_pa1510_forced_release_keys,
  	},
+	{
+		.ident = "OQO Model 01+",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
+		},
+		.callback = atkbd_setup_inline_fix,
+		.driver_data = atkbd_oqo_01plus_remap_release_keys,
+	},
  	{ }
  };
-- 
1.6.2.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help