| From 180ca4a1a1f322ea899e7fee62c9b636b390cf93 Mon Sep 17 00:00:00 2001 |
| From: Hans de Goede <hdegoede@redhat.com> |
| Date: Sat, 20 Jun 2020 14:32:29 +0200 |
| Subject: [PATCH] HID: apple: Disable Fn-key key-re-mapping on clone keyboards |
| |
| commit a5d81646fa294eed57786a9310b06ca48902adf8 upstream. |
| |
| 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 <mail@joaomoreno.com> |
| Signed-off-by: Hans de Goede <hdegoede@redhat.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c |
| index d732d1d10caf..6909c045fece 100644 |
| --- a/drivers/hid/hid-apple.c |
| +++ b/drivers/hid/hid-apple.c |
| @@ -54,6 +54,7 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") |
| struct apple_sc { |
| unsigned long quirks; |
| unsigned int fn_on; |
| + unsigned int fn_found; |
| DECLARE_BITMAP(pressed_numlock, KEY_CNT); |
| }; |
| |
| @@ -339,12 +340,15 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
| struct hid_field *field, struct hid_usage *usage, |
| unsigned long **bit, int *max) |
| { |
| + struct apple_sc *asc = hid_get_drvdata(hdev); |
| + |
| if (usage->hid == (HID_UP_CUSTOM | 0x0003) || |
| usage->hid == (HID_UP_MSVENDOR | 0x0003) || |
| usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { |
| /* The fn key on Apple USB keyboards */ |
| set_bit(EV_REP, hi->input->evbit); |
| hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); |
| + asc->fn_found = true; |
| apple_setup_input(hi->input); |
| return 1; |
| } |
| @@ -371,6 +375,19 @@ static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
| return 0; |
| } |
| |
| +static int apple_input_configured(struct hid_device *hdev, |
| + struct hid_input *hidinput) |
| +{ |
| + struct apple_sc *asc = hid_get_drvdata(hdev); |
| + |
| + if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) { |
| + hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n"); |
| + asc->quirks = 0; |
| + } |
| + |
| + return 0; |
| +} |
| + |
| static int apple_probe(struct hid_device *hdev, |
| const struct hid_device_id *id) |
| { |
| @@ -585,6 +602,7 @@ static struct hid_driver apple_driver = { |
| .event = apple_event, |
| .input_mapping = apple_input_mapping, |
| .input_mapped = apple_input_mapped, |
| + .input_configured = apple_input_configured, |
| }; |
| module_hid_driver(apple_driver); |
| |
| -- |
| 2.27.0 |
| |