Merge branch 'proc-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[linux-2.6-microblaze.git] / drivers / hid / hid-apple.c
index d732d1d..359bdfb 100644 (file)
@@ -51,6 +51,12 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\")
                "(For people who want to keep Windows PC keyboard muscle memory. "
                "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)");
 
+static unsigned int swap_fn_leftctrl;
+module_param(swap_fn_leftctrl, uint, 0644);
+MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
+               "(For people who want to keep PC keyboard muscle memory. "
+               "[0] = as-is, Mac layout, 1 = swapped, PC layout)");
+
 struct apple_sc {
        unsigned long quirks;
        unsigned int fn_on;
@@ -162,6 +168,11 @@ static const struct apple_key_translation swapped_option_cmd_keys[] = {
        { }
 };
 
+static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
+       { KEY_FN, KEY_LEFTCTRL },
+       { }
+};
+
 static const struct apple_key_translation *apple_find_translation(
                const struct apple_key_translation *table, u16 from)
 {
@@ -183,9 +194,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
        bool do_translate;
        u16 code = 0;
 
-       if (usage->code == KEY_FN) {
+       u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
+
+       if (usage->code == fn_keycode) {
                asc->fn_on = !!value;
-               input_event(input, usage->type, usage->code, value);
+               input_event(input, usage->type, KEY_FN, value);
                return 1;
        }
 
@@ -270,6 +283,14 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
                }
        }
 
+       if (swap_fn_leftctrl) {
+               trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
+               if (trans) {
+                       input_event(input, usage->type, trans->to, value);
+                       return 1;
+               }
+       }
+
        return 0;
 }
 
@@ -333,6 +354,11 @@ static void apple_setup_input(struct input_dev *input)
 
        for (trans = apple_iso_keyboard; trans->from; trans++)
                set_bit(trans->to, input->keybit);
+
+       if (swap_fn_leftctrl) {
+               for (trans = swapped_fn_leftctrl_keys; trans->from; trans++)
+                       set_bit(trans->to, input->keybit);
+       }
 }
 
 static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,