Skip to content

Commit a5d8164

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
HID: apple: Disable Fn-key key-re-mapping on clone keyboards
The Maxxter KB-BT-001 Bluetooth keyboard, which looks somewhat like the Apple Wireless Keyboard, is using the vendor and product IDs (05AC:0239) of the Apple Wireless Keyboard (2009 ANSI version) <sigh>. But its F1 - F10 keys are marked as sending F1 - F10, not the special functions hid-apple.c maps them too; and since its descriptors do not contain the HID_UP_CUSTOM | 0x0003 usage apple-hid looks for for the Fn-key, apple_setup_input() never gets called, so F1 - F6 are mapped to key-codes which have not been set in the keybit array causing them to not send any events at all. The lack of a usage code matching the Fn key in the clone is actually useful as this allows solving this problem in a generic way. This commits adds a fn_found flag and it adds a input_configured callback which checks if this flag is set once all usages have been mapped. If it is not set, then assume this is a clone and clear the quirks bitmap so that the hid-apple code does not add any special handling to this keyboard. This fixes F1 - F6 not sending anything at all and F7 - F12 sending the wrong codes on the Maxxter KB-BT-001 Bluetooth keyboard and on similar clones. Cc: Joao Moreno <[email protected]> Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent a06bb88 commit a5d8164

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

drivers/hid/hid-apple.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
6060
struct apple_sc {
6161
unsigned long quirks;
6262
unsigned int fn_on;
63+
unsigned int fn_found;
6364
DECLARE_BITMAP(pressed_numlock, KEY_CNT);
6465
};
6566

@@ -365,12 +366,15 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
365366
struct hid_field *field, struct hid_usage *usage,
366367
unsigned long **bit, int *max)
367368
{
369+
struct apple_sc *asc = hid_get_drvdata(hdev);
370+
368371
if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
369372
usage->hid == (HID_UP_MSVENDOR | 0x0003) ||
370373
usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) {
371374
/* The fn key on Apple USB keyboards */
372375
set_bit(EV_REP, hi->input->evbit);
373376
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
377+
asc->fn_found = true;
374378
apple_setup_input(hi->input);
375379
return 1;
376380
}
@@ -397,6 +401,19 @@ static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
397401
return 0;
398402
}
399403

404+
static int apple_input_configured(struct hid_device *hdev,
405+
struct hid_input *hidinput)
406+
{
407+
struct apple_sc *asc = hid_get_drvdata(hdev);
408+
409+
if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
410+
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
411+
asc->quirks = 0;
412+
}
413+
414+
return 0;
415+
}
416+
400417
static int apple_probe(struct hid_device *hdev,
401418
const struct hid_device_id *id)
402419
{
@@ -611,6 +628,7 @@ static struct hid_driver apple_driver = {
611628
.event = apple_event,
612629
.input_mapping = apple_input_mapping,
613630
.input_mapped = apple_input_mapped,
631+
.input_configured = apple_input_configured,
614632
};
615633
module_hid_driver(apple_driver);
616634

0 commit comments

Comments
 (0)