.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * USB HID quirks support for Linux |
---|
3 | 4 | * |
---|
.. | .. |
---|
9 | 10 | */ |
---|
10 | 11 | |
---|
11 | 12 | /* |
---|
12 | | - * This program is free software; you can redistribute it and/or modify it |
---|
13 | | - * under the terms of the GNU General Public License as published by the Free |
---|
14 | | - * Software Foundation; either version 2 of the License, or (at your option) |
---|
15 | | - * any later version. |
---|
16 | 13 | */ |
---|
17 | 14 | |
---|
18 | 15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
53 | 50 | MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. " |
---|
54 | 51 | "(For people who want to keep Windows PC keyboard muscle memory. " |
---|
55 | 52 | "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); |
---|
| 53 | + |
---|
| 54 | +static unsigned int swap_fn_leftctrl; |
---|
| 55 | +module_param(swap_fn_leftctrl, uint, 0644); |
---|
| 56 | +MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " |
---|
| 57 | + "(For people who want to keep PC keyboard muscle memory. " |
---|
| 58 | + "[0] = as-is, Mac layout, 1 = swapped, PC layout)"); |
---|
56 | 59 | |
---|
57 | 60 | struct apple_sc { |
---|
58 | 61 | unsigned long quirks; |
---|
.. | .. |
---|
166 | 169 | { } |
---|
167 | 170 | }; |
---|
168 | 171 | |
---|
| 172 | +static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { |
---|
| 173 | + { KEY_FN, KEY_LEFTCTRL }, |
---|
| 174 | + { } |
---|
| 175 | +}; |
---|
| 176 | + |
---|
169 | 177 | static const struct apple_key_translation *apple_find_translation( |
---|
170 | 178 | const struct apple_key_translation *table, u16 from) |
---|
171 | 179 | { |
---|
.. | .. |
---|
187 | 195 | bool do_translate; |
---|
188 | 196 | u16 code = 0; |
---|
189 | 197 | |
---|
190 | | - if (usage->code == KEY_FN) { |
---|
| 198 | + u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN); |
---|
| 199 | + |
---|
| 200 | + if (usage->code == fn_keycode) { |
---|
191 | 201 | asc->fn_on = !!value; |
---|
192 | | - input_event(input, usage->type, usage->code, value); |
---|
| 202 | + input_event(input, usage->type, KEY_FN, value); |
---|
193 | 203 | return 1; |
---|
194 | 204 | } |
---|
195 | 205 | |
---|
.. | .. |
---|
274 | 284 | } |
---|
275 | 285 | } |
---|
276 | 286 | |
---|
| 287 | + if (swap_fn_leftctrl) { |
---|
| 288 | + trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code); |
---|
| 289 | + if (trans) { |
---|
| 290 | + input_event(input, usage->type, trans->to, value); |
---|
| 291 | + return 1; |
---|
| 292 | + } |
---|
| 293 | + } |
---|
| 294 | + |
---|
277 | 295 | return 0; |
---|
278 | 296 | } |
---|
279 | 297 | |
---|
.. | .. |
---|
344 | 362 | |
---|
345 | 363 | for (trans = apple_iso_keyboard; trans->from; trans++) |
---|
346 | 364 | set_bit(trans->to, input->keybit); |
---|
| 365 | + |
---|
| 366 | + if (swap_fn_leftctrl) { |
---|
| 367 | + for (trans = swapped_fn_leftctrl_keys; trans->from; trans++) |
---|
| 368 | + set_bit(trans->to, input->keybit); |
---|
| 369 | + } |
---|
347 | 370 | } |
---|
348 | 371 | |
---|
349 | 372 | static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
---|
.. | .. |
---|
487 | 510 | .driver_data = APPLE_HAS_FN }, |
---|
488 | 511 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
---|
489 | 512 | .driver_data = APPLE_HAS_FN }, |
---|
| 513 | + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO), |
---|
| 514 | + .driver_data = APPLE_HAS_FN }, |
---|
490 | 515 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS), |
---|
491 | 516 | .driver_data = APPLE_HAS_FN }, |
---|
492 | 517 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), |
---|