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