2006-03-10 09:24:49

by Lanslott Gish

[permalink] [raw]
Subject: [PATCH] Try to add support for universal USB touchscreen device, and WISH for help~

Hi all,

i try to arrange some codes, and named "usbtouchdev",
wish to help merging all USB touchscreen devices like
mtouchusb.c, itmtouch.c, touchkitusb.c, usbtouchset.c, etc.

in this moment, only add my touchscreen driver here and test pass.
if anyone wanna add another USB touchscreen driver, or wanna modify the codes,
or any help i can do, please feel free to tell me.

wish help some.

======
--- linux-2.6.16-rc5.org/drivers/usb/input/hid-core.c 2006-02-27
+++ linux-2.6.16-rc5/drivers/usb/input/hid-core.c 2006-03-10
@@ -1459,6 +1459,9 @@
#define USB_VENDOR_ID_HP 0x03f0
#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c

+#define USB_VENDOR_ID_TOUCHSET 0x134c
+#define USB_DEVICE_ID_TOUCHSET 0x0001
+
/*
* Alphabetically sorted blacklist by quirk type.
*/
@@ -1602,6 +1605,15 @@
{ USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
+
+ { USB_VENDOR_ID_TOUCHSET, USB_DEVICE_ID_TOUCHSET,
+ HID_QUIRK_IGNORE},
+ { USB_VENDOR_ID_TOUCHSET, USB_DEVICE_ID_TOUCHSET + 1,
+ HID_QUIRK_IGNORE},
+ { USB_VENDOR_ID_TOUCHSET, USB_DEVICE_ID_TOUCHSET + 2,
+ HID_QUIRK_IGNORE},
+ { USB_VENDOR_ID_TOUCHSET, USB_DEVICE_ID_TOUCHSET + 3,
+ HID_QUIRK_IGNORE},

{ 0, 0 }
};
--- linux-2.6.16-rc5.org/drivers/usb/input/Kconfig 2006-02-27
+++ linux-2.6.16-rc5/drivers/usb/input/Kconfig 2006-03-10
@@ -330,3 +330,15 @@

To compile this driver as a module, choose M here: the
module will be called appletouch.
+
+config USB_TOUCHDEV
+ tristate "Touchscreen General USB Device"
+ depends on USB && INPUT
+ ---help---
+ Say Y here if you want to use a USB Touchscreen controller.
+
+ Have a look at <http://linux.chapter7.ch/touchkit/> for
+ a usage description and the required user-space stuff.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtouchset.
--- linux-2.6.16-rc5.org/drivers/usb/input/Makefile 2006-02-27
+++ linux-2.6.16-rc5/drivers/usb/input/Makefile 2006-03-10
@@ -43,6 +43,7 @@
obj-$(CONFIG_USB_YEALINK) += yealink.o
obj-$(CONFIG_USB_XPAD) += xpad.o
obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
++obj-$(CONFIG_USB_TOUCHDEV) += usbtouchdev.o

ifeq ($(CONFIG_USB_DEBUG),y)
EXTRA_CFLAGS += -DDEBUG
--- linux-2.6.16-rc5.org/drivers/usb/input/usbtouchdev.c 1970-01-01
+++ linux-2.6.16-rc5/drivers/usb/input/usbtouchdev.c 2006-03-10
@@ -0,0 +1,280 @@
+/******************************************************************************
+ * usbtouchdev.c -- Driver for TouchScreen USB Device
+ *
+ * Copyright (C) 2004-2005 by Daniel Ritz <[email protected]>
+ * Copyright (C) by Todd E. Johnson (mtouchusb.c)
+ *
+ * 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.
+ *
+ * Try to united general USB touchscreen devices.
+ *
+ * -- 2006/3/10 --
+ *
+ * Changlog:
+ * v0.1 2006/3/10 Lanslott Gish
+ * Initial release based on mtouchusb.c & touchkitusb.c (Thx Todd & Daniel!)
+ *
+ * ToDo:
+ * * Merge USB touchscreen devices(mtouchusb.c,
+ * touchkitusb.c, itmtouch.c, etc.) if possible.
+ * * Functions to swap raw data for axies(X,Y,Z,...)
+ * * Access I/O devices with file operators.
+ * * ask for any idea :)
+ *
+ * NOTE:
+ * This kernel driver is required X.org/XFree86 input driver
+ * for your X server, as well as refer to "Evtouch",
+ * Touchscreen-Driver for X.
+ *
+ *****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb_input.h>
+
+#include "usbtouchdev.c"
+
+#define DRIVER_VERSION "0.1"
+#define DRIVER_AUTHOR "Lanslott Gish <[email protected]>"
+#define DRIVER_DESC "Touchscreen General USB Device"
+#define DRIVER_LICENSE "GPL"
+
+static int swap_xy;
+module_param(swap_xy, bool, 0644);
+MODULE_PARM_DESC(swap_xy, "Swap X and Y axes.");
+
+static void usbtouchdev_irq(struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_touchdev *usbtouchdev = urb->context;
+ int retval;
+ int x, y;
+
+ 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;
+ }
+
+ if (swap_xy) {
+ y = touchset_get_x(usbtouchdev->data);
+ x = touchset_get_y(usbtouchdev->data);
+ } else {
+ x = touchset_get_x(usbtouchdev->data);
+ y = touchset_get_y(usbtouchdev->data);
+ }
+
+ input_regs(usbtouchdev->input, regs);
+ input_report_key(usbtouchdev->input, BTN_TOUCH,
+ usbtouchdev_get_touched(usbtouchdev->data));
+ input_report_abs(usbtouchdev->input, ABS_X, x);
+ input_report_abs(usbtouchdev->input, ABS_Y, y);
+ input_sync(usbtouchdev->input);
+
+exit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err("%s - usb_submit_urb failed with result: %d",
+ __FUNCTION__, retval);
+}
+
+static int usbtouchdev_open(struct input_dev *input)
+{
+ struct usb_touchdev *usbtouchdev = input->private;
+
+ usbtouchdev->irq->dev = usbtouchdev->udev;
+
+ if (usb_submit_urb(usbtouchdev->irq, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void usbtouchdev_close(struct input_dev *input)
+{
+ struct usb_touchdev *usbtouchdev = input->private;
+
+ usb_kill_urb(usbtouchdev->irq);
+}
+
+static int usbtouchdev_alloc_buffers(struct usb_device *udev,
+ struct usb_touchdev *usbtouchdev)
+{
+ usbtouchdev->data = usb_buffer_alloc(udev,
+ TOUCHSET_REPORT_DATA_SIZE, SLAB_KERNEL,
+ &usbtouchdev->data_dma);
+
+ if (!usbtouchdev->data)
+ return -1;
+
+ return 0;
+}
+
+static void usbtouchdev_free_buffers(struct usb_device *udev,
+ struct usb_touchdev *usbtouchdev)
+{
+ if (usbtouchdev->data)
+ usb_buffer_free(udev,
+ TOUCHSET_REPORT_DATA_SIZE,
+ usbtouchdev->data, usbtouchdev->data_dma);
+}
+
+static int usbtouchdev_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_touchdev *usbtouchdev;
+ struct input_dev *input_dev;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+
+ usbtouchdev = kzalloc(sizeof(struct usb_touchdev), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!usbtouchdev || !input_dev)
+ goto out_free;
+
+ if (usbtouchdev_alloc_buffers(udev, usbtouchdev))
+ goto out_free;
+
+ usbtouchdev->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usbtouchdev->irq) {
+ dbg("%s - usb_alloc_urb failed: usbtouchdev->irq",
+ __FUNCTION__);
+ goto out_free_buffers;
+ }
+
+ usbtouchdev->udev = udev;
+ usbtouchdev->input = input_dev;
+
+ if (udev->manufacturer)
+ strlcpy(usbtouchdev->name, udev->manufacturer,
+ sizeof(usbtouchdev->name));
+
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(usbtouchdev->name, " ",
+ sizeof(usbtouchdev->name));
+ strlcat(usbtouchdev->name, udev->product,
+ sizeof(usbtouchdev->name));
+ }
+
+ if (!strlen(usbtouchdev->name))
+ snprintf(usbtouchdev->name, sizeof(usbtouchdev->name),
+ "USB Device %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ usb_make_path(udev, usbtouchdev->phys, sizeof(usbtouchdev->phys));
+ strlcpy(usbtouchdev->phys, "/input0", sizeof(usbtouchdev->phys));
+
+ input_dev->name = usbtouchdev->name;
+ input_dev->phys = usbtouchdev->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = usbtouchdev;
+ input_dev->open = usbtouchdev_open;
+ input_dev->close = usbtouchdev_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, TOUCHSET_MIN_XC,
+ TOUCHSET_MAX_XC, TOUCHSET_XC_FUZZ, TOUCHSET_XC_FLAT);
+ input_set_abs_params(input_dev, ABS_Y, TOUCHSET_MIN_YC,
+ TOUCHSET_MAX_YC, TOUCHSET_YC_FUZZ, TOUCHSET_YC_FLAT);
+
+ usb_fill_int_urb(usbtouchdev->irq, usbtouchdev->udev,
+ usb_rcvintpipe(usbtouchdev->udev, 0x81),
+ usbtouchdev->data, TOUCHSET_REPORT_DATA_SIZE,
+ usbtouchdev_irq, usbtouchdev, endpoint->bInterval);
+
+ input_register_device(usbtouchdev->input);
+
+ usb_set_intfdata(intf, usbtouchdev);
+ return 0;
+
+out_free_buffers:
+ usbtouchdev_free_buffers(udev, usbtouchdev);
+out_free:
+ input_free_device(input_dev);
+ kfree(usbtouchdev);
+ return -ENOMEM;
+}
+
+static void usbtouchdev_disconnect(struct usb_interface *intf)
+{
+ struct usb_touchdev *usbtouchdev = usb_get_intfdata(intf);
+
+ dbg("%s - called", __FUNCTION__);
+
+ if (!usbtouchdev)
+ return;
+
+ dbg("%s - usbtouchdev is initialized, cleaning up", __FUNCTION__);
+ usb_set_intfdata(intf, NULL);
+ usb_kill_urb(usbtouchdev->irq);
+ input_unregister_device(usbtouchdev->input);
+ usb_free_urb(usbtouchdev->irq);
+ usbtouchdev_free_buffers(interface_to_usbdev(intf), usbtouchdev);
+ kfree(usbtouchdev);
+}
+
+MODULE_DEVICE_TABLE(usb, usbtouchdev_devices);
+
+static struct usb_driver usbtouchdev_driver = {
+ .name = "usbtouchdev",
+ .probe = usbtouchdev_probe,
+ .disconnect = usbtouchdev_disconnect,
+ .id_table = usbtouchdev_devices,
+};
+
+static int __init usbtouchdev_init(void)
+{
+ return usb_register(&usbtouchdev_driver);
+}
+
+static void __exit usbtouchdev_cleanup(void)
+{
+ usb_deregister(&usbtouchdev_driver);
+}
+
+module_init(usbtouchdev_init);
+module_exit(usbtouchdev_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
--- linux-2.6.16-rc5.org/drivers/usb/input/usbtouchdev.h 1970-01-01
+++ linux-2.6.16-rc5/drivers/usb/input/usbtouchdev.h 2006-03-10
@@ -0,0 +1,100 @@
+/******************************************************************************
+ * usbtouchdev.h -- Driver for TouchScreen USB Device
+ *
+ * Copyright (C) 2004-2005 by Daniel Ritz <[email protected]>
+ * Copyright (C) by Todd E. Johnson (mtouchusb.c)
+ *
+ * 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.
+ *
+ * TouchScreen Universal USB Device Drivers.
+ *
+ *****************************************************************************/
+
+
+
+/*** Here for the touchscreen USB Device infomation ***/
+
+/*TouchSet USB Touch Panel*/
+#define TOUCHSET_VENDOR_ID 0x134c
+#define TOUCHSET_PRODUCT_ID 0x0001
+
+/*** Here for the touchscreen data like axies or something ***/
+
+
+/*TouchSet USB Touch Panel*/
+#define TOUCHSET_MIN_XC 0x0
+#define TOUCHSET_MAX_XC 0x0fff
+#define TOUCHSET_XC_FUZZ 0x0
+#define TOUCHSET_XC_FLAT 0x0
+#define TOUCHSET_MIN_YC 0x0
+#define TOUCHSET_MAX_YC 0x0fff
+#define TOUCHSET_YC_FUZZ 0x0
+#define TOUCHSET_YC_FLAT 0x0
+#define TOUCHSET_REPORT_DATA_SIZE 8
+
+#define TOUCHSET_DOWN 0x01
+#define TOUCHSET_POINT_TOUCH 0x81
+#define TOUCHSET_POINT_NOTOUCH 0x80
+
+/*** Structure for touchscreen devices ***/
+
+/*TouchSet USB Touch Panel*/
+struct usb_touchdev {
+ unsigned char *data;
+ dma_addr_t data_dma;
+ struct urb *irq;
+ struct usb_device *udev;
+ struct input_dev *input;
+ char name[128];
+ char phys[64];
+};
+
+
+/*** Structure for touch device ***/
+
+/*TouchSet USB Touch Panel*/
+static struct usb_device_id usbtouchdev_devices[] = {
+
+ /*TouchSet USB Device ID*/
+ {USB_DEVICE(TOUCHSET_VENDOR_ID, TOUCHSET_PRODUCT_ID)},
+ {USB_DEVICE(TOUCHSET_VENDOR_ID, TOUCHSET_PRODUCT_ID + 1)},
+ {USB_DEVICE(TOUCHSET_VENDOR_ID, TOUCHSET_PRODUCT_ID + 2)},
+ {USB_DEVICE(TOUCHSET_VENDOR_ID, TOUCHSET_PRODUCT_ID + 3)},
+
+ /*and something else...*/
+ {}
+};
+
+
+/*** Handle packets form touchscreen devices ***/
+
+/*TouchSet USB Touch Panel*/
+static inline int touchset_get_touched(char *data)
+{
+ return ((((data)[0]) & TOUCHSET_DOWN) ? 1 : 0);
+}
+
+static inline int touchset_get_x(char *data)
+{
+ return ((data)[1] | ((data)[2] << 8));
+}
+
+static inline int touchset_get_y(char *data)
+{
+ return ((data)[3] | ((data)[4] << 8));
+}
+
+
+


======
--
L.G, Life's Good~


2006-03-11 21:00:40

by Daniel Ritz

[permalink] [raw]
Subject: [RFC][PATCH] USB touch screen driver, all-in-one

hi

here my merge of the USB touchscreen drivers, based on my patch from
thursday for touchkitusb. this time it's a new driver...

and of course it's untested. i can test the egalax part next week...

[ also cc'ing the authors of the other drivers ]

the sizes for comparison:
text data bss dec hex filename
2942 724 4 3670 e56 touchkitusb.ko
2647 660 0 3307 ceb mtouchusb.ko
2448 628 0 3076 c04 itmtouch.ko
4097 1012 4 5113 13f9 usbtouchscreen.ko

comments?

rgds
-daniel

------------

Signed-off-by: Daniel Ritz <[email protected]>

diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 5246b35..2f16657 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -240,6 +240,42 @@ config USB_EGALAX
To compile this driver as a module, choose M here: the
module will be called touchkitusb.

+config USB_TOUCHSCREEN
+ tristate "USB Touchscreen Driver"
+ depends on USB && INPUT
+ ---help---
+ USB Touchscreen driver for:
+ - eGalax Touchkit USB
+ - PanJit TouchSet USB
+ - 3M MicroTouch USB
+ - ITM
+
+ Have a look at <http://linux.chapter7.ch/touchkit/> for
+ a usage description and the required user-space stuff.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtouchscreen.
+
+config USB_TOUCHSCREEN_EGALAX
+ default y
+ bool "eGalax device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
+config USB_TOUCHSCREEN_PANJIT
+ default y
+ bool "PanJit device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
+config USB_TOUCHSCREEN_3M
+ default y
+ bool "3M/Microtouch device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
+config USB_TOUCHSCREEN_ITM
+ default y
+ bool "ITM device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
config USB_YEALINK
tristate "Yealink usb-p1k voip phone"
depends on USB && INPUT && EXPERIMENTAL
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index d512d9f..7641145 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -37,6 +37,7 @@ 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_TOUCHSCREEN) += usbtouchscreen.o
obj-$(CONFIG_USB_POWERMATE) += powermate.o
obj-$(CONFIG_USB_WACOM) += wacom.o
obj-$(CONFIG_USB_ACECAD) += acecad.o
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 07a012f..103e33f 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1460,6 +1460,8 @@ void hid_init_reports(struct hid_device
#define USB_VENDOR_ID_HP 0x03f0
#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c

+#define USB_VENDOR_ID_PANJIT 0x134c
+
/*
* Alphabetically sorted blacklist by quirk type.
*/
@@ -1605,6 +1607,11 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },

+ { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
+
{ 0, 0 }
};

--- /dev/null 1998-05-05 22:32:27.000000000 +0200
+++ b/drivers/usb/input/usbtouchscreen.c 2006-03-11 16:06:04.000000000 +0100
@@ -0,0 +1,587 @@
+/******************************************************************************
+ * usbtouchscreen.c
+ * Driver for USB Touchscreens, supporting those devices:
+ * - eGalax Touchkit
+ * - 3M/Microtouch
+ * - ITM
+ * - PanJit TouchSet
+ *
+ * Copyright (C) 2004-2006 by Daniel Ritz <[email protected]>
+ * Copyright (C) by Todd E. Johnson (mtouchusb.c)
+ *
+ * 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.
+ *
+ * Driver is based on touchkitusb.c
+ * - ITM parts are from itmtouch.c
+ * - 3M parts are from mtouchusb.c
+ * - PanJit parts are from an unmerged driver by Lanslott Gish
+ *
+ *****************************************************************************/
+
+//#define DEBUG
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb_input.h>
+
+
+#define DRIVER_VERSION "v0.3"
+#define DRIVER_AUTHOR "Daniel Ritz <[email protected]>"
+#define DRIVER_DESC "USB Touchscreen Driver"
+
+static int swap_xy;
+module_param(swap_xy, bool, 0644);
+MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
+
+
+/* device specifc data/functions */
+struct usbtouch_usb;
+struct usbtouch_device_info {
+ int min_xc, max_xc;
+ int min_yc, max_yc;
+ int min_press, max_press;
+ int rept_size;
+ int flags;
+
+ void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, char *pkt, int len);
+ int (*read_data) (char *pkt, int *x, int *y, int *touch, int *press);
+ void (*init) (struct usbtouch_usb *usbtouch);
+};
+
+#define USBTOUCH_FLG_BUFFER 0x01
+
+
+/* a usbtouch device */
+struct usbtouch_usb {
+ unsigned char *data;
+ dma_addr_t data_dma;
+ char *buffer;
+ int buf_len;
+ struct urb *irq;
+ struct usb_device *udev;
+ struct input_dev *input;
+ struct usbtouch_device_info *type;
+ char name[128];
+ char phys[64];
+};
+
+static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
+ struct pt_regs *regs, char *pkt, int len);
+
+/* device types */
+enum {
+ DEVTPYE_DUMMY = -1,
+ DEVTYPE_EGALAX,
+ DEVTYPE_PANJIT,
+ DEVTYPE_3M,
+ DEVTYPE_ITM,
+};
+
+static struct usb_device_id usbtouch_devices[] = {
+#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+ {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
+ {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
+ {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX},
+ {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX},
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+ {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT},
+ {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT},
+ {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT},
+ {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT},
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_3M
+ {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M},
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+ {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
+#endif
+
+ {}
+};
+
+
+/*****************************************************************************
+ * eGalax part
+ */
+
+#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+
+#define EGALAX_PKT_TYPE_MASK 0xFE
+#define EGALAX_PKT_TYPE_REPT 0x80
+#define EGALAX_PKT_TYPE_DIAG 0x0A
+
+static int egalax_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
+ return 0;
+
+ *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F);
+ *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F);
+ *touch = (pkt[0] & 0x01) ? 1 : 0;
+
+ return 1;
+
+}
+
+static int egalax_get_pkt_len(char *buf)
+{
+ switch (buf[0] & EGALAX_PKT_TYPE_MASK) {
+ case EGALAX_PKT_TYPE_REPT:
+ return 5;
+
+ case EGALAX_PKT_TYPE_DIAG:
+ return buf[1] + 2;
+ }
+
+ return 0;
+}
+
+static void egalax_process(struct usbtouch_usb *usbtouch,
+ struct pt_regs *regs, char *pkt, int len)
+{
+ char *buffer;
+ int pkt_len, buf_len, pos;
+
+ /* if the buffer contains data, append */
+ if (unlikely(usbtouch->buf_len)) {
+ int tmp;
+
+ /* if only 1 byte in buffer, add another one to get length */
+ if (usbtouch->buf_len == 1)
+ usbtouch->buffer[1] = pkt[0];
+
+ pkt_len = egalax_get_pkt_len(usbtouch->buffer);
+
+ /* unknown packet: drop everything */
+ if (!pkt_len)
+ return;
+
+ /* append, process */
+ tmp = pkt_len - usbtouch->buf_len;
+ memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
+ usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len);
+
+ buffer = pkt + tmp;
+ buf_len = len - tmp;
+ } else {
+ buffer = pkt;
+ buf_len = len;
+ }
+
+ /* only one byte left in buffer */
+ if (unlikely(buf_len == 1)) {
+ usbtouch->buffer[0] = buffer[0];
+ usbtouch->buf_len = 1;
+ return;
+ }
+
+ /* loop over the buffer */
+ pos = 0;
+ while (pos < buf_len) {
+ /* get packet len */
+ pkt_len = egalax_get_pkt_len(buffer + pos);
+
+ /* unknown packet: drop everything */
+ if (unlikely(!pkt_len))
+ return;
+
+ /* full packet: process */
+ if (likely(pkt_len <= buf_len)) {
+ usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len);
+ } else {
+ /* incomplete packet: save in buffer */
+ memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
+ usbtouch->buf_len = buf_len - pos;
+ }
+ pos += pkt_len;
+ }
+}
+#endif
+
+
+/*****************************************************************************
+ * PanJit Part
+ */
+#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ *x = pkt[1] | (pkt[2] << 8);
+ *y = pkt[3] | (pkt[4] << 8);
+ *touch = (pkt[0] & 0x01) ? 1 : 0;
+
+ return 1;
+}
+#endif
+
+
+/*****************************************************************************
+ * 3M/Microtouch Part
+ */
+#ifdef CONFIG_USB_TOUCHSCREEN_3M
+
+#define MTOUCHUSB_ASYNC_REPORT 1
+#define MTOUCHUSB_RESET 7
+#define MTOUCHUSB_REQ_CTRLLR_ID 10
+
+static int mtouch_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ *x = (pkt[8] << 8) | pkt[7];
+ *y = (pkt[10] << 8) | pkt[9];
+ *touch = (pkt[2] & 0x40) ? 1 : 0;
+
+ return 1;
+}
+
+static void mtouch_init(struct usbtouch_usb *usbtouch)
+{
+ int ret;
+
+ ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+ MTOUCHUSB_RESET,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
+ __FUNCTION__, ret);
+
+ ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+ MTOUCHUSB_ASYNC_REPORT,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
+ __FUNCTION__, ret);
+}
+#endif
+
+
+/*****************************************************************************
+ * ITM Part
+ */
+#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+static int itm_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F);
+ *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
+ *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F);
+ *touch = ~pkt[7] & 0x20;
+
+ return 1;
+}
+#endif
+
+
+/*****************************************************************************
+ * the different device descriptors
+ */
+static struct usbtouch_device_info usbtouch_dev_info[] = {
+#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+ [DEVTYPE_EGALAX] = {
+ .min_xc = 0x0,
+ .max_xc = 0x07ff,
+ .min_yc = 0x0,
+ .max_yc = 0x07ff,
+ .rept_size = 16,
+ .flags = USBTOUCH_FLG_BUFFER,
+ .process_pkt = egalax_process,
+ .read_data = egalax_read_data,
+ },
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+ [DEVTYPE_PANJIT] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .rept_size = 8,
+ .read_data = panjit_read_data,
+ },
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_3M
+ [DEVTYPE_3M] = {
+ .min_xc = 0x0,
+ .max_xc = 0x4000,
+ .min_yc = 0x0,
+ .max_yc = 0x4000,
+ .rept_size = 11,
+ .read_data = mtouch_read_data,
+ .init = mtouch_init,
+ },
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+ [DEVTYPE_ITM] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .max_press = 0xff,
+ .rept_size = 8,
+ .read_data = itm_read_data,
+ },
+#endif
+};
+
+
+/*****************************************************************************
+ * Generic Part
+ */
+static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
+ struct pt_regs *regs, char *pkt, int len)
+{
+ int x, y, touch, press;
+
+ if (!usbtouch->type->read_data(pkt, &x, &y, &touch, &press))
+ return;
+
+ input_regs(usbtouch->input, regs);
+ input_report_key(usbtouch->input, BTN_TOUCH, touch);
+
+ if (swap_xy) {
+ input_report_abs(usbtouch->input, ABS_X, y);
+ input_report_abs(usbtouch->input, ABS_Y, x);
+ } else {
+ input_report_abs(usbtouch->input, ABS_X, x);
+ input_report_abs(usbtouch->input, ABS_Y, y);
+ }
+ if (usbtouch->type->max_press)
+ input_report_abs(usbtouch->input, ABS_PRESSURE, press);
+ input_sync(usbtouch->input);
+}
+
+
+static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+ struct usbtouch_usb *usbtouch = 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;
+ }
+
+ usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length);
+
+exit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err("%s - usb_submit_urb failed with result: %d",
+ __FUNCTION__, retval);
+}
+
+static int usbtouch_open(struct input_dev *input)
+{
+ struct usbtouch_usb *usbtouch = input->private;
+
+ usbtouch->irq->dev = usbtouch->udev;
+
+ if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void usbtouch_close(struct input_dev *input)
+{
+ struct usbtouch_usb *usbtouch = input->private;
+
+ usb_kill_urb(usbtouch->irq);
+}
+
+
+static void usbtouch_free_buffers(struct usb_device *udev,
+ struct usbtouch_usb *usbtouch)
+{
+ if (usbtouch->data)
+ usb_buffer_free(udev, usbtouch->type->rept_size,
+ usbtouch->data, usbtouch->data_dma);
+ kfree(usbtouch->buffer);
+}
+
+
+static int usbtouch_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usbtouch_usb *usbtouch;
+ struct input_dev *input_dev;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct usbtouch_device_info *type;
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+
+ usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!usbtouch || !input_dev)
+ goto out_free;
+
+ type = &usbtouch_dev_info[id->driver_info];
+ usbtouch->type = type;
+ if (!type->process_pkt)
+ type->process_pkt = usbtouch_process_pkt;
+
+ usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
+ SLAB_KERNEL, &usbtouch->data_dma);
+ if (!usbtouch->data)
+ goto out_free;
+
+ if (type->flags & USBTOUCH_FLG_BUFFER) {
+ usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL);
+ if (!usbtouch->buffer)
+ goto out_free_buffers;
+ }
+
+ usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usbtouch->irq) {
+ dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
+ goto out_free_buffers;
+ }
+
+ usbtouch->udev = udev;
+ usbtouch->input = input_dev;
+
+ if (udev->manufacturer)
+ strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name));
+
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(usbtouch->name, " ", sizeof(usbtouch->name));
+ strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name));
+ }
+
+ if (!strlen(usbtouch->name))
+ snprintf(usbtouch->name, sizeof(usbtouch->name),
+ "USB Touchscreen %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));
+ strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
+
+ input_dev->name = usbtouch->name;
+ input_dev->phys = usbtouch->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = usbtouch;
+ input_dev->open = usbtouch_open;
+ input_dev->close = usbtouch_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, type->max_press, 0, 0);
+
+ usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
+ usb_rcvintpipe(usbtouch->udev, 0x81),
+ usbtouch->data, type->rept_size,
+ usbtouch_irq, usbtouch, endpoint->bInterval);
+
+ usbtouch->irq->transfer_dma = usbtouch->data_dma;
+ usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ input_register_device(usbtouch->input);
+
+ usb_set_intfdata(intf, usbtouch);
+
+ /* device specific init */
+ if (type->init)
+ type->init(usbtouch);
+
+ return 0;
+
+out_free_buffers:
+ usbtouch_free_buffers(udev, usbtouch);
+out_free:
+ input_free_device(input_dev);
+ kfree(usbtouch);
+ return -ENOMEM;
+}
+
+static void usbtouch_disconnect(struct usb_interface *intf)
+{
+ struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
+
+ dbg("%s - called", __FUNCTION__);
+
+ if (!usbtouch)
+ return;
+
+ dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
+ usb_set_intfdata(intf, NULL);
+ usb_kill_urb(usbtouch->irq);
+ input_unregister_device(usbtouch->input);
+ usb_free_urb(usbtouch->irq);
+ usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
+ kfree(usbtouch);
+}
+
+MODULE_DEVICE_TABLE(usb, usbtouch_devices);
+
+static struct usb_driver usbtouch_driver = {
+ .name = "usbtouchscreen",
+ .probe = usbtouch_probe,
+ .disconnect = usbtouch_disconnect,
+ .id_table = usbtouch_devices,
+};
+
+static int __init usbtouch_init(void)
+{
+ return usb_register(&usbtouch_driver);
+}
+
+static void __exit usbtouch_cleanup(void)
+{
+ usb_deregister(&usbtouch_driver);
+}
+
+module_init(usbtouch_init);
+module_exit(usbtouch_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("touchkitusb");
+MODULE_ALIAS("itmtouch");
+MODULE_ALIAS("mtouchusb");

2006-03-12 01:31:38

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Saturday 11 March 2006 15:55, Daniel Ritz wrote:
> hi
>
> here my merge of the USB touchscreen drivers, based on my patch from
> thursday for touchkitusb. this time it's a new driver...
>
> and of course it's untested. i can test the egalax part next week...
>
> [ also cc'ing the authors of the other drivers ]
>
> the sizes for comparison:
> text data bss dec hex filename
> 2942 724 4 3670 e56 touchkitusb.ko
> 2647 660 0 3307 ceb mtouchusb.ko
> 2448 628 0 3076 c04 itmtouch.ko
> 4097 1012 4 5113 13f9 usbtouchscreen.ko
>
> comments?
>

I like it.

> +
> + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
> + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
> + input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
> + input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
> + input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press, type->max_press, 0, 0);
> +

Not all devices report pressure; driver should only advertise ABS_PRESSURE for
devices that actually support it.

> + usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
> + usb_rcvintpipe(usbtouch->udev, 0x81),
> + usbtouch->data, type->rept_size,
> + usbtouch_irq, usbtouch, endpoint->bInterval);
> +
> + usbtouch->irq->transfer_dma = usbtouch->data_dma;
> + usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
> +
> + input_register_device(usbtouch->input);
> +

Please add error handling now that input_register_device() returns errors.

> + usb_set_intfdata(intf, usbtouch);
> +
> + /* device specific init */
> + if (type->init)
> + type->init(usbtouch);
> +

Should we do device-specific init before registering input device and also
handle errors here?

--
Dmitry

2006-03-13 01:01:48

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

Hi, Daniel,
it's great. i will test touchset part today.

Regards,

Lanslott Gish

On 3/12/06, Daniel Ritz <[email protected]> wrote:
> hi
>
> here my merge of the USB touchscreen drivers, based on my patch from
> thursday for touchkitusb. this time it's a new driver...
>
> and of course it's untested. i can test the egalax part next week...
>
> [ also cc'ing the authors of the other drivers ]
>
> the sizes for comparison:
> text data bss dec hex filename
> 2942 724 4 3670 e56 touchkitusb.ko
> 2647 660 0 3307 ceb mtouchusb.ko
> 2448 628 0 3076 c04 itmtouch.ko
> 4097 1012 4 5113 13f9 usbtouchscreen.ko
>
> comments?
>
> rgds
> -daniel
>

2006-03-14 01:10:15

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

Hi, Daniel,

i fixed some codes and add swap_x & swap_y functions.
and test your patch passed for my touchset hrdware.
here is the patch only for your usbtouchscreen.c
could you help to apply this?
thank you.

Regards,

Lanslott Gish

==============================================================
--- linux-2.6.16-rc6.patched/drivers/usb/input/usbtouchscreen.c
+++ linux-2.6.16-rc6/drivers/usb/input/usbtouchscreen.c
@@ -224,13 +224,24 @@
* PanJit Part
*/
#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+
+static int swap_x;
+module_param(swap_x, bool, 0644);
+MODULE_PARM_DESC(swap_x, "If set X axe is swapped before XY swapped.");
+static int swap_y;
+module_param(swap_y, bool, 0644);
+MODULE_PARM_DESC(swap_y, "If set Y axe is swapped before XY swapped.");
+
static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
{
- *x = pkt[1] | (pkt[2] << 8);
- *y = pkt[3] | (pkt[4] << 8);
+ *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
+ *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);
*touch = (pkt[0] & 0x01) ? 1 : 0;

- return 1;
+ if(swap_x) *x = *x ^ 0x0FFF;
+ if(swap_y) *y = *y ^ 0x0FFF;
+
+ return 1;
}
#endif

==============================================================



On 3/13/06, Lanslott Gish <[email protected]> wrote:
> Hi, Daniel,
> it's great. i will test touchset part today.
>
> Regards,
>
> Lanslott Gish
>
> On 3/12/06, Daniel Ritz <[email protected]> wrote:
> > hi
> >
> > here my merge of the USB touchscreen drivers, based on my patch from
> > thursday for touchkitusb. this time it's a new driver...
> >
> > and of course it's untested. i can test the egalax part next week...
> >
> > [ also cc'ing the authors of the other drivers ]
> >
> > the sizes for comparison:
> > text data bss dec hex filename
> > 2942 724 4 3670 e56 touchkitusb.ko
> > 2647 660 0 3307 ceb mtouchusb.ko
> > 2448 628 0 3076 c04 itmtouch.ko
> > 4097 1012 4 5113 13f9 usbtouchscreen.ko
> >
> > comments?
> >
> > rgds
> > -daniel
> >
>


--
L.G, Life's Good~

2006-03-14 10:38:59

by Jan-Benedict Glaw

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Tue, 2006-03-14 09:10:13 +0800, Lanslott Gish <[email protected]> wrote:
> i fixed some codes and add swap_x & swap_y functions.
> and test your patch passed for my touchset hrdware.
> here is the patch only for your usbtouchscreen.c
> could you help to apply this?
> thank you.
>
> Regards,
>
> Lanslott Gish
>
> ==============================================================
> --- linux-2.6.16-rc6.patched/drivers/usb/input/usbtouchscreen.c
> +++ linux-2.6.16-rc6/drivers/usb/input/usbtouchscreen.c
> @@ -224,13 +224,24 @@
> * PanJit Part
> */
> #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
> +
> +static int swap_x;
> +module_param(swap_x, bool, 0644);
> +MODULE_PARM_DESC(swap_x, "If set X axe is swapped before XY swapped.");
> +static int swap_y;
> +module_param(swap_y, bool, 0644);
> +MODULE_PARM_DESC(swap_y, "If set Y axe is swapped before XY swapped.");
> +
> static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
> {
> - *x = pkt[1] | (pkt[2] << 8);
> - *y = pkt[3] | (pkt[4] << 8);
> + *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
> + *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);
> *touch = (pkt[0] & 0x01) ? 1 : 0;
>
> - return 1;
> + if(swap_x) *x = *x ^ 0x0FFF;
> + if(swap_y) *y = *y ^ 0x0FFF;
> +
> + return 1;
> }
> #endif
>

Um, I think it's generally a good idea to allow this, but I'd say this
should go into the common code part using the pre-known number range.

MfG, JBG

--
Jan-Benedict Glaw [email protected] . +49-172-7608481 _ O _
"Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg _ _ O
für einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));


Attachments:
(No filename) (1.76 kB)
signature.asc (189.00 B)
Digital signature
Download all attachments

2006-03-15 04:30:07

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

did you mean like that? thx.

regards,

Lanslott Gish
===================================================================
--- linux-2.6.16-rc6.patched/drivers/usb/input/usbtouchscreen.c
+++ linux-2.6.16-rc6/drivers/usb/input/usbtouchscreen.c
@@ -49,6 +49,13 @@
static int swap_xy;
module_param(swap_xy, bool, 0644);
MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
+static int swap_x;
+module_param(swap_x, bool, 0644);
+MODULE_PARM_DESC(swap_x, "If set X axe is swapped before XY swapped.");
+static int swap_y;
+module_param(swap_y, bool, 0644);
+MODULE_PARM_DESC(swap_y, "If set Y axe is swapped before XY swapped.");
+


/* device specifc data/functions */
@@ -224,13 +231,17 @@
* PanJit Part
*/
#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+
static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
{
- *x = pkt[1] | (pkt[2] << 8);
- *y = pkt[3] | (pkt[4] << 8);
+ *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
+ *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);
*touch = (pkt[0] & 0x01) ? 1 : 0;

- return 1;
+ if(swap_x) *x = *x ^ 0x0FFF;
+ if(swap_y) *y = *y ^ 0x0FFF;
+
+ return 1;
}
#endif
===================================================================

On 3/14/06, Jan-Benedict Glaw <[email protected]> wrote:
> On Tue, 2006-03-14 09:10:13 +0800, Lanslott Gish <[email protected]> wrote:
> > i fixed some codes and add swap_x & swap_y functions.
> > and test your patch passed for my touchset hrdware.
> > here is the patch only for your usbtouchscreen.c
> > could you help to apply this?
> > thank you.
> >
> > Regards,
> >
> > Lanslott Gish
> >
> > ==============================================================

>
> Um, I think it's generally a good idea to allow this, but I'd say this
> should go into the common code part using the pre-known number range.
>
> MfG, JBG
>
> --
> Jan-Benedict Glaw [email protected] . +49-172-7608481 _ O _
> "Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg _ _ O
> f?r einen Freien Staat voll Freier B?rger" | im Internet! | im Irak! O O O
> ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));
>
>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.1 (GNU/Linux)
>
> iD8DBQFEFp0+Hb1edYOZ4bsRAhntAJ9tmcgcvR57teoeJIaJRqxBbrQpoACeNPFE
> HrHJmjM0mkN9ZQsvARoLx+0=
> =06aU
> -----END PGP SIGNATURE-----
>
>
>


--
L.G, Life's Good~

2006-03-15 14:08:05

by Jan-Benedict Glaw

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Wed, 2006-03-15 12:30:04 +0800, Lanslott Gish <[email protected]> wrote:
> did you mean like that? thx.

That's basically the same patch as before?! What was ment is to move
inverting the axes into usbtouch_process_pkt().

MfG, JBG

--
Jan-Benedict Glaw [email protected] . +49-172-7608481 _ O _
"Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg _ _ O
für einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));


Attachments:
(No filename) (567.00 B)
signature.asc (189.00 B)
Digital signature
Download all attachments

2006-03-15 21:53:09

by Daniel Ritz

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Wednesday 15 March 2006 05.30, Lanslott Gish wrote:
> did you mean like that? thx.
>
> regards,
>
> Lanslott Gish
> ===================================================================
> --- linux-2.6.16-rc6.patched/drivers/usb/input/usbtouchscreen.c
> +++ linux-2.6.16-rc6/drivers/usb/input/usbtouchscreen.c
> @@ -49,6 +49,13 @@
> static int swap_xy;
> module_param(swap_xy, bool, 0644);
> MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
> +static int swap_x;
> +module_param(swap_x, bool, 0644);
> +MODULE_PARM_DESC(swap_x, "If set X axe is swapped before XY swapped.");
> +static int swap_y;
> +module_param(swap_y, bool, 0644);
> +MODULE_PARM_DESC(swap_y, "If set Y axe is swapped before XY swapped.");
> +
>
(i prefer invert_x and invert_y...)

>
> /* device specifc data/functions */
> @@ -224,13 +231,17 @@
> * PanJit Part
> */
> #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
> +
> static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
> {
> - *x = pkt[1] | (pkt[2] << 8);
> - *y = pkt[3] | (pkt[4] << 8);
> + *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
> + *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);

that just can't be right. you probably mean
+ *y = pkt[3] | ((pkt[4] & 0x0F) << 8);

otherwise you mask out bits 4-7. but you want to limit it to 12 bits...
(btw. no need for the & 0xFF mask since *pkt is char)


anyway, i updated the driver with all the comments i got so far.
will send out in a minute as a new mail.

rgds
-daniel

2006-03-15 21:54:19

by Daniel Ritz

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

hi

here the updated version of the patch. changes since first version:
- only advertise ABS_PRESSURE when device supports it
- handle input_register_device() errors
- allow vendor specifc init to fail.
- add invert_x/invert_y modparams
- only care about 12 bits for panjit

thanks for all the inputs.

rgds
-daniel

-----

[PATCH] usb/input/usbtouchscreen: unified USB touchscreen driver

A new single driver for various USB touchscreen devices. It currently
supports:
- eGalax TouchKit
- PanJit TouchSet
- 3M/Microtouch
- ITM Touchscreens

Support for the diffent devices can be enabled/disable when CONFIG_EMBEDDED
is set.

It's offering the same module params for all screens:
- swap_xy: swaps X and Y axes
- invert_x/invert_y: inverts X/Y.

Sizes for comparision:
text data bss dec hex filename
2942 724 4 3670 e56 touchkitusb.ko
2647 660 0 3307 ceb mtouchusb.ko
2448 628 0 3076 c04 itmtouch.ko
4425 1012 12 5449 1549 usbtouchscreen.ko

Signed-off-by: Daniel Ritz <[email protected]>


diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 5246b35..2f16657 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -240,6 +240,42 @@ config USB_EGALAX
To compile this driver as a module, choose M here: the
module will be called touchkitusb.

+config USB_TOUCHSCREEN
+ tristate "USB Touchscreen Driver"
+ depends on USB && INPUT
+ ---help---
+ USB Touchscreen driver for:
+ - eGalax Touchkit USB
+ - PanJit TouchSet USB
+ - 3M MicroTouch USB
+ - ITM
+
+ Have a look at <http://linux.chapter7.ch/touchkit/> for
+ a usage description and the required user-space stuff.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtouchscreen.
+
+config USB_TOUCHSCREEN_EGALAX
+ default y
+ bool "eGalax device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
+config USB_TOUCHSCREEN_PANJIT
+ default y
+ bool "PanJit device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
+config USB_TOUCHSCREEN_3M
+ default y
+ bool "3M/Microtouch device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
+config USB_TOUCHSCREEN_ITM
+ default y
+ bool "ITM device support" if EMBEDDED
+ depends on USB_TOUCHSCREEN
+
config USB_YEALINK
tristate "Yealink usb-p1k voip phone"
depends on USB && INPUT && EXPERIMENTAL
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index d512d9f..7641145 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -37,6 +37,7 @@ 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_TOUCHSCREEN) += usbtouchscreen.o
obj-$(CONFIG_USB_POWERMATE) += powermate.o
obj-$(CONFIG_USB_WACOM) += wacom.o
obj-$(CONFIG_USB_ACECAD) += acecad.o
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 07a012f..103e33f 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1460,6 +1460,8 @@ void hid_init_reports(struct hid_device
#define USB_VENDOR_ID_HP 0x03f0
#define USB_DEVICE_ID_HP_USBHUB_KB 0x020c

+#define USB_VENDOR_ID_PANJIT 0x134c
+
/*
* Alphabetically sorted blacklist by quirk type.
*/
@@ -1605,6 +1607,11 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },

+ { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
+
{ 0, 0 }
};

--- /dev/null 1998-05-05 22:32:27.000000000 +0200
+++ b/drivers/usb/input/usbtouchscreen.c 2006-03-15 22:34:13.000000000 +0100
@@ -0,0 +1,616 @@
+/******************************************************************************
+ * usbtouchscreen.c
+ * Driver for USB Touchscreens, supporting those devices:
+ * - eGalax Touchkit
+ * - 3M/Microtouch
+ * - ITM
+ * - PanJit TouchSet
+ *
+ * Copyright (C) 2004-2006 by Daniel Ritz <[email protected]>
+ * Copyright (C) by Todd E. Johnson (mtouchusb.c)
+ *
+ * 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.
+ *
+ * Driver is based on touchkitusb.c
+ * - ITM parts are from itmtouch.c
+ * - 3M parts are from mtouchusb.c
+ * - PanJit parts are from an unmerged driver by Lanslott Gish
+ *
+ *****************************************************************************/
+
+//#define DEBUG
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb_input.h>
+
+
+#define DRIVER_VERSION "v0.3"
+#define DRIVER_AUTHOR "Daniel Ritz <[email protected]>"
+#define DRIVER_DESC "USB Touchscreen Driver"
+
+static int swap_xy;
+static int invert_x, invert_y;
+module_param(swap_xy, bool, 0644);
+MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
+module_param(invert_x, bool, 0644);
+MODULE_PARM_DESC(invert_x, "If set the X axis is inverted.");
+module_param(invert_y, bool, 0644);
+MODULE_PARM_DESC(invert_y, "If set the Y axis is inverted.");
+
+
+/* device specifc data/functions */
+struct usbtouch_usb;
+struct usbtouch_device_info {
+ int min_xc, max_xc;
+ int min_yc, max_yc;
+ int min_press, max_press;
+ int rept_size;
+ int flags;
+
+ void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, char *pkt, int len);
+ int (*read_data) (char *pkt, int *x, int *y, int *touch, int *press);
+ int (*init) (struct usbtouch_usb *usbtouch);
+};
+
+#define USBTOUCH_FLG_BUFFER 0x01
+
+
+/* a usbtouch device */
+struct usbtouch_usb {
+ unsigned char *data;
+ dma_addr_t data_dma;
+ char *buffer;
+ int buf_len;
+ struct urb *irq;
+ struct usb_device *udev;
+ struct input_dev *input;
+ struct usbtouch_device_info *type;
+ char name[128];
+ char phys[64];
+};
+
+static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
+ struct pt_regs *regs, char *pkt, int len);
+
+/* device types */
+enum {
+ DEVTPYE_DUMMY = -1,
+ DEVTYPE_EGALAX,
+ DEVTYPE_PANJIT,
+ DEVTYPE_3M,
+ DEVTYPE_ITM,
+};
+
+static struct usb_device_id usbtouch_devices[] = {
+#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+ {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
+ {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
+ {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX},
+ {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX},
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+ {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT},
+ {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT},
+ {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT},
+ {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT},
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_3M
+ {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M},
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+ {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
+#endif
+
+ {}
+};
+
+
+/*****************************************************************************
+ * eGalax part
+ */
+
+#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+
+#define EGALAX_PKT_TYPE_MASK 0xFE
+#define EGALAX_PKT_TYPE_REPT 0x80
+#define EGALAX_PKT_TYPE_DIAG 0x0A
+
+static int egalax_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
+ return 0;
+
+ *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F);
+ *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F);
+ *touch = pkt[0] & 0x01;
+
+ return 1;
+
+}
+
+static int egalax_get_pkt_len(char *buf)
+{
+ switch (buf[0] & EGALAX_PKT_TYPE_MASK) {
+ case EGALAX_PKT_TYPE_REPT:
+ return 5;
+
+ case EGALAX_PKT_TYPE_DIAG:
+ return buf[1] + 2;
+ }
+
+ return 0;
+}
+
+static void egalax_process(struct usbtouch_usb *usbtouch,
+ struct pt_regs *regs, char *pkt, int len)
+{
+ char *buffer;
+ int pkt_len, buf_len, pos;
+
+ /* if the buffer contains data, append */
+ if (unlikely(usbtouch->buf_len)) {
+ int tmp;
+
+ /* if only 1 byte in buffer, add another one to get length */
+ if (usbtouch->buf_len == 1)
+ usbtouch->buffer[1] = pkt[0];
+
+ pkt_len = egalax_get_pkt_len(usbtouch->buffer);
+
+ /* unknown packet: drop everything */
+ if (!pkt_len)
+ return;
+
+ /* append, process */
+ tmp = pkt_len - usbtouch->buf_len;
+ memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
+ usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len);
+
+ buffer = pkt + tmp;
+ buf_len = len - tmp;
+ } else {
+ buffer = pkt;
+ buf_len = len;
+ }
+
+ /* only one byte left in buffer */
+ if (unlikely(buf_len == 1)) {
+ usbtouch->buffer[0] = buffer[0];
+ usbtouch->buf_len = 1;
+ return;
+ }
+
+ /* loop over the buffer */
+ pos = 0;
+ while (pos < buf_len) {
+ /* get packet len */
+ pkt_len = egalax_get_pkt_len(buffer + pos);
+
+ /* unknown packet: drop everything */
+ if (unlikely(!pkt_len))
+ return;
+
+ /* full packet: process */
+ if (likely(pkt_len <= buf_len)) {
+ usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len);
+ } else {
+ /* incomplete packet: save in buffer */
+ memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
+ usbtouch->buf_len = buf_len - pos;
+ }
+ pos += pkt_len;
+ }
+}
+#endif
+
+
+/*****************************************************************************
+ * PanJit Part
+ */
+#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ *x = pkt[1] | ((pkt[2] & 0x0F) << 8);
+ *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
+ *touch = pkt[0] & 0x01;
+
+ return 1;
+}
+#endif
+
+
+/*****************************************************************************
+ * 3M/Microtouch Part
+ */
+#ifdef CONFIG_USB_TOUCHSCREEN_3M
+
+#define MTOUCHUSB_ASYNC_REPORT 1
+#define MTOUCHUSB_RESET 7
+#define MTOUCHUSB_REQ_CTRLLR_ID 10
+
+static int mtouch_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ *x = (pkt[8] << 8) | pkt[7];
+ *y = (pkt[10] << 8) | pkt[9];
+ *touch = (pkt[2] & 0x40) ? 1 : 0;
+
+ return 1;
+}
+
+static int mtouch_init(struct usbtouch_usb *usbtouch)
+{
+ int ret;
+
+ ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+ MTOUCHUSB_RESET,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
+ __FUNCTION__, ret);
+ if (ret < 0)
+ return ret;
+
+ ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+ MTOUCHUSB_ASYNC_REPORT,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
+ dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
+ __FUNCTION__, ret);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+#endif
+
+
+/*****************************************************************************
+ * ITM Part
+ */
+#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+static int itm_read_data(char *pkt, int *x, int *y, int *touch, int *press)
+{
+ *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F);
+ *x = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
+ *press = ((pkt[2] & 0x1F) << 7) | (pkt[5] & 0x7F);
+ *touch = ~pkt[7] & 0x20;
+
+ return 1;
+}
+#endif
+
+
+/*****************************************************************************
+ * the different device descriptors
+ */
+static struct usbtouch_device_info usbtouch_dev_info[] = {
+#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
+ [DEVTYPE_EGALAX] = {
+ .min_xc = 0x0,
+ .max_xc = 0x07ff,
+ .min_yc = 0x0,
+ .max_yc = 0x07ff,
+ .rept_size = 16,
+ .flags = USBTOUCH_FLG_BUFFER,
+ .process_pkt = egalax_process,
+ .read_data = egalax_read_data,
+ },
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
+ [DEVTYPE_PANJIT] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .rept_size = 8,
+ .read_data = panjit_read_data,
+ },
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_3M
+ [DEVTYPE_3M] = {
+ .min_xc = 0x0,
+ .max_xc = 0x4000,
+ .min_yc = 0x0,
+ .max_yc = 0x4000,
+ .rept_size = 11,
+ .read_data = mtouch_read_data,
+ .init = mtouch_init,
+ },
+#endif
+
+#ifdef CONFIG_USB_TOUCHSCREEN_ITM
+ [DEVTYPE_ITM] = {
+ .min_xc = 0x0,
+ .max_xc = 0x0fff,
+ .min_yc = 0x0,
+ .max_yc = 0x0fff,
+ .max_press = 0xff,
+ .rept_size = 8,
+ .read_data = itm_read_data,
+ },
+#endif
+};
+
+
+/*****************************************************************************
+ * Generic Part
+ */
+static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
+ struct pt_regs *regs, char *pkt, int len)
+{
+ int x, y, touch, press;
+ struct usbtouch_device_info *type = usbtouch->type;
+
+ if (!type->read_data(pkt, &x, &y, &touch, &press))
+ return;
+
+ input_regs(usbtouch->input, regs);
+ input_report_key(usbtouch->input, BTN_TOUCH, touch);
+
+ if (invert_x)
+ x = type->max_xc - x;
+ if (invert_y)
+ y = type->max_yc - y;
+
+ if (swap_xy) {
+ input_report_abs(usbtouch->input, ABS_X, y);
+ input_report_abs(usbtouch->input, ABS_Y, x);
+ } else {
+ input_report_abs(usbtouch->input, ABS_X, x);
+ input_report_abs(usbtouch->input, ABS_Y, y);
+ }
+ if (type->max_press)
+ input_report_abs(usbtouch->input, ABS_PRESSURE, press);
+ input_sync(usbtouch->input);
+}
+
+
+static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+ struct usbtouch_usb *usbtouch = 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;
+ }
+
+ usbtouch->type->process_pkt(usbtouch, regs, usbtouch->data, urb->actual_length);
+
+exit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err("%s - usb_submit_urb failed with result: %d",
+ __FUNCTION__, retval);
+}
+
+static int usbtouch_open(struct input_dev *input)
+{
+ struct usbtouch_usb *usbtouch = input->private;
+
+ usbtouch->irq->dev = usbtouch->udev;
+
+ if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void usbtouch_close(struct input_dev *input)
+{
+ struct usbtouch_usb *usbtouch = input->private;
+
+ usb_kill_urb(usbtouch->irq);
+}
+
+
+static void usbtouch_free_buffers(struct usb_device *udev,
+ struct usbtouch_usb *usbtouch)
+{
+ if (usbtouch->data)
+ usb_buffer_free(udev, usbtouch->type->rept_size,
+ usbtouch->data, usbtouch->data_dma);
+ kfree(usbtouch->buffer);
+}
+
+
+static int usbtouch_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usbtouch_usb *usbtouch;
+ struct input_dev *input_dev;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct usbtouch_device_info *type;
+ int err;
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+
+ usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!usbtouch || !input_dev)
+ goto out_free;
+
+ type = &usbtouch_dev_info[id->driver_info];
+ usbtouch->type = type;
+ if (!type->process_pkt)
+ type->process_pkt = usbtouch_process_pkt;
+
+ usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
+ SLAB_KERNEL, &usbtouch->data_dma);
+ if (!usbtouch->data)
+ goto out_free;
+
+ if (type->flags & USBTOUCH_FLG_BUFFER) {
+ usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL);
+ if (!usbtouch->buffer)
+ goto out_free_buffers;
+ }
+
+ usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!usbtouch->irq) {
+ dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
+ goto out_free_buffers;
+ }
+
+ usbtouch->udev = udev;
+ usbtouch->input = input_dev;
+
+ if (udev->manufacturer)
+ strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name));
+
+ if (udev->product) {
+ if (udev->manufacturer)
+ strlcat(usbtouch->name, " ", sizeof(usbtouch->name));
+ strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name));
+ }
+
+ if (!strlen(usbtouch->name))
+ snprintf(usbtouch->name, sizeof(usbtouch->name),
+ "USB Touchscreen %04x:%04x",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct));
+
+ usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));
+ strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
+
+ input_dev->name = usbtouch->name;
+ input_dev->phys = usbtouch->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->cdev.dev = &intf->dev;
+ input_dev->private = usbtouch;
+ input_dev->open = usbtouch_open;
+ input_dev->close = usbtouch_close;
+
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
+ if (type->max_press)
+ input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,
+ type->max_press, 0, 0);
+
+ usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
+ usb_rcvintpipe(usbtouch->udev, 0x81),
+ usbtouch->data, type->rept_size,
+ usbtouch_irq, usbtouch, endpoint->bInterval);
+
+ usbtouch->irq->transfer_dma = usbtouch->data_dma;
+ usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ /* device specific init */
+ if (type->init) {
+ err = type->init(usbtouch);
+ if (err) {
+ dbg("%s - type->init() failed, err: %d", __FUNCTION__, err);
+ goto out_free_buffers;
+ }
+ }
+
+ err = input_register_device(usbtouch->input);
+ if (err) {
+ dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err);
+ goto out_free_buffers;
+ }
+
+ usb_set_intfdata(intf, usbtouch);
+
+ return 0;
+
+out_free_buffers:
+ usbtouch_free_buffers(udev, usbtouch);
+out_free:
+ input_free_device(input_dev);
+ kfree(usbtouch);
+ return -ENOMEM;
+}
+
+static void usbtouch_disconnect(struct usb_interface *intf)
+{
+ struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
+
+ dbg("%s - called", __FUNCTION__);
+
+ if (!usbtouch)
+ return;
+
+ dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
+ usb_set_intfdata(intf, NULL);
+ usb_kill_urb(usbtouch->irq);
+ input_unregister_device(usbtouch->input);
+ usb_free_urb(usbtouch->irq);
+ usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
+ kfree(usbtouch);
+}
+
+MODULE_DEVICE_TABLE(usb, usbtouch_devices);
+
+static struct usb_driver usbtouch_driver = {
+ .name = "usbtouchscreen",
+ .probe = usbtouch_probe,
+ .disconnect = usbtouch_disconnect,
+ .id_table = usbtouch_devices,
+};
+
+static int __init usbtouch_init(void)
+{
+ return usb_register(&usbtouch_driver);
+}
+
+static void __exit usbtouch_cleanup(void)
+{
+ usb_deregister(&usbtouch_driver);
+}
+
+module_init(usbtouch_init);
+module_exit(usbtouch_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS("touchkitusb");
+MODULE_ALIAS("itmtouch");
+MODULE_ALIAS("mtouchusb");

2006-03-15 22:13:25

by Greg KH

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Wed, Mar 15, 2006 at 10:54:37PM +0100, Daniel Ritz wrote:
> hi
>
> here the updated version of the patch. changes since first version:
> - only advertise ABS_PRESSURE when device supports it
> - handle input_register_device() errors
> - allow vendor specifc init to fail.
> - add invert_x/invert_y modparams
> - only care about 12 bits for panjit
>
> thanks for all the inputs.
>
> rgds
> -daniel
>
> -----
>
> [PATCH] usb/input/usbtouchscreen: unified USB touchscreen driver
>
> A new single driver for various USB touchscreen devices. It currently
> supports:
> - eGalax TouchKit
> - PanJit TouchSet
> - 3M/Microtouch
> - ITM Touchscreens
>
> Support for the diffent devices can be enabled/disable when CONFIG_EMBEDDED
> is set.
>
> It's offering the same module params for all screens:
> - swap_xy: swaps X and Y axes
> - invert_x/invert_y: inverts X/Y.

These should be sysfs attributes, on the devices, which will allow them
to be set individually for the different devices. You can use the
module paramater as the default to start with, so don't drop that.

thanks,

greg k-h

2006-03-16 06:46:36

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

i'm not sure if any touch device need this.
If some need, please move any code to general part. thx.


On 3/15/06, Jan-Benedict Glaw <[email protected]> wrote:
> On Wed, 2006-03-15 12:30:04 +0800, Lanslott Gish <[email protected]> wrote:
> > did you mean like that? thx.
>
> That's basically the same patch as before?! What was ment is to move
> inverting the axes into usbtouch_process_pkt().
>
> MfG, JBG
>
> --


--
L.G, Life's Good~

2006-03-17 02:46:09

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On 3/16/06, Daniel Ritz <[email protected]> wrote:
> On Wednesday 15 March 2006 05.30, Lanslott Gish wrote:
> > did you mean like that? thx.
> >
> > regards,
> >
> > Lanslott Gish
> > ===================================================================
> > --- linux-2.6.16-rc6.patched/drivers/usb/input/usbtouchscreen.c
> > +++ linux-2.6.16-rc6/drivers/usb/input/usbtouchscreen.c
> > @@ -49,6 +49,13 @@
> > static int swap_xy;
> > module_param(swap_xy, bool, 0644);
> > MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
> > +static int swap_x;
> > +module_param(swap_x, bool, 0644);
> > +MODULE_PARM_DESC(swap_x, "If set X axe is swapped before XY swapped.");
> > +static int swap_y;
> > +module_param(swap_y, bool, 0644);
> > +MODULE_PARM_DESC(swap_y, "If set Y axe is swapped before XY swapped.");
> > +
> >
> (i prefer invert_x and invert_y...)
>
"invert" is great, thx.
evtouch(X11 driver) called these swap_x and swap_y

> >
> > /* device specifc data/functions */
> > @@ -224,13 +231,17 @@
> > * PanJit Part
> > */
> > #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
> > +
> > static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
> > {
> > - *x = pkt[1] | (pkt[2] << 8);
> > - *y = pkt[3] | (pkt[4] << 8);
> > + *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
> > + *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);
>
> that just can't be right. you probably mean
> + *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
>
> otherwise you mask out bits 4-7. but you want to limit it to 12 bits...
> (btw. no need for the & 0xFF mask since *pkt is char)
>

you are right, sorry for my fault. the truely way is

+ *x = (pkt[1] & 0xFF) | ((pkt[2] & 0x0F) << 8);
+ *y = (pkt[3] & 0xFF) | ((pkt[4] & 0x0F) << 8);

still need 12 bits( 0x0FFF) and the masks to avoid get negative.


BTW, may i also suggest add more module_param to max_x, max_y, min_x, min_y ?
i think these options is useful, too.

regards,

Lanslott Gish
--
L.G, Life's Good~

2006-03-17 21:50:09

by Daniel Ritz

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Friday 17 March 2006 03.46, Lanslott Gish wrote:
> On 3/16/06, Daniel Ritz <[email protected]> wrote:
> > On Wednesday 15 March 2006 05.30, Lanslott Gish wrote:
> > > did you mean like that? thx.
> > >
> > > regards,
> > >
> > > Lanslott Gish
> > > ===================================================================
> > > --- linux-2.6.16-rc6.patched/drivers/usb/input/usbtouchscreen.c
> > > +++ linux-2.6.16-rc6/drivers/usb/input/usbtouchscreen.c
> > > @@ -49,6 +49,13 @@
> > > static int swap_xy;
> > > module_param(swap_xy, bool, 0644);
> > > MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
> > > +static int swap_x;
> > > +module_param(swap_x, bool, 0644);
> > > +MODULE_PARM_DESC(swap_x, "If set X axe is swapped before XY swapped.");
> > > +static int swap_y;
> > > +module_param(swap_y, bool, 0644);
> > > +MODULE_PARM_DESC(swap_y, "If set Y axe is swapped before XY swapped.");
> > > +
> > >
> > (i prefer invert_x and invert_y...)
> >
> "invert" is great, thx.
> evtouch(X11 driver) called these swap_x and swap_y
>

i think i drop it alltogether. as greg already mentioned it should be
sysfs attributes. ( besides it's completely doable in userspace. and
evtouch can do it. )

> > >
> > > /* device specifc data/functions */
> > > @@ -224,13 +231,17 @@
> > > * PanJit Part
> > > */
> > > #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
> > > +
> > > static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
> > > {
> > > - *x = pkt[1] | (pkt[2] << 8);
> > > - *y = pkt[3] | (pkt[4] << 8);
> > > + *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
> > > + *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);
> >
> > that just can't be right. you probably mean
> > + *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
> >
> > otherwise you mask out bits 4-7. but you want to limit it to 12 bits...
> > (btw. no need for the & 0xFF mask since *pkt is char)
> >
>
> you are right, sorry for my fault. the truely way is
>
> + *x = (pkt[1] & 0xFF) | ((pkt[2] & 0x0F) << 8);
> + *y = (pkt[3] & 0xFF) | ((pkt[4] & 0x0F) << 8);
>
> still need 12 bits( 0x0FFF) and the masks to avoid get negative.

my latest patch has it right. and no, you don't need the mask for the lower
8 bits, only for the upper 4.

>
>
> BTW, may i also suggest add more module_param to max_x, max_y, min_x, min_y ?
> i think these options is useful, too.

no chance. (and if i remember correctly it's possible via evdev ioctl)

rgds
-daniel

2006-03-21 04:23:09

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On 3/18/06, Daniel Ritz <[email protected]> wrote:
> On Friday 17 March 2006 03.46, Lanslott Gish wrote:
> > On 3/16/06, Daniel Ritz <[email protected]> wrote:
> > "invert" is great, thx.
> > evtouch(X11 driver) called these swap_x and swap_y
> >
>
> i think i drop it alltogether. as greg already mentioned it should be
> sysfs attributes. ( besides it's completely doable in userspace. and
> evtouch can do it. )
>
> >
> >
> > BTW, may i also suggest add more module_param to max_x, max_y, min_x, min_y ?
> > i think these options is useful, too.
>
> no chance. (and if i remember correctly it's possible via evdev ioctl)
>


i could use my device in X without evtouch.o or any X-module or any
xorg.conf modified, but wrong positions to cursor.

and consider using touchscreens in console(framebuffer) mode, or
without evtouch in X, or devices do not provide several functions.

suppose we can something in /etc/rc.d/rc.local or some files:

/sbin/modprobe usbtouchscreen swap_xy=1,min_x=123,max_y=456,....

we don't need any calibrate tool or guest several functions from
devices, and complete this module.



Anyway, just some suggestions. thx :)

regards,

Lanslott Gish



> > > >
> > > > /* device specifc data/functions */
> > > > @@ -224,13 +231,17 @@
> > > > * PanJit Part
> > > > */
> > > > #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
> > > > +
> > > > static int panjit_read_data(char *pkt, int *x, int *y, int *touch, int *press)
> > > > {
> > > > - *x = pkt[1] | (pkt[2] << 8);
> > > > - *y = pkt[3] | (pkt[4] << 8);
> > > > + *x = (pkt[1] & 0x0F) | ((pkt[2]& 0xFF) << 8);
> > > > + *y = (pkt[3] & 0x0F) | ((pkt[4]& 0xFF) << 8);
> > >
> > > that just can't be right. you probably mean
> > > + *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
> > >
> > > otherwise you mask out bits 4-7. but you want to limit it to 12 bits...
> > > (btw. no need for the & 0xFF mask since *pkt is char)
> > >
> >
> > you are right, sorry for my fault. the truely way is
> >

> >
> > still need 12 bits( 0x0FFF) and the masks to avoid get negative.
>
> my latest patch has it right. and no, you don't need the mask for the lower
> 8 bits, only for the upper 4.
>

--
L.G, Life's Good~

2006-03-21 06:39:10

by Lanslott Gish

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On 3/17/06, Lanslott Gish <[email protected]> wrote:
> On 3/16/06, Daniel Ritz <[email protected]> wrote:
> that just can't be right. you probably mean
> + *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
>
> otherwise you mask out bits 4-7. but you want to limit it to 12 bits...
> (btw. no need for the & 0xFF mask since *pkt is char)
>
>
> you are right, sorry for my fault. the truely way is
>
> + *x = (pkt[1] & 0xFF) | ((pkt[2] & 0x0F) << 8);
> + *y = (pkt[3] & 0xFF) | ((pkt[4] & 0x0F) << 8);
>
> still need 12 bits( 0x0FFF) and the masks to avoid get negative.
>


OK, Here we go~
i try your patch:

+ printk("pkg_dbg,%x,%x,%x,%x\n",pkt[1],pkt[2],pkt[3],pkt[4]);
+ *x = pkt[1] | ((pkt[2] & 0x0F) << 8);
+ *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
+ printk("touchset_dbg,%x,%x,%d,%d\n",*x,*y,*x,*y);

and here is parts of the /var/log/message (raw data from 4 corners of
the panel):

---------------------------------------------------------------------------
Mar 21 14:33:52 localhost kernel: input: PANJIT TouchSet USB Touch
Panel as /class/input/input12
Mar 21 14:33:55 localhost input.agent[10300]: joydev: already loaded
Mar 21 14:34:38 localhost kernel: pkg_dbg,fffffff9,1,2d,e
Mar 21 14:34:38 localhost kernel: touchset_dbg,fffffff9,e2d,-7,3629
Mar 21 14:34:38 localhost kernel: pkg_dbg,fffffff8,1,2c,e
Mar 21 14:34:38 localhost kernel: touchset_dbg,fffffff8,e2c,-8,3628
Mar 21 14:34:38 localhost kernel: pkg_dbg,fffffff4,1,2d,e
Mar 21 14:34:38 localhost kernel: touchset_dbg,fffffff4,e2d,-12,3629
Mar 21 14:34:38 localhost kernel: pkg_dbg,fffffff2,1,2d,e
Mar 21 14:34:38 localhost kernel: touchset_dbg,fffffff2,e2d,-14,3629
Mar 21 14:34:38 localhost kernel: pkg_dbg,fffffff1,1,2e,e
Mar 21 14:34:38 localhost kernel: touchset_dbg,fffffff1,e2e,-15,3630
Mar 21 14:34:39 localhost kernel: pkg_dbg,20,3,ffffffae,2
Mar 21 14:34:39 localhost kernel: touchset_dbg,320,ffffffae,800,-82
Mar 21 14:34:39 localhost kernel: pkg_dbg,20,3,ffffffae,2
Mar 21 14:34:39 localhost kernel: touchset_dbg,320,ffffffae,800,-82
Mar 21 14:34:39 localhost kernel: pkg_dbg,1d,3,ffffffb2,2
Mar 21 14:34:39 localhost kernel: touchset_dbg,31d,ffffffb2,797,-78
Mar 21 14:34:39 localhost kernel: pkg_dbg,1b,3,ffffffb4,2
Mar 21 14:34:39 localhost kernel: touchset_dbg,31b,ffffffb4,795,-76
Mar 21 14:34:41 localhost kernel: pkg_dbg,ffffffa4,c,75,d
Mar 21 14:34:41 localhost kernel: touchset_dbg,ffffffa4,d75,-92,3445
Mar 21 14:34:41 localhost kernel: pkg_dbg,ffffffa4,c,7a,d
Mar 21 14:34:41 localhost kernel: touchset_dbg,ffffffa4,d7a,-92,3450
Mar 21 14:34:41 localhost kernel: pkg_dbg,ffffffa2,c,ffffff81,d
Mar 21 14:34:41 localhost kernel: touchset_dbg,ffffffa2,ffffff81,-94,-127
Mar 21 14:34:41 localhost kernel: pkg_dbg,ffffff9d,c,ffffff87,d
Mar 21 14:34:41 localhost kernel: touchset_dbg,ffffff9d,ffffff87,-99,-121
Mar 21 14:34:42 localhost kernel: pkg_dbg,ffffff86,d,ffffffcf,1
Mar 21 14:34:42 localhost kernel: touchset_dbg,ffffff86,ffffffcf,-122,-49
Mar 21 14:34:42 localhost kernel: pkg_dbg,74,d,ffffffd7,1
Mar 21 14:34:42 localhost kernel: touchset_dbg,d74,ffffffd7,3444,-41
Mar 21 14:34:42 localhost kernel: pkg_dbg,58,d,ffffffe0,1
Mar 21 14:34:42 localhost kernel: touchset_dbg,d58,ffffffe0,3416,-32
----------------------------------------------------------------------


is anything weird?
and i try my codes:

+ printk("pkg_dbg,%x,%x,%x,%x\n",pkt[1],pkt[2],pkt[3],pkt[4]);
+ *x = (pkt[1] & 0xFF) | ((pkt[2] & 0x0F) << 8);
+ *y = (pkt[3] & 0xFF) | ((pkt[4] & 0x0F) << 8);
+ printk("touchset_dbg,%x,%x,%d,%d\n",*x,*y,*x,*y);

and here is the /var/log/message (the same, 4 coners):

---------------------------------------------------------------------
Mar 21 14:38:14 localhost kernel: usbcore: deregistering driver usbtouchscreen
Mar 21 14:38:14 localhost kernel: input: PANJIT TouchSet USB Touch
Panel as /class/input/input14
Mar 21 14:38:14 localhost kernel: usbcore: registered new driver usbtouchscreen
Mar 21 14:38:17 localhost input.agent[10688]: joydev: already loaded
Mar 21 14:38:38 localhost kernel: pkg_dbg,5,2,6,e
Mar 21 14:38:38 localhost kernel: touchset_dbg,205,e06,517,3590
Mar 21 14:38:38 localhost kernel: pkg_dbg,fffffffe,1,13,e
Mar 21 14:38:38 localhost kernel: touchset_dbg,1fe,e13,510,3603
Mar 21 14:38:38 localhost kernel: pkg_dbg,fffffff0,1,22,e
Mar 21 14:38:38 localhost kernel: touchset_dbg,1f0,e22,496,3618
Mar 21 14:38:39 localhost kernel: pkg_dbg,ffffffd5,2,ffffff99,2
Mar 21 14:38:39 localhost kernel: touchset_dbg,2d5,299,725,665
Mar 21 14:38:39 localhost kernel: pkg_dbg,ffffffd2,2,ffffff9a,2
Mar 21 14:38:39 localhost kernel: touchset_dbg,2d2,29a,722,666
Mar 21 14:38:39 localhost kernel: pkg_dbg,ffffffce,2,ffffff9c,2
Mar 21 14:38:39 localhost kernel: touchset_dbg,2ce,29c,718,668
Mar 21 14:38:39 localhost kernel: pkg_dbg,ffffffc9,2,ffffff9e,2
Mar 21 14:38:39 localhost kernel: touchset_dbg,2c9,29e,713,670
Mar 21 14:38:41 localhost kernel: pkg_dbg,6e,d,ffffffec,d
Mar 21 14:38:41 localhost kernel: touchset_dbg,d6e,dec,3438,3564
Mar 21 14:38:41 localhost kernel: pkg_dbg,71,d,ffffffed,d
Mar 21 14:38:41 localhost kernel: touchset_dbg,d71,ded,3441,3565
Mar 21 14:38:41 localhost kernel: pkg_dbg,72,d,ffffffed,d
Mar 21 14:38:41 localhost kernel: touchset_dbg,d72,ded,3442,3565
Mar 21 14:38:41 localhost kernel: pkg_dbg,71,d,ffffffed,d
Mar 21 14:38:41 localhost kernel: touchset_dbg,d71,ded,3441,3565
Mar 21 14:38:41 localhost kernel: pkg_dbg,5f,d,ffffffec,d
Mar 21 14:38:41 localhost kernel: touchset_dbg,d5f,dec,3423,3564
Mar 21 14:38:42 localhost kernel: pkg_dbg,ffffffac,d,ffffffd0,1
Mar 21 14:38:42 localhost kernel: touchset_dbg,dac,1d0,3500,464
Mar 21 14:38:42 localhost kernel: pkg_dbg,ffffffae,d,ffffffd0,1
Mar 21 14:38:42 localhost kernel: touchset_dbg,dae,1d0,3502,464
Mar 21 14:38:42 localhost kernel: pkg_dbg,ffffffa3,d,ffffffdb,1
Mar 21 14:38:42 localhost kernel: touchset_dbg,da3,1db,3491,475
Mar 21 14:38:42 localhost kernel: pkg_dbg,ffffff92,d,ffffffe6,1
Mar 21 14:38:42 localhost kernel: touchset_dbg,d92,1e6,3474,486
---------------------------------------------------------------------
i think my codes is correct.

so, make sure that your device differ with mine. :)


regards,

Lanslott Gish
--
L.G, Life's Good~

2006-03-21 20:21:45

by Daniel Ritz

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Tuesday 21 March 2006 05.23, Lanslott Gish wrote:
> On 3/18/06, Daniel Ritz <[email protected]> wrote:
> > On Friday 17 March 2006 03.46, Lanslott Gish wrote:
> > >
> > > BTW, may i also suggest add more module_param to max_x, max_y, min_x, min_y ?
> > > i think these options is useful, too.
> >
> > no chance. (and if i remember correctly it's possible via evdev ioctl)
> >
>
>
> i could use my device in X without evtouch.o or any X-module or any
> xorg.conf modified, but wrong positions to cursor.
>
> and consider using touchscreens in console(framebuffer) mode, or
> without evtouch in X, or devices do not provide several functions.
>
> suppose we can something in /etc/rc.d/rc.local or some files:
>
> /sbin/modprobe usbtouchscreen swap_xy=1,min_x=123,max_y=456,....
>
> we don't need any calibrate tool or guest several functions from
> devices, and complete this module.
>
>
>
> Anyway, just some suggestions. thx :)

well, all nice and good, but...it doesn't belong into the driver.
it would belong into the input subsystem or evdev. there are other
absolute devices not handled by this driver that need the same
calibration...
but i still think it should be in userspace...

still, it might be worth discussing it with the input hackers.

>
> regards,
>
> Lanslott Gish
>

rgds
-daniel

2006-03-21 20:21:43

by Daniel Ritz

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

On Tuesday 21 March 2006 07.39, Lanslott Gish wrote:
> On 3/17/06, Lanslott Gish <[email protected]> wrote:
> > On 3/16/06, Daniel Ritz <[email protected]> wrote:
> > that just can't be right. you probably mean
> > + *y = pkt[3] | ((pkt[4] & 0x0F) << 8);
> >
> > otherwise you mask out bits 4-7. but you want to limit it to 12 bits...
> > (btw. no need for the & 0xFF mask since *pkt is char)
> >
> >
> > you are right, sorry for my fault. the truely way is
> >
> > + *x = (pkt[1] & 0xFF) | ((pkt[2] & 0x0F) << 8);
> > + *y = (pkt[3] & 0xFF) | ((pkt[4] & 0x0F) << 8);
> >
> > still need 12 bits( 0x0FFF) and the masks to avoid get negative.
> >

ok, ok, there is a bug. but the mask is still not needed. the
real bug is that pkt is of type char instead of unsigned char.
so a simple cast would be enough:
+ *x = (unsigned char) pkt[1] | ((pkt[2] & 0x0F) << 8);

but i changed the whole thing to unsigned char all over the place.
it's better anyway.

rgds
-daniel

2006-03-21 22:48:08

by Todd E. Johnson

[permalink] [raw]
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one

Howdy,

This has always been a bit of a fuzzy area to me since the 3M / Microtouch controllers support calibration within the device. (i.e.: send raw output, or the devices internally calculated - calibrated - output.). After asking this question long ago, I decided to document it and move on... Is there a userland calibration mechanism for anything in the userspace besides something like QT Embedded?


Regards,

Todd E. Johnson


----- Original Message ----
From: Daniel Ritz <[email protected]>
To: Lanslott Gish <[email protected]>
Cc: Greg KH <[email protected]>; Dmitry Torokhov <[email protected]>; linux-kernel <[email protected]>; linux-usb <[email protected]>; [email protected]; [email protected]; [email protected]
Sent: Tuesday, March 21, 2006 3:22:02 PM
Subject: Re: [RFC][PATCH] USB touch screen driver, all-in-one


On Tuesday 21 March 2006 05.23, Lanslott Gish wrote:
> On 3/18/06, Daniel Ritz <[email protected]> wrote:
> > On Friday 17 March 2006 03.46, Lanslott Gish wrote:
> > >
> > > BTW, may i also suggest add more module_param to max_x, max_y, min_x, min_y ?
> > > i think these options is useful, too.
> >
> > no chance. (and if i remember correctly it's possible via evdev ioctl)
> >
>
>
> i could use my device in X without evtouch.o or any X-module or any
> xorg.conf modified, but wrong positions to cursor.
>
> and consider using touchscreens in console(framebuffer) mode, or
> without evtouch in X, or devices do not provide several functions.
>
> suppose we can something in /etc/rc.d/rc.local or some files:
>
> /sbin/modprobe usbtouchscreen swap_xy=1,min_x=123,max_y=456,....
>
> we don't need any calibrate tool or guest several functions from
> devices, and complete this module.
>
>
>
> Anyway, just some suggestions. thx :)

well, all nice and good, but...it doesn't belong into the driver.
it would belong into the input subsystem or evdev. there are other
absolute devices not handled by this driver that need the same
calibration...
but i still think it should be in userspace...

still, it might be worth discussing it with the input hackers.

>
> regards,
>
> Lanslott Gish
>

rgds
-daniel