* [PATCH] Try to add support for universal USB touchscreen device, and WISH for help~
@ 2006-03-10 9:24 Lanslott Gish
2006-03-11 20:55 ` [RFC][PATCH] USB touch screen driver, all-in-one Daniel Ritz
0 siblings, 1 reply; 19+ messages in thread
From: Lanslott Gish @ 2006-03-10 9:24 UTC (permalink / raw)
To: Greg KH, Daniel Ritz, Dmitry Torokhov
Cc: linux-kernel, linux-usb, Daniel Ritz
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 <daniel.ritz@gmx.ch>
+ * 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 <lanslott.gish@gmail.com>"
+#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 <daniel.ritz@gmx.ch>
+ * 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~
^ permalink raw reply [flat|nested] 19+ messages in thread* [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-10 9:24 [PATCH] Try to add support for universal USB touchscreen device, and WISH for help~ Lanslott Gish @ 2006-03-11 20:55 ` Daniel Ritz 2006-03-12 1:31 ` Dmitry Torokhov ` (2 more replies) 0 siblings, 3 replies; 19+ messages in thread From: Daniel Ritz @ 2006-03-11 20:55 UTC (permalink / raw) To: Lanslott Gish, Greg KH, Dmitry Torokhov, linux-kernel, linux-usb Cc: tejohnson, hc, vojtech 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 <daniel.ritz@gmx.ch> 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 <daniel.ritz@gmx.ch> + * 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 <daniel.ritz@gmx.ch>" +#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"); ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-11 20:55 ` [RFC][PATCH] USB touch screen driver, all-in-one Daniel Ritz @ 2006-03-12 1:31 ` Dmitry Torokhov 2006-03-13 1:01 ` Lanslott Gish 2006-03-15 21:54 ` Daniel Ritz 2 siblings, 0 replies; 19+ messages in thread From: Dmitry Torokhov @ 2006-03-12 1:31 UTC (permalink / raw) To: Daniel Ritz Cc: Lanslott Gish, Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-11 20:55 ` [RFC][PATCH] USB touch screen driver, all-in-one Daniel Ritz 2006-03-12 1:31 ` Dmitry Torokhov @ 2006-03-13 1:01 ` Lanslott Gish 2006-03-14 1:10 ` Lanslott Gish 2006-03-15 21:54 ` Daniel Ritz 2 siblings, 1 reply; 19+ messages in thread From: Lanslott Gish @ 2006-03-13 1:01 UTC (permalink / raw) To: Daniel Ritz Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech Hi, Daniel, it's great. i will test touchset part today. Regards, Lanslott Gish On 3/12/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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 > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-13 1:01 ` Lanslott Gish @ 2006-03-14 1:10 ` Lanslott Gish 2006-03-14 10:38 ` Jan-Benedict Glaw 0 siblings, 1 reply; 19+ messages in thread From: Lanslott Gish @ 2006-03-14 1:10 UTC (permalink / raw) To: Daniel Ritz Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech 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 <lanslott.gish@gmail.com> wrote: > Hi, Daniel, > it's great. i will test touchset part today. > > Regards, > > Lanslott Gish > > On 3/12/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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~ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-14 1:10 ` Lanslott Gish @ 2006-03-14 10:38 ` Jan-Benedict Glaw 2006-03-15 4:30 ` Lanslott Gish 0 siblings, 1 reply; 19+ messages in thread From: Jan-Benedict Glaw @ 2006-03-14 10:38 UTC (permalink / raw) To: Lanslott Gish Cc: Daniel Ritz, Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech [-- Attachment #1: Type: text/plain, Size: 1856 bytes --] On Tue, 2006-03-14 09:10:13 +0800, Lanslott Gish <lanslott.gish@gmail.com> 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 jbglaw@lug-owl.de . +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)); [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-14 10:38 ` Jan-Benedict Glaw @ 2006-03-15 4:30 ` Lanslott Gish 2006-03-15 14:08 ` Jan-Benedict Glaw 2006-03-15 21:53 ` Daniel Ritz 0 siblings, 2 replies; 19+ messages in thread From: Lanslott Gish @ 2006-03-15 4:30 UTC (permalink / raw) To: Lanslott Gish, Daniel Ritz, Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech 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 <jbglaw@lug-owl.de> wrote: > On Tue, 2006-03-14 09:10:13 +0800, Lanslott Gish <lanslott.gish@gmail.com> 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 jbglaw@lug-owl.de . +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~ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-15 4:30 ` Lanslott Gish @ 2006-03-15 14:08 ` Jan-Benedict Glaw 2006-03-16 6:46 ` Lanslott Gish 2006-03-15 21:53 ` Daniel Ritz 1 sibling, 1 reply; 19+ messages in thread From: Jan-Benedict Glaw @ 2006-03-15 14:08 UTC (permalink / raw) To: Lanslott Gish Cc: Daniel Ritz, Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech [-- Attachment #1: Type: text/plain, Size: 580 bytes --] On Wed, 2006-03-15 12:30:04 +0800, Lanslott Gish <lanslott.gish@gmail.com> 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 jbglaw@lug-owl.de . +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)); [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-15 14:08 ` Jan-Benedict Glaw @ 2006-03-16 6:46 ` Lanslott Gish 0 siblings, 0 replies; 19+ messages in thread From: Lanslott Gish @ 2006-03-16 6:46 UTC (permalink / raw) To: Lanslott Gish, Daniel Ritz, Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech 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 <jbglaw@lug-owl.de> wrote: > On Wed, 2006-03-15 12:30:04 +0800, Lanslott Gish <lanslott.gish@gmail.com> 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~ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-15 4:30 ` Lanslott Gish 2006-03-15 14:08 ` Jan-Benedict Glaw @ 2006-03-15 21:53 ` Daniel Ritz 2006-03-17 2:46 ` Lanslott Gish 1 sibling, 1 reply; 19+ messages in thread From: Daniel Ritz @ 2006-03-15 21:53 UTC (permalink / raw) To: Lanslott Gish Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-15 21:53 ` Daniel Ritz @ 2006-03-17 2:46 ` Lanslott Gish 2006-03-17 21:50 ` Daniel Ritz 2006-03-21 6:39 ` Lanslott Gish 0 siblings, 2 replies; 19+ messages in thread From: Lanslott Gish @ 2006-03-17 2:46 UTC (permalink / raw) To: Daniel Ritz Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech On 3/16/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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~ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-17 2:46 ` Lanslott Gish @ 2006-03-17 21:50 ` Daniel Ritz 2006-03-21 4:23 ` Lanslott Gish 2006-03-21 6:39 ` Lanslott Gish 1 sibling, 1 reply; 19+ messages in thread From: Daniel Ritz @ 2006-03-17 21:50 UTC (permalink / raw) To: Lanslott Gish Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech On Friday 17 March 2006 03.46, Lanslott Gish wrote: > On 3/16/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-17 21:50 ` Daniel Ritz @ 2006-03-21 4:23 ` Lanslott Gish 2006-03-21 20:22 ` Daniel Ritz 0 siblings, 1 reply; 19+ messages in thread From: Lanslott Gish @ 2006-03-21 4:23 UTC (permalink / raw) To: Daniel Ritz Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech On 3/18/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> wrote: > On Friday 17 March 2006 03.46, Lanslott Gish wrote: > > On 3/16/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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~ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-21 4:23 ` Lanslott Gish @ 2006-03-21 20:22 ` Daniel Ritz 2006-03-21 22:48 ` Todd E. Johnson 0 siblings, 1 reply; 19+ messages in thread From: Daniel Ritz @ 2006-03-21 20:22 UTC (permalink / raw) To: Lanslott Gish Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech On Tuesday 21 March 2006 05.23, Lanslott Gish wrote: > On 3/18/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-21 20:22 ` Daniel Ritz @ 2006-03-21 22:48 ` Todd E. Johnson 0 siblings, 0 replies; 19+ messages in thread From: Todd E. Johnson @ 2006-03-21 22:48 UTC (permalink / raw) To: Daniel Ritz, Lanslott Gish Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, hc, vojtech 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 <daniel.ritz-ml@swissonline.ch> To: Lanslott Gish <lanslott.gish@gmail.com> Cc: Greg KH <greg@kroah.com>; Dmitry Torokhov <dmitry.torokhov@gmail.com>; linux-kernel <linux-kernel@vger.kernel.org>; linux-usb <linux-usb-devel@lists.sourceforge.net>; tejohnson@yahoo.com; hc@mivu.no; vojtech@suse.cz 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 <daniel.ritz-ml@swissonline.ch> 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-17 2:46 ` Lanslott Gish 2006-03-17 21:50 ` Daniel Ritz @ 2006-03-21 6:39 ` Lanslott Gish 2006-03-21 20:21 ` Daniel Ritz 1 sibling, 1 reply; 19+ messages in thread From: Lanslott Gish @ 2006-03-21 6:39 UTC (permalink / raw) To: Daniel Ritz Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech On 3/17/06, Lanslott Gish <lanslott.gish@gmail.com> wrote: > On 3/16/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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~ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-21 6:39 ` Lanslott Gish @ 2006-03-21 20:21 ` Daniel Ritz 0 siblings, 0 replies; 19+ messages in thread From: Daniel Ritz @ 2006-03-21 20:21 UTC (permalink / raw) To: Lanslott Gish Cc: Greg KH, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech On Tuesday 21 March 2006 07.39, Lanslott Gish wrote: > On 3/17/06, Lanslott Gish <lanslott.gish@gmail.com> wrote: > > On 3/16/06, Daniel Ritz <daniel.ritz-ml@swissonline.ch> 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-11 20:55 ` [RFC][PATCH] USB touch screen driver, all-in-one Daniel Ritz 2006-03-12 1:31 ` Dmitry Torokhov 2006-03-13 1:01 ` Lanslott Gish @ 2006-03-15 21:54 ` Daniel Ritz 2006-03-15 22:13 ` Greg KH 2 siblings, 1 reply; 19+ messages in thread From: Daniel Ritz @ 2006-03-15 21:54 UTC (permalink / raw) To: Lanslott Gish, Greg KH, Dmitry Torokhov Cc: linux-kernel, linux-usb, tejohnson, hc, vojtech 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 <daniel.ritz@gmx.ch> 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 <daniel.ritz@gmx.ch> + * 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 <daniel.ritz@gmx.ch>" +#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"); ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [RFC][PATCH] USB touch screen driver, all-in-one 2006-03-15 21:54 ` Daniel Ritz @ 2006-03-15 22:13 ` Greg KH 0 siblings, 0 replies; 19+ messages in thread From: Greg KH @ 2006-03-15 22:13 UTC (permalink / raw) To: Daniel Ritz Cc: Lanslott Gish, Dmitry Torokhov, linux-kernel, linux-usb, tejohnson, hc, vojtech 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2006-03-21 22:48 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-03-10 9:24 [PATCH] Try to add support for universal USB touchscreen device, and WISH for help~ Lanslott Gish 2006-03-11 20:55 ` [RFC][PATCH] USB touch screen driver, all-in-one Daniel Ritz 2006-03-12 1:31 ` Dmitry Torokhov 2006-03-13 1:01 ` Lanslott Gish 2006-03-14 1:10 ` Lanslott Gish 2006-03-14 10:38 ` Jan-Benedict Glaw 2006-03-15 4:30 ` Lanslott Gish 2006-03-15 14:08 ` Jan-Benedict Glaw 2006-03-16 6:46 ` Lanslott Gish 2006-03-15 21:53 ` Daniel Ritz 2006-03-17 2:46 ` Lanslott Gish 2006-03-17 21:50 ` Daniel Ritz 2006-03-21 4:23 ` Lanslott Gish 2006-03-21 20:22 ` Daniel Ritz 2006-03-21 22:48 ` Todd E. Johnson 2006-03-21 6:39 ` Lanslott Gish 2006-03-21 20:21 ` Daniel Ritz 2006-03-15 21:54 ` Daniel Ritz 2006-03-15 22:13 ` Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox