Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.19 724 lines 18 kB view raw
1/****************************************************************************** 2 * usbtouchscreen.c 3 * Driver for USB Touchscreens, supporting those devices: 4 * - eGalax Touchkit 5 * includes eTurboTouch CT-410/510/700 6 * - 3M/Microtouch EX II series 7 * - ITM 8 * - PanJit TouchSet 9 * - eTurboTouch 10 * - Gunze AHL61 11 * 12 * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch> 13 * Copyright (C) by Todd E. Johnson (mtouchusb.c) 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License as 17 * published by the Free Software Foundation; either version 2 of the 18 * License, or (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, but 21 * WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 * General Public License for more details. 24 * 25 * You should have received a copy of the GNU General Public License 26 * along with this program; if not, write to the Free Software 27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 28 * 29 * Driver is based on touchkitusb.c 30 * - ITM parts are from itmtouch.c 31 * - 3M parts are from mtouchusb.c 32 * - PanJit parts are from an unmerged driver by Lanslott Gish 33 * 34 *****************************************************************************/ 35 36//#define DEBUG 37 38#include <linux/kernel.h> 39#include <linux/slab.h> 40#include <linux/input.h> 41#include <linux/module.h> 42#include <linux/init.h> 43#include <linux/usb.h> 44#include <linux/usb/input.h> 45 46 47#define DRIVER_VERSION "v0.4" 48#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" 49#define DRIVER_DESC "USB Touchscreen Driver" 50 51static int swap_xy; 52module_param(swap_xy, bool, 0644); 53MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); 54 55/* device specifc data/functions */ 56struct usbtouch_usb; 57struct usbtouch_device_info { 58 int min_xc, max_xc; 59 int min_yc, max_yc; 60 int min_press, max_press; 61 int rept_size; 62 int flags; 63 64 void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); 65 int (*get_pkt_len) (unsigned char *pkt, int len); 66 int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); 67 int (*init) (struct usbtouch_usb *usbtouch); 68}; 69 70#define USBTOUCH_FLG_BUFFER 0x01 71 72 73/* a usbtouch device */ 74struct usbtouch_usb { 75 unsigned char *data; 76 dma_addr_t data_dma; 77 unsigned char *buffer; 78 int buf_len; 79 struct urb *irq; 80 struct usb_device *udev; 81 struct input_dev *input; 82 struct usbtouch_device_info *type; 83 char name[128]; 84 char phys[64]; 85}; 86 87 88#if defined(CONFIG_USB_TOUCHSCREEN_EGALAX) || defined(CONFIG_USB_TOUCHSCREEN_ETURBO) 89#define MULTI_PACKET 90#endif 91 92#ifdef MULTI_PACKET 93static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, 94 unsigned char *pkt, int len); 95#endif 96 97/* device types */ 98enum { 99 DEVTPYE_DUMMY = -1, 100 DEVTYPE_EGALAX, 101 DEVTYPE_PANJIT, 102 DEVTYPE_3M, 103 DEVTYPE_ITM, 104 DEVTYPE_ETURBO, 105 DEVTYPE_GUNZE, 106}; 107 108static struct usb_device_id usbtouch_devices[] = { 109#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX 110 {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, 111 {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX}, 112 {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, 113 {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, 114 {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, 115 {USB_DEVICE(0x1234, 0x0001), .driver_info = DEVTYPE_EGALAX}, 116 {USB_DEVICE(0x1234, 0x0002), .driver_info = DEVTYPE_EGALAX}, 117#endif 118 119#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT 120 {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT}, 121 {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT}, 122 {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT}, 123 {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT}, 124#endif 125 126#ifdef CONFIG_USB_TOUCHSCREEN_3M 127 {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M}, 128#endif 129 130#ifdef CONFIG_USB_TOUCHSCREEN_ITM 131 {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, 132#endif 133 134#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO 135 {USB_DEVICE(0x1234, 0x5678), .driver_info = DEVTYPE_ETURBO}, 136#endif 137 138#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE 139 {USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE}, 140#endif 141 142 {} 143}; 144 145 146/***************************************************************************** 147 * eGalax part 148 */ 149 150#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX 151 152#define EGALAX_PKT_TYPE_MASK 0xFE 153#define EGALAX_PKT_TYPE_REPT 0x80 154#define EGALAX_PKT_TYPE_DIAG 0x0A 155 156static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) 157{ 158 if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) 159 return 0; 160 161 *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); 162 *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); 163 *touch = pkt[0] & 0x01; 164 165 return 1; 166} 167 168static int egalax_get_pkt_len(unsigned char *buf, int len) 169{ 170 switch (buf[0] & EGALAX_PKT_TYPE_MASK) { 171 case EGALAX_PKT_TYPE_REPT: 172 return 5; 173 174 case EGALAX_PKT_TYPE_DIAG: 175 if (len < 2) 176 return -1; 177 178 return buf[1] + 2; 179 } 180 181 return 0; 182} 183#endif 184 185 186/***************************************************************************** 187 * PanJit Part 188 */ 189#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT 190static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) 191{ 192 *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; 193 *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; 194 *touch = pkt[0] & 0x01; 195 196 return 1; 197} 198#endif 199 200 201/***************************************************************************** 202 * 3M/Microtouch Part 203 */ 204#ifdef CONFIG_USB_TOUCHSCREEN_3M 205 206#define MTOUCHUSB_ASYNC_REPORT 1 207#define MTOUCHUSB_RESET 7 208#define MTOUCHUSB_REQ_CTRLLR_ID 10 209 210static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) 211{ 212 *x = (pkt[8] << 8) | pkt[7]; 213 *y = (pkt[10] << 8) | pkt[9]; 214 *touch = (pkt[2] & 0x40) ? 1 : 0; 215 216 return 1; 217} 218 219static int mtouch_init(struct usbtouch_usb *usbtouch) 220{ 221 int ret, i; 222 223 ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), 224 MTOUCHUSB_RESET, 225 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 226 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 227 dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", 228 __FUNCTION__, ret); 229 if (ret < 0) 230 return ret; 231 msleep(150); 232 233 for (i = 0; i < 3; i++) { 234 ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), 235 MTOUCHUSB_ASYNC_REPORT, 236 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 237 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); 238 dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", 239 __FUNCTION__, ret); 240 if (ret >= 0) 241 break; 242 if (ret != -EPIPE) 243 return ret; 244 } 245 246 return 0; 247} 248#endif 249 250 251/***************************************************************************** 252 * ITM Part 253 */ 254#ifdef CONFIG_USB_TOUCHSCREEN_ITM 255static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) 256{ 257 *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); 258 *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); 259 *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); 260 *touch = ~pkt[7] & 0x20; 261 262 return *touch; 263} 264#endif 265 266 267/***************************************************************************** 268 * eTurboTouch part 269 */ 270#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO 271static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) 272{ 273 unsigned int shift; 274 275 /* packets should start with sync */ 276 if (!(pkt[0] & 0x80)) 277 return 0; 278 279 shift = (6 - (pkt[0] & 0x03)); 280 *x = ((pkt[3] << 7) | pkt[4]) >> shift; 281 *y = ((pkt[1] << 7) | pkt[2]) >> shift; 282 *touch = (pkt[0] & 0x10) ? 1 : 0; 283 284 return 1; 285} 286 287static int eturbo_get_pkt_len(unsigned char *buf, int len) 288{ 289 if (buf[0] & 0x80) 290 return 5; 291 if (buf[0] == 0x01) 292 return 3; 293 return 0; 294} 295#endif 296 297 298/***************************************************************************** 299 * Gunze part 300 */ 301#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE 302static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) 303{ 304 if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) 305 return 0; 306 307 *x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); 308 *y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); 309 *touch = pkt[0] & 0x20; 310 311 return 1; 312} 313#endif 314 315/***************************************************************************** 316 * the different device descriptors 317 */ 318static struct usbtouch_device_info usbtouch_dev_info[] = { 319#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX 320 [DEVTYPE_EGALAX] = { 321 .min_xc = 0x0, 322 .max_xc = 0x07ff, 323 .min_yc = 0x0, 324 .max_yc = 0x07ff, 325 .rept_size = 16, 326 .flags = USBTOUCH_FLG_BUFFER, 327 .process_pkt = usbtouch_process_multi, 328 .get_pkt_len = egalax_get_pkt_len, 329 .read_data = egalax_read_data, 330 }, 331#endif 332 333#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT 334 [DEVTYPE_PANJIT] = { 335 .min_xc = 0x0, 336 .max_xc = 0x0fff, 337 .min_yc = 0x0, 338 .max_yc = 0x0fff, 339 .rept_size = 8, 340 .read_data = panjit_read_data, 341 }, 342#endif 343 344#ifdef CONFIG_USB_TOUCHSCREEN_3M 345 [DEVTYPE_3M] = { 346 .min_xc = 0x0, 347 .max_xc = 0x4000, 348 .min_yc = 0x0, 349 .max_yc = 0x4000, 350 .rept_size = 11, 351 .read_data = mtouch_read_data, 352 .init = mtouch_init, 353 }, 354#endif 355 356#ifdef CONFIG_USB_TOUCHSCREEN_ITM 357 [DEVTYPE_ITM] = { 358 .min_xc = 0x0, 359 .max_xc = 0x0fff, 360 .min_yc = 0x0, 361 .max_yc = 0x0fff, 362 .max_press = 0xff, 363 .rept_size = 8, 364 .read_data = itm_read_data, 365 }, 366#endif 367 368#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO 369 [DEVTYPE_ETURBO] = { 370 .min_xc = 0x0, 371 .max_xc = 0x07ff, 372 .min_yc = 0x0, 373 .max_yc = 0x07ff, 374 .rept_size = 8, 375 .flags = USBTOUCH_FLG_BUFFER, 376 .process_pkt = usbtouch_process_multi, 377 .get_pkt_len = eturbo_get_pkt_len, 378 .read_data = eturbo_read_data, 379 }, 380#endif 381 382#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE 383 [DEVTYPE_GUNZE] = { 384 .min_xc = 0x0, 385 .max_xc = 0x0fff, 386 .min_yc = 0x0, 387 .max_yc = 0x0fff, 388 .rept_size = 4, 389 .read_data = gunze_read_data, 390 }, 391#endif 392}; 393 394 395/***************************************************************************** 396 * Generic Part 397 */ 398static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, 399 unsigned char *pkt, int len) 400{ 401 int x, y, touch, press; 402 struct usbtouch_device_info *type = usbtouch->type; 403 404 if (!type->read_data(pkt, &x, &y, &touch, &press)) 405 return; 406 407 input_report_key(usbtouch->input, BTN_TOUCH, touch); 408 409 if (swap_xy) { 410 input_report_abs(usbtouch->input, ABS_X, y); 411 input_report_abs(usbtouch->input, ABS_Y, x); 412 } else { 413 input_report_abs(usbtouch->input, ABS_X, x); 414 input_report_abs(usbtouch->input, ABS_Y, y); 415 } 416 if (type->max_press) 417 input_report_abs(usbtouch->input, ABS_PRESSURE, press); 418 input_sync(usbtouch->input); 419} 420 421 422#ifdef MULTI_PACKET 423static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, 424 unsigned char *pkt, int len) 425{ 426 unsigned char *buffer; 427 int pkt_len, pos, buf_len, tmp; 428 429 /* process buffer */ 430 if (unlikely(usbtouch->buf_len)) { 431 /* try to get size */ 432 pkt_len = usbtouch->type->get_pkt_len( 433 usbtouch->buffer, usbtouch->buf_len); 434 435 /* drop? */ 436 if (unlikely(!pkt_len)) 437 goto out_flush_buf; 438 439 /* need to append -pkt_len bytes before able to get size */ 440 if (unlikely(pkt_len < 0)) { 441 int append = -pkt_len; 442 if (unlikely(append > len)) 443 append = len; 444 if (usbtouch->buf_len + append >= usbtouch->type->rept_size) 445 goto out_flush_buf; 446 memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, append); 447 usbtouch->buf_len += append; 448 449 pkt_len = usbtouch->type->get_pkt_len( 450 usbtouch->buffer, usbtouch->buf_len); 451 if (pkt_len < 0) 452 return; 453 } 454 455 /* append */ 456 tmp = pkt_len - usbtouch->buf_len; 457 if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size) 458 goto out_flush_buf; 459 memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); 460 usbtouch_process_pkt(usbtouch, usbtouch->buffer, pkt_len); 461 462 buffer = pkt + tmp; 463 buf_len = len - tmp; 464 } else { 465 buffer = pkt; 466 buf_len = len; 467 } 468 469 /* loop over the received packet, process */ 470 pos = 0; 471 while (pos < buf_len) { 472 /* get packet len */ 473 pkt_len = usbtouch->type->get_pkt_len(buffer + pos, len); 474 475 /* unknown packet: drop everything */ 476 if (unlikely(!pkt_len)) 477 goto out_flush_buf; 478 479 /* full packet: process */ 480 if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) { 481 usbtouch_process_pkt(usbtouch, buffer + pos, pkt_len); 482 } else { 483 /* incomplete packet: save in buffer */ 484 memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); 485 usbtouch->buf_len = buf_len - pos; 486 return; 487 } 488 pos += pkt_len; 489 } 490 491out_flush_buf: 492 usbtouch->buf_len = 0; 493 return; 494} 495#endif 496 497 498static void usbtouch_irq(struct urb *urb) 499{ 500 struct usbtouch_usb *usbtouch = urb->context; 501 int retval; 502 503 switch (urb->status) { 504 case 0: 505 /* success */ 506 break; 507 case -ETIME: 508 /* this urb is timing out */ 509 dbg("%s - urb timed out - was the device unplugged?", 510 __FUNCTION__); 511 return; 512 case -ECONNRESET: 513 case -ENOENT: 514 case -ESHUTDOWN: 515 /* this urb is terminated, clean up */ 516 dbg("%s - urb shutting down with status: %d", 517 __FUNCTION__, urb->status); 518 return; 519 default: 520 dbg("%s - nonzero urb status received: %d", 521 __FUNCTION__, urb->status); 522 goto exit; 523 } 524 525 usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length); 526 527exit: 528 retval = usb_submit_urb(urb, GFP_ATOMIC); 529 if (retval) 530 err("%s - usb_submit_urb failed with result: %d", 531 __FUNCTION__, retval); 532} 533 534static int usbtouch_open(struct input_dev *input) 535{ 536 struct usbtouch_usb *usbtouch = input->private; 537 538 usbtouch->irq->dev = usbtouch->udev; 539 540 if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) 541 return -EIO; 542 543 return 0; 544} 545 546static void usbtouch_close(struct input_dev *input) 547{ 548 struct usbtouch_usb *usbtouch = input->private; 549 550 usb_kill_urb(usbtouch->irq); 551} 552 553 554static void usbtouch_free_buffers(struct usb_device *udev, 555 struct usbtouch_usb *usbtouch) 556{ 557 if (usbtouch->data) 558 usb_buffer_free(udev, usbtouch->type->rept_size, 559 usbtouch->data, usbtouch->data_dma); 560 kfree(usbtouch->buffer); 561} 562 563 564static int usbtouch_probe(struct usb_interface *intf, 565 const struct usb_device_id *id) 566{ 567 struct usbtouch_usb *usbtouch; 568 struct input_dev *input_dev; 569 struct usb_host_interface *interface; 570 struct usb_endpoint_descriptor *endpoint; 571 struct usb_device *udev = interface_to_usbdev(intf); 572 struct usbtouch_device_info *type; 573 int err = -ENOMEM; 574 575 interface = intf->cur_altsetting; 576 endpoint = &interface->endpoint[0].desc; 577 578 usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL); 579 input_dev = input_allocate_device(); 580 if (!usbtouch || !input_dev) 581 goto out_free; 582 583 type = &usbtouch_dev_info[id->driver_info]; 584 usbtouch->type = type; 585 if (!type->process_pkt) 586 type->process_pkt = usbtouch_process_pkt; 587 588 usbtouch->data = usb_buffer_alloc(udev, type->rept_size, 589 SLAB_KERNEL, &usbtouch->data_dma); 590 if (!usbtouch->data) 591 goto out_free; 592 593 if (type->flags & USBTOUCH_FLG_BUFFER) { 594 usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); 595 if (!usbtouch->buffer) 596 goto out_free_buffers; 597 } 598 599 usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); 600 if (!usbtouch->irq) { 601 dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__); 602 goto out_free_buffers; 603 } 604 605 usbtouch->udev = udev; 606 usbtouch->input = input_dev; 607 608 if (udev->manufacturer) 609 strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); 610 611 if (udev->product) { 612 if (udev->manufacturer) 613 strlcat(usbtouch->name, " ", sizeof(usbtouch->name)); 614 strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name)); 615 } 616 617 if (!strlen(usbtouch->name)) 618 snprintf(usbtouch->name, sizeof(usbtouch->name), 619 "USB Touchscreen %04x:%04x", 620 le16_to_cpu(udev->descriptor.idVendor), 621 le16_to_cpu(udev->descriptor.idProduct)); 622 623 usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys)); 624 strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys)); 625 626 input_dev->name = usbtouch->name; 627 input_dev->phys = usbtouch->phys; 628 usb_to_input_id(udev, &input_dev->id); 629 input_dev->cdev.dev = &intf->dev; 630 input_dev->private = usbtouch; 631 input_dev->open = usbtouch_open; 632 input_dev->close = usbtouch_close; 633 634 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); 635 input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); 636 input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0); 637 input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); 638 if (type->max_press) 639 input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, 640 type->max_press, 0, 0); 641 642 usb_fill_int_urb(usbtouch->irq, usbtouch->udev, 643 usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress), 644 usbtouch->data, type->rept_size, 645 usbtouch_irq, usbtouch, endpoint->bInterval); 646 647 usbtouch->irq->dev = usbtouch->udev; 648 usbtouch->irq->transfer_dma = usbtouch->data_dma; 649 usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 650 651 /* device specific init */ 652 if (type->init) { 653 err = type->init(usbtouch); 654 if (err) { 655 dbg("%s - type->init() failed, err: %d", __FUNCTION__, err); 656 goto out_free_buffers; 657 } 658 } 659 660 err = input_register_device(usbtouch->input); 661 if (err) { 662 dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err); 663 goto out_free_buffers; 664 } 665 666 usb_set_intfdata(intf, usbtouch); 667 668 return 0; 669 670out_free_buffers: 671 usbtouch_free_buffers(udev, usbtouch); 672out_free: 673 input_free_device(input_dev); 674 kfree(usbtouch); 675 return err; 676} 677 678static void usbtouch_disconnect(struct usb_interface *intf) 679{ 680 struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 681 682 dbg("%s - called", __FUNCTION__); 683 684 if (!usbtouch) 685 return; 686 687 dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__); 688 usb_set_intfdata(intf, NULL); 689 usb_kill_urb(usbtouch->irq); 690 input_unregister_device(usbtouch->input); 691 usb_free_urb(usbtouch->irq); 692 usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); 693 kfree(usbtouch); 694} 695 696MODULE_DEVICE_TABLE(usb, usbtouch_devices); 697 698static struct usb_driver usbtouch_driver = { 699 .name = "usbtouchscreen", 700 .probe = usbtouch_probe, 701 .disconnect = usbtouch_disconnect, 702 .id_table = usbtouch_devices, 703}; 704 705static int __init usbtouch_init(void) 706{ 707 return usb_register(&usbtouch_driver); 708} 709 710static void __exit usbtouch_cleanup(void) 711{ 712 usb_deregister(&usbtouch_driver); 713} 714 715module_init(usbtouch_init); 716module_exit(usbtouch_cleanup); 717 718MODULE_AUTHOR(DRIVER_AUTHOR); 719MODULE_DESCRIPTION(DRIVER_DESC); 720MODULE_LICENSE("GPL"); 721 722MODULE_ALIAS("touchkitusb"); 723MODULE_ALIAS("itmtouch"); 724MODULE_ALIAS("mtouchusb");