Hi! I've ported the works from Chris Collins so the drivers compiles without warnings and works (for me) with Linux 2.6.10 and 2.6.11. The driver is not in the kernel now, but I would like to see it be a driver among all the other touchscreen drivers.
The touchscreen panel is for example used on the LG L1510SF screen. Any comments on the driver would be much appreciated. -- Regards, Hans-Christian Egtvedt <[EMAIL PROTECTED]> MIVU Solutions DA
--- kernel-source-2.6.11/drivers/usb/input/Kconfig 2004-12-24 22:35:23.000000000 +0100 +++ linux-2.6.11/drivers/usb/input/Kconfig 2005-03-02 10:58:41.000000000 +0100 @@ -190,6 +190,18 @@ To compile this driver as a module, choose M here: the module will be called mtouchusb. +config USB_ITMTOUCH + tristate "ITM Touch USB Touchscreen Driver" + depends on USB && INPUT + ---help--- + Say Y here if you want to use a ITM Touch USB + Touchscreen controller. + + This touchscreen is used in LG 1510SF monitors. + + To compile this driver as a module, choose M here: the + module will be called itmtouch. + config USB_EGALAX tristate "eGalax TouchKit USB Touchscreen Driver" depends on USB && INPUT --- kernel-source-2.6.11/drivers/usb/input/Makefile 2004-12-24 22:35:00.000000000 +0100 +++ linux-2.6.11/drivers/usb/input/Makefile 2005-03-02 10:57:11.000000000 +0100 @@ -33,6 +33,7 @@ obj-$(CONFIG_USB_KBTAB) += kbtab.o obj-$(CONFIG_USB_MOUSE) += usbmouse.o obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o +obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o obj-$(CONFIG_USB_EGALAX) += touchkitusb.o obj-$(CONFIG_USB_POWERMATE) += powermate.o obj-$(CONFIG_USB_WACOM) += wacom.o --- /dev/null 2005-03-01 19:15:30.000000000 +0100 +++ linux-2.6.11/drivers/usb/input/itmtouch.c 2005-03-02 11:05:04.000000000 +0100 @@ -0,0 +1,326 @@ +/****************************************************************************** + * itmtouch.c -- Driver for ITM touchscreen panel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon original work by Chris Collins <[EMAIL PROTECTED]>. + * + * History + * 1.0 & 1.1 2003 (CC) [EMAIL PROTECTED] + * Original version for 2.4.x kernels + * + * 1.2 02/03/2005 (HCE) [EMAIL PROTECTED] + * Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints. + * Unfortunately no calibration support at this time. + * + *****************************************************************************/ + +/* In order to prevent poluting device space with YET ANOTHER character + * device, this driver pumps out raw coordinate events into the input + * event stream. + * + * They can be extracted using the input core raw events module. + * + * Kudos to ITM for providing me with the datasheet for the panel, + * even though it was a day later than I had finished writing this + * driver. + * + * It has meant that I've been able to correct my interpretation of the + * protocol packets however. + * + * CC -- 2003/9/29 + */ + +#include <linux/config.h> + +#ifdef CONFIG_USB_DEBUG + #define DEBUG +#else + #undef DEBUG +#endif + +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/usb.h> + +/* only an 8 byte buffer necessary for a single packet */ +#define ITM_BUFSIZE 8 +/* support a maximum of 4 such touchscreens at once */ +#define MAXTOUCH 4 +#define UCP(x) ((unsigned char*)(x)) +#define UCOM(x,y,z) ((UCP((x)->transfer_buffer)[y]) & (z)) +#define PATH_SIZE 64 + +#define USB_VENDOR_ID_ITMINC 0x0403 +#define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9 + +#define DRIVER_AUTHOR "Hans-Christian Egtvedt <[EMAIL PROTECTED]>" +#define DRIVER_VERSION "v1.2" +#define DRIVER_DESC "USB ITM Inc Touch Panel Driver" +#define DRIVER_LICENSE "GPL" + +struct itmtouch_dev { + struct usb_device *usbdev; // usb device + struct input_dev inputdev; // input device + struct urb *readurb; // urb + char rbuf[ITM_BUFSIZE]; // data + int refcount; // + char name[128]; + char phys[64]; +}; + +struct usb_device_id itmtouch_ids [] = { + { USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) }, + { } +}; + +static void itmtouch_irq(struct urb *urb, struct pt_regs *regs) +{ + struct itmtouch_dev * itmtouch = urb->context; + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ETIMEDOUT: + /* this urb is timing out */ + dbg("%s - urb timed out - was the device unplugged?", + __FUNCTION__); + return; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); + goto exit; + } + + input_regs(&itmtouch->inputdev, regs); + + /* if pressure has been released, then don't report X/Y */ + if (!UCOM(urb, 7, 0x20)) { + input_report_abs(&itmtouch->inputdev, ABS_X, + UCOM(urb, 0, 0x1F) << 7 | UCOM(urb, 3, 0x7F)); + input_report_abs(&itmtouch->inputdev, ABS_Y, + UCOM(urb, 1, 0x1F) << 7 | UCOM(urb, 4, 0x7F)); + } + + input_report_abs(&itmtouch->inputdev, ABS_PRESSURE, + UCOM(urb, 2, 0x1) << 7 | UCOM(urb, 5, 0x7F)); + input_report_key(&itmtouch->inputdev, BTN_TOUCH, !UCOM(urb, 7, 0x20)); + // TODO: Do we need to use input_sync() ? + //input_sync(&itmtouch->inputdev); + +exit: + retval = usb_submit_urb (urb, GFP_ATOMIC); + if (retval) + printk(KERN_ERR "%s - usb_submit_urb failed with result: %d", + __FUNCTION__, retval); +} + +static int itmtouch_open(struct input_dev *input) +{ + struct itmtouch_dev *itmtouch = input->private; + + if (itmtouch->refcount++) + return 0; + + itmtouch->readurb->dev = itmtouch->usbdev; + + if (usb_submit_urb (itmtouch->readurb, GFP_KERNEL)) + { + itmtouch->refcount--; + return -EIO; + } + + return 0; +} + +static void itmtouch_close(struct input_dev *input) +{ + struct itmtouch_dev *itmtouch = input->private; + + if (!--itmtouch->refcount) + usb_unlink_urb (itmtouch->readurb); +} + + +static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct itmtouch_dev *itmtouch; + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_device * udev = interface_to_usbdev(intf); + unsigned int pipe; + unsigned int maxp; + char path[PATH_SIZE]; + + dbg("%s - called", __FUNCTION__); + + dbg("%s - setting interface", __FUNCTION__); + interface = intf->cur_altsetting; + + dbg("%s - setting endpoint", __FUNCTION__); + endpoint = &interface->endpoint[0].desc; + + if (id->idVendor != USB_VENDOR_ID_ITMINC || id->idProduct != USB_PRODUCT_ID_TOUCHPANEL) { + printk(KERN_WARNING "itmtouch: tried to bind to non-ts device.\n"); + return -ENODEV; + } + + /* allocate memory space */ + if (!(itmtouch = kmalloc (sizeof (struct itmtouch_dev), GFP_KERNEL))) { + err("%s - Out of memory.", __FUNCTION__); + return -ENOMEM; + } + memset(itmtouch, 0, sizeof(struct itmtouch_dev)); + + /* fill in the USB device info */ + itmtouch->usbdev = udev; + + itmtouch->inputdev.private = itmtouch; + itmtouch->inputdev.open = itmtouch_open; + itmtouch->inputdev.close = itmtouch_close; + + usb_make_path(udev, path, PATH_SIZE); + + /* set up the input queue */ + itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + + itmtouch->inputdev.name = itmtouch->name; + itmtouch->inputdev.phys = itmtouch->phys; + itmtouch->inputdev.id.bustype = BUS_USB; + itmtouch->inputdev.id.vendor = udev->descriptor.idVendor; + itmtouch->inputdev.id.product = udev->descriptor.idProduct; + itmtouch->inputdev.id.version = udev->descriptor.bcdDevice; + itmtouch->inputdev.dev = &intf->dev; + + if (!strlen(itmtouch->name)) + sprintf(itmtouch->name, "USB ITM touchscreen"); + + /* device limits */ + /* as specified by the ITM datasheet, X and Y are 12bit, + * Z (pressure) is 8 bit. However, the fields are defined up + * to 14 bits for future possible expansion. + */ + itmtouch->inputdev.absmax[ABS_X] = 0x0FFF; + //itmtouch->inputdev.absmin[ABS_X] = 0; + itmtouch->inputdev.absfuzz[ABS_X] = 2; + + itmtouch->inputdev.absmax[ABS_Y] = 0x0FFF; + //itmtouch->inputdev.absmin[ABS_Y] = 0; + itmtouch->inputdev.absfuzz[ABS_Y] = 2; + + itmtouch->inputdev.absmax[ABS_PRESSURE] = 0xFF; + //itmtouch->inputdev.absmin[ABS_PRESSURE] = 0; + itmtouch->inputdev.absfuzz[ABS_PRESSURE] = 2; + + /* initialise the URB so we can read from the transport stream */ + pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress); + + maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); + + if (maxp > ITM_BUFSIZE) { + printk(KERN_WARNING "itmtouch: WARNING: packet size > ITM_BUFSIZE\n"); + maxp = ITM_BUFSIZE; + } + + itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL); + + if (!itmtouch->readurb) { + dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__); + kfree(itmtouch); + return -ENOMEM; + } + + dbg("%s - usb_fill_int_urb", __FUNCTION__); + usb_fill_int_urb(itmtouch->readurb, + itmtouch->usbdev, + pipe, + itmtouch->rbuf, + maxp, + itmtouch_irq, + itmtouch, + endpoint->bInterval); + + /* register the device with the input system */ + dbg("%s - input_register_device", __FUNCTION__); + input_register_device(&itmtouch->inputdev); + + printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path); + usb_set_intfdata(intf, itmtouch); + + return 0; +} + + static void +//itmtouch_disconnect(struct usb_device *dev, void *ptr) +itmtouch_disconnect(struct usb_interface *intf) +{ + struct itmtouch_dev *itmtouch = usb_get_intfdata (intf); + + dbg("%s - called", __FUNCTION__); + + usb_set_intfdata(intf, NULL); + if (itmtouch) { + dbg("%s - itmtouch is initialized, cleaning up", __FUNCTION__); + usb_kill_urb(itmtouch->readurb); + input_unregister_device(&itmtouch->inputdev); + usb_free_urb(itmtouch->readurb); + kfree(itmtouch); + } +} + +MODULE_DEVICE_TABLE(usb, itmtouch_ids); + +static struct usb_driver itmtouch_driver = { + .owner = THIS_MODULE, + .name = "itmtouch", + .probe = itmtouch_probe, + .disconnect = itmtouch_disconnect, + .id_table = itmtouch_ids, +}; + +static int __init itmtouch_init(void) +{ + dbg("%s - called", __FUNCTION__); + info(DRIVER_VERSION " " DRIVER_AUTHOR); + info(DRIVER_DESC); + return usb_register(&itmtouch_driver); +} + +static void __exit itmtouch_exit(void) +{ + dbg("%s - called", __FUNCTION__); + usb_deregister(&itmtouch_driver); +} + +module_init(itmtouch_init); +module_exit(itmtouch_exit); + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE( DRIVER_LICENSE );
signature.asc
Description: This is a digitally signed message part