Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * USB Synaptics device driver
0004  *
0005  *  Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk)
0006  *  Copyright (c) 2003 Ron Lee (ron@debian.org)
0007  *  cPad driver for kernel 2.4
0008  *
0009  *  Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de)
0010  *  Copyright (c) 2004 Ron Lee (ron@debian.org)
0011  *  rewritten for kernel 2.6
0012  *
0013  *  cPad display character device part is not included. It can be found at
0014  *  http://jan-steinhoff.de/linux/synaptics-usb.html
0015  *
0016  * Bases on:    usb_skeleton.c v2.2 by Greg Kroah-Hartman
0017  *      drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik
0018  *      drivers/input/mouse/synaptics.c by Peter Osterlund
0019  *
0020  * Trademarks are the property of their respective owners.
0021  */
0022 
0023 /*
0024  * There are three different types of Synaptics USB devices: Touchpads,
0025  * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported
0026  * by this driver, touchstick support has not been tested much yet, and
0027  * touchscreens have not been tested at all.
0028  *
0029  * Up to three alternate settings are possible:
0030  *  setting 0: one int endpoint for relative movement (used by usbhid.ko)
0031  *  setting 1: one int endpoint for absolute finger position
0032  *  setting 2 (cPad only): one int endpoint for absolute finger position and
0033  *         two bulk endpoints for the display (in/out)
0034  * This driver uses setting 1.
0035  */
0036 
0037 #include <linux/kernel.h>
0038 #include <linux/slab.h>
0039 #include <linux/module.h>
0040 #include <linux/moduleparam.h>
0041 #include <linux/usb.h>
0042 #include <linux/input.h>
0043 #include <linux/usb/input.h>
0044 
0045 #define USB_VENDOR_ID_SYNAPTICS 0x06cb
0046 #define USB_DEVICE_ID_SYNAPTICS_TP  0x0001  /* Synaptics USB TouchPad */
0047 #define USB_DEVICE_ID_SYNAPTICS_INT_TP  0x0002  /* Integrated USB TouchPad */
0048 #define USB_DEVICE_ID_SYNAPTICS_CPAD    0x0003  /* Synaptics cPad */
0049 #define USB_DEVICE_ID_SYNAPTICS_TS  0x0006  /* Synaptics TouchScreen */
0050 #define USB_DEVICE_ID_SYNAPTICS_STICK   0x0007  /* Synaptics USB Styk */
0051 #define USB_DEVICE_ID_SYNAPTICS_WP  0x0008  /* Synaptics USB WheelPad */
0052 #define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009  /* Composite USB TouchPad */
0053 #define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010  /* Wireless TouchPad */
0054 #define USB_DEVICE_ID_SYNAPTICS_DPAD    0x0013  /* DisplayPad */
0055 
0056 #define SYNUSB_TOUCHPAD         (1 << 0)
0057 #define SYNUSB_STICK            (1 << 1)
0058 #define SYNUSB_TOUCHSCREEN      (1 << 2)
0059 #define SYNUSB_AUXDISPLAY       (1 << 3) /* For cPad */
0060 #define SYNUSB_COMBO            (1 << 4) /* Composite device (TP + stick) */
0061 #define SYNUSB_IO_ALWAYS        (1 << 5)
0062 
0063 #define USB_DEVICE_SYNAPTICS(prod, kind)        \
0064     USB_DEVICE(USB_VENDOR_ID_SYNAPTICS,     \
0065            USB_DEVICE_ID_SYNAPTICS_##prod), \
0066     .driver_info = (kind),
0067 
0068 #define SYNUSB_RECV_SIZE    8
0069 
0070 #define XMIN_NOMINAL        1472
0071 #define XMAX_NOMINAL        5472
0072 #define YMIN_NOMINAL        1408
0073 #define YMAX_NOMINAL        4448
0074 
0075 struct synusb {
0076     struct usb_device *udev;
0077     struct usb_interface *intf;
0078     struct urb *urb;
0079     unsigned char *data;
0080 
0081     /* serialize access to open/suspend */
0082     struct mutex pm_mutex;
0083     bool is_open;
0084 
0085     /* input device related data structures */
0086     struct input_dev *input;
0087     char name[128];
0088     char phys[64];
0089 
0090     /* characteristics of the device */
0091     unsigned long flags;
0092 };
0093 
0094 static void synusb_report_buttons(struct synusb *synusb)
0095 {
0096     struct input_dev *input_dev = synusb->input;
0097 
0098     input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04);
0099     input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01);
0100     input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02);
0101 }
0102 
0103 static void synusb_report_stick(struct synusb *synusb)
0104 {
0105     struct input_dev *input_dev = synusb->input;
0106     int x, y;
0107     unsigned int pressure;
0108 
0109     pressure = synusb->data[6];
0110     x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7;
0111     y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7;
0112 
0113     if (pressure > 0) {
0114         input_report_rel(input_dev, REL_X, x);
0115         input_report_rel(input_dev, REL_Y, -y);
0116     }
0117 
0118     input_report_abs(input_dev, ABS_PRESSURE, pressure);
0119 
0120     synusb_report_buttons(synusb);
0121 
0122     input_sync(input_dev);
0123 }
0124 
0125 static void synusb_report_touchpad(struct synusb *synusb)
0126 {
0127     struct input_dev *input_dev = synusb->input;
0128     unsigned int num_fingers, tool_width;
0129     unsigned int x, y;
0130     unsigned int pressure, w;
0131 
0132     pressure = synusb->data[6];
0133     x = be16_to_cpup((__be16 *)&synusb->data[2]);
0134     y = be16_to_cpup((__be16 *)&synusb->data[4]);
0135     w = synusb->data[0] & 0x0f;
0136 
0137     if (pressure > 0) {
0138         num_fingers = 1;
0139         tool_width = 5;
0140         switch (w) {
0141         case 0 ... 1:
0142             num_fingers = 2 + w;
0143             break;
0144 
0145         case 2:                 /* pen, pretend its a finger */
0146             break;
0147 
0148         case 4 ... 15:
0149             tool_width = w;
0150             break;
0151         }
0152     } else {
0153         num_fingers = 0;
0154         tool_width = 0;
0155     }
0156 
0157     /*
0158      * Post events
0159      * BTN_TOUCH has to be first as mousedev relies on it when doing
0160      * absolute -> relative conversion
0161      */
0162 
0163     if (pressure > 30)
0164         input_report_key(input_dev, BTN_TOUCH, 1);
0165     if (pressure < 25)
0166         input_report_key(input_dev, BTN_TOUCH, 0);
0167 
0168     if (num_fingers > 0) {
0169         input_report_abs(input_dev, ABS_X, x);
0170         input_report_abs(input_dev, ABS_Y,
0171                  YMAX_NOMINAL + YMIN_NOMINAL - y);
0172     }
0173 
0174     input_report_abs(input_dev, ABS_PRESSURE, pressure);
0175     input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width);
0176 
0177     input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1);
0178     input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
0179     input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
0180 
0181     synusb_report_buttons(synusb);
0182     if (synusb->flags & SYNUSB_AUXDISPLAY)
0183         input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08);
0184 
0185     input_sync(input_dev);
0186 }
0187 
0188 static void synusb_irq(struct urb *urb)
0189 {
0190     struct synusb *synusb = urb->context;
0191     int error;
0192 
0193     /* Check our status in case we need to bail out early. */
0194     switch (urb->status) {
0195     case 0:
0196         usb_mark_last_busy(synusb->udev);
0197         break;
0198 
0199     /* Device went away so don't keep trying to read from it. */
0200     case -ECONNRESET:
0201     case -ENOENT:
0202     case -ESHUTDOWN:
0203         return;
0204 
0205     default:
0206         goto resubmit;
0207         break;
0208     }
0209 
0210     if (synusb->flags & SYNUSB_STICK)
0211         synusb_report_stick(synusb);
0212     else
0213         synusb_report_touchpad(synusb);
0214 
0215 resubmit:
0216     error = usb_submit_urb(urb, GFP_ATOMIC);
0217     if (error && error != -EPERM)
0218         dev_err(&synusb->intf->dev,
0219             "%s - usb_submit_urb failed with result: %d",
0220             __func__, error);
0221 }
0222 
0223 static struct usb_endpoint_descriptor *
0224 synusb_get_in_endpoint(struct usb_host_interface *iface)
0225 {
0226 
0227     struct usb_endpoint_descriptor *endpoint;
0228     int i;
0229 
0230     for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
0231         endpoint = &iface->endpoint[i].desc;
0232 
0233         if (usb_endpoint_is_int_in(endpoint)) {
0234             /* we found our interrupt in endpoint */
0235             return endpoint;
0236         }
0237     }
0238 
0239     return NULL;
0240 }
0241 
0242 static int synusb_open(struct input_dev *dev)
0243 {
0244     struct synusb *synusb = input_get_drvdata(dev);
0245     int retval;
0246 
0247     retval = usb_autopm_get_interface(synusb->intf);
0248     if (retval) {
0249         dev_err(&synusb->intf->dev,
0250             "%s - usb_autopm_get_interface failed, error: %d\n",
0251             __func__, retval);
0252         return retval;
0253     }
0254 
0255     mutex_lock(&synusb->pm_mutex);
0256     retval = usb_submit_urb(synusb->urb, GFP_KERNEL);
0257     if (retval) {
0258         dev_err(&synusb->intf->dev,
0259             "%s - usb_submit_urb failed, error: %d\n",
0260             __func__, retval);
0261         retval = -EIO;
0262         goto out;
0263     }
0264 
0265     synusb->intf->needs_remote_wakeup = 1;
0266     synusb->is_open = true;
0267 
0268 out:
0269     mutex_unlock(&synusb->pm_mutex);
0270     usb_autopm_put_interface(synusb->intf);
0271     return retval;
0272 }
0273 
0274 static void synusb_close(struct input_dev *dev)
0275 {
0276     struct synusb *synusb = input_get_drvdata(dev);
0277     int autopm_error;
0278 
0279     autopm_error = usb_autopm_get_interface(synusb->intf);
0280 
0281     mutex_lock(&synusb->pm_mutex);
0282     usb_kill_urb(synusb->urb);
0283     synusb->intf->needs_remote_wakeup = 0;
0284     synusb->is_open = false;
0285     mutex_unlock(&synusb->pm_mutex);
0286 
0287     if (!autopm_error)
0288         usb_autopm_put_interface(synusb->intf);
0289 }
0290 
0291 static int synusb_probe(struct usb_interface *intf,
0292             const struct usb_device_id *id)
0293 {
0294     struct usb_device *udev = interface_to_usbdev(intf);
0295     struct usb_endpoint_descriptor *ep;
0296     struct synusb *synusb;
0297     struct input_dev *input_dev;
0298     unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber;
0299     unsigned int altsetting = min(intf->num_altsetting, 1U);
0300     int error;
0301 
0302     error = usb_set_interface(udev, intf_num, altsetting);
0303     if (error) {
0304         dev_err(&udev->dev,
0305             "Can not set alternate setting to %i, error: %i",
0306             altsetting, error);
0307         return error;
0308     }
0309 
0310     ep = synusb_get_in_endpoint(intf->cur_altsetting);
0311     if (!ep)
0312         return -ENODEV;
0313 
0314     synusb = kzalloc(sizeof(*synusb), GFP_KERNEL);
0315     input_dev = input_allocate_device();
0316     if (!synusb || !input_dev) {
0317         error = -ENOMEM;
0318         goto err_free_mem;
0319     }
0320 
0321     synusb->udev = udev;
0322     synusb->intf = intf;
0323     synusb->input = input_dev;
0324     mutex_init(&synusb->pm_mutex);
0325 
0326     synusb->flags = id->driver_info;
0327     if (synusb->flags & SYNUSB_COMBO) {
0328         /*
0329          * This is a combo device, we need to set proper
0330          * capability, depending on the interface.
0331          */
0332         synusb->flags |= intf_num == 1 ?
0333                     SYNUSB_STICK : SYNUSB_TOUCHPAD;
0334     }
0335 
0336     synusb->urb = usb_alloc_urb(0, GFP_KERNEL);
0337     if (!synusb->urb) {
0338         error = -ENOMEM;
0339         goto err_free_mem;
0340     }
0341 
0342     synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL,
0343                       &synusb->urb->transfer_dma);
0344     if (!synusb->data) {
0345         error = -ENOMEM;
0346         goto err_free_urb;
0347     }
0348 
0349     usb_fill_int_urb(synusb->urb, udev,
0350              usb_rcvintpipe(udev, ep->bEndpointAddress),
0351              synusb->data, SYNUSB_RECV_SIZE,
0352              synusb_irq, synusb,
0353              ep->bInterval);
0354     synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0355 
0356     if (udev->manufacturer)
0357         strlcpy(synusb->name, udev->manufacturer,
0358             sizeof(synusb->name));
0359 
0360     if (udev->product) {
0361         if (udev->manufacturer)
0362             strlcat(synusb->name, " ", sizeof(synusb->name));
0363         strlcat(synusb->name, udev->product, sizeof(synusb->name));
0364     }
0365 
0366     if (!strlen(synusb->name))
0367         snprintf(synusb->name, sizeof(synusb->name),
0368              "USB Synaptics Device %04x:%04x",
0369              le16_to_cpu(udev->descriptor.idVendor),
0370              le16_to_cpu(udev->descriptor.idProduct));
0371 
0372     if (synusb->flags & SYNUSB_STICK)
0373         strlcat(synusb->name, " (Stick)", sizeof(synusb->name));
0374 
0375     usb_make_path(udev, synusb->phys, sizeof(synusb->phys));
0376     strlcat(synusb->phys, "/input0", sizeof(synusb->phys));
0377 
0378     input_dev->name = synusb->name;
0379     input_dev->phys = synusb->phys;
0380     usb_to_input_id(udev, &input_dev->id);
0381     input_dev->dev.parent = &synusb->intf->dev;
0382 
0383     if (!(synusb->flags & SYNUSB_IO_ALWAYS)) {
0384         input_dev->open = synusb_open;
0385         input_dev->close = synusb_close;
0386     }
0387 
0388     input_set_drvdata(input_dev, synusb);
0389 
0390     __set_bit(EV_ABS, input_dev->evbit);
0391     __set_bit(EV_KEY, input_dev->evbit);
0392 
0393     if (synusb->flags & SYNUSB_STICK) {
0394         __set_bit(EV_REL, input_dev->evbit);
0395         __set_bit(REL_X, input_dev->relbit);
0396         __set_bit(REL_Y, input_dev->relbit);
0397         __set_bit(INPUT_PROP_POINTING_STICK, input_dev->propbit);
0398         input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0);
0399     } else {
0400         input_set_abs_params(input_dev, ABS_X,
0401                      XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
0402         input_set_abs_params(input_dev, ABS_Y,
0403                      YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
0404         input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
0405         input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
0406         __set_bit(BTN_TOUCH, input_dev->keybit);
0407         __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
0408         __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
0409         __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
0410     }
0411 
0412     if (synusb->flags & SYNUSB_TOUCHSCREEN)
0413         __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
0414     else
0415         __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
0416 
0417     __set_bit(BTN_LEFT, input_dev->keybit);
0418     __set_bit(BTN_RIGHT, input_dev->keybit);
0419     __set_bit(BTN_MIDDLE, input_dev->keybit);
0420 
0421     usb_set_intfdata(intf, synusb);
0422 
0423     if (synusb->flags & SYNUSB_IO_ALWAYS) {
0424         error = synusb_open(input_dev);
0425         if (error)
0426             goto err_free_dma;
0427     }
0428 
0429     error = input_register_device(input_dev);
0430     if (error) {
0431         dev_err(&udev->dev,
0432             "Failed to register input device, error %d\n",
0433             error);
0434         goto err_stop_io;
0435     }
0436 
0437     return 0;
0438 
0439 err_stop_io:
0440     if (synusb->flags & SYNUSB_IO_ALWAYS)
0441         synusb_close(synusb->input);
0442 err_free_dma:
0443     usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data,
0444               synusb->urb->transfer_dma);
0445 err_free_urb:
0446     usb_free_urb(synusb->urb);
0447 err_free_mem:
0448     input_free_device(input_dev);
0449     kfree(synusb);
0450     usb_set_intfdata(intf, NULL);
0451 
0452     return error;
0453 }
0454 
0455 static void synusb_disconnect(struct usb_interface *intf)
0456 {
0457     struct synusb *synusb = usb_get_intfdata(intf);
0458     struct usb_device *udev = interface_to_usbdev(intf);
0459 
0460     if (synusb->flags & SYNUSB_IO_ALWAYS)
0461         synusb_close(synusb->input);
0462 
0463     input_unregister_device(synusb->input);
0464 
0465     usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data,
0466               synusb->urb->transfer_dma);
0467     usb_free_urb(synusb->urb);
0468     kfree(synusb);
0469 
0470     usb_set_intfdata(intf, NULL);
0471 }
0472 
0473 static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
0474 {
0475     struct synusb *synusb = usb_get_intfdata(intf);
0476 
0477     mutex_lock(&synusb->pm_mutex);
0478     usb_kill_urb(synusb->urb);
0479     mutex_unlock(&synusb->pm_mutex);
0480 
0481     return 0;
0482 }
0483 
0484 static int synusb_resume(struct usb_interface *intf)
0485 {
0486     struct synusb *synusb = usb_get_intfdata(intf);
0487     int retval = 0;
0488 
0489     mutex_lock(&synusb->pm_mutex);
0490 
0491     if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
0492         usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
0493         retval = -EIO;
0494     }
0495 
0496     mutex_unlock(&synusb->pm_mutex);
0497 
0498     return retval;
0499 }
0500 
0501 static int synusb_pre_reset(struct usb_interface *intf)
0502 {
0503     struct synusb *synusb = usb_get_intfdata(intf);
0504 
0505     mutex_lock(&synusb->pm_mutex);
0506     usb_kill_urb(synusb->urb);
0507 
0508     return 0;
0509 }
0510 
0511 static int synusb_post_reset(struct usb_interface *intf)
0512 {
0513     struct synusb *synusb = usb_get_intfdata(intf);
0514     int retval = 0;
0515 
0516     if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
0517         usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
0518         retval = -EIO;
0519     }
0520 
0521     mutex_unlock(&synusb->pm_mutex);
0522 
0523     return retval;
0524 }
0525 
0526 static int synusb_reset_resume(struct usb_interface *intf)
0527 {
0528     return synusb_resume(intf);
0529 }
0530 
0531 static const struct usb_device_id synusb_idtable[] = {
0532     { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) },
0533     { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) },
0534     { USB_DEVICE_SYNAPTICS(CPAD,
0535         SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) },
0536     { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) },
0537     { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) },
0538     { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) },
0539     { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) },
0540     { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) },
0541     { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) },
0542     { }
0543 };
0544 MODULE_DEVICE_TABLE(usb, synusb_idtable);
0545 
0546 static struct usb_driver synusb_driver = {
0547     .name       = "synaptics_usb",
0548     .probe      = synusb_probe,
0549     .disconnect = synusb_disconnect,
0550     .id_table   = synusb_idtable,
0551     .suspend    = synusb_suspend,
0552     .resume     = synusb_resume,
0553     .pre_reset  = synusb_pre_reset,
0554     .post_reset = synusb_post_reset,
0555     .reset_resume   = synusb_reset_resume,
0556     .supports_autosuspend = 1,
0557 };
0558 
0559 module_usb_driver(synusb_driver);
0560 
0561 MODULE_AUTHOR("Rob Miller <rob@inpharmatica.co.uk>, "
0562               "Ron Lee <ron@debian.org>, "
0563               "Jan Steinhoff <cpad@jan-steinhoff.de>");
0564 MODULE_DESCRIPTION("Synaptics USB device driver");
0565 MODULE_LICENSE("GPL");