1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2f1918be1SHans de Goede /* 3f1918be1SHans de Goede * HID driver for some ITE "special" devices 4f1918be1SHans de Goede * Copyright (c) 2017 Hans de Goede <hdegoede@redhat.com> 5f1918be1SHans de Goede */ 6f1918be1SHans de Goede 7f1918be1SHans de Goede #include <linux/device.h> 8f1918be1SHans de Goede #include <linux/input.h> 9f1918be1SHans de Goede #include <linux/hid.h> 10f1918be1SHans de Goede #include <linux/module.h> 11f1918be1SHans de Goede 12f1918be1SHans de Goede #include "hid-ids.h" 13f1918be1SHans de Goede 143c785a06SHans de Goede #define QUIRK_TOUCHPAD_ON_OFF_REPORT BIT(0) 153c785a06SHans de Goede 163c785a06SHans de Goede static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) 173c785a06SHans de Goede { 183c785a06SHans de Goede unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 193c785a06SHans de Goede 203c785a06SHans de Goede if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) { 21*c961facbSHans de Goede /* For Acer Aspire Switch 10 SW5-012 keyboard-dock */ 223c785a06SHans de Goede if (*rsize == 188 && rdesc[162] == 0x81 && rdesc[163] == 0x02) { 23*c961facbSHans de Goede hid_info(hdev, "Fixing up Acer Sw5-012 ITE keyboard report descriptor\n"); 243c785a06SHans de Goede rdesc[163] = HID_MAIN_ITEM_RELATIVE; 253c785a06SHans de Goede } 26*c961facbSHans de Goede /* For Acer One S1002 keyboard-dock */ 27*c961facbSHans de Goede if (*rsize == 188 && rdesc[185] == 0x81 && rdesc[186] == 0x02) { 28*c961facbSHans de Goede hid_info(hdev, "Fixing up Acer S1002 ITE keyboard report descriptor\n"); 29*c961facbSHans de Goede rdesc[186] = HID_MAIN_ITEM_RELATIVE; 30*c961facbSHans de Goede } 313c785a06SHans de Goede } 323c785a06SHans de Goede 333c785a06SHans de Goede return rdesc; 343c785a06SHans de Goede } 353c785a06SHans de Goede 363c785a06SHans de Goede static int ite_input_mapping(struct hid_device *hdev, 373c785a06SHans de Goede struct hid_input *hi, struct hid_field *field, 383c785a06SHans de Goede struct hid_usage *usage, unsigned long **bit, 393c785a06SHans de Goede int *max) 403c785a06SHans de Goede { 413c785a06SHans de Goede 423c785a06SHans de Goede unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 433c785a06SHans de Goede 443c785a06SHans de Goede if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) && 453c785a06SHans de Goede (usage->hid & HID_USAGE_PAGE) == 0x00880000) { 463c785a06SHans de Goede if (usage->hid == 0x00880078) { 473c785a06SHans de Goede /* Touchpad on, userspace expects F22 for this */ 483c785a06SHans de Goede hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F22); 493c785a06SHans de Goede return 1; 503c785a06SHans de Goede } 513c785a06SHans de Goede if (usage->hid == 0x00880079) { 523c785a06SHans de Goede /* Touchpad off, userspace expects F23 for this */ 533c785a06SHans de Goede hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F23); 543c785a06SHans de Goede return 1; 553c785a06SHans de Goede } 563c785a06SHans de Goede return -1; 573c785a06SHans de Goede } 583c785a06SHans de Goede 593c785a06SHans de Goede return 0; 603c785a06SHans de Goede } 613c785a06SHans de Goede 62f1918be1SHans de Goede static int ite_event(struct hid_device *hdev, struct hid_field *field, 63f1918be1SHans de Goede struct hid_usage *usage, __s32 value) 64f1918be1SHans de Goede { 65f1918be1SHans de Goede struct input_dev *input; 66f1918be1SHans de Goede 67f1918be1SHans de Goede if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput) 68f1918be1SHans de Goede return 0; 69f1918be1SHans de Goede 70f1918be1SHans de Goede input = field->hidinput->input; 71f1918be1SHans de Goede 72f1918be1SHans de Goede /* 73f1918be1SHans de Goede * The ITE8595 always reports 0 as value for the rfkill button. Luckily 74f1918be1SHans de Goede * it is the only button in its report, and it sends a report on 75f1918be1SHans de Goede * release only, so receiving a report means the button was pressed. 76f1918be1SHans de Goede */ 77f1918be1SHans de Goede if (usage->hid == HID_GD_RFKILL_BTN) { 78f1918be1SHans de Goede input_event(input, EV_KEY, KEY_RFKILL, 1); 79f1918be1SHans de Goede input_sync(input); 80f1918be1SHans de Goede input_event(input, EV_KEY, KEY_RFKILL, 0); 81f1918be1SHans de Goede input_sync(input); 82f1918be1SHans de Goede return 1; 83f1918be1SHans de Goede } 84f1918be1SHans de Goede 85f1918be1SHans de Goede return 0; 86f1918be1SHans de Goede } 87f1918be1SHans de Goede 883c785a06SHans de Goede static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id) 893c785a06SHans de Goede { 903c785a06SHans de Goede int ret; 913c785a06SHans de Goede 923c785a06SHans de Goede hid_set_drvdata(hdev, (void *)id->driver_data); 933c785a06SHans de Goede 943c785a06SHans de Goede ret = hid_open_report(hdev); 953c785a06SHans de Goede if (ret) 963c785a06SHans de Goede return ret; 973c785a06SHans de Goede 983c785a06SHans de Goede return hid_hw_start(hdev, HID_CONNECT_DEFAULT); 993c785a06SHans de Goede } 1003c785a06SHans de Goede 101f1918be1SHans de Goede static const struct hid_device_id ite_devices[] = { 102f1918be1SHans de Goede { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, 10340502074SHans de Goede { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, 1048f18eca9SHans de Goede /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ 105beae5619SHans de Goede { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 106beae5619SHans de Goede USB_VENDOR_ID_SYNAPTICS, 1073c785a06SHans de Goede USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012), 1083c785a06SHans de Goede .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, 1095bf2f2f3SHans de Goede /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ 1105bf2f2f3SHans de Goede { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 1115bf2f2f3SHans de Goede USB_VENDOR_ID_SYNAPTICS, 112*c961facbSHans de Goede USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002), 113*c961facbSHans de Goede .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, 114*c961facbSHans de Goede /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ 115*c961facbSHans de Goede { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, 116*c961facbSHans de Goede USB_VENDOR_ID_SYNAPTICS, 1175bf2f2f3SHans de Goede USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003) }, 118f1918be1SHans de Goede { } 119f1918be1SHans de Goede }; 120f1918be1SHans de Goede MODULE_DEVICE_TABLE(hid, ite_devices); 121f1918be1SHans de Goede 122f1918be1SHans de Goede static struct hid_driver ite_driver = { 123f1918be1SHans de Goede .name = "itetech", 124f1918be1SHans de Goede .id_table = ite_devices, 1253c785a06SHans de Goede .probe = ite_probe, 1263c785a06SHans de Goede .report_fixup = ite_report_fixup, 1273c785a06SHans de Goede .input_mapping = ite_input_mapping, 128f1918be1SHans de Goede .event = ite_event, 129f1918be1SHans de Goede }; 130f1918be1SHans de Goede module_hid_driver(ite_driver); 131f1918be1SHans de Goede 132f1918be1SHans de Goede MODULE_LICENSE("GPL"); 133