^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * USB Synaptics device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2003 Ron Lee (ron@debian.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * cPad driver for kernel 2.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (c) 2004 Ron Lee (ron@debian.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * rewritten for kernel 2.6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * cPad display character device part is not included. It can be found at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * http://jan-steinhoff.de/linux/synaptics-usb.html
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Bases on: usb_skeleton.c v2.2 by Greg Kroah-Hartman
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * drivers/input/mouse/synaptics.c by Peter Osterlund
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Trademarks are the property of their respective owners.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * There are three different types of Synaptics USB devices: Touchpads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * by this driver, touchstick support has not been tested much yet, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * touchscreens have not been tested at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Up to three alternate settings are possible:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * setting 0: one int endpoint for relative movement (used by usbhid.ko)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * setting 1: one int endpoint for absolute finger position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * setting 2 (cPad only): one int endpoint for absolute finger position and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * two bulk endpoints for the display (in/out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * This driver uses setting 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/usb/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define USB_VENDOR_ID_SYNAPTICS 0x06cb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 /* Synaptics USB TouchPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 /* Integrated USB TouchPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 /* Synaptics cPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 /* Synaptics TouchScreen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 /* Synaptics USB Styk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 /* Synaptics USB WheelPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 /* Composite USB TouchPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 /* Wireless TouchPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 /* DisplayPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SYNUSB_TOUCHPAD (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SYNUSB_STICK (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SYNUSB_TOUCHSCREEN (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SYNUSB_AUXDISPLAY (1 << 3) /* For cPad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SYNUSB_COMBO (1 << 4) /* Composite device (TP + stick) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SYNUSB_IO_ALWAYS (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define USB_DEVICE_SYNAPTICS(prod, kind) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) USB_DEVICE_ID_SYNAPTICS_##prod), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .driver_info = (kind),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SYNUSB_RECV_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define XMIN_NOMINAL 1472
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define XMAX_NOMINAL 5472
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define YMIN_NOMINAL 1408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define YMAX_NOMINAL 4448
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct synusb {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct usb_interface *intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* serialize access to open/suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct mutex pm_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bool is_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* input device related data structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) char name[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) char phys[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* characteristics of the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static void synusb_report_buttons(struct synusb *synusb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct input_dev *input_dev = synusb->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void synusb_report_stick(struct synusb *synusb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct input_dev *input_dev = synusb->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned int pressure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) pressure = synusb->data[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (pressure > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) input_report_rel(input_dev, REL_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) input_report_rel(input_dev, REL_Y, -y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) input_report_abs(input_dev, ABS_PRESSURE, pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) synusb_report_buttons(synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) input_sync(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void synusb_report_touchpad(struct synusb *synusb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct input_dev *input_dev = synusb->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int num_fingers, tool_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned int x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unsigned int pressure, w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pressure = synusb->data[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) x = be16_to_cpup((__be16 *)&synusb->data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) y = be16_to_cpup((__be16 *)&synusb->data[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) w = synusb->data[0] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (pressure > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) num_fingers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) tool_width = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) switch (w) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) case 0 ... 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) num_fingers = 2 + w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case 2: /* pen, pretend its a finger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case 4 ... 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) tool_width = w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) num_fingers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) tool_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * Post events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * BTN_TOUCH has to be first as mousedev relies on it when doing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * absolute -> relative conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (pressure > 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) input_report_key(input_dev, BTN_TOUCH, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (pressure < 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) input_report_key(input_dev, BTN_TOUCH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (num_fingers > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) input_report_abs(input_dev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) input_report_abs(input_dev, ABS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) YMAX_NOMINAL + YMIN_NOMINAL - y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) input_report_abs(input_dev, ABS_PRESSURE, pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) synusb_report_buttons(synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (synusb->flags & SYNUSB_AUXDISPLAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) input_sync(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void synusb_irq(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct synusb *synusb = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Check our status in case we need to bail out early. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) usb_mark_last_busy(synusb->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Device went away so don't keep trying to read from it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (synusb->flags & SYNUSB_STICK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) synusb_report_stick(synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) synusb_report_touchpad(synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) resubmit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) error = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (error && error != -EPERM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev_err(&synusb->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) "%s - usb_submit_urb failed with result: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) __func__, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static struct usb_endpoint_descriptor *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) synusb_get_in_endpoint(struct usb_host_interface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) endpoint = &iface->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (usb_endpoint_is_int_in(endpoint)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* we found our interrupt in endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int synusb_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct synusb *synusb = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) retval = usb_autopm_get_interface(synusb->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dev_err(&synusb->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) "%s - usb_autopm_get_interface failed, error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_lock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) retval = usb_submit_urb(synusb->urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev_err(&synusb->intf->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) "%s - usb_submit_urb failed, error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) __func__, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) synusb->intf->needs_remote_wakeup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) synusb->is_open = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mutex_unlock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) usb_autopm_put_interface(synusb->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static void synusb_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct synusb *synusb = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int autopm_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) autopm_error = usb_autopm_get_interface(synusb->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mutex_lock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) usb_kill_urb(synusb->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) synusb->intf->needs_remote_wakeup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) synusb->is_open = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mutex_unlock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!autopm_error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) usb_autopm_put_interface(synusb->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int synusb_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct usb_device *udev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct usb_endpoint_descriptor *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct synusb *synusb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned int altsetting = min(intf->num_altsetting, 1U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) error = usb_set_interface(udev, intf_num, altsetting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_err(&udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) "Can not set alternate setting to %i, error: %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) altsetting, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ep = synusb_get_in_endpoint(intf->cur_altsetting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) synusb = kzalloc(sizeof(*synusb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) input_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (!synusb || !input_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) goto err_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) synusb->udev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) synusb->intf = intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) synusb->input = input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) mutex_init(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) synusb->flags = id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (synusb->flags & SYNUSB_COMBO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * This is a combo device, we need to set proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * capability, depending on the interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) synusb->flags |= intf_num == 1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) SYNUSB_STICK : SYNUSB_TOUCHPAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) synusb->urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!synusb->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) goto err_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) &synusb->urb->transfer_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (!synusb->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) goto err_free_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) usb_fill_int_urb(synusb->urb, udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) usb_rcvintpipe(udev, ep->bEndpointAddress),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) synusb->data, SYNUSB_RECV_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) synusb_irq, synusb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ep->bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (udev->manufacturer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) strlcpy(synusb->name, udev->manufacturer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) sizeof(synusb->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (udev->product) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (udev->manufacturer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) strlcat(synusb->name, " ", sizeof(synusb->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) strlcat(synusb->name, udev->product, sizeof(synusb->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!strlen(synusb->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) snprintf(synusb->name, sizeof(synusb->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) "USB Synaptics Device %04x:%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) le16_to_cpu(udev->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) le16_to_cpu(udev->descriptor.idProduct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (synusb->flags & SYNUSB_STICK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) strlcat(synusb->name, " (Stick)", sizeof(synusb->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) usb_make_path(udev, synusb->phys, sizeof(synusb->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) strlcat(synusb->phys, "/input0", sizeof(synusb->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) input_dev->name = synusb->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) input_dev->phys = synusb->phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) usb_to_input_id(udev, &input_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) input_dev->dev.parent = &synusb->intf->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!(synusb->flags & SYNUSB_IO_ALWAYS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) input_dev->open = synusb_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) input_dev->close = synusb_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) input_set_drvdata(input_dev, synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) __set_bit(EV_ABS, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) __set_bit(EV_KEY, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (synusb->flags & SYNUSB_STICK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) __set_bit(EV_REL, input_dev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) __set_bit(REL_X, input_dev->relbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) __set_bit(REL_Y, input_dev->relbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) __set_bit(INPUT_PROP_POINTING_STICK, input_dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) input_set_abs_params(input_dev, ABS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) input_set_abs_params(input_dev, ABS_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) __set_bit(BTN_TOUCH, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (synusb->flags & SYNUSB_TOUCHSCREEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) __set_bit(BTN_LEFT, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) __set_bit(BTN_RIGHT, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) __set_bit(BTN_MIDDLE, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) usb_set_intfdata(intf, synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (synusb->flags & SYNUSB_IO_ALWAYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) error = synusb_open(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto err_free_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) error = input_register_device(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) dev_err(&udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) "Failed to register input device, error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) goto err_stop_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) err_stop_io:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (synusb->flags & SYNUSB_IO_ALWAYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) synusb_close(synusb->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) err_free_dma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) synusb->urb->transfer_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) err_free_urb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) usb_free_urb(synusb->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) err_free_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) input_free_device(input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) kfree(synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void synusb_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct synusb *synusb = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct usb_device *udev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (synusb->flags & SYNUSB_IO_ALWAYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) synusb_close(synusb->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) input_unregister_device(synusb->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) synusb->urb->transfer_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) usb_free_urb(synusb->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) kfree(synusb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct synusb *synusb = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_lock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) usb_kill_urb(synusb->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) mutex_unlock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static int synusb_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct synusb *synusb = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) mutex_lock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) mutex_unlock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int synusb_pre_reset(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct synusb *synusb = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mutex_lock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) usb_kill_urb(synusb->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static int synusb_post_reset(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct synusb *synusb = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) mutex_unlock(&synusb->pm_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int synusb_reset_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return synusb_resume(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static const struct usb_device_id synusb_idtable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) { USB_DEVICE_SYNAPTICS(CPAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) MODULE_DEVICE_TABLE(usb, synusb_idtable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static struct usb_driver synusb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .name = "synaptics_usb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .probe = synusb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .disconnect = synusb_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .id_table = synusb_idtable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .suspend = synusb_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .resume = synusb_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .pre_reset = synusb_pre_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .post_reset = synusb_post_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .reset_resume = synusb_reset_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .supports_autosuspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) module_usb_driver(synusb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) MODULE_AUTHOR("Rob Miller <rob@inpharmatica.co.uk>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) "Ron Lee <ron@debian.org>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) "Jan Steinhoff <cpad@jan-steinhoff.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) MODULE_DESCRIPTION("Synaptics USB device driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) MODULE_LICENSE("GPL");