LCOV - code coverage report
Current view: top level - drivers/hid - hid-ite.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 38 2.6 %
Date: 2023-04-06 08:38:28 Functions: 1 6 16.7 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  * HID driver for some ITE "special" devices
       4             :  * Copyright (c) 2017 Hans de Goede <hdegoede@redhat.com>
       5             :  */
       6             : 
       7             : #include <linux/device.h>
       8             : #include <linux/input.h>
       9             : #include <linux/hid.h>
      10             : #include <linux/module.h>
      11             : 
      12             : #include "hid-ids.h"
      13             : 
      14             : #define QUIRK_TOUCHPAD_ON_OFF_REPORT            BIT(0)
      15             : 
      16           0 : static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize)
      17             : {
      18           0 :         unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
      19             : 
      20           0 :         if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) {
      21             :                 /* For Acer Aspire Switch 10 SW5-012 keyboard-dock */
      22           0 :                 if (*rsize == 188 && rdesc[162] == 0x81 && rdesc[163] == 0x02) {
      23           0 :                         hid_info(hdev, "Fixing up Acer Sw5-012 ITE keyboard report descriptor\n");
      24           0 :                         rdesc[163] = HID_MAIN_ITEM_RELATIVE;
      25             :                 }
      26             :                 /* For Acer One S1002/S1003 keyboard-dock */
      27           0 :                 if (*rsize == 188 && rdesc[185] == 0x81 && rdesc[186] == 0x02) {
      28           0 :                         hid_info(hdev, "Fixing up Acer S1002/S1003 ITE keyboard report descriptor\n");
      29           0 :                         rdesc[186] = HID_MAIN_ITEM_RELATIVE;
      30             :                 }
      31             :                 /* For Acer Aspire Switch 10E (SW3-016) keyboard-dock */
      32           0 :                 if (*rsize == 210 && rdesc[184] == 0x81 && rdesc[185] == 0x02) {
      33           0 :                         hid_info(hdev, "Fixing up Acer Aspire Switch 10E (SW3-016) ITE keyboard report descriptor\n");
      34           0 :                         rdesc[185] = HID_MAIN_ITEM_RELATIVE;
      35             :                 }
      36             :         }
      37             : 
      38           0 :         return rdesc;
      39             : }
      40             : 
      41           0 : static int ite_input_mapping(struct hid_device *hdev,
      42             :                 struct hid_input *hi, struct hid_field *field,
      43             :                 struct hid_usage *usage, unsigned long **bit,
      44             :                 int *max)
      45             : {
      46             : 
      47           0 :         unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
      48             : 
      49           0 :         if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) &&
      50           0 :             (usage->hid & HID_USAGE_PAGE) == 0x00880000) {
      51           0 :                 if (usage->hid == 0x00880078) {
      52             :                         /* Touchpad on, userspace expects F22 for this */
      53           0 :                         hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F22);
      54           0 :                         return 1;
      55             :                 }
      56           0 :                 if (usage->hid == 0x00880079) {
      57             :                         /* Touchpad off, userspace expects F23 for this */
      58           0 :                         hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F23);
      59           0 :                         return 1;
      60             :                 }
      61             :                 return -1;
      62             :         }
      63             : 
      64             :         return 0;
      65             : }
      66             : 
      67           0 : static int ite_event(struct hid_device *hdev, struct hid_field *field,
      68             :                      struct hid_usage *usage, __s32 value)
      69             : {
      70             :         struct input_dev *input;
      71             : 
      72           0 :         if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput)
      73             :                 return 0;
      74             : 
      75           0 :         input = field->hidinput->input;
      76             : 
      77             :         /*
      78             :          * The ITE8595 always reports 0 as value for the rfkill button. Luckily
      79             :          * it is the only button in its report, and it sends a report on
      80             :          * release only, so receiving a report means the button was pressed.
      81             :          */
      82           0 :         if (usage->hid == HID_GD_RFKILL_BTN) {
      83           0 :                 input_event(input, EV_KEY, KEY_RFKILL, 1);
      84           0 :                 input_sync(input);
      85           0 :                 input_event(input, EV_KEY, KEY_RFKILL, 0);
      86           0 :                 input_sync(input);
      87           0 :                 return 1;
      88             :         }
      89             : 
      90             :         return 0;
      91             : }
      92             : 
      93           0 : static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id)
      94             : {
      95             :         int ret;
      96             : 
      97           0 :         hid_set_drvdata(hdev, (void *)id->driver_data);
      98             : 
      99           0 :         ret = hid_open_report(hdev);
     100           0 :         if (ret)
     101             :                 return ret;
     102             : 
     103           0 :         return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
     104             : }
     105             : 
     106             : static const struct hid_device_id ite_devices[] = {
     107             :         { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) },
     108             :         { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) },
     109             :         /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */
     110             :         { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
     111             :                      USB_VENDOR_ID_SYNAPTICS,
     112             :                      USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012),
     113             :           .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
     114             :         /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
     115             :         { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
     116             :                      USB_VENDOR_ID_SYNAPTICS,
     117             :                      USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002),
     118             :           .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
     119             :         /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
     120             :         { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
     121             :                      USB_VENDOR_ID_SYNAPTICS,
     122             :                      USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003),
     123             :           .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
     124             :         /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
     125             :         { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
     126             :                      USB_VENDOR_ID_SYNAPTICS,
     127             :                      USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017),
     128             :           .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
     129             :         { }
     130             : };
     131             : MODULE_DEVICE_TABLE(hid, ite_devices);
     132             : 
     133             : static struct hid_driver ite_driver = {
     134             :         .name = "itetech",
     135             :         .id_table = ite_devices,
     136             :         .probe = ite_probe,
     137             :         .report_fixup = ite_report_fixup,
     138             :         .input_mapping = ite_input_mapping,
     139             :         .event = ite_event,
     140             : };
     141           1 : module_hid_driver(ite_driver);
     142             : 
     143             : MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
     144             : MODULE_LICENSE("GPL");

Generated by: LCOV version 1.14