diff options
| author | Ondrej Zary <linux@rainbow-software.org> | 2010-02-04 03:17:18 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-02-04 03:21:56 -0500 |
| commit | 5197424cdcccd2b0b1922babb93969b2515c43ce (patch) | |
| tree | 0dc1d6adda483519c20b3af650c2dcb6683d7e25 /drivers/input/touchscreen | |
| parent | f4a5e359c4bafc2269766ccd74256024160ed7ac (diff) | |
Input: usbtouchscreen - add NEXIO (or iNexio) support
Add support for NEXIO (or iNexio) USB touchscreens to usbtouchscreen
driver. Tested with NEX170MRT 17" LCD monitor with integrated touchscreen
(with xserver-xorg-input-evtouch 0.8.8-1):
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 54 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=02(comm.) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=1870 ProdID=0001 Rev= 1.00
S: Manufacturer=iNexio
S: Product=iNexio USB
C:* #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=00 Driver=(none)
E: Ad=83(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=(none)
E: Ad=01(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
No datasheet is available, this was written by capturing some data with
SniffUSB in Windows: http://www.rainbow-software.org/linux_files/nexio/
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/touchscreen')
| -rw-r--r-- | drivers/input/touchscreen/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/input/touchscreen/usbtouchscreen.c | 261 |
2 files changed, 264 insertions, 2 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index dfafc76da4fb..a1e2d845f680 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -537,6 +537,11 @@ config TOUCHSCREEN_USB_ETT_TC5UH | |||
| 537 | bool "ET&T TC5UH touchscreen controler support" if EMBEDDED | 537 | bool "ET&T TC5UH touchscreen controler support" if EMBEDDED |
| 538 | depends on TOUCHSCREEN_USB_COMPOSITE | 538 | depends on TOUCHSCREEN_USB_COMPOSITE |
| 539 | 539 | ||
| 540 | config TOUCHSCREEN_USB_NEXIO | ||
| 541 | default y | ||
| 542 | bool "NEXIO/iNexio device support" if EMBEDDED | ||
| 543 | depends on TOUCHSCREEN_USB_COMPOSITE | ||
| 544 | |||
| 540 | config TOUCHSCREEN_TOUCHIT213 | 545 | config TOUCHSCREEN_TOUCHIT213 |
| 541 | tristate "Sahara TouchIT-213 touchscreen" | 546 | tristate "Sahara TouchIT-213 touchscreen" |
| 542 | select SERIO | 547 | select SERIO |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index a2a82351a42f..07656efee654 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | * - GoTop Super_Q2/GogoPen/PenPower tablets | 15 | * - GoTop Super_Q2/GogoPen/PenPower tablets |
| 16 | * - JASTEC USB touch controller/DigiTech DTR-02U | 16 | * - JASTEC USB touch controller/DigiTech DTR-02U |
| 17 | * - Zytronic capacitive touchscreen | 17 | * - Zytronic capacitive touchscreen |
| 18 | * - NEXIO/iNexio | ||
| 18 | * | 19 | * |
| 19 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> | 20 | * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch> |
| 20 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | 21 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) |
| @@ -95,6 +96,7 @@ struct usbtouch_device_info { | |||
| 95 | 96 | ||
| 96 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); | 97 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); |
| 97 | int (*init) (struct usbtouch_usb *usbtouch); | 98 | int (*init) (struct usbtouch_usb *usbtouch); |
| 99 | void (*exit) (struct usbtouch_usb *usbtouch); | ||
| 98 | }; | 100 | }; |
| 99 | 101 | ||
| 100 | /* a usbtouch device */ | 102 | /* a usbtouch device */ |
| @@ -109,6 +111,7 @@ struct usbtouch_usb { | |||
| 109 | struct usbtouch_device_info *type; | 111 | struct usbtouch_device_info *type; |
| 110 | char name[128]; | 112 | char name[128]; |
| 111 | char phys[64]; | 113 | char phys[64]; |
| 114 | void *priv; | ||
| 112 | 115 | ||
| 113 | int x, y; | 116 | int x, y; |
| 114 | int touch, press; | 117 | int touch, press; |
| @@ -133,6 +136,7 @@ enum { | |||
| 133 | DEVTYPE_E2I, | 136 | DEVTYPE_E2I, |
| 134 | DEVTYPE_ZYTRONIC, | 137 | DEVTYPE_ZYTRONIC, |
| 135 | DEVTYPE_TC5UH, | 138 | DEVTYPE_TC5UH, |
| 139 | DEVTYPE_NEXIO, | ||
| 136 | }; | 140 | }; |
| 137 | 141 | ||
| 138 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 142 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
| @@ -222,6 +226,14 @@ static const struct usb_device_id usbtouch_devices[] = { | |||
| 222 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, | 226 | {USB_DEVICE(0x0664, 0x0309), .driver_info = DEVTYPE_TC5UH}, |
| 223 | #endif | 227 | #endif |
| 224 | 228 | ||
| 229 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
| 230 | /* data interface only */ | ||
| 231 | {USB_DEVICE_AND_INTERFACE_INFO(0x10f0, 0x2002, 0x0a, 0x00, 0x00), | ||
| 232 | .driver_info = DEVTYPE_NEXIO}, | ||
| 233 | {USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00), | ||
| 234 | .driver_info = DEVTYPE_NEXIO}, | ||
| 235 | #endif | ||
| 236 | |||
| 225 | {} | 237 | {} |
| 226 | }; | 238 | }; |
| 227 | 239 | ||
| @@ -692,6 +704,229 @@ static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
| 692 | #endif | 704 | #endif |
| 693 | 705 | ||
| 694 | /***************************************************************************** | 706 | /***************************************************************************** |
| 707 | * NEXIO Part | ||
| 708 | */ | ||
| 709 | #ifdef CONFIG_TOUCHSCREEN_USB_NEXIO | ||
| 710 | |||
| 711 | #define NEXIO_TIMEOUT 5000 | ||
| 712 | #define NEXIO_BUFSIZE 1024 | ||
| 713 | #define NEXIO_THRESHOLD 50 | ||
| 714 | |||
| 715 | struct nexio_priv { | ||
| 716 | struct urb *ack; | ||
| 717 | unsigned char *ack_buf; | ||
| 718 | }; | ||
| 719 | |||
| 720 | struct nexio_touch_packet { | ||
| 721 | u8 flags; /* 0xe1 = touch, 0xe1 = release */ | ||
| 722 | __be16 data_len; /* total bytes of touch data */ | ||
| 723 | __be16 x_len; /* bytes for X axis */ | ||
| 724 | __be16 y_len; /* bytes for Y axis */ | ||
| 725 | u8 data[]; | ||
| 726 | } __attribute__ ((packed)); | ||
| 727 | |||
| 728 | static unsigned char nexio_ack_pkt[2] = { 0xaa, 0x02 }; | ||
| 729 | static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f }; | ||
| 730 | |||
| 731 | static void nexio_ack_complete(struct urb *urb) | ||
| 732 | { | ||
| 733 | } | ||
| 734 | |||
| 735 | static int nexio_init(struct usbtouch_usb *usbtouch) | ||
| 736 | { | ||
| 737 | struct usb_device *dev = interface_to_usbdev(usbtouch->interface); | ||
| 738 | struct usb_host_interface *interface = usbtouch->interface->cur_altsetting; | ||
| 739 | struct nexio_priv *priv; | ||
| 740 | int ret = -ENOMEM; | ||
| 741 | int actual_len, i; | ||
| 742 | unsigned char *buf; | ||
| 743 | char *firmware_ver = NULL, *device_name = NULL; | ||
| 744 | int input_ep = 0, output_ep = 0; | ||
| 745 | |||
| 746 | /* find first input and output endpoint */ | ||
| 747 | for (i = 0; i < interface->desc.bNumEndpoints; i++) { | ||
| 748 | if (!input_ep && | ||
| 749 | usb_endpoint_dir_in(&interface->endpoint[i].desc)) | ||
| 750 | input_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
| 751 | if (!output_ep && | ||
| 752 | usb_endpoint_dir_out(&interface->endpoint[i].desc)) | ||
| 753 | output_ep = interface->endpoint[i].desc.bEndpointAddress; | ||
| 754 | } | ||
| 755 | if (!input_ep || !output_ep) | ||
| 756 | return -ENXIO; | ||
| 757 | |||
| 758 | buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL); | ||
| 759 | if (!buf) | ||
| 760 | goto out_buf; | ||
| 761 | |||
| 762 | /* two empty reads */ | ||
| 763 | for (i = 0; i < 2; i++) { | ||
| 764 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
| 765 | buf, NEXIO_BUFSIZE, &actual_len, | ||
| 766 | NEXIO_TIMEOUT); | ||
| 767 | if (ret < 0) | ||
| 768 | goto out_buf; | ||
| 769 | } | ||
| 770 | |||
| 771 | /* send init command */ | ||
| 772 | memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt)); | ||
| 773 | ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep), | ||
| 774 | buf, sizeof(nexio_init_pkt), &actual_len, | ||
| 775 | NEXIO_TIMEOUT); | ||
| 776 | if (ret < 0) | ||
| 777 | goto out_buf; | ||
| 778 | |||
| 779 | /* read replies */ | ||
| 780 | for (i = 0; i < 3; i++) { | ||
| 781 | memset(buf, 0, NEXIO_BUFSIZE); | ||
| 782 | ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep), | ||
| 783 | buf, NEXIO_BUFSIZE, &actual_len, | ||
| 784 | NEXIO_TIMEOUT); | ||
| 785 | if (ret < 0 || actual_len < 1 || buf[1] != actual_len) | ||
| 786 | continue; | ||
| 787 | switch (buf[0]) { | ||
| 788 | case 0x83: /* firmware version */ | ||
| 789 | if (!firmware_ver) | ||
| 790 | firmware_ver = kstrdup(&buf[2], GFP_KERNEL); | ||
| 791 | break; | ||
| 792 | case 0x84: /* device name */ | ||
| 793 | if (!device_name) | ||
| 794 | device_name = kstrdup(&buf[2], GFP_KERNEL); | ||
| 795 | break; | ||
| 796 | } | ||
| 797 | } | ||
| 798 | |||
| 799 | printk(KERN_INFO "Nexio device: %s, firmware version: %s\n", | ||
| 800 | device_name, firmware_ver); | ||
| 801 | |||
