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 /* serialize access to open/suspend */ 86 struct mutex pm_mutex; 87 bool is_open; 88 89 /* input device related data structures */ 90 struct input_dev *input; 91 char name[128]; 92 char phys[64]; 93 94 /* characteristics of the device */ 95 unsigned long flags; 96 }; 97 98 static void synusb_report_buttons(struct synusb *synusb) 99 { 100 struct input_dev *input_dev = synusb->input; 101 102 input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04); 103 input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01); 104 input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02); 105 } 106 107 static void synusb_report_stick(struct synusb *synusb) 108 { 109 struct input_dev *input_dev = synusb->input; 110 int x, y; 111 unsigned int pressure; 112 113 pressure = synusb->data[6]; 114 x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7; 115 y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7; 116 117 if (pressure > 0) { 118 input_report_rel(input_dev, REL_X, x); 119 input_report_rel(input_dev, REL_Y, -y); 120 } 121 122 input_report_abs(input_dev, ABS_PRESSURE, pressure); 123 124 synusb_report_buttons(synusb); 125 126 input_sync(input_dev); 127 } 128 129 static void synusb_report_touchpad(struct synusb *synusb) 130 { 131 struct input_dev *input_dev = synusb->input; 132 unsigned int num_fingers, tool_width; 133 unsigned int x, y; 134 unsigned int pressure, w; 135 136 pressure = synusb->data[6]; 137 x = be16_to_cpup((__be16 *)&synusb->data[2]); 138 y = be16_to_cpup((__be16 *)&synusb->data[4]); 139 w = synusb->data[0] & 0x0f; 140 141 if (pressure > 0) { 142 num_fingers = 1; 143 tool_width = 5; 144 switch (w) { 145 case 0 ... 1: 146 num_fingers = 2 + w; 147 break; 148 149 case 2: /* pen, pretend its a finger */ 150 break; 151 152 case 4 ... 15: 153 tool_width = w; 154 break; 155 } 156 } else { 157 num_fingers = 0; 158 tool_width = 0; 159 } 160 161 /* 162 * Post events 163 * BTN_TOUCH has to be first as mousedev relies on it when doing 164 * absolute -> relative conversion 165 */ 166 167 if (pressure > 30) 168 input_report_key(input_dev, BTN_TOUCH, 1); 169 if (pressure < 25) 170 input_report_key(input_dev, BTN_TOUCH, 0); 171 172 if (num_fingers > 0) { 173 input_report_abs(input_dev, ABS_X, x); 174 input_report_abs(input_dev, ABS_Y, 175 YMAX_NOMINAL + YMIN_NOMINAL - y); 176 } 177 178 input_report_abs(input_dev, ABS_PRESSURE, pressure); 179 input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width); 180 181 input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1); 182 input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); 183 input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); 184 185 synusb_report_buttons(synusb); 186 if (synusb->flags & SYNUSB_AUXDISPLAY) 187 input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08); 188 189 input_sync(input_dev); 190 } 191 192 static void synusb_irq(struct urb *urb) 193 { 194 struct synusb *synusb = urb->context; 195 int error; 196 197 /* Check our status in case we need to bail out early. */ 198 switch (urb->status) { 199 case 0: 200 usb_mark_last_busy(synusb->udev); 201 break; 202 203 /* Device went away so don't keep trying to read from it. */ 204 case -ECONNRESET: 205 case -ENOENT: 206 case -ESHUTDOWN: 207 return; 208 209 default: 210 goto resubmit; 211 break; 212 } 213 214 if (synusb->flags & SYNUSB_STICK) 215 synusb_report_stick(synusb); 216 else 217 synusb_report_touchpad(synusb); 218 219 resubmit: 220 error = usb_submit_urb(urb, GFP_ATOMIC); 221 if (error && error != -EPERM) 222 dev_err(&synusb->intf->dev, 223 "%s - usb_submit_urb failed with result: %d", 224 __func__, error); 225 } 226 227 static struct usb_endpoint_descriptor * 228 synusb_get_in_endpoint(struct usb_host_interface *iface) 229 { 230 231 struct usb_endpoint_descriptor *endpoint; 232 int i; 233 234 for (i = 0; i < iface->desc.bNumEndpoints; ++i) { 235 endpoint = &iface->endpoint[i].desc; 236 237 if (usb_endpoint_is_int_in(endpoint)) { 238 /* we found our interrupt in endpoint */ 239 return endpoint; 240 } 241 } 242 243 return NULL; 244 } 245 246 static int synusb_open(struct input_dev *dev) 247 { 248 struct synusb *synusb = input_get_drvdata(dev); 249 int retval; 250 251 retval = usb_autopm_get_interface(synusb->intf); 252 if (retval) { 253 dev_err(&synusb->intf->dev, 254 "%s - usb_autopm_get_interface failed, error: %d\n", 255 __func__, retval); 256 return retval; 257 } 258 259 mutex_lock(&synusb->pm_mutex); 260 retval = usb_submit_urb(synusb->urb, GFP_KERNEL); 261 if (retval) { 262 dev_err(&synusb->intf->dev, 263 "%s - usb_submit_urb failed, error: %d\n", 264 __func__, retval); 265 retval = -EIO; 266 goto out; 267 } 268 269 synusb->intf->needs_remote_wakeup = 1; 270 synusb->is_open = true; 271 272 out: 273 mutex_unlock(&synusb->pm_mutex); 274 usb_autopm_put_interface(synusb->intf); 275 return retval; 276 } 277 278 static void synusb_close(struct input_dev *dev) 279 { 280 struct synusb *synusb = input_get_drvdata(dev); 281 int autopm_error; 282 283 autopm_error = usb_autopm_get_interface(synusb->intf); 284 285 mutex_lock(&synusb->pm_mutex); 286 usb_kill_urb(synusb->urb); 287 synusb->intf->needs_remote_wakeup = 0; 288 synusb->is_open = false; 289 mutex_unlock(&synusb->pm_mutex); 290 291 if (!autopm_error) 292 usb_autopm_put_interface(synusb->intf); 293 } 294 295 static int synusb_probe(struct usb_interface *intf, 296 const struct usb_device_id *id) 297 { 298 struct usb_device *udev = interface_to_usbdev(intf); 299 struct usb_endpoint_descriptor *ep; 300 struct synusb *synusb; 301 struct input_dev *input_dev; 302 unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber; 303 unsigned int altsetting = min(intf->num_altsetting, 1U); 304 int error; 305 306 error = usb_set_interface(udev, intf_num, altsetting); 307 if (error) { 308 dev_err(&udev->dev, 309 "Can not set alternate setting to %i, error: %i", 310 altsetting, error); 311 return error; 312 } 313 314 ep = synusb_get_in_endpoint(intf->cur_altsetting); 315 if (!ep) 316 return -ENODEV; 317 318 synusb = kzalloc(sizeof(*synusb), GFP_KERNEL); 319 input_dev = input_allocate_device(); 320 if (!synusb || !input_dev) { 321 error = -ENOMEM; 322 goto err_free_mem; 323 } 324 325 synusb->udev = udev; 326 synusb->intf = intf; 327 synusb->input = input_dev; 328 mutex_init(&synusb->pm_mutex); 329 330 synusb->flags = id->driver_info; 331 if (synusb->flags & SYNUSB_COMBO) { 332 /* 333 * This is a combo device, we need to set proper 334 * capability, depending on the interface. 335 */ 336 synusb->flags |= intf_num == 1 ? 337 SYNUSB_STICK : SYNUSB_TOUCHPAD; 338 } 339 340 synusb->urb = usb_alloc_urb(0, GFP_KERNEL); 341 if (!synusb->urb) { 342 error = -ENOMEM; 343 goto err_free_mem; 344 } 345 346 synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL, 347 &synusb->urb->transfer_dma); 348 if (!synusb->data) { 349 error = -ENOMEM; 350 goto err_free_urb; 351 } 352 353 usb_fill_int_urb(synusb->urb, udev, 354 usb_rcvintpipe(udev, ep->bEndpointAddress), 355 synusb->data, SYNUSB_RECV_SIZE, 356 synusb_irq, synusb, 357 ep->bInterval); 358 synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 359 360 if (udev->manufacturer) 361 strlcpy(synusb->name, udev->manufacturer, 362 sizeof(synusb->name)); 363 364 if (udev->product) { 365 if (udev->manufacturer) 366 strlcat(synusb->name, " ", sizeof(synusb->name)); 367 strlcat(synusb->name, udev->product, sizeof(synusb->name)); 368 } 369 370 if (!strlen(synusb->name)) 371 snprintf(synusb->name, sizeof(synusb->name), 372 "USB Synaptics Device %04x:%04x", 373 le16_to_cpu(udev->descriptor.idVendor), 374 le16_to_cpu(udev->descriptor.idProduct)); 375 376 if (synusb->flags & SYNUSB_STICK) 377 strlcat(synusb->name, " (Stick)", sizeof(synusb->name)); 378 379 usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); 380 strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); 381 382 input_dev->name = synusb->name; 383 input_dev->phys = synusb->phys; 384 usb_to_input_id(udev, &input_dev->id); 385 input_dev->dev.parent = &synusb->intf->dev; 386 387 if (!(synusb->flags & SYNUSB_IO_ALWAYS)) { 388 input_dev->open = synusb_open; 389 input_dev->close = synusb_close; 390 } 391 392 input_set_drvdata(input_dev, synusb); 393 394 __set_bit(EV_ABS, input_dev->evbit); 395 __set_bit(EV_KEY, input_dev->evbit); 396 397 if (synusb->flags & SYNUSB_STICK) { 398 __set_bit(EV_REL, input_dev->evbit); 399 __set_bit(REL_X, input_dev->relbit); 400 __set_bit(REL_Y, input_dev->relbit); 401 __set_bit(INPUT_PROP_POINTING_STICK, input_dev->propbit); 402 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); 403 } else { 404 input_set_abs_params(input_dev, ABS_X, 405 XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); 406 input_set_abs_params(input_dev, ABS_Y, 407 YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); 408 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); 409 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); 410 __set_bit(BTN_TOUCH, input_dev->keybit); 411 __set_bit(BTN_TOOL_FINGER, input_dev->keybit); 412 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); 413 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); 414 } 415 416 if (synusb->flags & SYNUSB_TOUCHSCREEN) 417 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); 418 else 419 __set_bit(INPUT_PROP_POINTER, input_dev->propbit); 420 421 __set_bit(BTN_LEFT, input_dev->keybit); 422 __set_bit(BTN_RIGHT, input_dev->keybit); 423 __set_bit(BTN_MIDDLE, input_dev->keybit); 424 425 usb_set_intfdata(intf, synusb); 426 427 if (synusb->flags & SYNUSB_IO_ALWAYS) { 428 error = synusb_open(input_dev); 429 if (error) 430 goto err_free_dma; 431 } 432 433 error = input_register_device(input_dev); 434 if (error) { 435 dev_err(&udev->dev, 436 "Failed to register input device, error %d\n", 437 error); 438 goto err_stop_io; 439 } 440 441 return 0; 442 443 err_stop_io: 444 if (synusb->flags & SYNUSB_IO_ALWAYS) 445 synusb_close(synusb->input); 446 err_free_dma: 447 usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, 448 synusb->urb->transfer_dma); 449 err_free_urb: 450 usb_free_urb(synusb->urb); 451 err_free_mem: 452 input_free_device(input_dev); 453 kfree(synusb); 454 usb_set_intfdata(intf, NULL); 455 456 return error; 457 } 458 459 static void synusb_disconnect(struct usb_interface *intf) 460 { 461 struct synusb *synusb = usb_get_intfdata(intf); 462 struct usb_device *udev = interface_to_usbdev(intf); 463 464 if (synusb->flags & SYNUSB_IO_ALWAYS) 465 synusb_close(synusb->input); 466 467 input_unregister_device(synusb->input); 468 469 usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, 470 synusb->urb->transfer_dma); 471 usb_free_urb(synusb->urb); 472 kfree(synusb); 473 474 usb_set_intfdata(intf, NULL); 475 } 476 477 static int synusb_suspend(struct usb_interface *intf, pm_message_t message) 478 { 479 struct synusb *synusb = usb_get_intfdata(intf); 480 481 mutex_lock(&synusb->pm_mutex); 482 usb_kill_urb(synusb->urb); 483 mutex_unlock(&synusb->pm_mutex); 484 485 return 0; 486 } 487 488 static int synusb_resume(struct usb_interface *intf) 489 { 490 struct synusb *synusb = usb_get_intfdata(intf); 491 int retval = 0; 492 493 mutex_lock(&synusb->pm_mutex); 494 495 if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) && 496 usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { 497 retval = -EIO; 498 } 499 500 mutex_unlock(&synusb->pm_mutex); 501 502 return retval; 503 } 504 505 static int synusb_pre_reset(struct usb_interface *intf) 506 { 507 struct synusb *synusb = usb_get_intfdata(intf); 508 509 mutex_lock(&synusb->pm_mutex); 510 usb_kill_urb(synusb->urb); 511 512 return 0; 513 } 514 515 static int synusb_post_reset(struct usb_interface *intf) 516 { 517 struct synusb *synusb = usb_get_intfdata(intf); 518 int retval = 0; 519 520 if ((synusb->is_open || (synusb->flags & SYNUSB_IO_ALWAYS)) && 521 usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { 522 retval = -EIO; 523 } 524 525 mutex_unlock(&synusb->pm_mutex); 526 527 return retval; 528 } 529 530 static int synusb_reset_resume(struct usb_interface *intf) 531 { 532 return synusb_resume(intf); 533 } 534 535 static const struct usb_device_id synusb_idtable[] = { 536 { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) }, 537 { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) }, 538 { USB_DEVICE_SYNAPTICS(CPAD, 539 SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) }, 540 { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) }, 541 { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) }, 542 { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) }, 543 { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) }, 544 { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) }, 545 { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) }, 546 { } 547 }; 548 MODULE_DEVICE_TABLE(usb, synusb_idtable); 549 550 static struct usb_driver synusb_driver = { 551 .name = "synaptics_usb", 552 .probe = synusb_probe, 553 .disconnect = synusb_disconnect, 554 .id_table = synusb_idtable, 555 .suspend = synusb_suspend, 556 .resume = synusb_resume, 557 .pre_reset = synusb_pre_reset, 558 .post_reset = synusb_post_reset, 559 .reset_resume = synusb_reset_resume, 560 .supports_autosuspend = 1, 561 }; 562 563 module_usb_driver(synusb_driver); 564 565 MODULE_AUTHOR("Rob Miller <rob@inpharmatica.co.uk>, " 566 "Ron Lee <ron@debian.org>, " 567 "Jan Steinhoff <cpad@jan-steinhoff.de>"); 568 MODULE_DESCRIPTION("Synaptics USB device driver"); 569 MODULE_LICENSE("GPL"); 570