--- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -52,6 +52,22 @@ "(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)"); + +static unsigned int rightalt_as_rightctrl; +module_param(rightalt_as_rightctrl, uint, 0644); +MODULE_PARM_DESC(rightalt_as_rightctrl, "Use the right Alt key as a right Ctrl key. " + "[0] = as-is, Mac layout. 1 = Right Alt is right Ctrl"); + +static unsigned int ejectcd_as_delete; +module_param(ejectcd_as_delete, uint, 0644); +MODULE_PARM_DESC(ejectcd_as_delete, "Use Eject-CD key as Delete key. " + "([0] = disabled, 1 = enabled)"); + struct apple_sc { unsigned long quirks; unsigned int fn_on; @@ -164,6 +180,21 @@ { } }; +static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { + { KEY_FN, KEY_LEFTCTRL }, + { } +}; + +static const struct apple_key_translation rightalt_as_rightctrl_keys[] = { + { KEY_RIGHTALT, KEY_RIGHTCTRL }, + { } +}; + +static const struct apple_key_translation ejectcd_as_delete_keys[] = { + { KEY_EJECTCD, KEY_DELETE }, + { } +}; + static const struct apple_key_translation *apple_find_translation( const struct apple_key_translation *table, u16 from) { @@ -183,9 +214,11 @@ struct apple_sc *asc = hid_get_drvdata(hid); const struct apple_key_translation *trans, *table; - 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; } @@ -264,6 +297,30 @@ } } + 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; + } + } + + if (ejectcd_as_delete) { + trans = apple_find_translation(ejectcd_as_delete_keys, usage->code); + if (trans) { + input_event(input, usage->type, trans->to, value); + return 1; + } + } + + if (rightalt_as_rightctrl) { + trans = apple_find_translation(rightalt_as_rightctrl_keys, usage->code); + if (trans) { + input_event(input, usage->type, trans->to, value); + return 1; + } + } + return 0; } @@ -327,6 +384,21 @@ 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); + } + + if (ejectcd_as_delete) { + for (trans = ejectcd_as_delete_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + } + + if (rightalt_as_rightctrl) { + for (trans = rightalt_as_rightctrl_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + } } static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,