aboutsummaryrefslogtreecommitdiffstats
path: root/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch
diff options
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-23 09:21:56 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-01-23 09:21:56 -0800
commit4a411fc9cd1b86d9a2ed4e3df49809258d90a1ae (patch)
treeb3ac3e260848c976b545911fa08fdd0cb3c1a3f3 /simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch
parent676ce066faeb64332c10434fc255cb34aeb30f71 (diff)
downloadpatches-4a411fc9cd1b86d9a2ed4e3df49809258d90a1ae.tar.gz
remove some patches already upstream and add more rtl8821ae patches
Diffstat (limited to 'simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch')
-rw-r--r--simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch156
1 files changed, 156 insertions, 0 deletions
diff --git a/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch b/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch
new file mode 100644
index 00000000000000..d9eb686afe021e
--- /dev/null
+++ b/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch
@@ -0,0 +1,156 @@
+From 2b68920c417303e3adb90631ed9a9cbf864c0a94 Mon Sep 17 00:00:00 2001
+From: Dirk Hohndel <dirk@hohndel.org>
+Date: Wed, 1 May 2013 11:23:28 -0700
+Subject: [PATCH 1/1] Simulate fake Fn key on PS/2 keyboards w/o one (eg. Chromebook Pixel)
+
+This establishes a somewhat generic way to do this and implements a
+specific solution for the Pixel where the right ALT key is redefined
+to be an Fn key.
+
+Press/release events for the fake Fn key are no longer reported up,
+but if the fake Fn key is pressed, then other keys are potentially
+translated.
+
+Implemented in this patch are the following mappings:
+ BS -> Delete
+ Up -> PgUp
+ Down -> PgDn
+ Left -> Home
+ Right -> End
+
+Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
+---
+ drivers/input/keyboard/atkbd.c | 80 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 80 insertions(+)
+
+--- a/drivers/input/keyboard/atkbd.c
++++ b/drivers/input/keyboard/atkbd.c
+@@ -161,6 +161,19 @@ static const unsigned short atkbd_unxlat
+ #define ATKBD_KEY_UNKNOWN 0
+ #define ATKBD_KEY_NULL 255
+
++#define ATKBD_KEY_IGNORE 0x8000
++#define ATKBD_KEY_BS 0x0e
++#define ATKBD_KEY_DEL 0x53 /* actually E0 53 - same for the rest here */
++#define ATKBD_KEY_ALT_R 0x38
++#define ATKBD_KEY_HOME 0x47
++#define ATKBD_KEY_UP 0x48
++#define ATKBD_KEY_PGUP 0x49
++#define ATKBD_KEY_LEFT 0x4b
++#define ATKBD_KEY_RIGHT 0x4d
++#define ATKBD_KEY_END 0x4f
++#define ATKBD_KEY_DOWN 0x50
++#define ATKBD_KEY_PGDN 0x51
++
+ #define ATKBD_SCR_1 0xfffe
+ #define ATKBD_SCR_2 0xfffd
+ #define ATKBD_SCR_4 0xfffc
+@@ -218,6 +231,7 @@ struct atkbd {
+ bool softraw;
+ bool scroll;
+ bool enabled;
++ bool fake_fn;
+
+ /* Accessed only from interrupt */
+ unsigned char emul;
+@@ -242,6 +256,7 @@ struct atkbd {
+ static void (*atkbd_platform_fixup)(struct atkbd *, const void *data);
+ static void *atkbd_platform_fixup_data;
+ static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int);
++static unsigned int (*atkbd_fake_fn_fixup)(struct atkbd *, unsigned int);
+
+ static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
+ ssize_t (*handler)(struct atkbd *, char *));
+@@ -398,6 +413,13 @@ static irqreturn_t atkbd_interrupt(struc
+ if (!atkbd->enabled)
+ goto out;
+
++ if (atkbd_fake_fn_fixup) {
++ code = atkbd_fake_fn_fixup(atkbd, code);
++ if (code == ATKBD_KEY_IGNORE)
++ /* fake Fn key pressed - ignore */
++ goto out;
++ }
++
+ input_event(dev, EV_MSC, MSC_RAW, code);
+
+ if (atkbd_platform_scancode_fixup)
+@@ -988,6 +1010,48 @@ static unsigned int atkbd_oqo_01plus_sca
+ }
+
+ /*
++ * Google Chromebook Pixel is lacking an Fn key. In order to use as
++ * a regular Linux laptop we steal the left Alt key and turn it into
++ * an Fn key
++ */
++static unsigned int atkbd_pixel_fake_fn_fixup(struct atkbd *atkbd, unsigned int code)
++{
++ if (atkbd->emul != 1) {
++ /* handle backspace here as it's the only one w/o
++ * a leading E0/E1 (i.e., emul == 0) */
++ if (atkbd->emul == 0 && atkbd->fake_fn && (code & 0x7f) == ATKBD_KEY_BS) {
++ /* when pretending that Delete was pressed we need
++ * to set emul as well as Delete is E0 53 */
++ atkbd->emul = 1;
++ code = (code & 0x80) | ATKBD_KEY_DEL;
++ }
++ } else if ((code & 0x7f) == ATKBD_KEY_ALT_R) {
++ atkbd->fake_fn = (code & 0x80) ? 0 : 1;
++ atkbd->emul = 0;
++ code = ATKBD_KEY_IGNORE;
++ } else if (atkbd->fake_fn) {
++ unsigned int oldcode = code;
++ switch(code & 0x7f) {
++ case ATKBD_KEY_UP:
++ code = ATKBD_KEY_PGUP;
++ break;
++ case ATKBD_KEY_DOWN:
++ code = ATKBD_KEY_PGDN;
++ break;
++ case ATKBD_KEY_LEFT:
++ code = ATKBD_KEY_HOME;
++ break;
++ case ATKBD_KEY_RIGHT:
++ code = ATKBD_KEY_END;
++ break;
++ }
++ code |= oldcode & 0x80;
++ }
++ return code;
++}
++
++
++/*
+ * atkbd_set_keycode_table() initializes keyboard's keycode table
+ * according to the selected scancode set
+ */
+@@ -1638,6 +1702,13 @@ static int __init atkbd_setup_scancode_f
+ return 1;
+ }
+
++static int __init atkbd_setup_fake_fn_fixup(const struct dmi_system_id *id)
++{
++ atkbd_fake_fn_fixup = id->driver_data;
++
++ return 1;
++}
++
+ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = {
+ {
+ .matches = {
+@@ -1775,6 +1846,15 @@ static const struct dmi_system_id atkbd_
+ .callback = atkbd_setup_scancode_fixup,
+ .driver_data = atkbd_oqo_01plus_scancode_fixup,
+ },
++ {
++ /* Google Chromebook Pixel */
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
++ },
++ .callback = atkbd_setup_fake_fn_fixup,
++ .driver_data = atkbd_pixel_fake_fn_fixup,
++ },
+ { }
+ };
+