diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-31 12:10:28 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-31 12:10:28 -0800 |
commit | 80d534567378ce62ba8e2c51a3b6621e5b8b5605 (patch) | |
tree | 805322f31f88df173918bec787285835c33d1ccf /usb | |
parent | 7446377126dc0e69c4d60dd3edf557efdd150337 (diff) | |
download | patches-80d534567378ce62ba8e2c51a3b6621e5b8b5605.tar.gz |
more patches
Diffstat (limited to 'usb')
11 files changed, 1579 insertions, 0 deletions
diff --git a/usb/usb-add-support-for-papouch-tmu.patch b/usb/usb-add-support-for-papouch-tmu.patch new file mode 100644 index 00000000000000..48cc7ea267e7b4 --- /dev/null +++ b/usb/usb-add-support-for-papouch-tmu.patch @@ -0,0 +1,64 @@ +From kalin@thinrope.net Tue Mar 28 03:41:52 2006 +Message-ID: <442920E6.3020603@thinrope.net> +Date: Tue, 28 Mar 2006 20:41:26 +0900 +From: Kalin KOZHUHAROV <kalin@thinrope.net> +Cc: Greg KH <greg@kroah.com>, Folkert van Heusden <folkert@vanheusden.com> +Subject: USB: add support for Papouch TMU (USB thermometer) + +From: Folkert van Heusden <folkert@vanheusden.com> + +This patch adds support for new vendor (papouch) and one of their +devices - TMU (a USB thermometer). + +More information: +vendor homepage: + http://www.papouch.com/en/ +product homepage (Polish): + http://www.papouch.com/shop/scripts/_detail.asp?katcislo=0188 + +This patch is based on the submission from Folkert van Heusden [1]. +Then reviseted by Kalin KOZHUHAROV [2] and retested by Folkert. + +[1] http://article.gmane.org/gmane.linux.kernel/392970 +[2] http://article.gmane.org/gmane.linux.kernel/393386 + + + +Signed-off-by: Folkert van Heusden <folkert@vanheusden.com> +Signed-off-by: Kalin KOZHUHAROV <kalin@thinrope.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/usb/serial/ftdi_sio.c | 1 + + drivers/usb/serial/ftdi_sio.h | 9 +++++++++ + 2 files changed, 10 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c ++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c +@@ -494,6 +494,7 @@ static struct usb_device_id id_table_com + { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, + { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, ++ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) }, + { }, /* Optional parameter entry */ + { } /* Terminating entry */ + }; +--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.h ++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.h +@@ -405,6 +405,15 @@ + */ + #define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ + ++/* ++ * Papouch products (http://www.papouch.com/) ++ * Submitted by Folkert van Heusden ++ */ ++ ++#define PAPOUCH_VID 0x5050 /* Vendor ID */ ++#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ ++ ++ + /* Commands */ + #define FTDI_SIO_RESET 0 /* Reset the port */ + #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/usb/usb-cleanups-for-ohci-s3c2410.c.patch b/usb/usb-cleanups-for-ohci-s3c2410.c.patch new file mode 100644 index 00000000000000..5a98e0fe55be2d --- /dev/null +++ b/usb/usb-cleanups-for-ohci-s3c2410.c.patch @@ -0,0 +1,51 @@ +From ben@fluff.org.uk Tue Mar 21 14:56:19 2006 +Date: Tue, 21 Mar 2006 22:54:47 +0000 +From: Ben Dooks <ben-linux-usb@fluff.org> +To: linux-usb-devel@lists.sourceforge.net, greg@kroah.com +Subject: USB: cleanups for ohci-s3c2410.c +Message-ID: <20060321225447.GA6198@home.fluff.org> +Content-Disposition: inline + + +Fix compile errors due to functions not being +defined static + +Signed-off-by: Ben Dooks <ben-linux@fluff.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/ohci-s3c2410.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/host/ohci-s3c2410.c ++++ gregkh-2.6/drivers/usb/host/ohci-s3c2410.c +@@ -37,7 +37,7 @@ static void s3c2410_hcd_oc(struct s3c241 + + /* conversion functions */ + +-struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) ++static struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) + { + return hcd->self.controller->platform_data; + } +@@ -316,7 +316,8 @@ static void s3c2410_hcd_oc(struct s3c241 + * + */ + +-void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) ++static void ++usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) + { + usb_remove_hcd(hcd); + s3c2410_stop_hc(dev); +@@ -334,8 +335,8 @@ void usb_hcd_s3c2410_remove (struct usb_ + * through the hotplug entry's driver_data. + * + */ +-int usb_hcd_s3c2410_probe (const struct hc_driver *driver, +- struct platform_device *dev) ++static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, ++ struct platform_device *dev) + { + struct usb_hcd *hcd = NULL; + int retval; diff --git a/usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch b/usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch new file mode 100644 index 00000000000000..4606d44b1863f4 --- /dev/null +++ b/usb/usb-ftdi_sio-add-support-for-eclo-com-to-1-wire-usb-adapter.patch @@ -0,0 +1,46 @@ +From ian.abbott@mev.co.uk Tue Mar 21 06:55:57 2006 +Message-ID: <442013D8.40902@mev.co.uk> +Date: Tue, 21 Mar 2006 14:55:20 +0000 +From: Ian Abbott <abbotti@mev.co.uk> +Cc: Greg KH <greg@kroah.com>, Martin Grill <m.grill@lancaster.ac.uk> +Subject: USB: ftdi_sio: add support for Eclo COM to 1-Wire USB adapter + +This patch adds support for the Eclo COM to 1-Wire USB adapter +<http://www.eclo.pt/products_ibutton_adapters_usb01_en.asp> to the +ftdi_sio driver's device ID table. Details were provided by Martin +Grill on the ftdi-sio-usb-devel mailing list and I (Ian Abbott) +confirmed it matched the INF file in the Eclo's Windows driver package. + +Signed-off-by: Ian Abbott <abbotti@mev.co.uk> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ftdi_sio.c | 1 + + drivers/usb/serial/ftdi_sio.h | 6 ++++++ + 2 files changed, 7 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c ++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c +@@ -489,6 +489,7 @@ static struct usb_device_id id_table_com + { USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) }, + { USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_TTUSB_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_ECLO_COM_1WIRE_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_777_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_WESTREX_MODEL_8900F_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, +--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.h ++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.h +@@ -399,6 +399,12 @@ + #define FTDI_WESTREX_MODEL_777_PID 0xDC00 /* Model 777 */ + #define FTDI_WESTREX_MODEL_8900F_PID 0xDC01 /* Model 8900F */ + ++/* ++ * Eclo (http://www.eclo.pt/) product IDs. ++ * PID 0xEA90 submitted by Martin Grill. ++ */ ++#define FTDI_ECLO_COM_1WIRE_PID 0xEA90 /* COM to 1-Wire USB adaptor */ ++ + /* Commands */ + #define FTDI_SIO_RESET 0 /* Reset the port */ + #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch b/usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch new file mode 100644 index 00000000000000..ac272b253b515f --- /dev/null +++ b/usb/usb-g_file_storage-add-comment-about-buffer-allocation.patch @@ -0,0 +1,44 @@ +From stern@rowland.harvard.edu Thu Mar 23 12:07:29 2006 +Date: Thu, 23 Mar 2006 15:07:25 -0500 (EST) +From: Alan Stern <stern@rowland.harvard.edu> +To: Greg KH <greg@kroah.com> +Subject: USB: g_file_storage: add comment about buffer allocation +Message-ID: <Pine.LNX.4.44L0.0603231505170.4830-100000@iolanthe.rowland.org> + +This patch (as664) adds a comment to file_storage.c, noting that the +driver is slightly non-portable because it assumes that a buffer +allocated for a bulk-in endpoint will also be useable for a bulk-out +endpoint. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/file_storage.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c ++++ gregkh-2.6/drivers/usb/gadget/file_storage.c +@@ -71,6 +71,12 @@ + * requirement amounts to two 16K buffers, size configurable by a parameter. + * Support is included for both full-speed and high-speed operation. + * ++ * Note that the driver is slightly non-portable in that it assumes a ++ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and ++ * interrupt-in endpoints. With most device controllers this isn't an ++ * issue, but there may be some with hardware restrictions that prevent ++ * a buffer from being used by more than one endpoint. ++ * + * Module options: + * + * file=filename[,filename...] +@@ -3956,6 +3962,9 @@ static int __init fsg_bind(struct usb_ga + for (i = 0; i < NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &fsg->buffhds[i]; + ++ /* Allocate for the bulk-in endpoint. We assume that ++ * the buffer will also work with the bulk-out (and ++ * interrupt-in) endpoint. */ + bh->buf = usb_ep_alloc_buffer(fsg->bulk_in, mod_data.buflen, + &bh->dma, GFP_KERNEL); + if (!bh->buf) diff --git a/usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch b/usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch new file mode 100644 index 00000000000000..530b3c9006ead3 --- /dev/null +++ b/usb/usb-g_file_storage-set-short_not_ok-for-bulk-out-transfers.patch @@ -0,0 +1,46 @@ +From stern@rowland.harvard.edu Thu Mar 23 12:05:19 2006 +Date: Thu, 23 Mar 2006 15:05:16 -0500 (EST) +From: Alan Stern <stern@rowland.harvard.edu> +To: Greg KH <greg@kroah.com> +Subject: USB: g_file_storage: Set short_not_ok for bulk-out transfers +Message-ID: <Pine.LNX.4.44L0.0603231500350.4830-100000@iolanthe.rowland.org> + +I'm told that some UDC hardware may work better if it knows that +receiving a short packet should always cause an error. Accordingly, +this patch (as663) sets the short_not_ok flag for bulk-out transfers in +g_file_storage. Oddly enough, there are no circumstances where that +driver can legally receive a shorter-than-expected bulk-out packet. + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/file_storage.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c ++++ gregkh-2.6/drivers/usb/gadget/file_storage.c +@@ -1795,6 +1795,7 @@ static int do_write(struct fsg_dev *fsg) + * the bulk-out maxpacket size */ + bh->outreq->length = bh->bulk_out_intended_length = + amount; ++ bh->outreq->short_not_ok = 1; + start_transfer(fsg, fsg->bulk_out, bh->outreq, + &bh->outreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; +@@ -2398,6 +2399,7 @@ static int throw_away_data(struct fsg_de + * the bulk-out maxpacket size */ + bh->outreq->length = bh->bulk_out_intended_length = + amount; ++ bh->outreq->short_not_ok = 1; + start_transfer(fsg, fsg->bulk_out, bh->outreq, + &bh->outreq_busy, &bh->state); + fsg->next_buffhd_to_fill = bh->next; +@@ -3029,6 +3031,7 @@ static int get_next_command(struct fsg_d + + /* Queue a request to read a Bulk-only CBW */ + set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); ++ bh->outreq->short_not_ok = 1; + start_transfer(fsg, fsg->bulk_out, bh->outreq, + &bh->outreq_busy, &bh->state); + diff --git a/usb/usb-g_file_storage-use-module_param_array_named-macro.patch b/usb/usb-g_file_storage-use-module_param_array_named-macro.patch new file mode 100644 index 00000000000000..3d63bf72c9107d --- /dev/null +++ b/usb/usb-g_file_storage-use-module_param_array_named-macro.patch @@ -0,0 +1,86 @@ +From stern@rowland.harvard.edu Fri Mar 31 08:46:55 2006 +Date: Fri, 31 Mar 2006 11:46:43 -0500 (EST) +From: Alan Stern <stern@rowland.harvard.edu> +To: Greg KH <greg@kroah.com> +cc: Pat LaVarre <p.lavarre@ieee.org> +Subject: USB: g_file_storage: use module_param_array_named macro +Message-ID: <Pine.LNX.4.44L0.0603311141240.5091-100000@iolanthe.rowland.org> + +Randy Dunlap pointed out that there now is a module_param_array_named +macro available. This patch (as666) updates g_file_storage to make use of +it. It also adds a comment listing the specifications documents used in +the design of the driver's SCSI operation (at Pat LaVarre's request). + +Signed-off-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/file_storage.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/gadget/file_storage.c ++++ gregkh-2.6/drivers/usb/gadget/file_storage.c +@@ -114,6 +114,14 @@ + * setting are not allowed when the medium is loaded. + * + * This gadget driver is heavily based on "Gadget Zero" by David Brownell. ++ * The driver's SCSI command interface was based on the "Information ++ * technology - Small Computer System Interface - 2" document from ++ * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at ++ * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>. The single exception ++ * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the ++ * "Universal Serial Bus Mass Storage Class UFI Command Specification" ++ * document, Revision 1.0, December 14, 1998, available at ++ * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>. + */ + + +@@ -340,11 +348,9 @@ MODULE_LICENSE("Dual BSD/GPL"); + + #define MAX_LUNS 8 + +- /* Arggh! There should be a module_param_array_named macro! */ +-static char *file[MAX_LUNS]; +-static int ro[MAX_LUNS]; +- + static struct { ++ char *file[MAX_LUNS]; ++ int ro[MAX_LUNS]; + int num_filenames; + int num_ros; + unsigned int nluns; +@@ -376,10 +382,11 @@ static struct { + }; + + +-module_param_array(file, charp, &mod_data.num_filenames, S_IRUGO); ++module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, ++ S_IRUGO); + MODULE_PARM_DESC(file, "names of backing files or devices"); + +-module_param_array(ro, bool, &mod_data.num_ros, S_IRUGO); ++module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); + MODULE_PARM_DESC(ro, "true to force read-only"); + + module_param_named(luns, mod_data.nluns, uint, S_IRUGO); +@@ -3868,7 +3875,7 @@ static int __init fsg_bind(struct usb_ga + + for (i = 0; i < fsg->nluns; ++i) { + curlun = &fsg->luns[i]; +- curlun->ro = ro[i]; ++ curlun->ro = mod_data.ro[i]; + curlun->dev.parent = &gadget->dev; + curlun->dev.driver = &fsg_driver.driver; + dev_set_drvdata(&curlun->dev, fsg); +@@ -3885,8 +3892,9 @@ static int __init fsg_bind(struct usb_ga + kref_get(&fsg->ref); + } + +- if (file[i] && *file[i]) { +- if ((rc = open_backing_file(curlun, file[i])) != 0) ++ if (mod_data.file[i] && *mod_data.file[i]) { ++ if ((rc = open_backing_file(curlun, ++ mod_data.file[i])) != 0) + goto out; + } else if (!mod_data.removable) { + ERROR(fsg, "no file given for LUN%d\n", i); diff --git a/usb/usb-input-proper-prototypes.patch b/usb/usb-input-proper-prototypes.patch new file mode 100644 index 00000000000000..5e70b12e46b0ee --- /dev/null +++ b/usb/usb-input-proper-prototypes.patch @@ -0,0 +1,45 @@ +From bunk@stusta.de Sat Mar 25 09:03:43 2006 +Date: Sat, 25 Mar 2006 18:03:38 +0100 +From: Adrian Bunk <bunk@stusta.de> +To: gregkh@suse.de +Subject: USB: input/: proper prototypes +Message-ID: <20060325170338.GF4053@stusta.de> +Content-Disposition: inline + +This patch adds proper prototypes in a header file for some global +functions. + +Signed-off-by: Adrian Bunk <bunk@stusta.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/input/hid-ff.c | 6 ------ + drivers/usb/input/hid.h | 5 +++++ + 2 files changed, 5 insertions(+), 6 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/input/hid-ff.c ++++ gregkh-2.6/drivers/usb/input/hid-ff.c +@@ -34,12 +34,6 @@ + + #include "hid.h" + +-/* Drivers' initializing functions */ +-extern int hid_lgff_init(struct hid_device* hid); +-extern int hid_lg3d_init(struct hid_device* hid); +-extern int hid_pid_init(struct hid_device* hid); +-extern int hid_tmff_init(struct hid_device* hid); +- + /* + * This table contains pointers to initializers. To add support for new + * devices, you need to add the USB vendor and product ids here. +--- gregkh-2.6.orig/drivers/usb/input/hid.h ++++ gregkh-2.6/drivers/usb/input/hid.h +@@ -533,3 +533,8 @@ static inline int hid_ff_event(struct hi + return hid->ff_event(hid, input, type, code, value); + return -ENOSYS; + } ++ ++int hid_lgff_init(struct hid_device* hid); ++int hid_tmff_init(struct hid_device* hid); ++int hid_pid_init(struct hid_device* hid); ++ diff --git a/usb/usb-net2282-and-net2280-software-compatibility.patch b/usb/usb-net2282-and-net2280-software-compatibility.patch new file mode 100644 index 00000000000000..b2de18c9e7191c --- /dev/null +++ b/usb/usb-net2282-and-net2280-software-compatibility.patch @@ -0,0 +1,271 @@ +From g.liakhovetski@gmx.de Sun Mar 19 11:49:23 2006 +Date: Sun, 19 Mar 2006 20:49:14 +0100 (CET) +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +To: Greg KH <gregkh@suse.de> +Cc: Guennadi Liakhovetski <gl@dsa-ac.de> +Subject: USB: net2282 and net2280 software compatibility +Message-ID: <Pine.LNX.4.60.0603192046210.3832@poirot.grange> + +Below is a patch to gadgets/net2280.[ch] which adds support for the +net2282 controller. The original code was kindly provided by PLX +Technology, I just merged it with the current net2280 driver in the +kernel. Tested on 2.6.15.6, but only with 2282. I did the merge, so +that the behaviour for the 2280 is unaffected (except for short delays +for extra checks). + +Signed-off-by: G. Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +Support for net2282 in net2280 driver. + +--- + drivers/usb/gadget/Kconfig | 4 - + drivers/usb/gadget/net2280.c | 90 ++++++++++++++++++++++++++++++++----------- + drivers/usb/gadget/net2280.h | 2 + 3 files changed, 73 insertions(+), 23 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/gadget/Kconfig ++++ gregkh-2.6/drivers/usb/gadget/Kconfig +@@ -69,11 +69,11 @@ choice + often need board-specific hooks. + + config USB_GADGET_NET2280 +- boolean "NetChip 2280" ++ boolean "NetChip 228x" + depends on PCI + select USB_GADGET_DUALSPEED + help +- NetChip 2280 is a PCI based USB peripheral controller which ++ NetChip 2280 / 2282 is a PCI based USB peripheral controller which + supports both full and high speed USB 2.0 data transfers. + + It has six configurable endpoints, as well as endpoint zero +--- gregkh-2.6.orig/drivers/usb/gadget/net2280.c ++++ gregkh-2.6/drivers/usb/gadget/net2280.c +@@ -26,6 +26,8 @@ + * Copyright (C) 2003 David Brownell + * Copyright (C) 2003-2005 PLX Technology, Inc. + * ++ * Modified Seth Levy 2005 PLX Technology, Inc. to provide compatibility with 2282 chip ++ * + * 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 +@@ -71,8 +73,8 @@ + #include <asm/unaligned.h> + + +-#define DRIVER_DESC "PLX NET2280 USB Peripheral Controller" +-#define DRIVER_VERSION "2005 Feb 03" ++#define DRIVER_DESC "PLX NET228x USB Peripheral Controller" ++#define DRIVER_VERSION "2005 Sept 27" + + #define DMA_ADDR_INVALID (~(dma_addr_t)0) + #define EP_DONTUSE 13 /* nonzero */ +@@ -118,7 +120,7 @@ module_param (fifo_mode, ushort, 0644); + /* enable_suspend -- When enabled, the driver will respond to + * USB suspend requests by powering down the NET2280. Otherwise, + * USB suspend requests will be ignored. This is acceptible for +- * self-powered devices, and helps avoid some quirks. ++ * self-powered devices + */ + static int enable_suspend = 0; + +@@ -223,6 +225,11 @@ net2280_enable (struct usb_ep *_ep, cons + ep->is_in = (tmp & USB_DIR_IN) != 0; + if (!ep->is_in) + writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp); ++ else if (dev->pdev->device != 0x2280) { ++ /* Added for 2282, Don't use nak packets on an in endpoint, this was ignored on 2280 */ ++ writel ((1 << CLEAR_NAK_OUT_PACKETS) ++ | (1 << CLEAR_NAK_OUT_PACKETS_MODE), &ep->regs->ep_rsp); ++ } + + writel (tmp, &ep->regs->ep_cfg); + +@@ -232,8 +239,9 @@ net2280_enable (struct usb_ep *_ep, cons + writel (tmp, &dev->regs->pciirqenb0); + + tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE) +- | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE) +- | readl (&ep->regs->ep_irqenb); ++ | (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE); ++ if (dev->pdev->device == 0x2280) ++ tmp |= readl (&ep->regs->ep_irqenb); + writel (tmp, &ep->regs->ep_irqenb); + } else { /* dma, per-request */ + tmp = (1 << (8 + ep->num)); /* completion */ +@@ -314,10 +322,18 @@ static void ep_reset (struct net2280_reg + /* init to our chosen defaults, notably so that we NAK OUT + * packets until the driver queues a read (+note erratum 0112) + */ +- tmp = (1 << SET_NAK_OUT_PACKETS_MODE) ++ if (!ep->is_in || ep->dev->pdev->device == 0x2280) { ++ tmp = (1 << SET_NAK_OUT_PACKETS_MODE) + | (1 << SET_NAK_OUT_PACKETS) + | (1 << CLEAR_EP_HIDE_STATUS_PHASE) + | (1 << CLEAR_INTERRUPT_MODE); ++ } else { ++ /* added for 2282 */ ++ tmp = (1 << CLEAR_NAK_OUT_PACKETS_MODE) ++ | (1 << CLEAR_NAK_OUT_PACKETS) ++ | (1 << CLEAR_EP_HIDE_STATUS_PHASE) ++ | (1 << CLEAR_INTERRUPT_MODE); ++ } + + if (ep->num != 0) { + tmp |= (1 << CLEAR_ENDPOINT_TOGGLE) +@@ -326,14 +342,18 @@ static void ep_reset (struct net2280_reg + writel (tmp, &ep->regs->ep_rsp); + + /* scrub most status bits, and flush any fifo state */ +- writel ( (1 << TIMEOUT) ++ if (ep->dev->pdev->device == 0x2280) ++ tmp = (1 << FIFO_OVERFLOW) ++ | (1 << FIFO_UNDERFLOW); ++ else ++ tmp = 0; ++ ++ writel (tmp | (1 << TIMEOUT) + | (1 << USB_STALL_SENT) + | (1 << USB_IN_NAK_SENT) + | (1 << USB_IN_ACK_RCVD) + | (1 << USB_OUT_PING_NAK_SENT) + | (1 << USB_OUT_ACK_SENT) +- | (1 << FIFO_OVERFLOW) +- | (1 << FIFO_UNDERFLOW) + | (1 << FIFO_FLUSH) + | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) + | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) +@@ -718,7 +738,7 @@ fill_dma_desc (struct net2280_ep *ep, st + */ + if (ep->is_in) + dmacount |= (1 << DMA_DIRECTION); +- else if ((dmacount % ep->ep.maxpacket) != 0) ++ if ((!ep->is_in && (dmacount % ep->ep.maxpacket) != 0) || ep->dev->pdev->device != 0x2280) + dmacount |= (1 << END_OF_CHAIN); + + req->valid = valid; +@@ -760,9 +780,12 @@ static inline void stop_dma (struct net2 + static void start_queue (struct net2280_ep *ep, u32 dmactl, u32 td_dma) + { + struct net2280_dma_regs __iomem *dma = ep->dma; ++ unsigned int tmp = (1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION); + +- writel ((1 << VALID_BIT) | (ep->is_in << DMA_DIRECTION), +- &dma->dmacount); ++ if (ep->dev->pdev->device != 0x2280) ++ tmp |= (1 << END_OF_CHAIN); ++ ++ writel (tmp, &dma->dmacount); + writel (readl (&dma->dmastat), &dma->dmastat); + + writel (td_dma, &dma->dmadesc); +@@ -2110,7 +2133,11 @@ static void handle_ep_small (struct net2 + VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n", + ep->ep.name, t, req ? &req->req : 0); + #endif +- writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); ++ if (!ep->is_in || ep->dev->pdev->device == 0x2280) ++ writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat); ++ else ++ /* Added for 2282 */ ++ writel (t, &ep->regs->ep_stat); + + /* for ep0, monitor token irqs to catch data stage length errors + * and to synchronize on status. +@@ -2337,7 +2364,7 @@ static void handle_stat0_irqs (struct ne + u32 raw [2]; + struct usb_ctrlrequest r; + } u; +- int tmp = 0; ++ int tmp; + struct net2280_request *req; + + if (dev->gadget.speed == USB_SPEED_UNKNOWN) { +@@ -2364,14 +2391,19 @@ static void handle_stat0_irqs (struct ne + } + ep->stopped = 0; + dev->protocol_stall = 0; +- writel ( (1 << TIMEOUT) ++ ++ if (ep->dev->pdev->device == 0x2280) ++ tmp = (1 << FIFO_OVERFLOW) ++ | (1 << FIFO_UNDERFLOW); ++ else ++ tmp = 0; ++ ++ writel (tmp | (1 << TIMEOUT) + | (1 << USB_STALL_SENT) + | (1 << USB_IN_NAK_SENT) + | (1 << USB_IN_ACK_RCVD) + | (1 << USB_OUT_PING_NAK_SENT) + | (1 << USB_OUT_ACK_SENT) +- | (1 << FIFO_OVERFLOW) +- | (1 << FIFO_UNDERFLOW) + | (1 << SHORT_PACKET_OUT_DONE_INTERRUPT) + | (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT) + | (1 << DATA_PACKET_RECEIVED_INTERRUPT) +@@ -2385,6 +2417,8 @@ static void handle_stat0_irqs (struct ne + cpu_to_le32s (&u.raw [0]); + cpu_to_le32s (&u.raw [1]); + ++ tmp = 0; ++ + #define w_value le16_to_cpup (&u.r.wValue) + #define w_index le16_to_cpup (&u.r.wIndex) + #define w_length le16_to_cpup (&u.r.wLength) +@@ -2594,10 +2628,17 @@ static void handle_stat1_irqs (struct ne + writel (stat, &dev->regs->irqstat1); + + /* some status we can just ignore */ +- stat &= ~((1 << CONTROL_STATUS_INTERRUPT) +- | (1 << SUSPEND_REQUEST_INTERRUPT) +- | (1 << RESUME_INTERRUPT) +- | (1 << SOF_INTERRUPT)); ++ if (dev->pdev->device == 0x2280) ++ stat &= ~((1 << CONTROL_STATUS_INTERRUPT) ++ | (1 << SUSPEND_REQUEST_INTERRUPT) ++ | (1 << RESUME_INTERRUPT) ++ | (1 << SOF_INTERRUPT)); ++ else ++ stat &= ~((1 << CONTROL_STATUS_INTERRUPT) ++ | (1 << RESUME_INTERRUPT) ++ | (1 << SOF_DOWN_INTERRUPT) ++ | (1 << SOF_INTERRUPT)); ++ + if (!stat) + return; + // DEBUG (dev, "irqstat1 %08x\n", stat); +@@ -2939,6 +2980,13 @@ static struct pci_device_id pci_ids [] = + .device = 0x2280, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, ++}, { ++ .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), ++ .class_mask = ~0, ++ .vendor = 0x17cc, ++ .device = 0x2282, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, + + }, { /* end: all zeroes */ } + }; +--- gregkh-2.6.orig/drivers/usb/gadget/net2280.h ++++ gregkh-2.6/drivers/usb/gadget/net2280.h +@@ -179,6 +179,7 @@ struct net2280_regs { + #define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19 + #define PCI_RETRY_ABORT_INTERRUPT 17 + #define PCI_MASTER_CYCLE_DONE_INTERRUPT 16 ++#define SOF_DOWN_INTERRUPT 14 + #define GPIO_INTERRUPT 13 + #define DMA_D_INTERRUPT 12 + #define DMA_C_INTERRUPT 11 +@@ -346,6 +347,7 @@ struct net2280_dma_regs { /* [11.7] */ + #define DMA_ENABLE 1 + #define DMA_ADDRESS_HOLD 0 + u32 dmastat; ++#define DMA_ABORT_DONE_INTERRUPT 27 + #define DMA_SCATTER_GATHER_DONE_INTERRUPT 25 + #define DMA_TRANSACTION_DONE_INTERRUPT 24 + #define DMA_ABORT 1 diff --git a/usb/usb-pci-quirks.c-proper-prototypes.patch b/usb/usb-pci-quirks.c-proper-prototypes.patch new file mode 100644 index 00000000000000..20c17c7edf227a --- /dev/null +++ b/usb/usb-pci-quirks.c-proper-prototypes.patch @@ -0,0 +1,62 @@ +From bunk@stusta.de Sat Mar 25 09:02:30 2006 +Date: Sat, 25 Mar 2006 18:01:53 +0100 +From: Adrian Bunk <bunk@stusta.de> +To: stern@rowland.harvard.edu, gregkh@suse.de +Cc: linux-usb-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org +Subject: USB: pci-quirks.c: proper prototypes +Message-ID: <20060325170153.GE4053@stusta.de> +Content-Disposition: inline + +This patch adds a header file with proper prototypes for two functions +in drivers/usb/host/pci-quirks.c. + +Signed-off-by: Adrian Bunk <bunk@stusta.de> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/host/pci-quirks.c | 1 + + drivers/usb/host/pci-quirks.h | 7 +++++++ + drivers/usb/host/uhci-hcd.c | 4 +--- + 3 files changed, 9 insertions(+), 3 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/host/pci-quirks.c ++++ gregkh-2.6/drivers/usb/host/pci-quirks.c +@@ -15,6 +15,7 @@ + #include <linux/init.h> + #include <linux/delay.h> + #include <linux/acpi.h> ++#include "pci-quirks.h" + + + #define UHCI_USBLEGSUP 0xc0 /* legacy support */ +--- /dev/null ++++ gregkh-2.6/drivers/usb/host/pci-quirks.h +@@ -0,0 +1,7 @@ ++#ifndef __LINUX_USB_PCI_QUIRKS_H ++#define __LINUX_USB_PCI_QUIRKS_H ++ ++void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); ++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); ++ ++#endif /* __LINUX_USB_PCI_QUIRKS_H */ +--- gregkh-2.6.orig/drivers/usb/host/uhci-hcd.c ++++ gregkh-2.6/drivers/usb/host/uhci-hcd.c +@@ -50,6 +50,7 @@ + + #include "../core/hcd.h" + #include "uhci-hcd.h" ++#include "pci-quirks.h" + + /* + * Version Information +@@ -100,9 +101,6 @@ static void uhci_get_current_frame_numbe + #include "uhci-q.c" + #include "uhci-hub.c" + +-extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); +-extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); +- + /* + * Finish up a host controller reset and update the recorded state. + */ diff --git a/usb/usb-serial-converts-port-semaphore-to-mutexes.patch b/usb/usb-serial-converts-port-semaphore-to-mutexes.patch new file mode 100644 index 00000000000000..20a66c27704e17 --- /dev/null +++ b/usb/usb-serial-converts-port-semaphore-to-mutexes.patch @@ -0,0 +1,121 @@ +From lcapitulino@mandriva.com.br Fri Mar 24 12:12:58 2006 +Date: Fri, 24 Mar 2006 17:12:31 -0300 +From: Luiz Fernando Capitulino <lcapitulino@mandriva.com.br> +To: Greg KH <gregkh@suse.de> +Subject: USB serial: Converts port semaphore to mutexes. +Message-Id: <20060324171231.6b45576a.lcapitulino@mandriva.com.br> + + +The usbserial's port semaphore used to synchronize serial_open() +and serial_close() are strict mutexes, convert them to the mutex +implementation. + +Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/usb-serial.c | 16 ++++++++-------- + drivers/usb/serial/usb-serial.h | 6 +++--- + 2 files changed, 11 insertions(+), 11 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/serial/usb-serial.c ++++ gregkh-2.6/drivers/usb/serial/usb-serial.c +@@ -27,10 +27,10 @@ + #include <linux/module.h> + #include <linux/moduleparam.h> + #include <linux/spinlock.h> ++#include <linux/mutex.h> + #include <linux/list.h> + #include <linux/smp_lock.h> + #include <asm/uaccess.h> +-#include <asm/semaphore.h> + #include <linux/usb.h> + #include "usb-serial.h" + #include "pl2303.h" +@@ -192,7 +192,7 @@ static int serial_open (struct tty_struc + if (!port) + return -ENODEV; + +- if (down_interruptible(&port->sem)) ++ if (mutex_lock_interruptible(&port->mutex)) + return -ERESTARTSYS; + + ++port->open_count; +@@ -219,7 +219,7 @@ static int serial_open (struct tty_struc + goto bailout_module_put; + } + +- up(&port->sem); ++ mutex_unlock(&port->mutex); + return 0; + + bailout_module_put: +@@ -227,7 +227,7 @@ bailout_module_put: + bailout_kref_put: + kref_put(&serial->kref, destroy_serial); + port->open_count = 0; +- up(&port->sem); ++ mutex_unlock(&port->mutex); + return retval; + } + +@@ -240,10 +240,10 @@ static void serial_close(struct tty_stru + + dbg("%s - port %d", __FUNCTION__, port->number); + +- down(&port->sem); ++ mutex_lock(&port->mutex); + + if (port->open_count == 0) { +- up(&port->sem); ++ mutex_unlock(&port->mutex); + return; + } + +@@ -262,7 +262,7 @@ static void serial_close(struct tty_stru + module_put(port->serial->type->driver.owner); + } + +- up(&port->sem); ++ mutex_unlock(&port->mutex); + kref_put(&port->serial->kref, destroy_serial); + } + +@@ -783,7 +783,7 @@ int usb_serial_probe(struct usb_interfac + port->number = i + serial->minor; + port->serial = serial; + spin_lock_init(&port->lock); +- sema_init(&port->sem, 1); ++ mutex_init(&port->mutex); + INIT_WORK(&port->work, usb_serial_port_softint, port); + serial->port[i] = port; + } +--- gregkh-2.6.orig/drivers/usb/serial/usb-serial.h ++++ gregkh-2.6/drivers/usb/serial/usb-serial.h +@@ -16,7 +16,7 @@ + + #include <linux/config.h> + #include <linux/kref.h> +-#include <asm/semaphore.h> ++#include <linux/mutex.h> + + #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ + #define SERIAL_TTY_MINORS 255 /* loads of devices :) */ +@@ -31,7 +31,7 @@ + * @serial: pointer back to the struct usb_serial owner of this port. + * @tty: pointer to the corresponding tty for this port. + * @lock: spinlock to grab when updating portions of this structure. +- * @sem: semaphore used to synchronize serial_open() and serial_close() ++ * @mutex: mutex used to synchronize serial_open() and serial_close() + * access for this port. + * @number: the number of the port (the minor number). + * @interrupt_in_buffer: pointer to the interrupt in buffer for this port. +@@ -63,7 +63,7 @@ struct usb_serial_port { + struct usb_serial * serial; + struct tty_struct * tty; + spinlock_t lock; +- struct semaphore sem; ++ struct mutex mutex; + unsigned char number; + + unsigned char * interrupt_in_buffer; diff --git a/usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch b/usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch new file mode 100644 index 00000000000000..55a3fce3974c0d --- /dev/null +++ b/usb/usb-usbtouchscreen-unified-usb-touchscreen-driver.patch @@ -0,0 +1,743 @@ +From daniel.ritz-ml@swissonline.ch Wed Mar 29 12:40:33 2006 +From: Daniel Ritz <daniel.ritz-ml@swissonline.ch> +To: Greg KH <greg@kroah.com>, Dmitry Torokhov <dmitry.torokhov@gmail.com> +Subject: USB: usbtouchscreen: unified USB touchscreen driver +Date: Wed, 29 Mar 2006 22:41:07 +0200 +Content-Disposition: inline +Message-Id: <200603292241.07903.daniel.ritz-ml@swissonline.ch> + +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. + +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 + 4145 1012 12 5169 1431 usbtouchscreen.ko + +Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/input/Kconfig | 42 ++ + drivers/usb/input/Makefile | 1 + drivers/usb/input/hid-core.c | 7 + drivers/usb/input/usbtouchscreen.c | 605 +++++++++++++++++++++++++++++++++++++ + 4 files changed, 652 insertions(+), 3 deletions(-) + +--- gregkh-2.6.orig/drivers/usb/input/Kconfig ++++ gregkh-2.6/drivers/usb/input/Kconfig +@@ -200,9 +200,45 @@ config USB_POWERMATE + To compile this driver as a module, choose M here: the + module will be called powermate. + ++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_MTOUCH + tristate "MicroTouch USB Touchscreen Driver" +- depends on USB && INPUT ++ depends on USB && INPUT && !USB_TOUCHSCREEN_3M + ---help--- + Say Y here if you want to use a MicroTouch (Now 3M) USB + Touchscreen controller. +@@ -214,7 +250,7 @@ config USB_MTOUCH + + config USB_ITMTOUCH + tristate "ITM Touch USB Touchscreen Driver" +- depends on USB && INPUT ++ depends on USB && INPUT && !USB_TOUCHSCREEN_ITM + ---help--- + Say Y here if you want to use a ITM Touch USB + Touchscreen controller. +@@ -226,7 +262,7 @@ config USB_ITMTOUCH + + config USB_EGALAX + tristate "eGalax TouchKit USB Touchscreen Driver" +- depends on USB && INPUT ++ depends on USB && INPUT && !USB_TOUCHSCREEN_EGALAX + ---help--- + Say Y here if you want to use a eGalax TouchKit USB + Touchscreen controller. +--- gregkh-2.6.orig/drivers/usb/input/Makefile ++++ gregkh-2.6/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 +--- gregkh-2.6.orig/drivers/usb/input/hid-core.c ++++ gregkh-2.6/drivers/usb/input/hid-core.c +@@ -1372,6 +1372,8 @@ void hid_close(struct hid_device *hid) + usb_kill_urb(hid->urbin); + } + ++#define USB_VENDOR_ID_PANJIT 0x134c ++ + /* + * Initialize all reports + */ +@@ -1701,6 +1703,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 ++++ gregkh-2.6/drivers/usb/input/usbtouchscreen.c +@@ -0,0 +1,605 @@ ++/****************************************************************************** ++ * 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, unsigned char *pkt, int len); ++ int (*read_data) (unsigned 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; ++ unsigned 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, unsigned 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(unsigned 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(unsigned 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, ++ unsigned char *pkt, int len) ++{ ++ unsigned 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(unsigned char *pkt, int *x, int *y, int *touch, int *press) ++{ ++ *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; ++ *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; ++ *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(unsigned 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(unsigned 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, unsigned 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 (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"); |