Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: chicony: Add Wireless Radio Control feature for Chicony devices

Some Chicony's keyboards support airplane mode hotkey (Fn+F2) with
"Wireless Radio Control" feature. For example, the wireless keyboard
[04f2:1236] shipped with ASUS all-in-one desktop.

After consulting Chicony for this hotkey, learned the device will send
with 0x11 as the report ID and 0x1 as the value when the key is pressed
down.

This patch maps the event as KEY_RFKILL.

Signed-off-by: Jian-Hong Pan <jhp@endlessos.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Jian-Hong Pan and committed by
Jiri Kosina
859b510b de925e2f

+56
+55
drivers/hid/hid-chicony.c
··· 21 21 22 22 #include "hid-ids.h" 23 23 24 + #define CH_WIRELESS_CTL_REPORT_ID 0x11 25 + 26 + static int ch_report_wireless(struct hid_report *report, u8 *data, int size) 27 + { 28 + struct hid_device *hdev = report->device; 29 + struct input_dev *input; 30 + 31 + if (report->id != CH_WIRELESS_CTL_REPORT_ID || report->maxfield != 1) 32 + return 0; 33 + 34 + input = report->field[0]->hidinput->input; 35 + if (!input) { 36 + hid_warn(hdev, "can't find wireless radio control's input"); 37 + return 0; 38 + } 39 + 40 + input_report_key(input, KEY_RFKILL, 1); 41 + input_sync(input); 42 + input_report_key(input, KEY_RFKILL, 0); 43 + input_sync(input); 44 + 45 + return 1; 46 + } 47 + 48 + static int ch_raw_event(struct hid_device *hdev, 49 + struct hid_report *report, u8 *data, int size) 50 + { 51 + if (report->application == HID_GD_WIRELESS_RADIO_CTLS) 52 + return ch_report_wireless(report, data, size); 53 + 54 + return 0; 55 + } 56 + 24 57 #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 25 58 EV_KEY, (c)) 26 59 static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, ··· 110 77 return rdesc; 111 78 } 112 79 80 + static int ch_probe(struct hid_device *hdev, const struct hid_device_id *id) 81 + { 82 + int ret; 83 + 84 + hdev->quirks |= HID_QUIRK_INPUT_PER_APP; 85 + ret = hid_parse(hdev); 86 + if (ret) { 87 + hid_err(hdev, "Chicony hid parse failed: %d\n", ret); 88 + return ret; 89 + } 90 + 91 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 92 + if (ret) { 93 + hid_err(hdev, "Chicony hw start failed: %d\n", ret); 94 + return ret; 95 + } 96 + 97 + return 0; 98 + } 113 99 114 100 static const struct hid_device_id ch_devices[] = { 115 101 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 116 102 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, 103 + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS3) }, 117 104 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, 118 105 { } 119 106 }; ··· 144 91 .id_table = ch_devices, 145 92 .report_fixup = ch_switch12_report_fixup, 146 93 .input_mapping = ch_input_mapping, 94 + .probe = ch_probe, 95 + .raw_event = ch_raw_event, 147 96 }; 148 97 module_hid_driver(ch_driver); 149 98
+1
drivers/hid/hid-ids.h
··· 270 270 #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE 0x1053 271 271 #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2 0x0939 272 272 #define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 273 + #define USB_DEVICE_ID_CHICONY_WIRELESS3 0x1236 273 274 #define USB_DEVICE_ID_ASUS_AK1D 0x1125 274 275 #define USB_DEVICE_ID_CHICONY_TOSHIBA_WT10A 0x1408 275 276 #define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421