Merge branch 'for-5.17/hidraw' into for-linus
authorJiri Kosina <jkosina@suse.cz>
Mon, 10 Jan 2022 08:55:44 +0000 (09:55 +0100)
committerJiri Kosina <jkosina@suse.cz>
Mon, 10 Jan 2022 08:55:44 +0000 (09:55 +0100)
- locking performance improvement for hidraw code (AndrĂ© Almeida)

22 files changed:
Documentation/devicetree/bindings/input/hid-over-i2c.txt
drivers/hid/hid-apple.c
drivers/hid/hid-core.c
drivers/hid/hid-debug.c
drivers/hid/hid-holtek-mouse.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-quirks.c
drivers/hid/hid-uclogic-params.c
drivers/hid/hid-vivaldi.c
drivers/hid/i2c-hid/i2c-hid-acpi.c
drivers/hid/i2c-hid/i2c-hid-core.c
drivers/hid/i2c-hid/i2c-hid-of-goodix.c
drivers/hid/i2c-hid/i2c-hid-of.c
drivers/hid/i2c-hid/i2c-hid.h
drivers/hid/intel-ish-hid/ipc/ipc.c
drivers/hid/intel-ish-hid/ishtp-fw-loader.c
drivers/hid/surface-hid/surface_hid_core.c
drivers/hid/usbhid/hid-core.c
include/linux/hid.h

index c76bafa..34c43d3 100644 (file)
@@ -32,6 +32,8 @@ device-specific compatible properties, which should be used in addition to the
 - vdd-supply: phandle of the regulator that provides the supply voltage.
 - post-power-on-delay-ms: time required by the device after enabling its regulators
   or powering it on, before it is ready for communication.
+- touchscreen-inverted-x: See touchscreen.txt
+- touchscreen-inverted-y: See touchscreen.txt
 
 Example:
 
index 2c9c5fa..24802a4 100644 (file)
 
 #include <linux/device.h>
 #include <linux/hid.h>
+#include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/timer.h>
 
 #include "hid-ids.h"
 
-#define APPLE_RDESC_JIS                0x0001
-#define APPLE_IGNORE_MOUSE     0x0002
-#define APPLE_HAS_FN           0x0004
-/* 0x0008 reserved, was: APPLE_HIDDEV */
-#define APPLE_ISO_TILDE_QUIRK  0x0010
-#define APPLE_MIGHTYMOUSE      0x0020
-#define APPLE_INVERT_HWHEEL    0x0040
-/* 0x0080 reserved, was: APPLE_IGNORE_HIDINPUT */
-#define APPLE_NUMLOCK_EMULATION        0x0100
+#define APPLE_RDESC_JIS                BIT(0)
+#define APPLE_IGNORE_MOUSE     BIT(1)
+#define APPLE_HAS_FN           BIT(2)
+/* BIT(3) reserved, was: APPLE_HIDDEV */
+#define APPLE_ISO_TILDE_QUIRK  BIT(4)
+#define APPLE_MIGHTYMOUSE      BIT(5)
+#define APPLE_INVERT_HWHEEL    BIT(6)
+/* BIT(7) reserved, was: APPLE_IGNORE_HIDINPUT */
+#define APPLE_NUMLOCK_EMULATION        BIT(8)
+#define APPLE_RDESC_BATTERY    BIT(9)
 
 #define APPLE_FLAG_FKEY                0x01
 
 #define HID_COUNTRY_INTERNATIONAL_ISO  13
+#define APPLE_BATTERY_TIMEOUT_MS       60000
 
 static unsigned int fnmode = 1;
 module_param(fnmode, uint, 0644);
@@ -58,10 +62,12 @@ MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
                "[0] = as-is, Mac layout, 1 = swapped, PC layout)");
 
 struct apple_sc {
+       struct hid_device *hdev;
        unsigned long quirks;
        unsigned int fn_on;
        unsigned int fn_found;
        DECLARE_BITMAP(pressed_numlock, KEY_CNT);
+       struct timer_list battery_timer;
 };
 
 struct apple_key_translation {
@@ -70,6 +76,28 @@ struct apple_key_translation {
        u8 flags;
 };
 
+static const struct apple_key_translation apple2021_fn_keys[] = {
+       { KEY_BACKSPACE, KEY_DELETE },
+       { KEY_ENTER,    KEY_INSERT },
+       { KEY_F1,       KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
+       { KEY_F2,       KEY_BRIGHTNESSUP,   APPLE_FLAG_FKEY },
+       { KEY_F3,       KEY_SCALE,          APPLE_FLAG_FKEY },
+       { KEY_F4,       KEY_SEARCH,         APPLE_FLAG_FKEY },
+       { KEY_F5,       KEY_MICMUTE,        APPLE_FLAG_FKEY },
+       { KEY_F6,       KEY_SLEEP,          APPLE_FLAG_FKEY },
+       { KEY_F7,       KEY_PREVIOUSSONG,   APPLE_FLAG_FKEY },
+       { KEY_F8,       KEY_PLAYPAUSE,      APPLE_FLAG_FKEY },
+       { KEY_F9,       KEY_NEXTSONG,       APPLE_FLAG_FKEY },
+       { KEY_F10,      KEY_MUTE,           APPLE_FLAG_FKEY },
+       { KEY_F11,      KEY_VOLUMEDOWN,     APPLE_FLAG_FKEY },
+       { KEY_F12,      KEY_VOLUMEUP,       APPLE_FLAG_FKEY },
+       { KEY_UP,       KEY_PAGEUP },
+       { KEY_DOWN,     KEY_PAGEDOWN },
+       { KEY_LEFT,     KEY_HOME },
+       { KEY_RIGHT,    KEY_END },
+       { }
+};
+
 static const struct apple_key_translation macbookair_fn_keys[] = {
        { KEY_BACKSPACE, KEY_DELETE },
        { KEY_ENTER,    KEY_INSERT },
@@ -214,7 +242,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
        }
 
        if (fnmode) {
-               if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
+               if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 ||
+                   hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 ||
+                   hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021)
+                       table = apple2021_fn_keys;
+               else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
                                hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
                        table = macbookair_fn_keys;
                else if (hid->product < 0x21d || hid->product >= 0x300)
@@ -333,6 +365,43 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
        return 0;
 }
 
+static int apple_fetch_battery(struct hid_device *hdev)
+{
+#ifdef CONFIG_HID_BATTERY_STRENGTH
+       struct apple_sc *asc = hid_get_drvdata(hdev);
+       struct hid_report_enum *report_enum;
+       struct hid_report *report;
+
+       if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery)
+               return -1;
+
+       report_enum = &hdev->report_enum[hdev->battery_report_type];
+       report = report_enum->report_id_hash[hdev->battery_report_id];
+
+       if (!report || report->maxfield < 1)
+               return -1;
+
+       if (hdev->battery_capacity == hdev->battery_max)
+               return -1;
+
+       hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
+       return 0;
+#else
+       return -1;
+#endif
+}
+
+static void apple_battery_timer_tick(struct timer_list *t)
+{
+       struct apple_sc *asc = from_timer(asc, t, battery_timer);
+       struct hid_device *hdev = asc->hdev;
+
+       if (apple_fetch_battery(hdev) == 0) {
+               mod_timer(&asc->battery_timer,
+                         jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
+       }
+}
+
 /*
  * MacBook JIS keyboard has wrong logical maximum
  * Magic Keyboard JIS has wrong logical maximum
@@ -354,6 +423,30 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                         "fixing up MacBook JIS keyboard report descriptor\n");
                rdesc[53] = rdesc[59] = 0xe7;
        }
+
+       /*
+        * Change the usage from:
+        *   0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1)  0
+        *   0x09, 0x0b,       // Usage (Vendor Usage 0x0b)           3
+        * To:
+        *   0x05, 0x01,       // Usage Page (Generic Desktop)        0
+        *   0x09, 0x06,       // Usage (Keyboard)                    2
+        */
+       if ((asc->quirks & APPLE_RDESC_BATTERY) && *rsize == 83 &&
+           rdesc[46] == 0x84 && rdesc[58] == 0x85) {
+               hid_info(hdev,
+                        "fixing up Magic Keyboard battery report descriptor\n");
+               *rsize = *rsize - 1;
+               rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL);
+               if (!rdesc)
+                       return NULL;
+
+               rdesc[0] = 0x05;
+               rdesc[1] = 0x01;
+               rdesc[2] = 0x09;
+               rdesc[3] = 0x06;
+       }
+
        return rdesc;
 }
 
@@ -376,6 +469,9 @@ static void apple_setup_input(struct input_dev *input)
        for (trans = apple_iso_keyboard; trans->from; trans++)
                set_bit(trans->to, input->keybit);
 
+       for (trans = apple2021_fn_keys; trans->from; trans++)
+               set_bit(trans->to, input->keybit);
+
        if (swap_fn_leftctrl) {
                for (trans = swapped_fn_leftctrl_keys; trans->from; trans++)
                        set_bit(trans->to, input->keybit);
@@ -428,7 +524,7 @@ static int apple_input_configured(struct hid_device *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;
+               asc->quirks &= ~APPLE_HAS_FN;
        }
 
        return 0;
@@ -447,6 +543,7 @@ static int apple_probe(struct hid_device *hdev,
                return -ENOMEM;
        }
 
+       asc->hdev = hdev;
        asc->quirks = quirks;
 
        hid_set_drvdata(hdev, asc);
@@ -463,9 +560,23 @@ static int apple_probe(struct hid_device *hdev,
                return ret;
        }
 
+       timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0);
+       mod_timer(&asc->battery_timer,
+                 jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS));
+       apple_fetch_battery(hdev);
+
        return 0;
 }
 
+static void apple_remove(struct hid_device *hdev)
+{
+       struct apple_sc *asc = hid_get_drvdata(hdev);
+
+       del_timer_sync(&asc->battery_timer);
+
+       hid_hw_stop(hdev);
+}
+
 static const struct hid_device_id apple_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
                .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
@@ -540,11 +651,11 @@ static const struct hid_device_id apple_devices[] = {
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
-               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
        { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2015),
                .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
-               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_RDESC_BATTERY },
        { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2015),
                .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
@@ -640,6 +751,14 @@ static const struct hid_device_id apple_devices[] = {
                .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
        { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
                .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+       { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
 
        { }
 };
@@ -650,6 +769,7 @@ static struct hid_driver apple_driver = {
        .id_table = apple_devices,
        .report_fixup = apple_report_fixup,
        .probe = apple_probe,
+       .remove = apple_remove,
        .event = apple_event,
        .input_mapping = apple_input_mapping,
        .input_mapped = apple_input_mapped,
index dbed252..f1aed5b 100644 (file)
@@ -2126,6 +2126,99 @@ void hid_hw_close(struct hid_device *hdev)
 }
 EXPORT_SYMBOL_GPL(hid_hw_close);
 
+/**
+ * hid_hw_request - send report request to device
+ *
+ * @hdev: hid device
+ * @report: report to send
+ * @reqtype: hid request type
+ */
+void hid_hw_request(struct hid_device *hdev,
+                   struct hid_report *report, int reqtype)
+{
+       if (hdev->ll_driver->request)
+               return hdev->ll_driver->request(hdev, report, reqtype);
+
+       __hid_request(hdev, report, reqtype);
+}
+EXPORT_SYMBOL_GPL(hid_hw_request);
+
+/**
+ * hid_hw_raw_request - send report request to device
+ *
+ * @hdev: hid device
+ * @reportnum: report ID
+ * @buf: in/out data to transfer
+ * @len: length of buf
+ * @rtype: HID report type
+ * @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT
+ *
+ * Return: count of data transferred, negative if error
+ *
+ * Same behavior as hid_hw_request, but with raw buffers instead.
+ */
+int hid_hw_raw_request(struct hid_device *hdev,
+                      unsigned char reportnum, __u8 *buf,
+                      size_t len, unsigned char rtype, int reqtype)
+{
+       if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
+               return -EINVAL;
+
+       return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
+                                           rtype, reqtype);
+}
+EXPORT_SYMBOL_GPL(hid_hw_raw_request);
+
+/**
+ * hid_hw_output_report - send output report to device
+ *
+ * @hdev: hid device
+ * @buf: raw data to transfer
+ * @len: length of buf
+ *
+ * Return: count of data transferred, negative if error
+ */
+int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len)
+{
+       if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
+               return -EINVAL;
+
+       if (hdev->ll_driver->output_report)
+               return hdev->ll_driver->output_report(hdev, buf, len);
+
+       return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(hid_hw_output_report);
+
+#ifdef CONFIG_PM
+int hid_driver_suspend(struct hid_device *hdev, pm_message_t state)
+{
+       if (hdev->driver && hdev->driver->suspend)
+               return hdev->driver->suspend(hdev, state);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(hid_driver_suspend);
+
+int hid_driver_reset_resume(struct hid_device *hdev)
+{
+       if (hdev->driver && hdev->driver->reset_resume)
+               return hdev->driver->reset_resume(hdev);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(hid_driver_reset_resume);
+
+int hid_driver_resume(struct hid_device *hdev)
+{
+       if (hdev->driver && hdev->driver->resume)
+               return hdev->driver->resume(hdev);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(hid_driver_resume);
+#endif /* CONFIG_PM */
+
 struct hid_dynid {
        struct list_head list;
        struct hid_device_id id;
index 7a92e2a..26c31d7 100644 (file)
@@ -141,8 +141,10 @@ static const struct hid_usage_entry hid_usage_table[] = {
     {0, 0x33, "Touch"},
     {0, 0x34, "UnTouch"},
     {0, 0x35, "Tap"},
+    {0, 0x38, "Transducer Index"},
     {0, 0x39, "TabletFunctionKey"},
     {0, 0x3a, "ProgramChangeKey"},
+    {0, 0x3B, "Battery Strength"},
     {0, 0x3c, "Invert"},
     {0, 0x42, "TipSwitch"},
     {0, 0x43, "SecondaryTipSwitch"},
@@ -160,7 +162,40 @@ static const struct hid_usage_entry hid_usage_table[] = {
     {0, 0x59, "ButtonType"},
     {0, 0x5A, "SecondaryBarrelSwitch"},
     {0, 0x5B, "TransducerSerialNumber"},
+    {0, 0x5C, "Preferred Color"},
+    {0, 0x5D, "Preferred Color is Locked"},
+    {0, 0x5E, "Preferred Line Width"},
+    {0, 0x5F, "Preferred Line Width is Locked"},
     {0, 0x6e, "TransducerSerialNumber2"},
+    {0, 0x70, "Preferred Line Style"},
+      {0, 0x71, "Preferred Line Style is Locked"},
+      {0, 0x72, "Ink"},
+      {0, 0x73, "Pencil"},
+      {0, 0x74, "Highlighter"},
+      {0, 0x75, "Chisel Marker"},
+      {0, 0x76, "Brush"},
+      {0, 0x77, "No Preference"},
+    {0, 0x80, "Digitizer Diagnostic"},
+    {0, 0x81, "Digitizer Error"},
+      {0, 0x82, "Err Normal Status"},
+      {0, 0x83, "Err Transducers Exceeded"},
+      {0, 0x84, "Err Full Trans Features Unavailable"},
+      {0, 0x85, "Err Charge Low"},
+    {0, 0x90, "Transducer Software Info"},
+      {0, 0x91, "Transducer Vendor Id"},
+      {0, 0x92, "Transducer Product Id"},
+    {0, 0x93, "Device Supported Protocols"},
+    {0, 0x94, "Transducer Supported Protocols"},
+      {0, 0x95, "No Protocol"},
+      {0, 0x96, "Wacom AES Protocol"},
+      {0, 0x97, "USI Protocol"},
+      {0, 0x98, "Microsoft Pen Protocol"},
+    {0, 0xA0, "Supported Report Rates"},
+      {0, 0xA1, "Report Rate"},
+      {0, 0xA2, "Transducer Connected"},
+      {0, 0xA3, "Switch Disabled"},
+      {0, 0xA4, "Switch Unimplemented"},
+      {0, 0xA5, "Transducer Switches"},
   { 15, 0, "PhysicalInterfaceDevice" },
     {0, 0x00, "Undefined"},
     {0, 0x01, "Physical_Interface_Device"},
index b7172c4..7c90793 100644 (file)
@@ -65,8 +65,23 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 static int holtek_mouse_probe(struct hid_device *hdev,
                              const struct hid_device_id *id)
 {
+       int ret;
+
        if (!hid_is_usb(hdev))
                return -EINVAL;
+
+       ret = hid_parse(hdev);
+       if (ret) {
+               hid_err(hdev, "hid parse failed: %d\n", ret);
+               return ret;
+       }
+
+       ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+       if (ret) {
+               hid_err(hdev, "hw start failed: %d\n", ret);
+               return ret;
+       }
+
        return 0;
 }
 
index 19da077..df7bbdf 100644 (file)
 #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
 #define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021   0x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021   0x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021   0x029f
 
 #define USB_VENDOR_ID_ASUS             0x0486
 #define USB_DEVICE_ID_ASUS_T91MT       0x0185
index 03f9945..1ce75e8 100644 (file)
@@ -52,6 +52,7 @@ static const struct {
 #define map_rel(c)     hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))
 #define map_key(c)     hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))
 #define map_led(c)     hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))
+#define map_msc(c)     hid_map_usage(hidinput, usage, &bit, &max, EV_MSC, (c))
 
 #define map_abs_clear(c)       hid_map_usage_clear(hidinput, usage, &bit, \
                &max, EV_ABS, (c))
@@ -876,10 +877,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
                case 0x5b: /* TransducerSerialNumber */
                case 0x6e: /* TransducerSerialNumber2 */
-                       usage->type = EV_MSC;
-                       usage->code = MSC_SERIAL;
-                       bit = input->mscbit;
-                       max = MSC_MAX;
+                       map_msc(MSC_SERIAL);
                        break;
 
                default:  goto unknown;
@@ -1333,6 +1331,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 
        input = field->hidinput->input;
 
+       if (usage->type == EV_ABS &&
+           (((*quirks & HID_QUIRK_X_INVERT) && usage->code == ABS_X) ||
+            ((*quirks & HID_QUIRK_Y_INVERT) && usage->code == ABS_Y))) {
+               value = field->logical_maximum - value;
+       }
+
        if (usage->hat_min < usage->hat_max || usage->hat_dir) {
                int hat_dir = usage->hat_dir;
                if (!hat_dir)
@@ -1465,7 +1469,8 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
 }
 EXPORT_SYMBOL_GPL(hidinput_report_event);
 
-int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
+static int hidinput_find_field(struct hid_device *hid, unsigned int type,
+                              unsigned int code, struct hid_field **field)
 {
        struct hid_report *report;
        int i, j;
@@ -1480,7 +1485,6 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
        }
        return -1;
 }
-EXPORT_SYMBOL_GPL(hidinput_find_field);
 
 struct hid_field *hidinput_get_led_field(struct hid_device *hid)
 {
@@ -1743,6 +1747,16 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
                case HID_GD_MOUSE:
                        suffix = "Mouse";
                        break;
+               case HID_DG_PEN:
+                       /*
+                        * yes, there is an issue here:
+                        *  DG_PEN -> "Stylus"
+                        *  DG_STYLUS -> "Pen"
+                        * But changing this now means users with config snippets
+                        * will have to change it and the test suite will not be happy.
+                        */
+                       suffix = "Stylus";
+                       break;
                case HID_DG_STYLUS:
                        suffix = "Pen";
                        break;
index d7687ce..2ccded3 100644 (file)
@@ -51,6 +51,8 @@ static bool report_undeciphered;
 module_param(report_undeciphered, bool, 0644);
 MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
 
+#define TRACKPAD2_2021_BT_VERSION 0x110
+
 #define TRACKPAD_REPORT_ID 0x28
 #define TRACKPAD2_USB_REPORT_ID 0x02
 #define TRACKPAD2_BT_REPORT_ID 0x31
@@ -538,10 +540,22 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
                        __set_bit(REL_HWHEEL_HI_RES, input->relbit);
                }
        } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
-               /* setting the device name to ensure the same driver settings
-                * get loaded, whether connected through bluetooth or USB
+               /* If the trackpad has been connected to a Mac, the name is
+                * automatically personalized, e.g., "JosĂ© ExpĂ³sito's Trackpad".
+                * When connected through Bluetooth, the personalized name is
+                * reported, however, when connected through USB the generic
+                * name is reported.
+                * Set the device name to ensure the same driver settings get
+                * loaded, whether connected through bluetooth or USB.
                 */
-               input->name = "Apple Inc. Magic Trackpad 2";
+               if (hdev->vendor == BT_VENDOR_ID_APPLE) {
+                       if (input->id.version == TRACKPAD2_2021_BT_VERSION)
+                               input->name = "Apple Inc. Magic Trackpad";
+                       else
+                               input->name = "Apple Inc. Magic Trackpad 2";
+               } else { /* USB_VENDOR_ID_APPLE */
+                       input->name = hdev->name;
+               }
 
                __clear_bit(EV_MSC, input->evbit);
                __clear_bit(BTN_0, input->keybit);
index 082376a..99eabfb 100644 (file)
@@ -1606,9 +1606,6 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
        case HID_DG_STYLUS:
                /* force BTN_STYLUS to allow tablet matching in udev */
                __set_bit(BTN_STYLUS, hi->input->keybit);
-               fallthrough;
-       case HID_DG_PEN:
-               suffix = "Stylus";
                break;
        default:
                suffix = "UNKNOWN";
index ee7e504..9af1dc8 100644 (file)
@@ -304,6 +304,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021) },
 #endif
 #if IS_ENABLED(CONFIG_HID_APPLEIR)
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
index adff1bd..3e70f96 100644 (file)
@@ -66,7 +66,7 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
                                        __u8 idx, size_t len)
 {
        int rc;
-       struct usb_device *udev = hid_to_usb_dev(hdev);
+       struct usb_device *udev;
        __u8 *buf = NULL;
 
        /* Check arguments */
@@ -75,6 +75,8 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
                goto cleanup;
        }
 
+       udev = hid_to_usb_dev(hdev);
+
        buf = kmalloc(len, GFP_KERNEL);
        if (buf == NULL) {
                rc = -ENOMEM;
@@ -450,7 +452,7 @@ static int uclogic_params_frame_init_v1_buttonpad(
 {
        int rc;
        bool found = false;
-       struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+       struct usb_device *usb_dev;
        char *str_buf = NULL;
        const size_t str_len = 16;
 
@@ -460,6 +462,8 @@ static int uclogic_params_frame_init_v1_buttonpad(
                goto cleanup;
        }
 
+       usb_dev = hid_to_usb_dev(hdev);
+
        /*
         * Enable generic button mode
         */
@@ -707,9 +711,9 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
                                     struct hid_device *hdev)
 {
        int rc;
-       struct usb_device *udev = hid_to_usb_dev(hdev);
-       struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
-       __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
+       struct usb_device *udev;
+       struct usb_interface *iface;
+       __u8 bInterfaceNumber;
        bool found;
        /* The resulting parameters (noop) */
        struct uclogic_params p = {0, };
@@ -723,6 +727,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
                goto cleanup;
        }
 
+       udev = hid_to_usb_dev(hdev);
+       iface = to_usb_interface(hdev->dev.parent);
+       bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
+
        /* If it's not a pen interface */
        if (bInterfaceNumber != 0) {
                /* TODO: Consider marking the interface invalid */
@@ -834,10 +842,10 @@ int uclogic_params_init(struct uclogic_params *params,
                        struct hid_device *hdev)
 {
        int rc;
-       struct usb_device *udev = hid_to_usb_dev(hdev);
-       __u8  bNumInterfaces = udev->config->desc.bNumInterfaces;
-       struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
-       __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
+       struct usb_device *udev;
+       __u8  bNumInterfaces;
+       struct usb_interface *iface;
+       __u8 bInterfaceNumber;
        bool found;
        /* The resulting parameters (noop) */
        struct uclogic_params p = {0, };
@@ -848,6 +856,11 @@ int uclogic_params_init(struct uclogic_params *params,
                goto cleanup;
        }
 
+       udev = hid_to_usb_dev(hdev);
+       bNumInterfaces = udev->config->desc.bNumInterfaces;
+       iface = to_usb_interface(hdev->dev.parent);
+       bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
+
        /*
         * Set replacement report descriptor if the original matches the
         * specified size. Otherwise keep interface unchanged.
index cd7ada4..72957a9 100644 (file)
@@ -57,6 +57,9 @@ static int vivaldi_probe(struct hid_device *hdev,
        int ret;
 
        drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+       if (!drvdata)
+               return -ENOMEM;
+
        hid_set_drvdata(hdev, drvdata);
 
        ret = hid_parse(hdev);
index a6f0257..b96ae15 100644 (file)
@@ -111,7 +111,7 @@ static int i2c_hid_acpi_probe(struct i2c_client *client)
        }
 
        return i2c_hid_core_probe(client, &ihid_acpi->ops,
-                                 hid_descriptor_address);
+                                 hid_descriptor_address, 0);
 }
 
 static const struct acpi_device_id i2c_hid_acpi_match[] = {
index 5171411..be00e07 100644 (file)
@@ -912,7 +912,7 @@ static void i2c_hid_core_shutdown_tail(struct i2c_hid *ihid)
 }
 
 int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
-                      u16 hid_descriptor_address)
+                      u16 hid_descriptor_address, u32 quirks)
 {
        int ret;
        struct i2c_hid *ihid;
@@ -1009,6 +1009,8 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
                goto err_mem_free;
        }
 
+       hid->quirks |= quirks;
+
        return 0;
 
 err_mem_free:
@@ -1063,11 +1065,9 @@ static int i2c_hid_core_suspend(struct device *dev)
        int ret;
        int wake_status;
 
-       if (hid->driver && hid->driver->suspend) {
-               ret = hid->driver->suspend(hid, PMSG_SUSPEND);
-               if (ret < 0)
-                       return ret;
-       }
+       ret = hid_driver_suspend(hid, PMSG_SUSPEND);
+       if (ret < 0)
+               return ret;
 
        /* Save some power */
        i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
@@ -1125,12 +1125,7 @@ static int i2c_hid_core_resume(struct device *dev)
        if (ret)
                return ret;
 
-       if (hid->driver && hid->driver->reset_resume) {
-               ret = hid->driver->reset_resume(hid);
-               return ret;
-       }
-
-       return 0;
+       return hid_driver_reset_resume(hid);
 }
 #endif
 
index 5267414..b4dad66 100644 (file)
@@ -150,7 +150,7 @@ static int i2c_hid_of_goodix_probe(struct i2c_client *client,
                goodix_i2c_hid_deassert_reset(ihid_goodix, true);
        mutex_unlock(&ihid_goodix->regulator_mutex);
 
-       return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001);
+       return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001, 0);
 }
 
 static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data = {
index 4bf7cea..97a27a8 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/hid.h>
 #include <linux/i2c.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -71,6 +72,7 @@ static int i2c_hid_of_probe(struct i2c_client *client,
        struct device *dev = &client->dev;
        struct i2c_hid_of *ihid_of;
        u16 hid_descriptor_address;
+       u32 quirks = 0;
        int ret;
        u32 val;
 
@@ -105,8 +107,14 @@ static int i2c_hid_of_probe(struct i2c_client *client,
        if (ret)
                return ret;
 
+       if (device_property_read_bool(dev, "touchscreen-inverted-x"))
+               quirks |= HID_QUIRK_X_INVERT;
+
+       if (device_property_read_bool(dev, "touchscreen-inverted-y"))
+               quirks |= HID_QUIRK_Y_INVERT;
+
        return i2c_hid_core_probe(client, &ihid_of->ops,
-                                 hid_descriptor_address);
+                                 hid_descriptor_address, quirks);
 }
 
 static const struct of_device_id i2c_hid_of_match[] = {
index 05a7827..236cc06 100644 (file)
@@ -32,7 +32,7 @@ struct i2chid_ops {
 };
 
 int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
-                      u16 hid_descriptor_address);
+                      u16 hid_descriptor_address, u32 quirks);
 int i2c_hid_core_remove(struct i2c_client *client);
 
 void i2c_hid_core_shutdown(struct i2c_client *client);
index 45e0c7b..8ccb246 100644 (file)
@@ -909,7 +909,11 @@ static uint32_t ish_ipc_get_header(struct ishtp_device *dev, int length,
  */
 static bool _dma_no_cache_snooping(struct ishtp_device *dev)
 {
-       return dev->pdev->device == EHL_Ax_DEVICE_ID;
+       return (dev->pdev->device == EHL_Ax_DEVICE_ID ||
+               dev->pdev->device == TGL_LP_DEVICE_ID ||
+               dev->pdev->device == TGL_H_DEVICE_ID ||
+               dev->pdev->device == ADL_S_DEVICE_ID ||
+               dev->pdev->device == ADL_P_DEVICE_ID);
 }
 
 static const struct ishtp_hw_ops ish_hw_ops = {
index 0e1183e..e249885 100644 (file)
@@ -268,7 +268,8 @@ static int get_firmware_variant(struct ishtp_cl_data *client_data,
 }
 
 /**
- * loader_cl_send()    Send message from host to firmware
+ * loader_cl_send() - Send message from host to firmware
+ *
  * @client_data:       Client data instance
  * @out_msg:           Message buffer to be sent to firmware
  * @out_size:          Size of out going message
index 5571e74..e46330b 100644 (file)
@@ -204,50 +204,35 @@ static int surface_hid_suspend(struct device *dev)
 {
        struct surface_hid_device *d = dev_get_drvdata(dev);
 
-       if (d->hid->driver && d->hid->driver->suspend)
-               return d->hid->driver->suspend(d->hid, PMSG_SUSPEND);
-
-       return 0;
+       return hid_driver_suspend(d->hid, PMSG_SUSPEND);
 }
 
 static int surface_hid_resume(struct device *dev)
 {
        struct surface_hid_device *d = dev_get_drvdata(dev);
 
-       if (d->hid->driver && d->hid->driver->resume)
-               return d->hid->driver->resume(d->hid);
-
-       return 0;
+       return hid_driver_resume(d->hid);
 }
 
 static int surface_hid_freeze(struct device *dev)
 {
        struct surface_hid_device *d = dev_get_drvdata(dev);
 
-       if (d->hid->driver && d->hid->driver->suspend)
-               return d->hid->driver->suspend(d->hid, PMSG_FREEZE);
-
-       return 0;
+       return hid_driver_suspend(d->hid, PMSG_FREEZE);
 }
 
 static int surface_hid_poweroff(struct device *dev)
 {
        struct surface_hid_device *d = dev_get_drvdata(dev);
 
-       if (d->hid->driver && d->hid->driver->suspend)
-               return d->hid->driver->suspend(d->hid, PMSG_HIBERNATE);
-
-       return 0;
+       return hid_driver_suspend(d->hid, PMSG_HIBERNATE);
 }
 
 static int surface_hid_restore(struct device *dev)
 {
        struct surface_hid_device *d = dev_get_drvdata(dev);
 
-       if (d->hid->driver && d->hid->driver->reset_resume)
-               return d->hid->driver->reset_resume(d->hid);
-
-       return 0;
+       return hid_driver_reset_resume(d->hid);
 }
 
 const struct dev_pm_ops surface_hid_pm_ops = {
index 2dcaf31..54752c8 100644 (file)
@@ -1563,8 +1563,8 @@ static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
        int status = 0;
 
        hid_restart_io(hid);
-       if (driver_suspended && hid->driver && hid->driver->resume)
-               status = hid->driver->resume(hid);
+       if (driver_suspended)
+               status = hid_driver_resume(hid);
        return status;
 }
 
@@ -1588,11 +1588,9 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
                {
                        set_bit(HID_SUSPENDED, &usbhid->iofl);
                        spin_unlock_irq(&usbhid->lock);
-                       if (hid->driver && hid->driver->suspend) {
-                               status = hid->driver->suspend(hid, message);
-                               if (status < 0)
-                                       goto failed;
-                       }
+                       status = hid_driver_suspend(hid, message);
+                       if (status < 0)
+                               goto failed;
                        driver_suspended = true;
                } else {
                        usbhid_mark_busy(usbhid);
@@ -1602,8 +1600,7 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
 
        } else {
                /* TODO: resume() might need to handle suspend failure */
-               if (hid->driver && hid->driver->suspend)
-                       status = hid->driver->suspend(hid, message);
+               status = hid_driver_suspend(hid, message);
                driver_suspended = true;
                spin_lock_irq(&usbhid->lock);
                set_bit(HID_SUSPENDED, &usbhid->iofl);
@@ -1644,8 +1641,8 @@ static int hid_reset_resume(struct usb_interface *intf)
        int status;
 
        status = hid_post_reset(intf);
-       if (status >= 0 && hid->driver && hid->driver->reset_resume) {
-               int ret = hid->driver->reset_resume(hid);
+       if (status >= 0) {
+               int ret = hid_driver_reset_resume(hid);
                if (ret < 0)
                        status = ret;
        }
index f453be3..7487b05 100644 (file)
@@ -241,6 +241,7 @@ struct hid_item {
 #define HID_DG_TOUCH           0x000d0033
 #define HID_DG_UNTOUCH         0x000d0034
 #define HID_DG_TAP             0x000d0035
+#define HID_DG_TRANSDUCER_INDEX        0x000d0038
 #define HID_DG_TABLETFUNCTIONKEY       0x000d0039
 #define HID_DG_PROGRAMCHANGEKEY        0x000d003a
 #define HID_DG_BATTERYSTRENGTH 0x000d003b
@@ -253,6 +254,15 @@ struct hid_item {
 #define HID_DG_BARRELSWITCH    0x000d0044
 #define HID_DG_ERASER          0x000d0045
 #define HID_DG_TABLETPICK      0x000d0046
+#define HID_DG_PEN_COLOR                       0x000d005c
+#define HID_DG_PEN_LINE_WIDTH                  0x000d005e
+#define HID_DG_PEN_LINE_STYLE                  0x000d0070
+#define HID_DG_PEN_LINE_STYLE_INK              0x000d0072
+#define HID_DG_PEN_LINE_STYLE_PENCIL           0x000d0073
+#define HID_DG_PEN_LINE_STYLE_HIGHLIGHTER      0x000d0074
+#define HID_DG_PEN_LINE_STYLE_CHISEL_MARKER    0x000d0075
+#define HID_DG_PEN_LINE_STYLE_BRUSH            0x000d0076
+#define HID_DG_PEN_LINE_STYLE_NO_PREFERENCE    0x000d0077
 
 #define HID_CP_CONSUMERCONTROL 0x000c0001
 #define HID_CP_NUMERICKEYPAD   0x000c0002
@@ -349,6 +359,8 @@ struct hid_item {
 /* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
 #define HID_QUIRK_ALWAYS_POLL                  BIT(10)
 #define HID_QUIRK_INPUT_PER_APP                        BIT(11)
+#define HID_QUIRK_X_INVERT                     BIT(12)
+#define HID_QUIRK_Y_INVERT                     BIT(13)
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS          BIT(16)
 #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID                BIT(17)
 #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18)
@@ -788,7 +800,7 @@ struct hid_driver {
        container_of(pdrv, struct hid_driver, driver)
 
 /**
- * hid_ll_driver - low level driver callbacks
+ * struct hid_ll_driver - low level driver callbacks
  * @start: called on probe to start the device
  * @stop: called on remove
  * @open: called by input layer on open
@@ -894,7 +906,6 @@ extern void hidinput_disconnect(struct hid_device *);
 
 int hid_set_field(struct hid_field *, unsigned, __s32);
 int hid_input_report(struct hid_device *, int type, u8 *, u32, int);
-int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 unsigned int hidinput_count_leds(struct hid_device *hid);
 __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
@@ -928,6 +939,16 @@ s32 hid_snto32(__u32 value, unsigned n);
 __u32 hid_field_extract(const struct hid_device *hid, __u8 *report,
                     unsigned offset, unsigned n);
 
+#ifdef CONFIG_PM
+int hid_driver_suspend(struct hid_device *hdev, pm_message_t state);
+int hid_driver_reset_resume(struct hid_device *hdev);
+int hid_driver_resume(struct hid_device *hdev);
+#else
+static inline int hid_driver_suspend(struct hid_device *hdev, pm_message_t state) { return 0; }
+static inline int hid_driver_reset_resume(struct hid_device *hdev) { return 0; }
+static inline int hid_driver_resume(struct hid_device *hdev) { return 0; }
+#endif
+
 /**
  * hid_device_io_start - enable HID input during probe, remove
  *
@@ -1005,6 +1026,10 @@ static inline void hid_map_usage(struct hid_input *hidinput,
                bmap = input->ledbit;
                limit = LED_MAX;
                break;
+       case EV_MSC:
+               bmap = input->mscbit;
+               limit = MSC_MAX;
+               break;
        }
 
        if (unlikely(c > limit || !bmap)) {
@@ -1061,6 +1086,12 @@ int __must_check hid_hw_start(struct hid_device *hdev,
 void hid_hw_stop(struct hid_device *hdev);
 int __must_check hid_hw_open(struct hid_device *hdev);
 void hid_hw_close(struct hid_device *hdev);
+void hid_hw_request(struct hid_device *hdev,
+                   struct hid_report *report, int reqtype);
+int hid_hw_raw_request(struct hid_device *hdev,
+                      unsigned char reportnum, __u8 *buf,
+                      size_t len, unsigned char rtype, int reqtype);
+int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len);
 
 /**
  * hid_hw_power - requests underlying HW to go into given power mode
@@ -1078,68 +1109,6 @@ static inline int hid_hw_power(struct hid_device *hdev, int level)
 }
 
 
-/**
- * hid_hw_request - send report request to device
- *
- * @hdev: hid device
- * @report: report to send
- * @reqtype: hid request type
- */
-static inline void hid_hw_request(struct hid_device *hdev,
-                                 struct hid_report *report, int reqtype)
-{
-       if (hdev->ll_driver->request)
-               return hdev->ll_driver->request(hdev, report, reqtype);
-
-       __hid_request(hdev, report, reqtype);
-}
-
-/**
- * hid_hw_raw_request - send report request to device
- *
- * @hdev: hid device
- * @reportnum: report ID
- * @buf: in/out data to transfer
- * @len: length of buf
- * @rtype: HID report type
- * @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT
- *
- * Return: count of data transferred, negative if error
- *
- * Same behavior as hid_hw_request, but with raw buffers instead.
- */
-static inline int hid_hw_raw_request(struct hid_device *hdev,
-                                 unsigned char reportnum, __u8 *buf,
-                                 size_t len, unsigned char rtype, int reqtype)
-{
-       if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
-               return -EINVAL;
-
-       return hdev->ll_driver->raw_request(hdev, reportnum, buf, len,
-                                                   rtype, reqtype);
-}
-
-/**
- * hid_hw_output_report - send output report to device
- *
- * @hdev: hid device
- * @buf: raw data to transfer
- * @len: length of buf
- *
- * Return: count of data transferred, negative if error
- */
-static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf,
-                                       size_t len)
-{
-       if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
-               return -EINVAL;
-
-       if (hdev->ll_driver->output_report)
-               return hdev->ll_driver->output_report(hdev, buf, len);
-
-       return -ENOSYS;
-}
-
 /**
  * hid_hw_idle - send idle request to device
  *
@@ -1158,7 +1127,7 @@ static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
 }
 
 /**
- * hid_may_wakeup - return if the hid device may act as a wakeup source during system-suspend
+ * hid_hw_may_wakeup - return if the hid device may act as a wakeup source during system-suspend
  *
  * @hdev: hid device
  */