174ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2d05e84e6SDmitry Torokhov /****************************************************************************** 3d05e84e6SDmitry Torokhov * usbtouchscreen.c 4d05e84e6SDmitry Torokhov * Driver for USB Touchscreens, supporting those devices: 5d05e84e6SDmitry Torokhov * - eGalax Touchkit 6d05e84e6SDmitry Torokhov * includes eTurboTouch CT-410/510/700 7d05e84e6SDmitry Torokhov * - 3M/Microtouch EX II series 8d05e84e6SDmitry Torokhov * - ITM 9d05e84e6SDmitry Torokhov * - PanJit TouchSet 10d05e84e6SDmitry Torokhov * - eTurboTouch 11d05e84e6SDmitry Torokhov * - Gunze AHL61 12d05e84e6SDmitry Torokhov * - DMC TSC-10/25 13df561fcdSOndrej Zary * - IRTOUCHSYSTEMS/UNITOP 14a14a8401SOndrej Zary * - IdealTEK URTC1000 1562aa366dSDaniel Ritz * - General Touch 1614e40206SJerrold Jones * - GoTop Super_Q2/GogoPen/PenPower tablets 17f7370699SJim Persson * - JASTEC USB touch controller/DigiTech DTR-02U 182330ed18SDaniel Silverstone * - Zytronic capacitive touchscreen 195197424cSOndrej Zary * - NEXIO/iNexio 20d2cc817aSMichael Gebetsroither * - Elo TouchSystems 2700 IntelliTouch 21aa87512fSArmando Visconti * - EasyTouch USB Dual/Multi touch controller from Data Modul 22d05e84e6SDmitry Torokhov * 2314e40206SJerrold Jones * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> 24d05e84e6SDmitry Torokhov * Copyright (C) by Todd E. Johnson (mtouchusb.c) 25d05e84e6SDmitry Torokhov * 26d05e84e6SDmitry Torokhov * Driver is based on touchkitusb.c 27d05e84e6SDmitry Torokhov * - ITM parts are from itmtouch.c 28d05e84e6SDmitry Torokhov * - 3M parts are from mtouchusb.c 29d05e84e6SDmitry Torokhov * - PanJit parts are from an unmerged driver by Lanslott Gish 30d05e84e6SDmitry Torokhov * - DMC TSC 10/25 are from Holger Schurig, with ideas from an unmerged 31d05e84e6SDmitry Torokhov * driver from Marius Vollmer 32d05e84e6SDmitry Torokhov * 33d05e84e6SDmitry Torokhov *****************************************************************************/ 34d05e84e6SDmitry Torokhov 35d05e84e6SDmitry Torokhov //#define DEBUG 36d05e84e6SDmitry Torokhov 37d05e84e6SDmitry Torokhov #include <linux/kernel.h> 38d05e84e6SDmitry Torokhov #include <linux/slab.h> 39d05e84e6SDmitry Torokhov #include <linux/input.h> 40d05e84e6SDmitry Torokhov #include <linux/module.h> 41d05e84e6SDmitry Torokhov #include <linux/usb.h> 42d05e84e6SDmitry Torokhov #include <linux/usb/input.h> 43ec42d448SDaniel Ritz #include <linux/hid.h> 4412e510dbSMarcus Folkesson #include <linux/mutex.h> 45d05e84e6SDmitry Torokhov 4690ab5ee9SRusty Russell static bool swap_xy; 47d05e84e6SDmitry Torokhov module_param(swap_xy, bool, 0644); 48d05e84e6SDmitry Torokhov MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); 49d05e84e6SDmitry Torokhov 5090ab5ee9SRusty Russell static bool hwcalib_xy; 51c9cbf3d3SDan Streetman module_param(hwcalib_xy, bool, 0644); 52c9cbf3d3SDan Streetman MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available"); 53c9cbf3d3SDan Streetman 54d05e84e6SDmitry Torokhov /* device specifc data/functions */ 55d05e84e6SDmitry Torokhov struct usbtouch_usb; 56d05e84e6SDmitry Torokhov struct usbtouch_device_info { 57d05e84e6SDmitry Torokhov int min_xc, max_xc; 58d05e84e6SDmitry Torokhov int min_yc, max_yc; 59d05e84e6SDmitry Torokhov int min_press, max_press; 60d05e84e6SDmitry Torokhov int rept_size; 61d05e84e6SDmitry Torokhov 622330ed18SDaniel Silverstone /* 632330ed18SDaniel Silverstone * Always service the USB devices irq not just when the input device is 642330ed18SDaniel Silverstone * open. This is useful when devices have a watchdog which prevents us 652330ed18SDaniel Silverstone * from periodically polling the device. Leave this unset unless your 662330ed18SDaniel Silverstone * touchscreen device requires it, as it does consume more of the USB 672330ed18SDaniel Silverstone * bandwidth. 682330ed18SDaniel Silverstone */ 692330ed18SDaniel Silverstone bool irq_always; 702330ed18SDaniel Silverstone 7162aa366dSDaniel Ritz /* 7262aa366dSDaniel Ritz * used to get the packet len. possible return values: 7362aa366dSDaniel Ritz * > 0: packet len 7462aa366dSDaniel Ritz * = 0: skip one byte 7562aa366dSDaniel Ritz * < 0: -return value more bytes needed 7662aa366dSDaniel Ritz */ 77d05e84e6SDmitry Torokhov int (*get_pkt_len) (unsigned char *pkt, int len); 7862aa366dSDaniel Ritz 79d05e84e6SDmitry Torokhov int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); 80a8aef622SOliver Neukum int (*alloc) (struct usbtouch_usb *usbtouch); 81d05e84e6SDmitry Torokhov int (*init) (struct usbtouch_usb *usbtouch); 825197424cSOndrej Zary void (*exit) (struct usbtouch_usb *usbtouch); 83d05e84e6SDmitry Torokhov }; 84d05e84e6SDmitry Torokhov 85d05e84e6SDmitry Torokhov /* a usbtouch device */ 86d05e84e6SDmitry Torokhov struct usbtouch_usb { 87d05e84e6SDmitry Torokhov unsigned char *data; 88d05e84e6SDmitry Torokhov dma_addr_t data_dma; 894ef38351SChristian Engelmayer int data_size; 90d05e84e6SDmitry Torokhov unsigned char *buffer; 91d05e84e6SDmitry Torokhov int buf_len; 92d05e84e6SDmitry Torokhov struct urb *irq; 93fea4d14bSOndrej Zary struct usb_interface *interface; 94d05e84e6SDmitry Torokhov struct input_dev *input; 95*830f06c0SDmitry Torokhov const struct usbtouch_device_info *type; 9612e510dbSMarcus Folkesson struct mutex pm_mutex; /* serialize access to open/suspend */ 9785f46fbfSMarcus Folkesson bool is_open; 98d05e84e6SDmitry Torokhov char name[128]; 99d05e84e6SDmitry Torokhov char phys[64]; 1005197424cSOndrej Zary void *priv; 101d05e84e6SDmitry Torokhov 102d05e84e6SDmitry Torokhov int x, y; 103d05e84e6SDmitry Torokhov int touch, press; 104fbb1c922SDmitry Torokhov 105fbb1c922SDmitry Torokhov void (*process_pkt)(struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); 106d05e84e6SDmitry Torokhov }; 107d05e84e6SDmitry Torokhov 108d05e84e6SDmitry Torokhov 109d05e84e6SDmitry Torokhov /* device types */ 110d05e84e6SDmitry Torokhov enum { 111ec42d448SDaniel Ritz DEVTYPE_IGNORE = -1, 112d05e84e6SDmitry Torokhov DEVTYPE_EGALAX, 113d05e84e6SDmitry Torokhov DEVTYPE_PANJIT, 114d05e84e6SDmitry Torokhov DEVTYPE_3M, 115d05e84e6SDmitry Torokhov DEVTYPE_ITM, 116d05e84e6SDmitry Torokhov DEVTYPE_ETURBO, 117d05e84e6SDmitry Torokhov DEVTYPE_GUNZE, 118d05e84e6SDmitry Torokhov DEVTYPE_DMC_TSC10, 119df561fcdSOndrej Zary DEVTYPE_IRTOUCH, 120dbea4032SLars Poeschel DEVTYPE_IRTOUCH_HIRES, 121a14a8401SOndrej Zary DEVTYPE_IDEALTEK, 1229d5657dbSIlya Frolov DEVTYPE_GENERAL_TOUCH, 12314e40206SJerrold Jones DEVTYPE_GOTOP, 124f7370699SJim Persson DEVTYPE_JASTEC, 1259e3b2583SFlorian Echtler DEVTYPE_E2I, 1262330ed18SDaniel Silverstone DEVTYPE_ZYTRONIC, 12738771bb4SPetr Štetiar DEVTYPE_TC45USB, 1285197424cSOndrej Zary DEVTYPE_NEXIO, 129d2cc817aSMichael Gebetsroither DEVTYPE_ELO, 130aa87512fSArmando Visconti DEVTYPE_ETOUCH, 131d05e84e6SDmitry Torokhov }; 132d05e84e6SDmitry Torokhov 133*830f06c0SDmitry Torokhov static const struct usbtouch_device_info usbtouch_dev_info[]; 134d05e84e6SDmitry Torokhov 135d05e84e6SDmitry Torokhov /***************************************************************************** 1369e3b2583SFlorian Echtler * e2i Part 1379e3b2583SFlorian Echtler */ 1389e3b2583SFlorian Echtler 1399e3b2583SFlorian Echtler #ifdef CONFIG_TOUCHSCREEN_USB_E2I 1409e3b2583SFlorian Echtler static int e2i_init(struct usbtouch_usb *usbtouch) 1419e3b2583SFlorian Echtler { 1429e3b2583SFlorian Echtler int ret; 143fea4d14bSOndrej Zary struct usb_device *udev = interface_to_usbdev(usbtouch->interface); 1449e3b2583SFlorian Echtler 14541e81022SJohan Hovold ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 1469e3b2583SFlorian Echtler 0x01, 0x02, 0x0000, 0x0081, 1479e3b2583SFlorian Echtler NULL, 0, USB_CTRL_SET_TIMEOUT); 1489e3b2583SFlorian Echtler 1490a5ebc88SGreg Kroah-Hartman dev_dbg(&usbtouch->interface->dev, 150b741ab9dSGreg Kroah-Hartman "%s - usb_control_msg - E2I_RESET - bytes|err: %d\n", 1519e3b2583SFlorian Echtler __func__, ret); 1529e3b2583SFlorian Echtler return ret; 1539e3b2583SFlorian Echtler } 1549e3b2583SFlorian Echtler 1559e3b2583SFlorian Echtler static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 1569e3b2583SFlorian Echtler { 1579e3b2583SFlorian Echtler int tmp = (pkt[0] << 8) | pkt[1]; 1589e3b2583SFlorian Echtler dev->x = (pkt[2] << 8) | pkt[3]; 1599e3b2583SFlorian Echtler dev->y = (pkt[4] << 8) | pkt[5]; 1609e3b2583SFlorian Echtler 1619e3b2583SFlorian Echtler tmp = tmp - 0xA000; 1629e3b2583SFlorian Echtler dev->touch = (tmp > 0); 1639e3b2583SFlorian Echtler dev->press = (tmp > 0 ? tmp : 0); 1649e3b2583SFlorian Echtler 1659e3b2583SFlorian Echtler return 1; 1669e3b2583SFlorian Echtler } 1679e3b2583SFlorian Echtler #endif 1689e3b2583SFlorian Echtler 1699e3b2583SFlorian Echtler 1709e3b2583SFlorian Echtler /***************************************************************************** 171d05e84e6SDmitry Torokhov * eGalax part 172d05e84e6SDmitry Torokhov */ 173d05e84e6SDmitry Torokhov 174c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX 175d05e84e6SDmitry Torokhov 17662aa366dSDaniel Ritz #ifndef MULTI_PACKET 17762aa366dSDaniel Ritz #define MULTI_PACKET 17862aa366dSDaniel Ritz #endif 17962aa366dSDaniel Ritz 180d05e84e6SDmitry Torokhov #define EGALAX_PKT_TYPE_MASK 0xFE 181d05e84e6SDmitry Torokhov #define EGALAX_PKT_TYPE_REPT 0x80 182d05e84e6SDmitry Torokhov #define EGALAX_PKT_TYPE_DIAG 0x0A 183d05e84e6SDmitry Torokhov 184037a833eSForest Bond static int egalax_init(struct usbtouch_usb *usbtouch) 185037a833eSForest Bond { 186037a833eSForest Bond int ret, i; 187037a833eSForest Bond unsigned char *buf; 188037a833eSForest Bond struct usb_device *udev = interface_to_usbdev(usbtouch->interface); 189037a833eSForest Bond 190037a833eSForest Bond /* 191037a833eSForest Bond * An eGalax diagnostic packet kicks the device into using the right 192037a833eSForest Bond * protocol. We send a "check active" packet. The response will be 193037a833eSForest Bond * read later and ignored. 194037a833eSForest Bond */ 195037a833eSForest Bond 196037a833eSForest Bond buf = kmalloc(3, GFP_KERNEL); 197037a833eSForest Bond if (!buf) 198037a833eSForest Bond return -ENOMEM; 199037a833eSForest Bond 200037a833eSForest Bond buf[0] = EGALAX_PKT_TYPE_DIAG; 201037a833eSForest Bond buf[1] = 1; /* length */ 202037a833eSForest Bond buf[2] = 'A'; /* command - check active */ 203037a833eSForest Bond 204037a833eSForest Bond for (i = 0; i < 3; i++) { 205037a833eSForest Bond ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 206037a833eSForest Bond 0, 207037a833eSForest Bond USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 208037a833eSForest Bond 0, 0, buf, 3, 209037a833eSForest Bond USB_CTRL_SET_TIMEOUT); 210037a833eSForest Bond if (ret >= 0) { 211037a833eSForest Bond ret = 0; 212037a833eSForest Bond break; 213037a833eSForest Bond } 214037a833eSForest Bond if (ret != -EPIPE) 215037a833eSForest Bond break; 216037a833eSForest Bond } 217037a833eSForest Bond 218037a833eSForest Bond kfree(buf); 219037a833eSForest Bond 220037a833eSForest Bond return ret; 221037a833eSForest Bond } 222037a833eSForest Bond 223d05e84e6SDmitry Torokhov static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 224d05e84e6SDmitry Torokhov { 225d05e84e6SDmitry Torokhov if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) 226d05e84e6SDmitry Torokhov return 0; 227d05e84e6SDmitry Torokhov 228d05e84e6SDmitry Torokhov dev->x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); 229d05e84e6SDmitry Torokhov dev->y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); 230d05e84e6SDmitry Torokhov dev->touch = pkt[0] & 0x01; 231d05e84e6SDmitry Torokhov 232d05e84e6SDmitry Torokhov return 1; 233d05e84e6SDmitry Torokhov } 234d05e84e6SDmitry Torokhov 235d05e84e6SDmitry Torokhov static int egalax_get_pkt_len(unsigned char *buf, int len) 236d05e84e6SDmitry Torokhov { 237d05e84e6SDmitry Torokhov switch (buf[0] & EGALAX_PKT_TYPE_MASK) { 238d05e84e6SDmitry Torokhov case EGALAX_PKT_TYPE_REPT: 239d05e84e6SDmitry Torokhov return 5; 240d05e84e6SDmitry Torokhov 241d05e84e6SDmitry Torokhov case EGALAX_PKT_TYPE_DIAG: 242d05e84e6SDmitry Torokhov if (len < 2) 243d05e84e6SDmitry Torokhov return -1; 244d05e84e6SDmitry Torokhov 245d05e84e6SDmitry Torokhov return buf[1] + 2; 246d05e84e6SDmitry Torokhov } 247d05e84e6SDmitry Torokhov 248d05e84e6SDmitry Torokhov return 0; 249d05e84e6SDmitry Torokhov } 250d05e84e6SDmitry Torokhov #endif 251d05e84e6SDmitry Torokhov 252aa87512fSArmando Visconti /***************************************************************************** 253aa87512fSArmando Visconti * EasyTouch part 254aa87512fSArmando Visconti */ 255aa87512fSArmando Visconti 256aa87512fSArmando Visconti #ifdef CONFIG_TOUCHSCREEN_USB_EASYTOUCH 257aa87512fSArmando Visconti 258aa87512fSArmando Visconti #ifndef MULTI_PACKET 259aa87512fSArmando Visconti #define MULTI_PACKET 260aa87512fSArmando Visconti #endif 261aa87512fSArmando Visconti 262aa87512fSArmando Visconti #define ETOUCH_PKT_TYPE_MASK 0xFE 263aa87512fSArmando Visconti #define ETOUCH_PKT_TYPE_REPT 0x80 264aa87512fSArmando Visconti #define ETOUCH_PKT_TYPE_REPT2 0xB0 265aa87512fSArmando Visconti #define ETOUCH_PKT_TYPE_DIAG 0x0A 266aa87512fSArmando Visconti 267aa87512fSArmando Visconti static int etouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 268aa87512fSArmando Visconti { 269aa87512fSArmando Visconti if ((pkt[0] & ETOUCH_PKT_TYPE_MASK) != ETOUCH_PKT_TYPE_REPT && 270aa87512fSArmando Visconti (pkt[0] & ETOUCH_PKT_TYPE_MASK) != ETOUCH_PKT_TYPE_REPT2) 271aa87512fSArmando Visconti return 0; 272aa87512fSArmando Visconti 273aa87512fSArmando Visconti dev->x = ((pkt[1] & 0x1F) << 7) | (pkt[2] & 0x7F); 274aa87512fSArmando Visconti dev->y = ((pkt[3] & 0x1F) << 7) | (pkt[4] & 0x7F); 275aa87512fSArmando Visconti dev->touch = pkt[0] & 0x01; 276aa87512fSArmando Visconti 277aa87512fSArmando Visconti return 1; 278aa87512fSArmando Visconti } 279aa87512fSArmando Visconti 280aa87512fSArmando Visconti static int etouch_get_pkt_len(unsigned char *buf, int len) 281aa87512fSArmando Visconti { 282aa87512fSArmando Visconti switch (buf[0] & ETOUCH_PKT_TYPE_MASK) { 283aa87512fSArmando Visconti case ETOUCH_PKT_TYPE_REPT: 284aa87512fSArmando Visconti case ETOUCH_PKT_TYPE_REPT2: 285aa87512fSArmando Visconti return 5; 286aa87512fSArmando Visconti 287aa87512fSArmando Visconti case ETOUCH_PKT_TYPE_DIAG: 288aa87512fSArmando Visconti if (len < 2) 289aa87512fSArmando Visconti return -1; 290aa87512fSArmando Visconti 291aa87512fSArmando Visconti return buf[1] + 2; 292aa87512fSArmando Visconti } 293aa87512fSArmando Visconti 294aa87512fSArmando Visconti return 0; 295aa87512fSArmando Visconti } 296aa87512fSArmando Visconti #endif 297d05e84e6SDmitry Torokhov 298d05e84e6SDmitry Torokhov /***************************************************************************** 299d05e84e6SDmitry Torokhov * PanJit Part 300d05e84e6SDmitry Torokhov */ 301c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_PANJIT 302d05e84e6SDmitry Torokhov static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 303d05e84e6SDmitry Torokhov { 304d05e84e6SDmitry Torokhov dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; 305d05e84e6SDmitry Torokhov dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; 306d05e84e6SDmitry Torokhov dev->touch = pkt[0] & 0x01; 307d05e84e6SDmitry Torokhov 308d05e84e6SDmitry Torokhov return 1; 309d05e84e6SDmitry Torokhov } 310d05e84e6SDmitry Torokhov #endif 311d05e84e6SDmitry Torokhov 312d05e84e6SDmitry Torokhov 313d05e84e6SDmitry Torokhov /***************************************************************************** 314d05e84e6SDmitry Torokhov * 3M/Microtouch Part 315d05e84e6SDmitry Torokhov */ 316c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_3M 317d05e84e6SDmitry Torokhov 318d05e84e6SDmitry Torokhov #define MTOUCHUSB_ASYNC_REPORT 1 319d05e84e6SDmitry Torokhov #define MTOUCHUSB_RESET 7 320d05e84e6SDmitry Torokhov #define MTOUCHUSB_REQ_CTRLLR_ID 10 321d05e84e6SDmitry Torokhov 32289f84b84SNick Dyer #define MTOUCHUSB_REQ_CTRLLR_ID_LEN 16 32389f84b84SNick Dyer 324d05e84e6SDmitry Torokhov static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 325d05e84e6SDmitry Torokhov { 326c9cbf3d3SDan Streetman if (hwcalib_xy) { 327c9cbf3d3SDan Streetman dev->x = (pkt[4] << 8) | pkt[3]; 328c9cbf3d3SDan Streetman dev->y = 0xffff - ((pkt[6] << 8) | pkt[5]); 329c9cbf3d3SDan Streetman } else { 330d05e84e6SDmitry Torokhov dev->x = (pkt[8] << 8) | pkt[7]; 331d05e84e6SDmitry Torokhov dev->y = (pkt[10] << 8) | pkt[9]; 332c9cbf3d3SDan Streetman } 333d05e84e6SDmitry Torokhov dev->touch = (pkt[2] & 0x40) ? 1 : 0; 334d05e84e6SDmitry Torokhov 335d05e84e6SDmitry Torokhov return 1; 336d05e84e6SDmitry Torokhov } 337d05e84e6SDmitry Torokhov 33889f84b84SNick Dyer struct mtouch_priv { 33989f84b84SNick Dyer u8 fw_rev_major; 34089f84b84SNick Dyer u8 fw_rev_minor; 34189f84b84SNick Dyer }; 34289f84b84SNick Dyer 34389f84b84SNick Dyer static ssize_t mtouch_firmware_rev_show(struct device *dev, 34489f84b84SNick Dyer struct device_attribute *attr, char *output) 34589f84b84SNick Dyer { 34689f84b84SNick Dyer struct usb_interface *intf = to_usb_interface(dev); 34789f84b84SNick Dyer struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 34889f84b84SNick Dyer struct mtouch_priv *priv = usbtouch->priv; 34989f84b84SNick Dyer 350e50389f2Sye xingchen return sysfs_emit(output, "%1x.%1x\n", 35189f84b84SNick Dyer priv->fw_rev_major, priv->fw_rev_minor); 35289f84b84SNick Dyer } 35389f84b84SNick Dyer static DEVICE_ATTR(firmware_rev, 0444, mtouch_firmware_rev_show, NULL); 35489f84b84SNick Dyer 35589f84b84SNick Dyer static struct attribute *mtouch_attrs[] = { 35689f84b84SNick Dyer &dev_attr_firmware_rev.attr, 35789f84b84SNick Dyer NULL 35889f84b84SNick Dyer }; 35989f84b84SNick Dyer 3606797e19dSDmitry Torokhov static bool mtouch_group_visible(struct kobject *kobj) 3616797e19dSDmitry Torokhov { 3626797e19dSDmitry Torokhov struct device *dev = kobj_to_dev(kobj); 3636797e19dSDmitry Torokhov struct usb_interface *intf = to_usb_interface(dev); 3646797e19dSDmitry Torokhov struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 3656797e19dSDmitry Torokhov 3666797e19dSDmitry Torokhov return usbtouch->type == &usbtouch_dev_info[DEVTYPE_3M]; 3676797e19dSDmitry Torokhov } 3686797e19dSDmitry Torokhov 3696797e19dSDmitry Torokhov DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(mtouch); 3706797e19dSDmitry Torokhov 37189f84b84SNick Dyer static const struct attribute_group mtouch_attr_group = { 3726797e19dSDmitry Torokhov .is_visible = SYSFS_GROUP_VISIBLE(mtouch), 37389f84b84SNick Dyer .attrs = mtouch_attrs, 37489f84b84SNick Dyer }; 37589f84b84SNick Dyer 37689f84b84SNick Dyer static int mtouch_get_fw_revision(struct usbtouch_usb *usbtouch) 37789f84b84SNick Dyer { 37889f84b84SNick Dyer struct usb_device *udev = interface_to_usbdev(usbtouch->interface); 37989f84b84SNick Dyer struct mtouch_priv *priv = usbtouch->priv; 38089f84b84SNick Dyer u8 *buf; 38189f84b84SNick Dyer int ret; 38289f84b84SNick Dyer 38389f84b84SNick Dyer buf = kzalloc(MTOUCHUSB_REQ_CTRLLR_ID_LEN, GFP_NOIO); 38489f84b84SNick Dyer if (!buf) 38589f84b84SNick Dyer return -ENOMEM; 38689f84b84SNick Dyer 38789f84b84SNick Dyer ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 38889f84b84SNick Dyer MTOUCHUSB_REQ_CTRLLR_ID, 38989f84b84SNick Dyer USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 39089f84b84SNick Dyer 0, 0, buf, MTOUCHUSB_REQ_CTRLLR_ID_LEN, 39189f84b84SNick Dyer USB_CTRL_SET_TIMEOUT); 39289f84b84SNick Dyer if (ret != MTOUCHUSB_REQ_CTRLLR_ID_LEN) { 39389f84b84SNick Dyer dev_warn(&usbtouch->interface->dev, 39489f84b84SNick Dyer "Failed to read FW rev: %d\n", ret); 39589f84b84SNick Dyer ret = ret < 0 ? ret : -EIO; 39689f84b84SNick Dyer goto free; 39789f84b84SNick Dyer } 39889f84b84SNick Dyer 39989f84b84SNick Dyer priv->fw_rev_major = buf[3]; 40089f84b84SNick Dyer priv->fw_rev_minor = buf[4]; 40189f84b84SNick Dyer 40289f84b84SNick Dyer ret = 0; 40389f84b84SNick Dyer 40489f84b84SNick Dyer free: 40589f84b84SNick Dyer kfree(buf); 40689f84b84SNick Dyer return ret; 40789f84b84SNick Dyer } 40889f84b84SNick Dyer 40989f84b84SNick Dyer static int mtouch_alloc(struct usbtouch_usb *usbtouch) 41089f84b84SNick Dyer { 411f81d03d4SErick Archer struct mtouch_priv *priv; 41289f84b84SNick Dyer 413f81d03d4SErick Archer priv = kmalloc(sizeof(*priv), GFP_KERNEL); 414f81d03d4SErick Archer if (!priv) 41589f84b84SNick Dyer return -ENOMEM; 41689f84b84SNick Dyer 417f81d03d4SErick Archer usbtouch->priv = priv; 41889f84b84SNick Dyer return 0; 41989f84b84SNick Dyer } 42089f84b84SNick Dyer 421d05e84e6SDmitry Torokhov static int mtouch_init(struct usbtouch_usb *usbtouch) 422d05e84e6SDmitry Torokhov { 423d05e84e6SDmitry Torokhov int ret, i; 424fea4d14bSOndrej Zary struct usb_device *udev = interface_to_usbdev(usbtouch->interface); 425d05e84e6SDmitry Torokhov 42689f84b84SNick Dyer ret = mtouch_get_fw_revision(usbtouch); 42789f84b84SNick Dyer if (ret) 42889f84b84SNick Dyer return ret; 42989f84b84SNick Dyer 43041e81022SJohan Hovold ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 431d05e84e6SDmitry Torokhov MTOUCHUSB_RESET, 432d05e84e6SDmitry Torokhov USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 433d05e84e6SDmitry Torokhov 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 4340a5ebc88SGreg Kroah-Hartman dev_dbg(&usbtouch->interface->dev, 435b741ab9dSGreg Kroah-Hartman "%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d\n", 436ea3e6c59SHarvey Harrison __func__, ret); 437d05e84e6SDmitry Torokhov if (ret < 0) 438d05e84e6SDmitry Torokhov return ret; 439d05e84e6SDmitry Torokhov msleep(150); 440d05e84e6SDmitry Torokhov 441d05e84e6SDmitry Torokhov for (i = 0; i < 3; i++) { 44241e81022SJohan Hovold ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 443d05e84e6SDmitry Torokhov MTOUCHUSB_ASYNC_REPORT, 444d05e84e6SDmitry Torokhov USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 445d05e84e6SDmitry Torokhov 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); 4460a5ebc88SGreg Kroah-Hartman dev_dbg(&usbtouch->interface->dev, 447b741ab9dSGreg Kroah-Hartman "%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d\n", 448ea3e6c59SHarvey Harrison __func__, ret); 449d05e84e6SDmitry Torokhov if (ret >= 0) 450d05e84e6SDmitry Torokhov break; 451d05e84e6SDmitry Torokhov if (ret != -EPIPE) 452d05e84e6SDmitry Torokhov return ret; 453d05e84e6SDmitry Torokhov } 454d05e84e6SDmitry Torokhov 455c9cbf3d3SDan Streetman /* Default min/max xy are the raw values, override if using hw-calib */ 456c9cbf3d3SDan Streetman if (hwcalib_xy) { 457c9cbf3d3SDan Streetman input_set_abs_params(usbtouch->input, ABS_X, 0, 0xffff, 0, 0); 458c9cbf3d3SDan Streetman input_set_abs_params(usbtouch->input, ABS_Y, 0, 0xffff, 0, 0); 459c9cbf3d3SDan Streetman } 460c9cbf3d3SDan Streetman 461d05e84e6SDmitry Torokhov return 0; 462d05e84e6SDmitry Torokhov } 46389f84b84SNick Dyer 46489f84b84SNick Dyer static void mtouch_exit(struct usbtouch_usb *usbtouch) 46589f84b84SNick Dyer { 46689f84b84SNick Dyer struct mtouch_priv *priv = usbtouch->priv; 46789f84b84SNick Dyer 46889f84b84SNick Dyer kfree(priv); 46989f84b84SNick Dyer } 470d05e84e6SDmitry Torokhov #endif 471d05e84e6SDmitry Torokhov 472d05e84e6SDmitry Torokhov 473d05e84e6SDmitry Torokhov /***************************************************************************** 474d05e84e6SDmitry Torokhov * ITM Part 475d05e84e6SDmitry Torokhov */ 476c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_ITM 477d05e84e6SDmitry Torokhov static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 478d05e84e6SDmitry Torokhov { 479d05e84e6SDmitry Torokhov int touch; 480d05e84e6SDmitry Torokhov /* 481d05e84e6SDmitry Torokhov * ITM devices report invalid x/y data if not touched. 482d05e84e6SDmitry Torokhov * if the screen was touched before but is not touched any more 483d05e84e6SDmitry Torokhov * report touch as 0 with the last valid x/y data once. then stop 484d05e84e6SDmitry Torokhov * reporting data until touched again. 485d05e84e6SDmitry Torokhov */ 486d05e84e6SDmitry Torokhov dev->press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); 487d05e84e6SDmitry Torokhov 488d05e84e6SDmitry Torokhov touch = ~pkt[7] & 0x20; 489d05e84e6SDmitry Torokhov if (!touch) { 490d05e84e6SDmitry Torokhov if (dev->touch) { 491d05e84e6SDmitry Torokhov dev->touch = 0; 492d05e84e6SDmitry Torokhov return 1; 493d05e84e6SDmitry Torokhov } 494d05e84e6SDmitry Torokhov 495d05e84e6SDmitry Torokhov return 0; 496d05e84e6SDmitry Torokhov } 497d05e84e6SDmitry Torokhov 498d05e84e6SDmitry Torokhov dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); 499d05e84e6SDmitry Torokhov dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); 500d05e84e6SDmitry Torokhov dev->touch = touch; 501d05e84e6SDmitry Torokhov 502d05e84e6SDmitry Torokhov return 1; 503d05e84e6SDmitry Torokhov } 504d05e84e6SDmitry Torokhov #endif 505d05e84e6SDmitry Torokhov 506d05e84e6SDmitry Torokhov 507d05e84e6SDmitry Torokhov /***************************************************************************** 508d05e84e6SDmitry Torokhov * eTurboTouch part 509d05e84e6SDmitry Torokhov */ 510c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO 51162aa366dSDaniel Ritz #ifndef MULTI_PACKET 51262aa366dSDaniel Ritz #define MULTI_PACKET 51362aa366dSDaniel Ritz #endif 514d05e84e6SDmitry Torokhov static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 515d05e84e6SDmitry Torokhov { 516d05e84e6SDmitry Torokhov unsigned int shift; 517d05e84e6SDmitry Torokhov 518d05e84e6SDmitry Torokhov /* packets should start with sync */ 519d05e84e6SDmitry Torokhov if (!(pkt[0] & 0x80)) 520d05e84e6SDmitry Torokhov return 0; 521d05e84e6SDmitry Torokhov 522d05e84e6SDmitry Torokhov shift = (6 - (pkt[0] & 0x03)); 523d05e84e6SDmitry Torokhov dev->x = ((pkt[3] << 7) | pkt[4]) >> shift; 524d05e84e6SDmitry Torokhov dev->y = ((pkt[1] << 7) | pkt[2]) >> shift; 525d05e84e6SDmitry Torokhov dev->touch = (pkt[0] & 0x10) ? 1 : 0; 526d05e84e6SDmitry Torokhov 527d05e84e6SDmitry Torokhov return 1; 528d05e84e6SDmitry Torokhov } 529d05e84e6SDmitry Torokhov 530d05e84e6SDmitry Torokhov static int eturbo_get_pkt_len(unsigned char *buf, int len) 531d05e84e6SDmitry Torokhov { 532d05e84e6SDmitry Torokhov if (buf[0] & 0x80) 533d05e84e6SDmitry Torokhov return 5; 534d05e84e6SDmitry Torokhov if (buf[0] == 0x01) 535d05e84e6SDmitry Torokhov return 3; 536d05e84e6SDmitry Torokhov return 0; 537d05e84e6SDmitry Torokhov } 538d05e84e6SDmitry Torokhov #endif 539d05e84e6SDmitry Torokhov 540d05e84e6SDmitry Torokhov 541d05e84e6SDmitry Torokhov /***************************************************************************** 542d05e84e6SDmitry Torokhov * Gunze part 543d05e84e6SDmitry Torokhov */ 544c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_GUNZE 545d05e84e6SDmitry Torokhov static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 546d05e84e6SDmitry Torokhov { 547d05e84e6SDmitry Torokhov if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) 548d05e84e6SDmitry Torokhov return 0; 549d05e84e6SDmitry Torokhov 550d05e84e6SDmitry Torokhov dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); 551d05e84e6SDmitry Torokhov dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); 552d05e84e6SDmitry Torokhov dev->touch = pkt[0] & 0x20; 553d05e84e6SDmitry Torokhov 554d05e84e6SDmitry Torokhov return 1; 555d05e84e6SDmitry Torokhov } 556d05e84e6SDmitry Torokhov #endif 557d05e84e6SDmitry Torokhov 558d05e84e6SDmitry Torokhov /***************************************************************************** 559d05e84e6SDmitry Torokhov * DMC TSC-10/25 Part 560d05e84e6SDmitry Torokhov * 561d05e84e6SDmitry Torokhov * Documentation about the controller and it's protocol can be found at 562d05e84e6SDmitry Torokhov * http://www.dmccoltd.com/files/controler/tsc10usb_pi_e.pdf 563d05e84e6SDmitry Torokhov * http://www.dmccoltd.com/files/controler/tsc25_usb_e.pdf 564d05e84e6SDmitry Torokhov */ 565c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10 566d05e84e6SDmitry Torokhov 567d05e84e6SDmitry Torokhov /* supported data rates. currently using 130 */ 568d05e84e6SDmitry Torokhov #define TSC10_RATE_POINT 0x50 569d05e84e6SDmitry Torokhov #define TSC10_RATE_30 0x40 570d05e84e6SDmitry Torokhov #define TSC10_RATE_50 0x41 571d05e84e6SDmitry Torokhov #define TSC10_RATE_80 0x42 572d05e84e6SDmitry Torokhov #define TSC10_RATE_100 0x43 573d05e84e6SDmitry Torokhov #define TSC10_RATE_130 0x44 574d05e84e6SDmitry Torokhov #define TSC10_RATE_150 0x45 575d05e84e6SDmitry Torokhov 576d05e84e6SDmitry Torokhov /* commands */ 577d05e84e6SDmitry Torokhov #define TSC10_CMD_RESET 0x55 578d05e84e6SDmitry Torokhov #define TSC10_CMD_RATE 0x05 579d05e84e6SDmitry Torokhov #define TSC10_CMD_DATA1 0x01 580d05e84e6SDmitry Torokhov 581d05e84e6SDmitry Torokhov static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) 582d05e84e6SDmitry Torokhov { 583fea4d14bSOndrej Zary struct usb_device *dev = interface_to_usbdev(usbtouch->interface); 58476d057ceSOliver Neukum int ret = -ENOMEM; 58576d057ceSOliver Neukum unsigned char *buf; 586d05e84e6SDmitry Torokhov 587a8aef622SOliver Neukum buf = kmalloc(2, GFP_NOIO); 58876d057ceSOliver Neukum if (!buf) 58976d057ceSOliver Neukum goto err_nobuf; 590d05e84e6SDmitry Torokhov /* reset */ 591d05e84e6SDmitry Torokhov buf[0] = buf[1] = 0xFF; 592d05e84e6SDmitry Torokhov ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), 593d05e84e6SDmitry Torokhov TSC10_CMD_RESET, 594d05e84e6SDmitry Torokhov USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 595d05e84e6SDmitry Torokhov 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT); 596d05e84e6SDmitry Torokhov if (ret < 0) 59776d057ceSOliver Neukum goto err_out; 5982ec6f246SNuno Lucas if (buf[0] != 0x06) { 59976d057ceSOliver Neukum ret = -ENODEV; 60076d057ceSOliver Neukum goto err_out; 60176d057ceSOliver Neukum } 602d05e84e6SDmitry Torokhov 60396849170SBernhard Bender /* TSC-25 data sheet specifies a delay after the RESET command */ 60496849170SBernhard Bender msleep(150); 60596849170SBernhard Bender 606d05e84e6SDmitry Torokhov /* set coordinate output rate */ 607d05e84e6SDmitry Torokhov buf[0] = buf[1] = 0xFF; 608d05e84e6SDmitry Torokhov ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), 609d05e84e6SDmitry Torokhov TSC10_CMD_RATE, 610d05e84e6SDmitry Torokhov USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 611d05e84e6SDmitry Torokhov TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT); 612d05e84e6SDmitry Torokhov if (ret < 0) 61376d057ceSOliver Neukum goto err_out; 6142ec6f246SNuno Lucas if ((buf[0] != 0x06) && (buf[0] != 0x15 || buf[1] != 0x01)) { 61576d057ceSOliver Neukum ret = -ENODEV; 61676d057ceSOliver Neukum goto err_out; 61776d057ceSOliver Neukum } 618d05e84e6SDmitry Torokhov 619d05e84e6SDmitry Torokhov /* start sending data */ 62041e81022SJohan Hovold ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 621d05e84e6SDmitry Torokhov TSC10_CMD_DATA1, 622d05e84e6SDmitry Torokhov USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 623d05e84e6SDmitry Torokhov 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); 62476d057ceSOliver Neukum err_out: 62576d057ceSOliver Neukum kfree(buf); 62676d057ceSOliver Neukum err_nobuf: 627d05e84e6SDmitry Torokhov return ret; 628d05e84e6SDmitry Torokhov } 629d05e84e6SDmitry Torokhov 630d05e84e6SDmitry Torokhov 631d05e84e6SDmitry Torokhov static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 632d05e84e6SDmitry Torokhov { 633d05e84e6SDmitry Torokhov dev->x = ((pkt[2] & 0x03) << 8) | pkt[1]; 634d05e84e6SDmitry Torokhov dev->y = ((pkt[4] & 0x03) << 8) | pkt[3]; 635d05e84e6SDmitry Torokhov dev->touch = pkt[0] & 0x01; 636d05e84e6SDmitry Torokhov 637d05e84e6SDmitry Torokhov return 1; 638d05e84e6SDmitry Torokhov } 639d05e84e6SDmitry Torokhov #endif 640d05e84e6SDmitry Torokhov 641d05e84e6SDmitry Torokhov 642d05e84e6SDmitry Torokhov /***************************************************************************** 643df561fcdSOndrej Zary * IRTOUCH Part 644df561fcdSOndrej Zary */ 645df561fcdSOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH 646df561fcdSOndrej Zary static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 647df561fcdSOndrej Zary { 648df561fcdSOndrej Zary dev->x = (pkt[3] << 8) | pkt[2]; 649df561fcdSOndrej Zary dev->y = (pkt[5] << 8) | pkt[4]; 650df561fcdSOndrej Zary dev->touch = (pkt[1] & 0x03) ? 1 : 0; 651df561fcdSOndrej Zary 652df561fcdSOndrej Zary return 1; 653df561fcdSOndrej Zary } 654df561fcdSOndrej Zary #endif 655df561fcdSOndrej Zary 656dbe1420bSPetr Štetiar /***************************************************************************** 65738771bb4SPetr Štetiar * ET&T TC5UH/TC4UM part 658dbe1420bSPetr Štetiar */ 65938771bb4SPetr Štetiar #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB 66038771bb4SPetr Štetiar static int tc45usb_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 661dbe1420bSPetr Štetiar { 662dbe1420bSPetr Štetiar dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; 663dbe1420bSPetr Štetiar dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; 664dbe1420bSPetr Štetiar dev->touch = pkt[0] & 0x01; 665dbe1420bSPetr Štetiar 666dbe1420bSPetr Štetiar return 1; 667dbe1420bSPetr Štetiar } 668dbe1420bSPetr Štetiar #endif 669df561fcdSOndrej Zary 670df561fcdSOndrej Zary /***************************************************************************** 671a14a8401SOndrej Zary * IdealTEK URTC1000 Part 672a14a8401SOndrej Zary */ 673a14a8401SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK 67462aa366dSDaniel Ritz #ifndef MULTI_PACKET 67562aa366dSDaniel Ritz #define MULTI_PACKET 67662aa366dSDaniel Ritz #endif 677a14a8401SOndrej Zary static int idealtek_get_pkt_len(unsigned char *buf, int len) 678a14a8401SOndrej Zary { 679a14a8401SOndrej Zary if (buf[0] & 0x80) 680a14a8401SOndrej Zary return 5; 681a14a8401SOndrej Zary if (buf[0] == 0x01) 682a14a8401SOndrej Zary return len; 683a14a8401SOndrej Zary return 0; 684a14a8401SOndrej Zary } 685a14a8401SOndrej Zary 686a14a8401SOndrej Zary static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 687a14a8401SOndrej Zary { 688a14a8401SOndrej Zary switch (pkt[0] & 0x98) { 689a14a8401SOndrej Zary case 0x88: 690a14a8401SOndrej Zary /* touch data in IdealTEK mode */ 691a14a8401SOndrej Zary dev->x = (pkt[1] << 5) | (pkt[2] >> 2); 692a14a8401SOndrej Zary dev->y = (pkt[3] << 5) | (pkt[4] >> 2); 693a14a8401SOndrej Zary dev->touch = (pkt[0] & 0x40) ? 1 : 0; 694a14a8401SOndrej Zary return 1; 695a14a8401SOndrej Zary 696a14a8401SOndrej Zary case 0x98: 697a14a8401SOndrej Zary /* touch data in MT emulation mode */ 698a14a8401SOndrej Zary dev->x = (pkt[2] << 5) | (pkt[1] >> 2); 699a14a8401SOndrej Zary dev->y = (pkt[4] << 5) | (pkt[3] >> 2); 700a14a8401SOndrej Zary dev->touch = (pkt[0] & 0x40) ? 1 : 0; 701a14a8401SOndrej Zary return 1; 702a14a8401SOndrej Zary 703a14a8401SOndrej Zary default: 704a14a8401SOndrej Zary return 0; 705a14a8401SOndrej Zary } 706a14a8401SOndrej Zary } 707a14a8401SOndrej Zary #endif 708a14a8401SOndrej Zary 7099d5657dbSIlya Frolov /***************************************************************************** 7109d5657dbSIlya Frolov * General Touch Part 7119d5657dbSIlya Frolov */ 7129d5657dbSIlya Frolov #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH 7139d5657dbSIlya Frolov static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 7149d5657dbSIlya Frolov { 715eb083ba2SRoy Yin dev->x = (pkt[2] << 8) | pkt[1]; 716eb083ba2SRoy Yin dev->y = (pkt[4] << 8) | pkt[3]; 7179d5657dbSIlya Frolov dev->press = pkt[5] & 0xff; 7189d5657dbSIlya Frolov dev->touch = pkt[0] & 0x01; 7199d5657dbSIlya Frolov 7209d5657dbSIlya Frolov return 1; 7219d5657dbSIlya Frolov } 7229d5657dbSIlya Frolov #endif 723a14a8401SOndrej Zary 724a14a8401SOndrej Zary /***************************************************************************** 72514e40206SJerrold Jones * GoTop Part 72614e40206SJerrold Jones */ 72714e40206SJerrold Jones #ifdef CONFIG_TOUCHSCREEN_USB_GOTOP 72814e40206SJerrold Jones static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 72914e40206SJerrold Jones { 73014e40206SJerrold Jones dev->x = ((pkt[1] & 0x38) << 4) | pkt[2]; 73114e40206SJerrold Jones dev->y = ((pkt[1] & 0x07) << 7) | pkt[3]; 73214e40206SJerrold Jones dev->touch = pkt[0] & 0x01; 733f7370699SJim Persson 734f7370699SJim Persson return 1; 735f7370699SJim Persson } 736f7370699SJim Persson #endif 737f7370699SJim Persson 738f7370699SJim Persson /***************************************************************************** 739f7370699SJim Persson * JASTEC Part 740f7370699SJim Persson */ 741f7370699SJim Persson #ifdef CONFIG_TOUCHSCREEN_USB_JASTEC 742f7370699SJim Persson static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 743f7370699SJim Persson { 744f7370699SJim Persson dev->x = ((pkt[0] & 0x3f) << 6) | (pkt[2] & 0x3f); 745f7370699SJim Persson dev->y = ((pkt[1] & 0x3f) << 6) | (pkt[3] & 0x3f); 746f7370699SJim Persson dev->touch = (pkt[0] & 0x40) >> 6; 747f7370699SJim Persson 74814e40206SJerrold Jones return 1; 74914e40206SJerrold Jones } 75014e40206SJerrold Jones #endif 75114e40206SJerrold Jones 7522330ed18SDaniel Silverstone /***************************************************************************** 7532330ed18SDaniel Silverstone * Zytronic Part 7542330ed18SDaniel Silverstone */ 7552330ed18SDaniel Silverstone #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC 7562330ed18SDaniel Silverstone static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 7572330ed18SDaniel Silverstone { 7580a5ebc88SGreg Kroah-Hartman struct usb_interface *intf = dev->interface; 759b741ab9dSGreg Kroah-Hartman 7602330ed18SDaniel Silverstone switch (pkt[0]) { 7612330ed18SDaniel Silverstone case 0x3A: /* command response */ 7620a5ebc88SGreg Kroah-Hartman dev_dbg(&intf->dev, "%s: Command response %d\n", __func__, pkt[1]); 7632330ed18SDaniel Silverstone break; 7642330ed18SDaniel Silverstone 7652330ed18SDaniel Silverstone case 0xC0: /* down */ 7662330ed18SDaniel Silverstone dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); 7672330ed18SDaniel Silverstone dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); 7682330ed18SDaniel Silverstone dev->touch = 1; 7690a5ebc88SGreg Kroah-Hartman dev_dbg(&intf->dev, "%s: down %d,%d\n", __func__, dev->x, dev->y); 7702330ed18SDaniel Silverstone return 1; 7712330ed18SDaniel Silverstone 7722330ed18SDaniel Silverstone case 0x80: /* up */ 7732330ed18SDaniel Silverstone dev->x = (pkt[1] & 0x7f) | ((pkt[2] & 0x07) << 7); 7742330ed18SDaniel Silverstone dev->y = (pkt[3] & 0x7f) | ((pkt[4] & 0x07) << 7); 7752330ed18SDaniel Silverstone dev->touch = 0; 7760a5ebc88SGreg Kroah-Hartman dev_dbg(&intf->dev, "%s: up %d,%d\n", __func__, dev->x, dev->y); 7772330ed18SDaniel Silverstone return 1; 7782330ed18SDaniel Silverstone 7792330ed18SDaniel Silverstone default: 7800a5ebc88SGreg Kroah-Hartman dev_dbg(&intf->dev, "%s: Unknown return %d\n", __func__, pkt[0]); 7812330ed18SDaniel Silverstone break; 7822330ed18SDaniel Silverstone } 7832330ed18SDaniel Silverstone 7842330ed18SDaniel Silverstone return 0; 7852330ed18SDaniel Silverstone } 7862330ed18SDaniel Silverstone #endif 78714e40206SJerrold Jones 78814e40206SJerrold Jones /***************************************************************************** 7895197424cSOndrej Zary * NEXIO Part 7905197424cSOndrej Zary */ 7915197424cSOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO 7925197424cSOndrej Zary 7935197424cSOndrej Zary #define NEXIO_TIMEOUT 5000 7945197424cSOndrej Zary #define NEXIO_BUFSIZE 1024 7955197424cSOndrej Zary #define NEXIO_THRESHOLD 50 7965197424cSOndrej Zary 7975197424cSOndrej Zary struct nexio_priv { 7985197424cSOndrej Zary struct urb *ack; 7995197424cSOndrej Zary unsigned char *ack_buf; 8005197424cSOndrej Zary }; 8015197424cSOndrej Zary 8025197424cSOndrej Zary struct nexio_touch_packet { 8035197424cSOndrej Zary u8 flags; /* 0xe1 = touch, 0xe1 = release */ 8045197424cSOndrej Zary __be16 data_len; /* total bytes of touch data */ 8055197424cSOndrej Zary __be16 x_len; /* bytes for X axis */ 8065197424cSOndrej Zary __be16 y_len; /* bytes for Y axis */ 8075197424cSOndrej Zary u8 data[]; 8085197424cSOndrej Zary } __attribute__ ((packed)); 8095197424cSOndrej Zary 8105197424cSOndrej Zary static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 }; 8115197424cSOndrej Zary static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f }; 8125197424cSOndrej Zary 8135197424cSOndrej Zary static void nexio_ack_complete(struct urb *urb) 8145197424cSOndrej Zary { 8155197424cSOndrej Zary } 8165197424cSOndrej Zary 817a8aef622SOliver Neukum static int nexio_alloc(struct usbtouch_usb *usbtouch) 818a8aef622SOliver Neukum { 819a8aef622SOliver Neukum struct nexio_priv *priv; 820a8aef622SOliver Neukum int ret = -ENOMEM; 821a8aef622SOliver Neukum 822f81d03d4SErick Archer priv = kmalloc(sizeof(*priv), GFP_KERNEL); 823f81d03d4SErick Archer if (!priv) 824a8aef622SOliver Neukum goto out_buf; 825a8aef622SOliver Neukum 826f81d03d4SErick Archer usbtouch->priv = priv; 827a8aef622SOliver Neukum priv->ack_buf = kmemdup(nexio_ack_pkt, sizeof(nexio_ack_pkt), 828a8aef622SOliver Neukum GFP_KERNEL); 829a8aef622SOliver Neukum if (!priv->ack_buf) 830a8aef622SOliver Neukum goto err_priv; 831a8aef622SOliver Neukum 832a8aef622SOliver Neukum priv->ack = usb_alloc_urb(0, GFP_KERNEL); 833a8aef622SOliver Neukum if (!priv->ack) { 8340a5ebc88SGreg Kroah-Hartman dev_dbg(&usbtouch->interface->dev, 835b741ab9dSGreg Kroah-Hartman "%s - usb_alloc_urb failed: usbtouch->ack\n", __func__); 836a8aef622SOliver Neukum goto err_ack_buf; 837a8aef622SOliver Neukum } 838a8aef622SOliver Neukum 839a8aef622SOliver Neukum return 0; 840a8aef622SOliver Neukum 841a8aef622SOliver Neukum err_ack_buf: 842a8aef622SOliver Neukum kfree(priv->ack_buf); 843a8aef622SOliver Neukum err_priv: 844a8aef622SOliver Neukum kfree(priv); 845a8aef622SOliver Neukum out_buf: 846a8aef622SOliver Neukum return ret; 847a8aef622SOliver Neukum } 848a8aef622SOliver Neukum 8495197424cSOndrej Zary static int nexio_init(struct usbtouch_usb *usbtouch) 8505197424cSOndrej Zary { 8515197424cSOndrej Zary struct usb_device *dev = interface_to_usbdev(usbtouch->interface); 8525197424cSOndrej Zary struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; 853a8aef622SOliver Neukum struct nexio_priv *priv = usbtouch->priv; 8545197424cSOndrej Zary int ret = -ENOMEM; 8555197424cSOndrej Zary int actual_len, i; 8565197424cSOndrej Zary unsigned char *buf; 8575197424cSOndrej Zary char *firmware_ver = NULL, *device_name = NULL; 8585197424cSOndrej Zary int input_ep = 0, output_ep = 0; 8595197424cSOndrej Zary 8605197424cSOndrej Zary /* find first input and output endpoint */ 8615197424cSOndrej Zary for (i = 0; i < interface->desc.bNumEndpoints; i++) { 8625197424cSOndrej Zary if (!input_ep && 8635197424cSOndrej Zary usb_endpoint_dir_in(&interface->endpoint[i].desc)) 8645197424cSOndrej Zary input_ep = interface->endpoint[i].desc.bEndpointAddress; 8655197424cSOndrej Zary if (!output_ep && 8665197424cSOndrej Zary usb_endpoint_dir_out(&interface->endpoint[i].desc)) 8675197424cSOndrej Zary output_ep = interface->endpoint[i].desc.bEndpointAddress; 8685197424cSOndrej Zary } 8695197424cSOndrej Zary if (!input_ep || !output_ep) 8705197424cSOndrej Zary return -ENXIO; 8715197424cSOndrej Zary 872a8aef622SOliver Neukum buf = kmalloc(NEXIO_BUFSIZE, GFP_NOIO); 8735197424cSOndrej Zary if (!buf) 8745197424cSOndrej Zary goto out_buf; 8755197424cSOndrej Zary 8765197424cSOndrej Zary /* two empty reads */ 8775197424cSOndrej Zary for (i = 0; i < 2; i++) { 8785197424cSOndrej Zary ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), 8795197424cSOndrej Zary buf, NEXIO_BUFSIZE, &actual_len, 8805197424cSOndrej Zary NEXIO_TIMEOUT); 8815197424cSOndrej Zary if (ret < 0) 8825197424cSOndrej Zary goto out_buf; 8835197424cSOndrej Zary } 8845197424cSOndrej Zary 8855197424cSOndrej Zary /* send init command */ 8865197424cSOndrej Zary memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt)); 8875197424cSOndrej Zary ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep), 8885197424cSOndrej Zary buf, sizeof(nexio_init_pkt), &actual_len, 8895197424cSOndrej Zary NEXIO_TIMEOUT); 8905197424cSOndrej Zary if (ret < 0) 8915197424cSOndrej Zary goto out_buf; 8925197424cSOndrej Zary 8935197424cSOndrej Zary /* read replies */ 8945197424cSOndrej Zary for (i = 0; i < 3; i++) { 8955197424cSOndrej Zary memset(buf, 0, NEXIO_BUFSIZE); 8965197424cSOndrej Zary ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), 8975197424cSOndrej Zary buf, NEXIO_BUFSIZE, &actual_len, 8985197424cSOndrej Zary NEXIO_TIMEOUT); 8995197424cSOndrej Zary if (ret < 0 || actual_len < 1 || buf[1] != actual_len) 9005197424cSOndrej Zary continue; 9015197424cSOndrej Zary switch (buf[0]) { 9025197424cSOndrej Zary case 0x83: /* firmware version */ 9035197424cSOndrej Zary if (!firmware_ver) 904a8aef622SOliver Neukum firmware_ver = kstrdup(&buf[2], GFP_NOIO); 9055197424cSOndrej Zary break; 9065197424cSOndrej Zary case 0x84: /* device name */ 9075197424cSOndrej Zary if (!device_name) 908a8aef622SOliver Neukum device_name = kstrdup(&buf[2], GFP_NOIO); 9095197424cSOndrej Zary break; 9105197424cSOndrej Zary } 9115197424cSOndrej Zary } 9125197424cSOndrej Zary 9135197424cSOndrej Zary printk(KERN_INFO "Nexio device: %s, firmware version: %s\n", 9145197424cSOndrej Zary device_name, firmware_ver); 9155197424cSOndrej Zary 9165197424cSOndrej Zary kfree(firmware_ver); 9175197424cSOndrej Zary kfree(device_name); 9185197424cSOndrej Zary 9195197424cSOndrej Zary usb_fill_bulk_urb(priv->ack, dev, usb_sndbulkpipe(dev, output_ep), 9205197424cSOndrej Zary priv->ack_buf, sizeof(nexio_ack_pkt), 9215197424cSOndrej Zary nexio_ack_complete, usbtouch); 9225197424cSOndrej Zary ret = 0; 9235197424cSOndrej Zary 9245197424cSOndrej Zary out_buf: 9255197424cSOndrej Zary kfree(buf); 9265197424cSOndrej Zary return ret; 9275197424cSOndrej Zary } 9285197424cSOndrej Zary 9295197424cSOndrej Zary static void nexio_exit(struct usbtouch_usb *usbtouch) 9305197424cSOndrej Zary { 9315197424cSOndrej Zary struct nexio_priv *priv = usbtouch->priv; 9325197424cSOndrej Zary 9335197424cSOndrej Zary usb_kill_urb(priv->ack); 9345197424cSOndrej Zary usb_free_urb(priv->ack); 9355197424cSOndrej Zary kfree(priv->ack_buf); 9365197424cSOndrej Zary kfree(priv); 9375197424cSOndrej Zary } 9385197424cSOndrej Zary 9395197424cSOndrej Zary static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt) 9405197424cSOndrej Zary { 94133f93726SLee Jones struct device *dev = &usbtouch->interface->dev; 9425197424cSOndrej Zary struct nexio_touch_packet *packet = (void *) pkt; 9435197424cSOndrej Zary struct nexio_priv *priv = usbtouch->priv; 9444aa5bbecSDmitry Torokhov unsigned int data_len = be16_to_cpu(packet->data_len); 9454aa5bbecSDmitry Torokhov unsigned int x_len = be16_to_cpu(packet->x_len); 9464aa5bbecSDmitry Torokhov unsigned int y_len = be16_to_cpu(packet->y_len); 9474aa5bbecSDmitry Torokhov int x, y, begin_x, begin_y, end_x, end_y, w, h, ret; 9485197424cSOndrej Zary 9495197424cSOndrej Zary /* got touch data? */ 9505197424cSOndrej Zary if ((pkt[0] & 0xe0) != 0xe0) 9515197424cSOndrej Zary return 0; 9525197424cSOndrej Zary 9534aa5bbecSDmitry Torokhov if (data_len > 0xff) 9544aa5bbecSDmitry Torokhov data_len -= 0x100; 9554aa5bbecSDmitry Torokhov if (x_len > 0xff) 9564aa5bbecSDmitry Torokhov x_len -= 0x80; 957388bbcadSOndrej Zary 9585197424cSOndrej Zary /* send ACK */ 9595197424cSOndrej Zary ret = usb_submit_urb(priv->ack, GFP_ATOMIC); 96033f93726SLee Jones if (ret) 96133f93726SLee Jones dev_warn(dev, "Failed to submit ACK URB: %d\n", ret); 9625197424cSOndrej Zary 963*830f06c0SDmitry Torokhov if (!input_abs_get_max(usbtouch->input, ABS_X)) { 9644aa5bbecSDmitry Torokhov input_set_abs_params(usbtouch->input, ABS_X, 965*830f06c0SDmitry Torokhov 0, 2 * x_len, 0, 0); 9664aa5bbecSDmitry Torokhov input_set_abs_params(usbtouch->input, ABS_Y, 967*830f06c0SDmitry Torokhov 0, 2 * y_len, 0, 0); 9685197424cSOndrej Zary } 9695197424cSOndrej Zary /* 9705197424cSOndrej Zary * The device reports state of IR sensors on X and Y axes. 9715197424cSOndrej Zary * Each byte represents "darkness" percentage (0-100) of one element. 9725197424cSOndrej Zary * 17" touchscreen reports only 64 x 52 bytes so the resolution is low. 9735197424cSOndrej Zary * This also means that there's a limited multi-touch capability but 9745197424cSOndrej Zary * it's disabled (and untested) here as there's no X driver for that. 9755197424cSOndrej Zary */ 9765197424cSOndrej Zary begin_x = end_x = begin_y = end_y = -1; 9774aa5bbecSDmitry Torokhov for (x = 0; x < x_len; x++) { 9785197424cSOndrej Zary if (begin_x == -1 && packet->data[x] > NEXIO_THRESHOLD) { 9795197424cSOndrej Zary begin_x = x; 9805197424cSOndrej Zary continue; 9815197424cSOndrej Zary } 9825197424cSOndrej Zary if (end_x == -1 && begin_x != -1 && packet->data[x] < NEXIO_THRESHOLD) { 9835197424cSOndrej Zary end_x = x - 1; 9844aa5bbecSDmitry Torokhov for (y = x_len; y < data_len; y++) { 9855197424cSOndrej Zary if (begin_y == -1 && packet->data[y] > NEXIO_THRESHOLD) { 9864aa5bbecSDmitry Torokhov begin_y = y - x_len; 9875197424cSOndrej Zary continue; 9885197424cSOndrej Zary } 9895197424cSOndrej Zary if (end_y == -1 && 9905197424cSOndrej Zary begin_y != -1 && packet->data[y] < NEXIO_THRESHOLD) { 9914aa5bbecSDmitry Torokhov end_y = y - 1 - x_len; 9925197424cSOndrej Zary w = end_x - begin_x; 9935197424cSOndrej Zary h = end_y - begin_y; 9945197424cSOndrej Zary #if 0 9955197424cSOndrej Zary /* multi-touch */ 9965197424cSOndrej Zary input_report_abs(usbtouch->input, 9975197424cSOndrej Zary ABS_MT_TOUCH_MAJOR, max(w,h)); 9985197424cSOndrej Zary input_report_abs(usbtouch->input, 9995197424cSOndrej Zary ABS_MT_TOUCH_MINOR, min(x,h)); 10005197424cSOndrej Zary input_report_abs(usbtouch->input, 10015197424cSOndrej Zary ABS_MT_POSITION_X, 2*begin_x+w); 10025197424cSOndrej Zary input_report_abs(usbtouch->input, 10035197424cSOndrej Zary ABS_MT_POSITION_Y, 2*begin_y+h); 10045197424cSOndrej Zary input_report_abs(usbtouch->input, 10055197424cSOndrej Zary ABS_MT_ORIENTATION, w > h); 10065197424cSOndrej Zary input_mt_sync(usbtouch->input); 10075197424cSOndrej Zary #endif 10085197424cSOndrej Zary /* single touch */ 10095197424cSOndrej Zary usbtouch->x = 2 * begin_x + w; 10105197424cSOndrej Zary usbtouch->y = 2 * begin_y + h; 10115197424cSOndrej Zary usbtouch->touch = packet->flags & 0x01; 10125197424cSOndrej Zary begin_y = end_y = -1; 10135197424cSOndrej Zary return 1; 10145197424cSOndrej Zary } 10155197424cSOndrej Zary } 10165197424cSOndrej Zary begin_x = end_x = -1; 10175197424cSOndrej Zary } 10185197424cSOndrej Zary 10195197424cSOndrej Zary } 10205197424cSOndrej Zary return 0; 10215197424cSOndrej Zary } 10225197424cSOndrej Zary #endif 10235197424cSOndrej Zary 10245197424cSOndrej Zary 10255197424cSOndrej Zary /***************************************************************************** 1026d2cc817aSMichael Gebetsroither * ELO part 1027d2cc817aSMichael Gebetsroither */ 1028d2cc817aSMichael Gebetsroither 1029d2cc817aSMichael Gebetsroither #ifdef CONFIG_TOUCHSCREEN_USB_ELO 1030d2cc817aSMichael Gebetsroither 1031d2cc817aSMichael Gebetsroither static int elo_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 1032d2cc817aSMichael Gebetsroither { 1033d2cc817aSMichael Gebetsroither dev->x = (pkt[3] << 8) | pkt[2]; 1034d2cc817aSMichael Gebetsroither dev->y = (pkt[5] << 8) | pkt[4]; 1035d2cc817aSMichael Gebetsroither dev->touch = pkt[6] > 0; 1036d2cc817aSMichael Gebetsroither dev->press = pkt[6]; 1037d2cc817aSMichael Gebetsroither 1038d2cc817aSMichael Gebetsroither return 1; 1039d2cc817aSMichael Gebetsroither } 1040d2cc817aSMichael Gebetsroither #endif 1041d2cc817aSMichael Gebetsroither 1042d2cc817aSMichael Gebetsroither 1043d2cc817aSMichael Gebetsroither /***************************************************************************** 1044d05e84e6SDmitry Torokhov * the different device descriptors 1045d05e84e6SDmitry Torokhov */ 1046*830f06c0SDmitry Torokhov static const struct usbtouch_device_info usbtouch_dev_info[] = { 1047d2cc817aSMichael Gebetsroither #ifdef CONFIG_TOUCHSCREEN_USB_ELO 1048d2cc817aSMichael Gebetsroither [DEVTYPE_ELO] = { 1049d2cc817aSMichael Gebetsroither .min_xc = 0x0, 1050d2cc817aSMichael Gebetsroither .max_xc = 0x0fff, 1051d2cc817aSMichael Gebetsroither .min_yc = 0x0, 1052d2cc817aSMichael Gebetsroither .max_yc = 0x0fff, 1053d2cc817aSMichael Gebetsroither .max_press = 0xff, 1054d2cc817aSMichael Gebetsroither .rept_size = 8, 1055d2cc817aSMichael Gebetsroither .read_data = elo_read_data, 1056d2cc817aSMichael Gebetsroither }, 1057d2cc817aSMichael Gebetsroither #endif 1058d2cc817aSMichael Gebetsroither 1059c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX 1060d05e84e6SDmitry Torokhov [DEVTYPE_EGALAX] = { 1061d05e84e6SDmitry Torokhov .min_xc = 0x0, 1062d05e84e6SDmitry Torokhov .max_xc = 0x07ff, 1063d05e84e6SDmitry Torokhov .min_yc = 0x0, 1064d05e84e6SDmitry Torokhov .max_yc = 0x07ff, 1065d05e84e6SDmitry Torokhov .rept_size = 16, 1066d05e84e6SDmitry Torokhov .get_pkt_len = egalax_get_pkt_len, 1067d05e84e6SDmitry Torokhov .read_data = egalax_read_data, 1068037a833eSForest Bond .init = egalax_init, 1069d05e84e6SDmitry Torokhov }, 1070d05e84e6SDmitry Torokhov #endif 1071d05e84e6SDmitry Torokhov 1072c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_PANJIT 1073d05e84e6SDmitry Torokhov [DEVTYPE_PANJIT] = { 1074d05e84e6SDmitry Torokhov .min_xc = 0x0, 1075d05e84e6SDmitry Torokhov .max_xc = 0x0fff, 1076d05e84e6SDmitry Torokhov .min_yc = 0x0, 1077d05e84e6SDmitry Torokhov .max_yc = 0x0fff, 1078d05e84e6SDmitry Torokhov .rept_size = 8, 1079d05e84e6SDmitry Torokhov .read_data = panjit_read_data, 1080d05e84e6SDmitry Torokhov }, 1081d05e84e6SDmitry Torokhov #endif 1082d05e84e6SDmitry Torokhov 1083c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_3M 1084d05e84e6SDmitry Torokhov [DEVTYPE_3M] = { 1085d05e84e6SDmitry Torokhov .min_xc = 0x0, 1086d05e84e6SDmitry Torokhov .max_xc = 0x4000, 1087d05e84e6SDmitry Torokhov .min_yc = 0x0, 1088d05e84e6SDmitry Torokhov .max_yc = 0x4000, 1089d05e84e6SDmitry Torokhov .rept_size = 11, 1090d05e84e6SDmitry Torokhov .read_data = mtouch_read_data, 109189f84b84SNick Dyer .alloc = mtouch_alloc, 1092d05e84e6SDmitry Torokhov .init = mtouch_init, 109389f84b84SNick Dyer .exit = mtouch_exit, 1094d05e84e6SDmitry Torokhov }, 1095d05e84e6SDmitry Torokhov #endif 1096d05e84e6SDmitry Torokhov 1097c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_ITM 1098d05e84e6SDmitry Torokhov [DEVTYPE_ITM] = { 1099d05e84e6SDmitry Torokhov .min_xc = 0x0, 1100d05e84e6SDmitry Torokhov .max_xc = 0x0fff, 1101d05e84e6SDmitry Torokhov .min_yc = 0x0, 1102d05e84e6SDmitry Torokhov .max_yc = 0x0fff, 1103d05e84e6SDmitry Torokhov .max_press = 0xff, 1104d05e84e6SDmitry Torokhov .rept_size = 8, 1105d05e84e6SDmitry Torokhov .read_data = itm_read_data, 1106d05e84e6SDmitry Torokhov }, 1107d05e84e6SDmitry Torokhov #endif 1108d05e84e6SDmitry Torokhov 1109c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO 1110d05e84e6SDmitry Torokhov [DEVTYPE_ETURBO] = { 1111d05e84e6SDmitry Torokhov .min_xc = 0x0, 1112d05e84e6SDmitry Torokhov .max_xc = 0x07ff, 1113d05e84e6SDmitry Torokhov .min_yc = 0x0, 1114d05e84e6SDmitry Torokhov .max_yc = 0x07ff, 1115d05e84e6SDmitry Torokhov .rept_size = 8, 1116d05e84e6SDmitry Torokhov .get_pkt_len = eturbo_get_pkt_len, 1117d05e84e6SDmitry Torokhov .read_data = eturbo_read_data, 1118d05e84e6SDmitry Torokhov }, 1119d05e84e6SDmitry Torokhov #endif 1120d05e84e6SDmitry Torokhov 1121c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_GUNZE 1122d05e84e6SDmitry Torokhov [DEVTYPE_GUNZE] = { 1123d05e84e6SDmitry Torokhov .min_xc = 0x0, 1124d05e84e6SDmitry Torokhov .max_xc = 0x0fff, 1125d05e84e6SDmitry Torokhov .min_yc = 0x0, 1126d05e84e6SDmitry Torokhov .max_yc = 0x0fff, 1127d05e84e6SDmitry Torokhov .rept_size = 4, 1128d05e84e6SDmitry Torokhov .read_data = gunze_read_data, 1129d05e84e6SDmitry Torokhov }, 1130d05e84e6SDmitry Torokhov #endif 1131d05e84e6SDmitry Torokhov 1132c6f8d706SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10 1133d05e84e6SDmitry Torokhov [DEVTYPE_DMC_TSC10] = { 1134d05e84e6SDmitry Torokhov .min_xc = 0x0, 1135d05e84e6SDmitry Torokhov .max_xc = 0x03ff, 1136d05e84e6SDmitry Torokhov .min_yc = 0x0, 1137d05e84e6SDmitry Torokhov .max_yc = 0x03ff, 1138d05e84e6SDmitry Torokhov .rept_size = 5, 1139d05e84e6SDmitry Torokhov .init = dmc_tsc10_init, 1140d05e84e6SDmitry Torokhov .read_data = dmc_tsc10_read_data, 1141d05e84e6SDmitry Torokhov }, 1142d05e84e6SDmitry Torokhov #endif 1143df561fcdSOndrej Zary 1144df561fcdSOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH 1145df561fcdSOndrej Zary [DEVTYPE_IRTOUCH] = { 1146df561fcdSOndrej Zary .min_xc = 0x0, 1147df561fcdSOndrej Zary .max_xc = 0x0fff, 1148df561fcdSOndrej Zary .min_yc = 0x0, 1149df561fcdSOndrej Zary .max_yc = 0x0fff, 1150df561fcdSOndrej Zary .rept_size = 8, 1151df561fcdSOndrej Zary .read_data = irtouch_read_data, 1152df561fcdSOndrej Zary }, 1153dbea4032SLars Poeschel 1154dbea4032SLars Poeschel [DEVTYPE_IRTOUCH_HIRES] = { 1155dbea4032SLars Poeschel .min_xc = 0x0, 1156dbea4032SLars Poeschel .max_xc = 0x7fff, 1157dbea4032SLars Poeschel .min_yc = 0x0, 1158dbea4032SLars Poeschel .max_yc = 0x7fff, 1159dbea4032SLars Poeschel .rept_size = 8, 1160dbea4032SLars Poeschel .read_data = irtouch_read_data, 1161dbea4032SLars Poeschel }, 1162df561fcdSOndrej Zary #endif 1163a14a8401SOndrej Zary 1164a14a8401SOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK 1165a14a8401SOndrej Zary [DEVTYPE_IDEALTEK] = { 1166a14a8401SOndrej Zary .min_xc = 0x0, 1167a14a8401SOndrej Zary .max_xc = 0x0fff, 1168a14a8401SOndrej Zary .min_yc = 0x0, 1169a14a8401SOndrej Zary .max_yc = 0x0fff, 1170a14a8401SOndrej Zary .rept_size = 8, 1171a14a8401SOndrej Zary .get_pkt_len = idealtek_get_pkt_len, 1172a14a8401SOndrej Zary .read_data = idealtek_read_data, 1173a14a8401SOndrej Zary }, 1174a14a8401SOndrej Zary #endif 11759d5657dbSIlya Frolov 11769d5657dbSIlya Frolov #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH 11779d5657dbSIlya Frolov [DEVTYPE_GENERAL_TOUCH] = { 11789d5657dbSIlya Frolov .min_xc = 0x0, 1179eb083ba2SRoy Yin .max_xc = 0x7fff, 11809d5657dbSIlya Frolov .min_yc = 0x0, 1181eb083ba2SRoy Yin .max_yc = 0x7fff, 11829d5657dbSIlya Frolov .rept_size = 7, 11839d5657dbSIlya Frolov .read_data = general_touch_read_data, 118414e40206SJerrold Jones }, 11859d5657dbSIlya Frolov #endif 11869d5657dbSIlya Frolov 118714e40206SJerrold Jones #ifdef CONFIG_TOUCHSCREEN_USB_GOTOP 118814e40206SJerrold Jones [DEVTYPE_GOTOP] = { 118914e40206SJerrold Jones .min_xc = 0x0, 119014e40206SJerrold Jones .max_xc = 0x03ff, 119114e40206SJerrold Jones .min_yc = 0x0, 119214e40206SJerrold Jones .max_yc = 0x03ff, 119314e40206SJerrold Jones .rept_size = 4, 119414e40206SJerrold Jones .read_data = gotop_read_data, 119514e40206SJerrold Jones }, 119614e40206SJerrold Jones #endif 1197f7370699SJim Persson 1198f7370699SJim Persson #ifdef CONFIG_TOUCHSCREEN_USB_JASTEC 1199f7370699SJim Persson [DEVTYPE_JASTEC] = { 1200f7370699SJim Persson .min_xc = 0x0, 1201f7370699SJim Persson .max_xc = 0x0fff, 1202f7370699SJim Persson .min_yc = 0x0, 1203f7370699SJim Persson .max_yc = 0x0fff, 1204f7370699SJim Persson .rept_size = 4, 1205f7370699SJim Persson .read_data = jastec_read_data, 1206f7370699SJim Persson }, 1207f7370699SJim Persson #endif 12089e3b2583SFlorian Echtler 12099e3b2583SFlorian Echtler #ifdef CONFIG_TOUCHSCREEN_USB_E2I 12109e3b2583SFlorian Echtler [DEVTYPE_E2I] = { 12119e3b2583SFlorian Echtler .min_xc = 0x0, 12129e3b2583SFlorian Echtler .max_xc = 0x7fff, 12139e3b2583SFlorian Echtler .min_yc = 0x0, 12149e3b2583SFlorian Echtler .max_yc = 0x7fff, 12159e3b2583SFlorian Echtler .rept_size = 6, 12169e3b2583SFlorian Echtler .init = e2i_init, 12179e3b2583SFlorian Echtler .read_data = e2i_read_data, 12189e3b2583SFlorian Echtler }, 12199e3b2583SFlorian Echtler #endif 12202330ed18SDaniel Silverstone 12212330ed18SDaniel Silverstone #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC 12222330ed18SDaniel Silverstone [DEVTYPE_ZYTRONIC] = { 12232330ed18SDaniel Silverstone .min_xc = 0x0, 12242330ed18SDaniel Silverstone .max_xc = 0x03ff, 12252330ed18SDaniel Silverstone .min_yc = 0x0, 12262330ed18SDaniel Silverstone .max_yc = 0x03ff, 12272330ed18SDaniel Silverstone .rept_size = 5, 12282330ed18SDaniel Silverstone .read_data = zytronic_read_data, 12292330ed18SDaniel Silverstone .irq_always = true, 12302330ed18SDaniel Silverstone }, 12312330ed18SDaniel Silverstone #endif 1232dbe1420bSPetr Štetiar 123338771bb4SPetr Štetiar #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB 123438771bb4SPetr Štetiar [DEVTYPE_TC45USB] = { 1235dbe1420bSPetr Štetiar .min_xc = 0x0, 1236dbe1420bSPetr Štetiar .max_xc = 0x0fff, 1237dbe1420bSPetr Štetiar .min_yc = 0x0, 1238dbe1420bSPetr Štetiar .max_yc = 0x0fff, 1239dbe1420bSPetr Štetiar .rept_size = 5, 124038771bb4SPetr Štetiar .read_data = tc45usb_read_data, 1241dbe1420bSPetr Štetiar }, 1242dbe1420bSPetr Štetiar #endif 12435197424cSOndrej Zary 12445197424cSOndrej Zary #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO 12455197424cSOndrej Zary [DEVTYPE_NEXIO] = { 1246388bbcadSOndrej Zary .rept_size = 1024, 12475197424cSOndrej Zary .irq_always = true, 12485197424cSOndrej Zary .read_data = nexio_read_data, 1249a8aef622SOliver Neukum .alloc = nexio_alloc, 12505197424cSOndrej Zary .init = nexio_init, 12515197424cSOndrej Zary .exit = nexio_exit, 12525197424cSOndrej Zary }, 12535197424cSOndrej Zary #endif 1254aa87512fSArmando Visconti #ifdef CONFIG_TOUCHSCREEN_USB_EASYTOUCH 1255aa87512fSArmando Visconti [DEVTYPE_ETOUCH] = { 1256aa87512fSArmando Visconti .min_xc = 0x0, 1257aa87512fSArmando Visconti .max_xc = 0x07ff, 1258aa87512fSArmando Visconti .min_yc = 0x0, 1259aa87512fSArmando Visconti .max_yc = 0x07ff, 1260aa87512fSArmando Visconti .rept_size = 16, 1261aa87512fSArmando Visconti .get_pkt_len = etouch_get_pkt_len, 1262aa87512fSArmando Visconti .read_data = etouch_read_data, 1263aa87512fSArmando Visconti }, 1264aa87512fSArmando Visconti #endif 1265d05e84e6SDmitry Torokhov }; 1266d05e84e6SDmitry Torokhov 1267d05e84e6SDmitry Torokhov 1268d05e84e6SDmitry Torokhov /***************************************************************************** 1269d05e84e6SDmitry Torokhov * Generic Part 1270d05e84e6SDmitry Torokhov */ 1271d05e84e6SDmitry Torokhov static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, 1272d05e84e6SDmitry Torokhov unsigned char *pkt, int len) 1273d05e84e6SDmitry Torokhov { 1274*830f06c0SDmitry Torokhov const struct usbtouch_device_info *type = usbtouch->type; 1275d05e84e6SDmitry Torokhov 1276d05e84e6SDmitry Torokhov if (!type->read_data(usbtouch, pkt)) 1277d05e84e6SDmitry Torokhov return; 1278d05e84e6SDmitry Torokhov 1279d05e84e6SDmitry Torokhov input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch); 1280d05e84e6SDmitry Torokhov 1281d05e84e6SDmitry Torokhov if (swap_xy) { 1282d05e84e6SDmitry Torokhov input_report_abs(usbtouch->input, ABS_X, usbtouch->y); 1283d05e84e6SDmitry Torokhov input_report_abs(usbtouch->input, ABS_Y, usbtouch->x); 1284d05e84e6SDmitry Torokhov } else { 1285d05e84e6SDmitry Torokhov input_report_abs(usbtouch->input, ABS_X, usbtouch->x); 1286d05e84e6SDmitry Torokhov input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); 1287d05e84e6SDmitry Torokhov } 1288d05e84e6SDmitry Torokhov if (type->max_press) 1289d05e84e6SDmitry Torokhov input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press); 1290d05e84e6SDmitry Torokhov input_sync(usbtouch->input); 1291d05e84e6SDmitry Torokhov } 1292d05e84e6SDmitry Torokhov 1293d05e84e6SDmitry Torokhov 1294d05e84e6SDmitry Torokhov #ifdef MULTI_PACKET 1295d05e84e6SDmitry Torokhov static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, 1296d05e84e6SDmitry Torokhov unsigned char *pkt, int len) 1297d05e84e6SDmitry Torokhov { 1298d05e84e6SDmitry Torokhov unsigned char *buffer; 1299d05e84e6SDmitry Torokhov int pkt_len, pos, buf_len, tmp; 1300d05e84e6SDmitry Torokhov 1301d05e84e6SDmitry Torokhov /* process buffer */ 1302d05e84e6SDmitry Torokhov if (unlikely(usbtouch->buf_len)) { 1303d05e84e6SDmitry Torokhov /* try to get size */ 1304d05e84e6SDmitry Torokhov pkt_len = usbtouch->type->get_pkt_len( 1305d05e84e6SDmitry Torokhov usbtouch->buffer, usbtouch->buf_len); 1306d05e84e6SDmitry Torokhov 1307d05e84e6SDmitry Torokhov /* drop? */ 1308d05e84e6SDmitry Torokhov if (unlikely(!pkt_len)) 1309d05e84e6SDmitry Torokhov goto out_flush_buf; 1310d05e84e6SDmitry Torokhov 1311d05e84e6SDmitry Torokhov /* need to append -pkt_len bytes before able to get size */ 1312d05e84e6SDmitry Torokhov if (unlikely(pkt_len < 0)) { 1313d05e84e6SDmitry Torokhov int append = -pkt_len; 1314d05e84e6SDmitry Torokhov if (unlikely(append > len)) 1315d05e84e6SDmitry Torokhov append = len; 1316d05e84e6SDmitry Torokhov if (usbtouch->buf_len + append >= usbtouch->type->rept_size) 1317d05e84e6SDmitry Torokhov goto out_flush_buf; 1318d05e84e6SDmitry Torokhov memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, append); 1319d05e84e6SDmitry Torokhov usbtouch->buf_len += append; 1320d05e84e6SDmitry Torokhov 1321d05e84e6SDmitry Torokhov pkt_len = usbtouch->type->get_pkt_len( 1322d05e84e6SDmitry Torokhov usbtouch->buffer, usbtouch->buf_len); 1323d05e84e6SDmitry Torokhov if (pkt_len < 0) 1324d05e84e6SDmitry Torokhov return; 1325d05e84e6SDmitry Torokhov } 1326d05e84e6SDmitry Torokhov 1327d05e84e6SDmitry Torokhov /* append */ 1328d05e84e6SDmitry Torokhov tmp = pkt_len - usbtouch->buf_len; 1329d05e84e6SDmitry Torokhov if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size) 1330d05e84e6SDmitry Torokhov goto out_flush_buf; 1331d05e84e6SDmitry Torokhov memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp); 1332d05e84e6SDmitry Torokhov usbtouch_process_pkt(usbtouch, usbtouch->buffer, pkt_len); 1333d05e84e6SDmitry Torokhov 1334d05e84e6SDmitry Torokhov buffer = pkt + tmp; 1335d05e84e6SDmitry Torokhov buf_len = len - tmp; 1336d05e84e6SDmitry Torokhov } else { 1337d05e84e6SDmitry Torokhov buffer = pkt; 1338d05e84e6SDmitry Torokhov buf_len = len; 1339d05e84e6SDmitry Torokhov } 1340d05e84e6SDmitry Torokhov 1341d05e84e6SDmitry Torokhov /* loop over the received packet, process */ 1342d05e84e6SDmitry Torokhov pos = 0; 1343d05e84e6SDmitry Torokhov while (pos < buf_len) { 1344d05e84e6SDmitry Torokhov /* get packet len */ 134562aa366dSDaniel Ritz pkt_len = usbtouch->type->get_pkt_len(buffer + pos, 134662aa366dSDaniel Ritz buf_len - pos); 1347d05e84e6SDmitry Torokhov 134862aa366dSDaniel Ritz /* unknown packet: skip one byte */ 134962aa366dSDaniel Ritz if (unlikely(!pkt_len)) { 135062aa366dSDaniel Ritz pos++; 135162aa366dSDaniel Ritz continue; 135262aa366dSDaniel Ritz } 1353d05e84e6SDmitry Torokhov 1354d05e84e6SDmitry Torokhov /* full packet: process */ 1355d05e84e6SDmitry Torokhov if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) { 1356d05e84e6SDmitry Torokhov usbtouch_process_pkt(usbtouch, buffer + pos, pkt_len); 1357d05e84e6SDmitry Torokhov } else { 1358d05e84e6SDmitry Torokhov /* incomplete packet: save in buffer */ 1359d05e84e6SDmitry Torokhov memcpy(usbtouch->buffer, buffer + pos, buf_len - pos); 1360d05e84e6SDmitry Torokhov usbtouch->buf_len = buf_len - pos; 1361d05e84e6SDmitry Torokhov return; 1362d05e84e6SDmitry Torokhov } 1363d05e84e6SDmitry Torokhov pos += pkt_len; 1364d05e84e6SDmitry Torokhov } 1365d05e84e6SDmitry Torokhov 1366d05e84e6SDmitry Torokhov out_flush_buf: 1367d05e84e6SDmitry Torokhov usbtouch->buf_len = 0; 1368d05e84e6SDmitry Torokhov return; 1369d05e84e6SDmitry Torokhov } 1370fbb1c922SDmitry Torokhov #else 1371fbb1c922SDmitry Torokhov static void usbtouch_process_multi(struct usbtouch_usb *usbtouch, 1372fbb1c922SDmitry Torokhov unsigned char *pkt, int len) 1373fbb1c922SDmitry Torokhov { 1374fbb1c922SDmitry Torokhov dev_WARN_ONCE(&usbtouch->interface->dev, 1, 1375fbb1c922SDmitry Torokhov "Protocol has ->get_pkt_len() without #define MULTI_PACKET"); 1376fbb1c922SDmitry Torokhov } 1377d05e84e6SDmitry Torokhov #endif 1378d05e84e6SDmitry Torokhov 1379d05e84e6SDmitry Torokhov static void usbtouch_irq(struct urb *urb) 1380d05e84e6SDmitry Torokhov { 1381d05e84e6SDmitry Torokhov struct usbtouch_usb *usbtouch = urb->context; 13820a5ebc88SGreg Kroah-Hartman struct device *dev = &usbtouch->interface->dev; 1383d05e84e6SDmitry Torokhov int retval; 1384d05e84e6SDmitry Torokhov 1385d05e84e6SDmitry Torokhov switch (urb->status) { 1386d05e84e6SDmitry Torokhov case 0: 1387d05e84e6SDmitry Torokhov /* success */ 1388d05e84e6SDmitry Torokhov break; 1389d05e84e6SDmitry Torokhov case -ETIME: 1390d05e84e6SDmitry Torokhov /* this urb is timing out */ 1391b741ab9dSGreg Kroah-Hartman dev_dbg(dev, 1392b741ab9dSGreg Kroah-Hartman "%s - urb timed out - was the device unplugged?\n", 1393ea3e6c59SHarvey Harrison __func__); 1394d05e84e6SDmitry Torokhov return; 1395d05e84e6SDmitry Torokhov case -ECONNRESET: 1396d05e84e6SDmitry Torokhov case -ENOENT: 1397d05e84e6SDmitry Torokhov case -ESHUTDOWN: 13985197424cSOndrej Zary case -EPIPE: 1399d05e84e6SDmitry Torokhov /* this urb is terminated, clean up */ 1400b741ab9dSGreg Kroah-Hartman dev_dbg(dev, "%s - urb shutting down with status: %d\n", 1401ea3e6c59SHarvey Harrison __func__, urb->status); 1402d05e84e6SDmitry Torokhov return; 1403d05e84e6SDmitry Torokhov default: 1404b741ab9dSGreg Kroah-Hartman dev_dbg(dev, "%s - nonzero urb status received: %d\n", 1405ea3e6c59SHarvey Harrison __func__, urb->status); 1406d05e84e6SDmitry Torokhov goto exit; 1407d05e84e6SDmitry Torokhov } 1408d05e84e6SDmitry Torokhov 1409fbb1c922SDmitry Torokhov usbtouch->process_pkt(usbtouch, usbtouch->data, urb->actual_length); 1410d05e84e6SDmitry Torokhov 1411d05e84e6SDmitry Torokhov exit: 14125d9efc59SOliver Neukum usb_mark_last_busy(interface_to_usbdev(usbtouch->interface)); 1413d05e84e6SDmitry Torokhov retval = usb_submit_urb(urb, GFP_ATOMIC); 1414d05e84e6SDmitry Torokhov if (retval) 14150a5ebc88SGreg Kroah-Hartman dev_err(dev, "%s - usb_submit_urb failed with result: %d\n", 1416ea3e6c59SHarvey Harrison __func__, retval); 1417d05e84e6SDmitry Torokhov } 1418d05e84e6SDmitry Torokhov 1419d05e84e6SDmitry Torokhov static int usbtouch_open(struct input_dev *input) 1420d05e84e6SDmitry Torokhov { 1421d05e84e6SDmitry Torokhov struct usbtouch_usb *usbtouch = input_get_drvdata(input); 14225d9efc59SOliver Neukum int r; 1423d05e84e6SDmitry Torokhov 1424fea4d14bSOndrej Zary usbtouch->irq->dev = interface_to_usbdev(usbtouch->interface); 1425d05e84e6SDmitry Torokhov 14265d9efc59SOliver Neukum r = usb_autopm_get_interface(usbtouch->interface) ? -EIO : 0; 14275d9efc59SOliver Neukum if (r < 0) 14285d9efc59SOliver Neukum goto out; 14295d9efc59SOliver Neukum 143012e510dbSMarcus Folkesson mutex_lock(&usbtouch->pm_mutex); 14312330ed18SDaniel Silverstone if (!usbtouch->type->irq_always) { 14325d9efc59SOliver Neukum if (usb_submit_urb(usbtouch->irq, GFP_KERNEL)) { 14335d9efc59SOliver Neukum r = -EIO; 14345d9efc59SOliver Neukum goto out_put; 14355d9efc59SOliver Neukum } 14362330ed18SDaniel Silverstone } 1437d05e84e6SDmitry Torokhov 14385d9efc59SOliver Neukum usbtouch->interface->needs_remote_wakeup = 1; 143985f46fbfSMarcus Folkesson usbtouch->is_open = true; 14405d9efc59SOliver Neukum out_put: 144112e510dbSMarcus Folkesson mutex_unlock(&usbtouch->pm_mutex); 14425d9efc59SOliver Neukum usb_autopm_put_interface(usbtouch->interface); 14435d9efc59SOliver Neukum out: 14445d9efc59SOliver Neukum return r; 1445d05e84e6SDmitry Torokhov } 1446d05e84e6SDmitry Torokhov 1447d05e84e6SDmitry Torokhov static void usbtouch_close(struct input_dev *input) 1448d05e84e6SDmitry Torokhov { 1449d05e84e6SDmitry Torokhov struct usbtouch_usb *usbtouch = input_get_drvdata(input); 14505d9efc59SOliver Neukum int r; 1451d05e84e6SDmitry Torokhov 145212e510dbSMarcus Folkesson mutex_lock(&usbtouch->pm_mutex); 14532330ed18SDaniel Silverstone if (!usbtouch->type->irq_always) 1454d05e84e6SDmitry Torokhov usb_kill_urb(usbtouch->irq); 145585f46fbfSMarcus Folkesson usbtouch->is_open = false; 145612e510dbSMarcus Folkesson mutex_unlock(&usbtouch->pm_mutex); 145712e510dbSMarcus Folkesson 14585d9efc59SOliver Neukum r = usb_autopm_get_interface(usbtouch->interface); 14595d9efc59SOliver Neukum usbtouch->interface->needs_remote_wakeup = 0; 14605d9efc59SOliver Neukum if (!r) 14615d9efc59SOliver Neukum usb_autopm_put_interface(usbtouch->interface); 1462d05e84e6SDmitry Torokhov } 1463d05e84e6SDmitry Torokhov 1464ed4299e1SOliver Neukum static int usbtouch_suspend 1465ed4299e1SOliver Neukum (struct usb_interface *intf, pm_message_t message) 1466ed4299e1SOliver Neukum { 1467ed4299e1SOliver Neukum struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 1468ed4299e1SOliver Neukum 1469ed4299e1SOliver Neukum usb_kill_urb(usbtouch->irq); 1470ed4299e1SOliver Neukum 1471ed4299e1SOliver Neukum return 0; 1472ed4299e1SOliver Neukum } 1473ed4299e1SOliver Neukum 1474ed4299e1SOliver Neukum static int usbtouch_resume(struct usb_interface *intf) 1475ed4299e1SOliver Neukum { 1476ed4299e1SOliver Neukum struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 1477ed4299e1SOliver Neukum int result = 0; 1478ed4299e1SOliver Neukum 147912e510dbSMarcus Folkesson mutex_lock(&usbtouch->pm_mutex); 148085f46fbfSMarcus Folkesson if (usbtouch->is_open || usbtouch->type->irq_always) 1481ed4299e1SOliver Neukum result = usb_submit_urb(usbtouch->irq, GFP_NOIO); 148212e510dbSMarcus Folkesson mutex_unlock(&usbtouch->pm_mutex); 1483ed4299e1SOliver Neukum 1484ed4299e1SOliver Neukum return result; 1485ed4299e1SOliver Neukum } 1486d05e84e6SDmitry Torokhov 1487a8aef622SOliver Neukum static int usbtouch_reset_resume(struct usb_interface *intf) 1488a8aef622SOliver Neukum { 1489a8aef622SOliver Neukum struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 1490a8aef622SOliver Neukum int err = 0; 1491a8aef622SOliver Neukum 1492a8aef622SOliver Neukum /* reinit the device */ 1493a8aef622SOliver Neukum if (usbtouch->type->init) { 1494a8aef622SOliver Neukum err = usbtouch->type->init(usbtouch); 1495a8aef622SOliver Neukum if (err) { 14960a5ebc88SGreg Kroah-Hartman dev_dbg(&intf->dev, 1497b741ab9dSGreg Kroah-Hartman "%s - type->init() failed, err: %d\n", 1498a8aef622SOliver Neukum __func__, err); 1499a8aef622SOliver Neukum return err; 1500a8aef622SOliver Neukum } 1501a8aef622SOliver Neukum } 1502a8aef622SOliver Neukum 1503a8aef622SOliver Neukum /* restart IO if needed */ 150412e510dbSMarcus Folkesson mutex_lock(&usbtouch->pm_mutex); 150585f46fbfSMarcus Folkesson if (usbtouch->is_open) 1506a8aef622SOliver Neukum err = usb_submit_urb(usbtouch->irq, GFP_NOIO); 150712e510dbSMarcus Folkesson mutex_unlock(&usbtouch->pm_mutex); 1508a8aef622SOliver Neukum 1509a8aef622SOliver Neukum return err; 1510a8aef622SOliver Neukum } 1511a8aef622SOliver Neukum 1512d05e84e6SDmitry Torokhov static void usbtouch_free_buffers(struct usb_device *udev, 1513d05e84e6SDmitry Torokhov struct usbtouch_usb *usbtouch) 1514d05e84e6SDmitry Torokhov { 15154ef38351SChristian Engelmayer usb_free_coherent(udev, usbtouch->data_size, 1516d05e84e6SDmitry Torokhov usbtouch->data, usbtouch->data_dma); 1517d05e84e6SDmitry Torokhov kfree(usbtouch->buffer); 1518d05e84e6SDmitry Torokhov } 1519d05e84e6SDmitry Torokhov 1520f4a5e359SOndrej Zary static struct usb_endpoint_descriptor * 1521f4a5e359SOndrej Zary usbtouch_get_input_endpoint(struct usb_host_interface *interface) 1522f4a5e359SOndrej Zary { 1523f4a5e359SOndrej Zary int i; 1524f4a5e359SOndrej Zary 1525f4a5e359SOndrej Zary for (i = 0; i < interface->desc.bNumEndpoints; i++) 1526f4a5e359SOndrej Zary if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) 1527f4a5e359SOndrej Zary return &interface->endpoint[i].desc; 1528f4a5e359SOndrej Zary 1529f4a5e359SOndrej Zary return NULL; 1530f4a5e359SOndrej Zary } 1531d05e84e6SDmitry Torokhov 1532d05e84e6SDmitry Torokhov static int usbtouch_probe(struct usb_interface *intf, 1533d05e84e6SDmitry Torokhov const struct usb_device_id *id) 1534d05e84e6SDmitry Torokhov { 1535d05e84e6SDmitry Torokhov struct usbtouch_usb *usbtouch; 1536d05e84e6SDmitry Torokhov struct input_dev *input_dev; 1537d05e84e6SDmitry Torokhov struct usb_endpoint_descriptor *endpoint; 1538d05e84e6SDmitry Torokhov struct usb_device *udev = interface_to_usbdev(intf); 1539*830f06c0SDmitry Torokhov const struct usbtouch_device_info *type; 1540d05e84e6SDmitry Torokhov int err = -ENOMEM; 1541d05e84e6SDmitry Torokhov 1542ec42d448SDaniel Ritz /* some devices are ignored */ 1543ec42d448SDaniel Ritz if (id->driver_info == DEVTYPE_IGNORE) 1544ec42d448SDaniel Ritz return -ENODEV; 1545ec42d448SDaniel Ritz 1546039d4ed3SJohan Hovold if (id->driver_info >= ARRAY_SIZE(usbtouch_dev_info)) 1547039d4ed3SJohan Hovold return -ENODEV; 1548039d4ed3SJohan Hovold 1549f4a5e359SOndrej Zary endpoint = usbtouch_get_input_endpoint(intf->cur_altsetting); 1550f4a5e359SOndrej Zary if (!endpoint) 1551f4a5e359SOndrej Zary return -ENXIO; 1552d05e84e6SDmitry Torokhov 1553f81d03d4SErick Archer usbtouch = kzalloc(sizeof(*usbtouch), GFP_KERNEL); 1554d05e84e6SDmitry Torokhov input_dev = input_allocate_device(); 1555d05e84e6SDmitry Torokhov if (!usbtouch || !input_dev) 1556d05e84e6SDmitry Torokhov goto out_free; 1557d05e84e6SDmitry Torokhov 1558b55d996fSOliver Neukum mutex_init(&usbtouch->pm_mutex); 1559b55d996fSOliver Neukum 1560d05e84e6SDmitry Torokhov type = &usbtouch_dev_info[id->driver_info]; 1561d05e84e6SDmitry Torokhov usbtouch->type = type; 1562d05e84e6SDmitry Torokhov 15634ef38351SChristian Engelmayer usbtouch->data_size = type->rept_size; 15644ef38351SChristian Engelmayer if (type->get_pkt_len) { 15654ef38351SChristian Engelmayer /* 15664ef38351SChristian Engelmayer * When dealing with variable-length packets we should 15674ef38351SChristian Engelmayer * not request more than wMaxPacketSize bytes at once 15684ef38351SChristian Engelmayer * as we do not know if there is more data coming or 15694ef38351SChristian Engelmayer * we filled exactly wMaxPacketSize bytes and there is 15704ef38351SChristian Engelmayer * nothing else. 15714ef38351SChristian Engelmayer */ 15724ef38351SChristian Engelmayer usbtouch->data_size = min(usbtouch->data_size, 15734ef38351SChristian Engelmayer usb_endpoint_maxp(endpoint)); 15744ef38351SChristian Engelmayer } 15754ef38351SChristian Engelmayer 15764ef38351SChristian Engelmayer usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size, 1577d05e84e6SDmitry Torokhov GFP_KERNEL, &usbtouch->data_dma); 1578d05e84e6SDmitry Torokhov if (!usbtouch->data) 1579d05e84e6SDmitry Torokhov goto out_free; 1580d05e84e6SDmitry Torokhov 158162aa366dSDaniel Ritz if (type->get_pkt_len) { 1582d05e84e6SDmitry Torokhov usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL); 1583d05e84e6SDmitry Torokhov if (!usbtouch->buffer) 1584d05e84e6SDmitry Torokhov goto out_free_buffers; 1585fbb1c922SDmitry Torokhov usbtouch->process_pkt = usbtouch_process_multi; 1586fbb1c922SDmitry Torokhov } else { 1587fbb1c922SDmitry Torokhov usbtouch->process_pkt = usbtouch_process_pkt; 1588d05e84e6SDmitry Torokhov } 1589d05e84e6SDmitry Torokhov 1590d05e84e6SDmitry Torokhov usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL); 1591d05e84e6SDmitry Torokhov if (!usbtouch->irq) { 1592b741ab9dSGreg Kroah-Hartman dev_dbg(&intf->dev, 1593b741ab9dSGreg Kroah-Hartman "%s - usb_alloc_urb failed: usbtouch->irq\n", __func__); 1594d05e84e6SDmitry Torokhov goto out_free_buffers; 1595d05e84e6SDmitry Torokhov } 1596d05e84e6SDmitry Torokhov 1597fea4d14bSOndrej Zary usbtouch->interface = intf; 1598d05e84e6SDmitry Torokhov usbtouch->input = input_dev; 1599d05e84e6SDmitry Torokhov 1600d05e84e6SDmitry Torokhov if (udev->manufacturer) 1601a9f08ad7SWolfram Sang strscpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name)); 1602d05e84e6SDmitry Torokhov 1603d05e84e6SDmitry Torokhov if (udev->product) { 1604d05e84e6SDmitry Torokhov if (udev->manufacturer) 1605d05e84e6SDmitry Torokhov strlcat(usbtouch->name, " ", sizeof(usbtouch->name)); 1606d05e84e6SDmitry Torokhov strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name)); 1607d05e84e6SDmitry Torokhov } 1608d05e84e6SDmitry Torokhov 1609d05e84e6SDmitry Torokhov if (!strlen(usbtouch->name)) 1610d05e84e6SDmitry Torokhov snprintf(usbtouch->name, sizeof(usbtouch->name), 1611d05e84e6SDmitry Torokhov "USB Touchscreen %04x:%04x", 1612d05e84e6SDmitry Torokhov le16_to_cpu(udev->descriptor.idVendor), 1613d05e84e6SDmitry Torokhov le16_to_cpu(udev->descriptor.idProduct)); 1614d05e84e6SDmitry Torokhov 1615d05e84e6SDmitry Torokhov usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys)); 16167b6dff98SVladimir Shebordaev strlcat(usbtouch->phys, "/input0", sizeof(usbtouch->phys)); 1617d05e84e6SDmitry Torokhov 1618d05e84e6SDmitry Torokhov input_dev->name = usbtouch->name; 1619d05e84e6SDmitry Torokhov input_dev->phys = usbtouch->phys; 1620d05e84e6SDmitry Torokhov usb_to_input_id(udev, &input_dev->id); 1621d05e84e6SDmitry Torokhov input_dev->dev.parent = &intf->dev; 1622d05e84e6SDmitry Torokhov 1623d05e84e6SDmitry Torokhov input_set_drvdata(input_dev, usbtouch); 1624d05e84e6SDmitry Torokhov 1625d05e84e6SDmitry Torokhov input_dev->open = usbtouch_open; 1626d05e84e6SDmitry Torokhov input_dev->close = usbtouch_close; 1627d05e84e6SDmitry Torokhov 16287b19ada2SJiri Slaby input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); 16297b19ada2SJiri Slaby input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 1630d05e84e6SDmitry Torokhov input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0); 1631d05e84e6SDmitry Torokhov input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); 1632d05e84e6SDmitry Torokhov if (type->max_press) 1633d05e84e6SDmitry Torokhov input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, 1634d05e84e6SDmitry Torokhov type->max_press, 0, 0); 1635d05e84e6SDmitry Torokhov 16365197424cSOndrej Zary if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT) 1637fea4d14bSOndrej Zary usb_fill_int_urb(usbtouch->irq, udev, 1638fea4d14bSOndrej Zary usb_rcvintpipe(udev, endpoint->bEndpointAddress), 16394ef38351SChristian Engelmayer usbtouch->data, usbtouch->data_size, 1640d05e84e6SDmitry Torokhov usbtouch_irq, usbtouch, endpoint->bInterval); 16415197424cSOndrej Zary else 16425197424cSOndrej Zary usb_fill_bulk_urb(usbtouch->irq, udev, 16435197424cSOndrej Zary usb_rcvbulkpipe(udev, endpoint->bEndpointAddress), 16444ef38351SChristian Engelmayer usbtouch->data, usbtouch->data_size, 16455197424cSOndrej Zary usbtouch_irq, usbtouch); 1646d05e84e6SDmitry Torokhov 1647fea4d14bSOndrej Zary usbtouch->irq->dev = udev; 1648d05e84e6SDmitry Torokhov usbtouch->irq->transfer_dma = usbtouch->data_dma; 1649d05e84e6SDmitry Torokhov usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 1650d05e84e6SDmitry Torokhov 1651a8aef622SOliver Neukum /* device specific allocations */ 1652a8aef622SOliver Neukum if (type->alloc) { 1653a8aef622SOliver Neukum err = type->alloc(usbtouch); 1654a8aef622SOliver Neukum if (err) { 1655b741ab9dSGreg Kroah-Hartman dev_dbg(&intf->dev, 1656b741ab9dSGreg Kroah-Hartman "%s - type->alloc() failed, err: %d\n", 1657b741ab9dSGreg Kroah-Hartman __func__, err); 1658a8aef622SOliver Neukum goto out_free_urb; 1659a8aef622SOliver Neukum } 1660a8aef622SOliver Neukum } 1661a8aef622SOliver Neukum 1662a8aef622SOliver Neukum /* device specific initialisation*/ 1663d05e84e6SDmitry Torokhov if (type->init) { 1664d05e84e6SDmitry Torokhov err = type->init(usbtouch); 1665d05e84e6SDmitry Torokhov if (err) { 1666b741ab9dSGreg Kroah-Hartman dev_dbg(&intf->dev, 1667b741ab9dSGreg Kroah-Hartman "%s - type->init() failed, err: %d\n", 1668b741ab9dSGreg Kroah-Hartman __func__, err); 1669a8aef622SOliver Neukum goto out_do_exit; 1670d05e84e6SDmitry Torokhov } 1671d05e84e6SDmitry Torokhov } 1672d05e84e6SDmitry Torokhov 1673d05e84e6SDmitry Torokhov err = input_register_device(usbtouch->input); 1674d05e84e6SDmitry Torokhov if (err) { 1675b741ab9dSGreg Kroah-Hartman dev_dbg(&intf->dev, 1676b741ab9dSGreg Kroah-Hartman "%s - input_register_device failed, err: %d\n", 1677b741ab9dSGreg Kroah-Hartman __func__, err); 16785197424cSOndrej Zary goto out_do_exit; 1679d05e84e6SDmitry Torokhov } 1680d05e84e6SDmitry Torokhov 1681d05e84e6SDmitry Torokhov usb_set_intfdata(intf, usbtouch); 1682d05e84e6SDmitry Torokhov 16831e87a430SOndrej Zary if (usbtouch->type->irq_always) { 16845d9efc59SOliver Neukum /* this can't fail */ 16855d9efc59SOliver Neukum usb_autopm_get_interface(intf); 16861e87a430SOndrej Zary err = usb_submit_urb(usbtouch->irq, GFP_KERNEL); 16871e87a430SOndrej Zary if (err) { 16885d9efc59SOliver Neukum usb_autopm_put_interface(intf); 16890a5ebc88SGreg Kroah-Hartman dev_err(&intf->dev, 1690e27ad0feSGreg Kroah-Hartman "%s - usb_submit_urb failed with result: %d\n", 16911e87a430SOndrej Zary __func__, err); 16921e87a430SOndrej Zary goto out_unregister_input; 16931e87a430SOndrej Zary } 16941e87a430SOndrej Zary } 16952330ed18SDaniel Silverstone 1696d05e84e6SDmitry Torokhov return 0; 1697d05e84e6SDmitry Torokhov 16981e87a430SOndrej Zary out_unregister_input: 16991e87a430SOndrej Zary input_unregister_device(input_dev); 17001e87a430SOndrej Zary input_dev = NULL; 17015197424cSOndrej Zary out_do_exit: 17025197424cSOndrej Zary if (type->exit) 17035197424cSOndrej Zary type->exit(usbtouch); 17041e87a430SOndrej Zary out_free_urb: 17051e87a430SOndrej Zary usb_free_urb(usbtouch->irq); 1706d05e84e6SDmitry Torokhov out_free_buffers: 1707d05e84e6SDmitry Torokhov usbtouch_free_buffers(udev, usbtouch); 1708d05e84e6SDmitry Torokhov out_free: 1709d05e84e6SDmitry Torokhov input_free_device(input_dev); 1710d05e84e6SDmitry Torokhov kfree(usbtouch); 1711d05e84e6SDmitry Torokhov return err; 1712d05e84e6SDmitry Torokhov } 1713d05e84e6SDmitry Torokhov 1714d05e84e6SDmitry Torokhov static void usbtouch_disconnect(struct usb_interface *intf) 1715d05e84e6SDmitry Torokhov { 1716d05e84e6SDmitry Torokhov struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); 1717d05e84e6SDmitry Torokhov 1718d05e84e6SDmitry Torokhov if (!usbtouch) 1719d05e84e6SDmitry Torokhov return; 1720d05e84e6SDmitry Torokhov 17210a5ebc88SGreg Kroah-Hartman dev_dbg(&intf->dev, 1722b741ab9dSGreg Kroah-Hartman "%s - usbtouch is initialized, cleaning up\n", __func__); 1723b741ab9dSGreg Kroah-Hartman 1724d05e84e6SDmitry Torokhov usb_set_intfdata(intf, NULL); 1725722232bcSOliver Neukum /* this will stop IO via close */ 1726d05e84e6SDmitry Torokhov input_unregister_device(usbtouch->input); 1727d05e84e6SDmitry Torokhov usb_free_urb(usbtouch->irq); 17285197424cSOndrej Zary if (usbtouch->type->exit) 17295197424cSOndrej Zary usbtouch->type->exit(usbtouch); 1730d05e84e6SDmitry Torokhov usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch); 1731d05e84e6SDmitry Torokhov kfree(usbtouch); 1732d05e84e6SDmitry Torokhov } 1733d05e84e6SDmitry Torokhov 17346797e19dSDmitry Torokhov static const struct attribute_group *usbtouch_groups[] = { 17356797e19dSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_3M 17366797e19dSDmitry Torokhov &mtouch_attr_group, 17376797e19dSDmitry Torokhov #endif 17386797e19dSDmitry Torokhov NULL 17396797e19dSDmitry Torokhov }; 17406797e19dSDmitry Torokhov 1741ca95a47eSDmitry Torokhov static const struct usb_device_id usbtouch_devices[] = { 1742ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX 1743ca95a47eSDmitry Torokhov /* ignore the HID capable devices, handled by usbhid */ 1744ca95a47eSDmitry Torokhov {USB_DEVICE_INTERFACE_CLASS(0x0eef, 0x0001, USB_INTERFACE_CLASS_HID), 1745ca95a47eSDmitry Torokhov .driver_info = DEVTYPE_IGNORE}, 1746ca95a47eSDmitry Torokhov {USB_DEVICE_INTERFACE_CLASS(0x0eef, 0x0002, USB_INTERFACE_CLASS_HID), 1747ca95a47eSDmitry Torokhov .driver_info = DEVTYPE_IGNORE}, 1748ca95a47eSDmitry Torokhov 1749ca95a47eSDmitry Torokhov /* normal device IDs */ 1750ca95a47eSDmitry Torokhov {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, 1751ca95a47eSDmitry Torokhov {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX}, 1752ca95a47eSDmitry Torokhov {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, 1753ca95a47eSDmitry Torokhov {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, 1754ca95a47eSDmitry Torokhov {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, 1755ca95a47eSDmitry Torokhov {USB_DEVICE(0x1234, 0x0001), .driver_info = DEVTYPE_EGALAX}, 1756ca95a47eSDmitry Torokhov {USB_DEVICE(0x1234, 0x0002), .driver_info = DEVTYPE_EGALAX}, 1757ca95a47eSDmitry Torokhov #endif 1758ca95a47eSDmitry Torokhov 1759ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_PANJIT 1760ca95a47eSDmitry Torokhov {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT}, 1761ca95a47eSDmitry Torokhov {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT}, 1762ca95a47eSDmitry Torokhov {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT}, 1763ca95a47eSDmitry Torokhov {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT}, 1764ca95a47eSDmitry Torokhov #endif 1765ca95a47eSDmitry Torokhov 1766ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_3M 1767ca95a47eSDmitry Torokhov {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M}, 1768ca95a47eSDmitry Torokhov #endif 1769ca95a47eSDmitry Torokhov 1770ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_ITM 1771ca95a47eSDmitry Torokhov {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, 1772ca95a47eSDmitry Torokhov {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, 1773ca95a47eSDmitry Torokhov #endif 1774ca95a47eSDmitry Torokhov 1775ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO 1776ca95a47eSDmitry Torokhov {USB_DEVICE(0x1234, 0x5678), .driver_info = DEVTYPE_ETURBO}, 1777ca95a47eSDmitry Torokhov #endif 1778ca95a47eSDmitry Torokhov 1779ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_GUNZE 1780ca95a47eSDmitry Torokhov {USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE}, 1781ca95a47eSDmitry Torokhov #endif 1782ca95a47eSDmitry Torokhov 1783ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_DMC_TSC10 1784ca95a47eSDmitry Torokhov {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10}, 1785ca95a47eSDmitry Torokhov #endif 1786ca95a47eSDmitry Torokhov 1787ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH 1788ca95a47eSDmitry Torokhov {USB_DEVICE(0x255e, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, 1789ca95a47eSDmitry Torokhov {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, 1790ca95a47eSDmitry Torokhov {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, 1791ca95a47eSDmitry Torokhov {USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES}, 1792ca95a47eSDmitry Torokhov #endif 1793ca95a47eSDmitry Torokhov 1794ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_IDEALTEK 1795ca95a47eSDmitry Torokhov {USB_DEVICE(0x1391, 0x1000), .driver_info = DEVTYPE_IDEALTEK}, 1796ca95a47eSDmitry Torokhov #endif 1797ca95a47eSDmitry Torokhov 1798ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH 1799ca95a47eSDmitry Torokhov {USB_DEVICE(0x0dfc, 0x0001), .driver_info = DEVTYPE_GENERAL_TOUCH}, 1800ca95a47eSDmitry Torokhov #endif 1801ca95a47eSDmitry Torokhov 1802ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_GOTOP 1803ca95a47eSDmitry Torokhov {USB_DEVICE(0x08f2, 0x007f), .driver_info = DEVTYPE_GOTOP}, 1804ca95a47eSDmitry Torokhov {USB_DEVICE(0x08f2, 0x00ce), .driver_info = DEVTYPE_GOTOP}, 1805ca95a47eSDmitry Torokhov {USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP}, 1806ca95a47eSDmitry Torokhov #endif 1807ca95a47eSDmitry Torokhov 1808ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_JASTEC 1809ca95a47eSDmitry Torokhov {USB_DEVICE(0x0f92, 0x0001), .driver_info = DEVTYPE_JASTEC}, 1810ca95a47eSDmitry Torokhov #endif 1811ca95a47eSDmitry Torokhov 1812ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_E2I 1813ca95a47eSDmitry Torokhov {USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I}, 1814ca95a47eSDmitry Torokhov #endif 1815ca95a47eSDmitry Torokhov 1816ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC 1817ca95a47eSDmitry Torokhov {USB_DEVICE(0x14c8, 0x0003), .driver_info = DEVTYPE_ZYTRONIC}, 1818ca95a47eSDmitry Torokhov #endif 1819ca95a47eSDmitry Torokhov 1820ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB 1821ca95a47eSDmitry Torokhov /* TC5UH */ 1822ca95a47eSDmitry Torokhov {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC45USB}, 1823ca95a47eSDmitry Torokhov /* TC4UM */ 1824ca95a47eSDmitry Torokhov {USB_DEVICE(0x0664, 0x0306), .driver_info = DEVTYPE_TC45USB}, 1825ca95a47eSDmitry Torokhov #endif 1826ca95a47eSDmitry Torokhov 1827ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO 1828ca95a47eSDmitry Torokhov /* data interface only */ 1829ca95a47eSDmitry Torokhov {USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00), 1830ca95a47eSDmitry Torokhov .driver_info = DEVTYPE_NEXIO}, 1831ca95a47eSDmitry Torokhov {USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00), 1832ca95a47eSDmitry Torokhov .driver_info = DEVTYPE_NEXIO}, 1833ca95a47eSDmitry Torokhov #endif 1834ca95a47eSDmitry Torokhov 1835ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_ELO 1836ca95a47eSDmitry Torokhov {USB_DEVICE(0x04e7, 0x0020), .driver_info = DEVTYPE_ELO}, 1837ca95a47eSDmitry Torokhov #endif 1838ca95a47eSDmitry Torokhov 1839ca95a47eSDmitry Torokhov #ifdef CONFIG_TOUCHSCREEN_USB_EASYTOUCH 1840ca95a47eSDmitry Torokhov {USB_DEVICE(0x7374, 0x0001), .driver_info = DEVTYPE_ETOUCH}, 1841ca95a47eSDmitry Torokhov #endif 1842ca95a47eSDmitry Torokhov 1843ca95a47eSDmitry Torokhov {} 1844ca95a47eSDmitry Torokhov }; 1845d05e84e6SDmitry Torokhov MODULE_DEVICE_TABLE(usb, usbtouch_devices); 1846d05e84e6SDmitry Torokhov 1847d05e84e6SDmitry Torokhov static struct usb_driver usbtouch_driver = { 1848d05e84e6SDmitry Torokhov .name = "usbtouchscreen", 1849d05e84e6SDmitry Torokhov .probe = usbtouch_probe, 1850d05e84e6SDmitry Torokhov .disconnect = usbtouch_disconnect, 1851ed4299e1SOliver Neukum .suspend = usbtouch_suspend, 1852ed4299e1SOliver Neukum .resume = usbtouch_resume, 1853a8aef622SOliver Neukum .reset_resume = usbtouch_reset_resume, 1854d05e84e6SDmitry Torokhov .id_table = usbtouch_devices, 18556797e19dSDmitry Torokhov .dev_groups = usbtouch_groups, 18565d9efc59SOliver Neukum .supports_autosuspend = 1, 1857d05e84e6SDmitry Torokhov }; 1858d05e84e6SDmitry Torokhov 185908642e7cSGreg Kroah-Hartman module_usb_driver(usbtouch_driver); 1860d05e84e6SDmitry Torokhov 1861698c03b4SJulia Lawall MODULE_AUTHOR("Daniel Ritz <daniel.ritz@gmx.ch>"); 1862698c03b4SJulia Lawall MODULE_DESCRIPTION("USB Touchscreen Driver"); 1863d05e84e6SDmitry Torokhov MODULE_LICENSE("GPL"); 1864d05e84e6SDmitry Torokhov 1865d05e84e6SDmitry Torokhov MODULE_ALIAS("touchkitusb"); 1866d05e84e6SDmitry Torokhov MODULE_ALIAS("itmtouch"); 1867d05e84e6SDmitry Torokhov MODULE_ALIAS("mtouchusb"); 1868