aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/input')
-rw-r--r--drivers/usb/input/Kconfig37
-rw-r--r--drivers/usb/input/Makefile3
-rw-r--r--drivers/usb/input/acecad.c285
-rw-r--r--drivers/usb/input/aiptek.c32
-rw-r--r--drivers/usb/input/ati_remote.c248
-rw-r--r--drivers/usb/input/hid-core.c50
-rw-r--r--drivers/usb/input/hid-debug.h16
-rw-r--r--drivers/usb/input/hid-input.c16
-rw-r--r--drivers/usb/input/hid-lgff.c18
-rw-r--r--drivers/usb/input/hid.h18
-rw-r--r--drivers/usb/input/hiddev.c56
-rw-r--r--drivers/usb/input/itmtouch.c268
-rw-r--r--drivers/usb/input/kbtab.c17
-rw-r--r--drivers/usb/input/keyspan_remote.c633
-rw-r--r--drivers/usb/input/mtouchusb.c410
-rw-r--r--drivers/usb/input/powermate.c30
-rw-r--r--drivers/usb/input/touchkitusb.c11
-rw-r--r--drivers/usb/input/usbkbd.c29
-rw-r--r--drivers/usb/input/usbmouse.c31
-rw-r--r--drivers/usb/input/wacom.c398
-rw-r--r--drivers/usb/input/xpad.c75
21 files changed, 1902 insertions, 779 deletions
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index d28e7eab6f9..298e4a25e3d 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -151,6 +151,18 @@ config USB_WACOM
To compile this driver as a module, choose M here: the
module will be called wacom.
+config USB_ACECAD
+ tristate "Acecad Flair tablet support"
+ depends on USB && INPUT
+ help
+ Say Y here if you want to use the USB version of the Acecad Flair
+ tablet. Make sure to say Y to "Mouse support"
+ (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+ (CONFIG_INPUT_EVDEV) as well.
+
+ To compile this driver as a module, choose M here: the
+ module will be called acecad.
+
config USB_KBTAB
tristate "KB Gear JamStudio tablet support"
depends on USB && INPUT
@@ -190,6 +202,18 @@ config USB_MTOUCH
To compile this driver as a module, choose M here: the
module will be called mtouchusb.
+config USB_ITMTOUCH
+ tristate "ITM Touch USB Touchscreen Driver"
+ depends on USB && INPUT
+ ---help---
+ Say Y here if you want to use a ITM Touch USB
+ Touchscreen controller.
+
+ This touchscreen is used in LG 1510SF monitors.
+
+ To compile this driver as a module, choose M here: the
+ module will be called itmtouch.
+
config USB_EGALAX
tristate "eGalax TouchKit USB Touchscreen Driver"
depends on USB && INPUT
@@ -235,3 +259,16 @@ config USB_ATI_REMOTE
To compile this driver as a module, choose M here: the module will be
called ati_remote.
+config USB_KEYSPAN_REMOTE
+ tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
+ depends on USB && INPUT && EXPERIMENTAL
+ ---help---
+ Say Y here if you want to use a Keyspan DMR USB remote control.
+ Currently only the UIA-11 type of receiver has been tested. The tag
+ on the receiver that connects to the USB port should have a P/N that
+ will tell you what type of DMR you have. The UIA-10 type is not
+ supported at this time. This driver maps all buttons to keypress
+ events.
+
+ To compile this driver as a module, choose M here: the module will
+ be called keyspan_remote.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 6bcedd16b0a..f1547be632d 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -31,9 +31,12 @@ obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o
obj-$(CONFIG_USB_HID) += usbhid.o
obj-$(CONFIG_USB_KBD) += usbkbd.o
obj-$(CONFIG_USB_KBTAB) += kbtab.o
+obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_USB_MOUSE) += usbmouse.o
obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o
+obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o
obj-$(CONFIG_USB_EGALAX) += touchkitusb.o
obj-$(CONFIG_USB_POWERMATE) += powermate.o
obj-$(CONFIG_USB_WACOM) += wacom.o
+obj-$(CONFIG_USB_ACECAD) += acecad.o
obj-$(CONFIG_USB_XPAD) += xpad.o
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
new file mode 100644
index 00000000000..ebcf7c95580
--- /dev/null
+++ b/drivers/usb/input/acecad.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2001-2005 Edouard TISSERANT <edouard.tisserant@wanadoo.fr>
+ * Copyright (c) 2004-2005 Stephane VOLTZ <svoltz@numericable.fr>
+ *
+ * USB Acecad "Acecad Flair" tablet support
+ *
+ * Changelog:
+ * v3.2 - Added sysfs support
+ */
+
+/*
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v3.2"
+#define DRIVER_DESC "USB Acecad Flair tablet driver"
+#define DRIVER_LICENSE "GPL"
+#define DRIVER_AUTHOR "Edouard TISSERANT <edouard.tisserant@wanadoo.fr>"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+#define USB_VENDOR_ID_ACECAD 0x0460
+#define USB_DEVICE_ID_FLAIR 0x0004
+#define USB_DEVICE_ID_302 0x0008
+
+struct usb_acecad {
+ char name[128];
+ char phys[64];
+ struct usb_device *usbdev;
+ struct input_dev dev;
+ struct urb *irq;
+
+ signed char *data;
+ dma_addr_t data_dma;
+};
+
+static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_acecad *acecad = urb->context;
+ unsigned char *data = acecad->data;
+ struct input_dev *dev = &acecad->dev;
+ int prox, status;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ 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 resubmit;
+ }
+
+ prox = (data[0] & 0x04) >> 2;
+ input_report_key(dev, BTN_TOOL_PEN, prox);
+
+ if (prox) {
+ int x = data[1] | (data[2] << 8);
+ int y = data[3] | (data[4] << 8);
+ /*Pressure should compute the same way for flair and 302*/
+ int pressure = data[5] | ((int)data[6] << 8);
+ int touch = data[0] & 0x01;
+ int stylus = (data[0] & 0x10) >> 4;
+ int stylus2 = (data[0] & 0x20) >> 5;
+ input_report_abs(dev, ABS_X, x);
+ input_report_abs(dev, ABS_Y, y);
+ input_report_abs(dev, ABS_PRESSURE, pressure);
+ input_report_key(dev, BTN_TOUCH, touch);
+ input_report_key(dev, BTN_STYLUS, stylus);
+ input_report_key(dev, BTN_STYLUS2, stylus2);
+ }
+
+ /* event termination */
+ input_sync(dev);
+
+resubmit:
+ status = usb_submit_urb (urb, GFP_ATOMIC);
+ if (status)
+ err ("can't resubmit intr, %s-%s/input0, status %d",
+ acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status);
+}
+
+static int usb_acecad_open(struct input_dev *dev)
+{
+ struct usb_acecad *acecad = dev->private;
+
+ acecad->irq->dev = acecad->usbdev;
+ if (usb_submit_urb(acecad->irq, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void usb_acecad_close(struct input_dev *dev)
+{
+ struct usb_acecad *acecad = dev->private;
+
+ usb_kill_urb(acecad->irq);
+}
+
+static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_host_interface *interface = intf->cur_altsetting;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_acecad *acecad;
+ int pipe, maxp;
+ char path[64];
+
+ if (interface->desc.bNumEndpoints != 1)
+ return -ENODEV;
+
+ endpoint = &interface->endpoint[0].desc;
+
+ if (!(endpoint->bEndpointAddress & 0x80))
+ return -ENODEV;
+
+ if ((endpoint->bmAttributes & 3) != 3)
+ return -ENODEV;
+
+ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+
+ acecad = kcalloc(1, sizeof(struct usb_acecad), GFP_KERNEL);
+ if (!acecad)
+ return -ENOMEM;
+
+ acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
+ if (!acecad->data)
+ goto fail1;
+
+ acecad->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!acecad->irq)
+ goto fail2;
+
+ if (dev->manufacturer)
+ strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
+
+ if (dev->product) {
+ if (dev->manufacturer)
+ strlcat(acecad->name, " ", sizeof(acecad->name));
+ strlcat(acecad->name, dev->product, sizeof(acecad->name));
+ }
+
+ usb_make_path(dev, path, sizeof(path));
+ snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
+
+ acecad->usbdev = dev;
+
+ acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+ acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+
+ switch (id->driver_info) {
+ case 0:
+ acecad->dev.absmax[ABS_X] = 5000;
+ acecad->dev.absmax[ABS_Y] = 3750;
+ acecad->dev.absmax[ABS_PRESSURE] = 512;
+ if (!strlen(acecad->name))
+ snprintf(acecad->name, sizeof(acecad->name),
+ "USB Acecad Flair Tablet %04x:%04x",
+ dev->descriptor.idVendor, dev->descriptor.idProduct);
+ break;
+ case 1:
+ acecad->dev.absmax[ABS_X] = 3000;
+ acecad->dev.absmax[ABS_Y] = 2250;
+ acecad->dev.absmax[ABS_PRESSURE] = 1024;
+ if (!strlen(acecad->name))
+ snprintf(acecad->name, sizeof(acecad->name),
+ "USB Acecad 302 Tablet %04x:%04x",
+ dev->descriptor.idVendor, dev->descriptor.idProduct);
+ break;
+ }
+
+ acecad->dev.absfuzz[ABS_X] = 4;
+ acecad->dev.absfuzz[ABS_Y] = 4;
+
+ acecad->dev.private = acecad;
+ acecad->dev.open = usb_acecad_open;
+ acecad->dev.close = usb_acecad_close;
+
+ acecad->dev.name = acecad->name;
+ acecad->dev.phys = acecad->phys;
+ acecad->dev.id.bustype = BUS_USB;
+ acecad->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ acecad->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
+ acecad->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+ acecad->dev.dev = &intf->dev;
+
+ usb_fill_int_urb(acecad->irq, dev, pipe,
+ acecad->data, maxp > 8 ? 8 : maxp,
+ usb_acecad_irq, acecad, endpoint->bInterval);
+ acecad->irq->transfer_dma = acecad->data_dma;
+ acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ input_register_device(&acecad->dev);
+
+ printk(KERN_INFO "input: %s with packet size %d on %s\n",
+ acecad->name, maxp, path);
+
+ usb_set_intfdata(intf, acecad);
+
+ return 0;
+
+ fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
+ fail1: kfree(acecad);
+ return -ENOMEM;
+}
+
+static void usb_acecad_disconnect(struct usb_interface *intf)
+{
+ struct usb_acecad *acecad = usb_get_intfdata(intf);
+
+ usb_set_intfdata(intf, NULL);
+ if (acecad) {
+ usb_kill_urb(acecad->irq);
+ input_unregister_device(&acecad->dev);
+ usb_free_urb(acecad->irq);
+ usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
+ kfree(acecad);
+ }
+}
+
+static struct usb_device_id usb_acecad_id_table [] = {
+ { USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_FLAIR), .driver_info = 0 },
+ { USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_302), .driver_info = 1 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, usb_acecad_id_table);
+
+static struct usb_driver usb_acecad_driver = {
+ .owner = THIS_MODULE,
+ .name = "usb_acecad",
+ .probe = usb_acecad_probe,
+ .disconnect = usb_acecad_disconnect,
+ .id_table = usb_acecad_id_table,
+};
+
+static int __init usb_acecad_init(void)
+{
+ int result = usb_register(&usb_acecad_driver);
+ if (result == 0)
+ info(DRIVER_VERSION ":" DRIVER_DESC);
+ return result;
+}
+
+static void __exit usb_acecad_exit(void)
+{
+ usb_deregister(&usb_acecad_driver);
+}
+
+module_init(usb_acecad_init);
+module_exit(usb_acecad_exit);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index e991f7ed733..6bb0f25e8e9 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -1,7 +1,7 @@
/*
* Native support for the Aiptek HyperPen USB Tablets
* (4000U/5000U/6000U/8000U/12000U)
- *
+ *
* Copyright (c) 2001 Chris Atenasio <chris@crud.net>
* Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net>
*
@@ -31,7 +31,7 @@
* - Added support for the sysfs interface, deprecating the
* procfs interface for 2.5.x kernel. Also added support for
* Wheel command. Bryan W. Headley July-15-2003.
- * v1.2 - Reworked jitter timer as a kernel thread.
+ * v1.2 - Reworked jitter timer as a kernel thread.
* Bryan W. Headley November-28-2003/Jan-10-2004.
* v1.3 - Repaired issue of kernel thread going nuts on single-processor
* machines, introduced programmableDelay as a command line
@@ -49,10 +49,10 @@
* NOTE:
* This kernel driver is augmented by the "Aiptek" XFree86 input
* driver for your X server, as well as the Gaiptek GUI Front-end
- * "Tablet Manager".
- * These three products are highly interactive with one another,
+ * "Tablet Manager".
+ * These three products are highly interactive with one another,
* so therefore it's easier to document them all as one subsystem.
- * Please visit the project's "home page", located at,
+ * Please visit the project's "home page", located at,
* http://aiptektablet.sourceforge.net.
*
* This program is free software; you can redistribute it and/or modify
@@ -156,7 +156,7 @@
* Command/Data Description Return Bytes Return Value
* 0x10/0x00 SwitchToMouse 0
* 0x10/0x01 SwitchToTablet 0
- * 0x18/0x04 SetResolution 0
+ * 0x18/0x04 SetResolution 0
* 0x12/0xFF AutoGainOn 0
* 0x17/0x00 FilterOn 0
* 0x01/0x00 GetXExtension 2 MaxX
@@ -247,7 +247,7 @@
#define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE 2
#define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED 3
- /* Time to wait (in ms) to help mask hand jittering
+ /* Time to wait (in ms) to help mask hand jittering
* when pressing the stylus buttons.
*/
#define AIPTEK_JITTER_DELAY_DEFAULT 50
@@ -324,7 +324,6 @@ struct aiptek {
struct aiptek_settings curSetting; /* tablet's current programmable */
struct aiptek_settings newSetting; /* ... and new param settings */
unsigned int ifnum; /* interface number for IO */
- int openCount; /* module use counter */
int diagnostic; /* tablet diagnostic codes */
unsigned long eventCount; /* event count */
int inDelay; /* jitter: in jitter delay? */
@@ -791,7 +790,7 @@ exit:
* specific Aiptek model numbers, because there has been overlaps,
* use, and reuse of id's in existing models. Certain models have
* been known to use more than one ID, indicative perhaps of
- * manufacturing revisions. In any event, we consider these
+ * manufacturing revisions. In any event, we consider these
* IDs to not be model-specific nor unique.
*/
static const struct usb_device_id aiptek_ids[] = {
@@ -814,15 +813,9 @@ static int aiptek_open(struct input_dev *inputdev)
{
struct aiptek *aiptek = inputdev->private;
- if (aiptek->openCount++ > 0) {
- return 0;
- }
-
aiptek->urb->dev = aiptek->usbdev;
- if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) {
- aiptek->openCount--;
+ if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0)
return -EIO;
- }
return 0;
}
@@ -834,13 +827,11 @@ static void aiptek_close(struct input_dev *inputdev)
{
struct aiptek *aiptek = inputdev->private;
- if (--aiptek->openCount == 0) {
- usb_kill_urb(aiptek->urb);
- }
+ usb_kill_urb(aiptek->urb);
}
/***********************************************************************
- * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x,
+ * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x,
* where they were known as usb_set_report and usb_get_report.
*/
static int
@@ -2252,7 +2243,6 @@ static void aiptek_disconnect(struct usb_interface *intf)
AIPTEK_PACKET_LENGTH,
aiptek->data, aiptek->data_dma);
kfree(aiptek);
- aiptek = NULL;
}
}
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 860df26323b..654ac454744 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -1,15 +1,15 @@
-/*
+/*
* USB ATI Remote support
*
* Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
* Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
*
* This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including
- * porting to the 2.6 kernel interfaces, along with other modification
+ * porting to the 2.6 kernel interfaces, along with other modification
* to better match the style of the existing usb/input drivers. However, the
* protocol and hardware handling is essentially unchanged from 2.1.1.
- *
- * The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by
+ *
+ * The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by
* Vojtech Pavlik.
*
* Changes:
@@ -23,64 +23,64 @@
* Added support for the "Lola" remote contributed by:
* Seth Cohn <sethcohn@yahoo.com>
*
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Hardware & software notes
*
- * These remote controls are distributed by ATI as part of their
- * "All-In-Wonder" video card packages. The receiver self-identifies as a
+ * These remote controls are distributed by ATI as part of their
+ * "All-In-Wonder" video card packages. The receiver self-identifies as a
* "USB Receiver" with manufacturer "X10 Wireless Technology Inc".
*
- * The "Lola" remote is available from X10. See:
+ * The "Lola" remote is available from X10. See:
* http://www.x10.com/products/lola_sg1.htm
* The Lola is similar to the ATI remote but has no mouse support, and slightly
* different keys.
*
- * It is possible to use multiple receivers and remotes on multiple computers
+ * It is possible to use multiple receivers and remotes on multiple computers
* simultaneously by configuring them to use specific channels.
- *
- * The RF protocol used by the remote supports 16 distinct channels, 1 to 16.
- * Actually, it may even support more, at least in some revisions of the
+ *
+ * The RF protocol used by the remote supports 16 distinct channels, 1 to 16.
+ * Actually, it may even support more, at least in some revisions of the
* hardware.
*
* Each remote can be configured to transmit on one channel as follows:
- * - Press and hold the "hand icon" button.
- * - When the red LED starts to blink, let go of the "hand icon" button.
- * - When it stops blinking, input the channel code as two digits, from 01
+ * - Press and hold the "hand icon" button.
+ * - When the red LED starts to blink, let go of the "hand icon" button.
+ * - When it stops blinking, input the channel code as two digits, from 01
* to 16, and press the hand icon again.
- *
+ *
* The timing can be a little tricky. Try loading the module with debug=1
* to have the kernel print out messages about the remote control number
* and mask. Note: debugging prints remote numbers as zero-based hexadecimal.
*
* The driver has a "channel_mask" parameter. This bitmask specifies which
- * channels will be ignored by the module. To mask out channels, just add
+ * channels will be ignored by the module. To mask out channels, just add
* all the 2^channel_number values together.
*
* For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote
- * ignore signals coming from remote controls transmitting on channel 4, but
+ * ignore signals coming from remote controls transmitting on channel 4, but
* accept all other channels.
*
- * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be
+ * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be
* ignored.
*
- * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this
+ * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this
* parameter are unused.
*
*/
@@ -99,13 +99,13 @@
/*
* Module and Version Information, Module Parameters
*/
-
-#define ATI_REMOTE_VENDOR_ID 0x0bc7
-#define ATI_REMOTE_PRODUCT_ID 0x004
-#define LOLA_REMOTE_PRODUCT_ID 0x002
+
+#define ATI_REMOTE_VENDOR_ID 0x0bc7
+#define ATI_REMOTE_PRODUCT_ID 0x004
+#define LOLA_REMOTE_PRODUCT_ID 0x002
#define MEDION_REMOTE_PRODUCT_ID 0x006
-#define DRIVER_VERSION "2.2.1"
+#define DRIVER_VERSION "2.2.1"
#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>"
#define DRIVER_DESC "ATI/X10 RF USB Remote Control"
@@ -113,18 +113,18 @@
#define DATA_BUFSIZE 63 /* size of URB data buffers */
#define ATI_INPUTNUM 1 /* Which input device to register as */
-static unsigned long channel_mask = 0;
+static unsigned long channel_mask;
module_param(channel_mask, ulong, 0444);
MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
-static int debug = 0;
+static int debug;
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
#undef err
#define err(format, arg...) printk(KERN_ERR format , ## arg)
-
+
static struct usb_device_id ati_remote_table[] = {
{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
@@ -148,7 +148,7 @@ static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
/* Acceleration curve for directional control pad */
static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
-/* Duplicate event filtering time.
+/* Duplicate event filtering time.
* Sequential, identical KIND_FILTERED inputs with less than
* FILTER_TIME jiffies between them are considered as repeat
* events. The hardware generates 5 events for the first keypress
@@ -161,10 +161,10 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
static DECLARE_MUTEX(disconnect_sem);
struct ati_remote {
- struct input_dev idev;
+ struct input_dev idev;
struct usb_device *udev;
struct usb_interface *interface;
-
+
struct urb *irq_urb;
struct urb *out_urb;
struct usb_endpoint_descriptor *endpoint_in;
@@ -174,13 +174,11 @@ struct ati_remote {
dma_addr_t inbuf_dma;
dma_addr_t outbuf_dma;
- int open; /* open counter */
-
unsigned char old_data[2]; /* Detect duplicate events */
unsigned long old_jiffies;
unsigned long acc_jiffies; /* handle acceleration */
unsigned int repeat_count;
-
+
char name[NAME_BUFSIZE];
char phys[NAME_BUFSIZE];
@@ -206,14 +204,14 @@ static struct
int type;
unsigned int code;
int value;
-} ati_remote_tbl[] =
+} ati_remote_tbl[] =
{
/* Directional control pad axes */
{KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */
{KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */
{KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */
{KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */
- /* Directional control pad diagonals */
+ /* Directional control pad diagonals */
{KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */
{KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */
{KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */
@@ -225,7 +223,7 @@ static struct
{KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */
{KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */
- /* Artificial "doubleclick" events are generated by the hardware.
+ /* Artificial "doubleclick" events are generated by the hardware.
* They are mapped to the "side" and "extra" mouse buttons here. */
{KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
{KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
@@ -273,15 +271,15 @@ static struct
{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */
{KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */
{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */
- {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */
+ {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */
{KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */
{KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */
{KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */
{KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */
{KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */
{KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */
- {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */
-
+ {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */
+
{KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
};
@@ -315,7 +313,7 @@ static void ati_remote_dump(unsigned char *data, unsigned int len)
if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00))
warn("Weird byte 0x%02x", data[0]);
else if (len == 4)
- warn("Weird key %02x %02x %02x %02x",
+ warn("Weird key %02x %02x %02x %02x",
data[0], data[1], data[2], data[3]);
else
warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...",
@@ -328,25 +326,16 @@ static void ati_remote_dump(unsigned char *data, unsigned int len)
static int ati_remote_open(struct input_dev *inputdev)
{
struct ati_remote *ati_remote = inputdev->private;
- int retval = 0;
-
- down(&disconnect_sem);
-
- if (ati_remote->open++)
- goto exit;
/* On first open, submit the read urb which was set up previously. */
ati_remote->irq_urb->dev = ati_remote->udev;
if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
- dev_err(&ati_remote->interface->dev,
+ dev_err(&ati_remote->interface->dev,
"%s: usb_submit_urb failed!\n", __FUNCTION__);
- ati_remote->open--;
- retval = -EIO;
+ return -EIO;
}
-exit:
- up(&disconnect_sem);
- return retval;
+ return 0;
}
/*
@@ -355,9 +344,8 @@ exit:
static void ati_remote_close(struct input_dev *inputdev)
{
struct ati_remote *ati_remote = inputdev->private;
-
- if (!--ati_remote->open)
- usb_kill_urb(ati_remote->irq_urb);
+
+ usb_kill_urb(ati_remote->irq_urb);
}
/*
@@ -366,13 +354,13 @@ static void ati_remote_close(struct input_dev *inputdev)
static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs)
{
struct ati_remote *ati_remote = urb->context;
-
+
if (urb->status) {
dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
__FUNCTION__, urb->status);
return;
}
-
+
ati_remote->send_flags |= SEND_FLAG_COMPLETE;
wmb();
wake_up(&ati_remote->wait);
@@ -380,16 +368,16 @@ static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs)
/*
* ati_remote_sendpacket
- *
+ *
* Used to send device initialization strings
*/
static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigned char *data)
{
int retval = 0;
-
+
/* Set up out_urb */
memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd));
- ((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd);
+ ((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd);
ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1;
ati_remote->out_urb->dev = ati_remote->udev;
@@ -397,17 +385,17 @@ static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigne
retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC);
if (retval) {
- dev_dbg(&ati_remote->interface->dev,
+ dev_dbg(&ati_remote->interface->dev,
"sendpacket: usb_submit_urb failed: %d\n", retval);
return retval;
}
wait_event_timeout(ati_remote->wait,
((ati_remote->out_urb->status != -EINPROGRESS) ||
- (ati_remote->send_flags & SEND_FLAG_COMPLETE)),
+ (ati_remote->send_flags & SEND_FLAG_COMPLETE)),
HZ);
usb_kill_urb(ati_remote->out_urb);
-
+
return retval;
}
@@ -419,15 +407,15 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
int i;
for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
- /*
- * Decide if the table entry matches the remote input.
+ /*
+ * Decide if the table entry matches the remote input.
*/
if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) &&
- ((((ati_remote_tbl[i].data1 >> 4) -
- (d1 >> 4) + rem) & 0x0f) == 0x0f) &&
+ ((((ati_remote_tbl[i].data1 >> 4) -
+ (d1 >> 4) + rem) & 0x0f) == 0x0f) &&
(ati_remote_tbl[i].data2 == d2))
return i;
-
+
}
return -1;
}
@@ -435,16 +423,16 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
/*
* ati_remote_report_input
*/
-static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
+static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
{
struct ati_remote *ati_remote = urb->context;
unsigned char *data= ati_remote->inbuf;
- struct input_dev *dev = &ati_remote->idev;
+ struct input_dev *dev = &ati_remote->idev;
int index, acc;
int remote_num;
-
+
/* Deal with strange looking inputs */
- if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
+ if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
((data[3] & 0x0f) != 0x00) ) {
ati_remote_dump(data, urb->actual_length);
return;
@@ -453,7 +441,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
/* Mask unwanted remote channels. */
/* note: remote_num is 0-based, channel 1 on remote == 0 here */
remote_num = (data[3] >> 4) & 0x0f;
- if (channel_mask & (1 << (remote_num + 1))) {
+ if (channel_mask & (1 << (remote_num + 1))) {
dbginfo(&ati_remote->interface->dev,
"Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n",
remote_num, data[1], data[2], channel_mask);
@@ -463,37 +451,36 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
/* Look up event code index in translation table */
index = ati_remote_event_lookup(remote_num, data[1], data[2]);
if (index < 0) {
- dev_warn(&ati_remote->interface->dev,
- "Unknown input from channel 0x%02x: data %02x,%02x\n",
+ dev_warn(&ati_remote->interface->dev,
+ "Unknown input from channel 0x%02x: data %02x,%02x\n",
remote_num, data[1], data[2]);
return;
- }
- dbginfo(&ati_remote->interface->dev,
+ }
+ dbginfo(&ati_remote->interface->dev,
"channel 0x%02x; data %02x,%02x; index %d; keycode %d\n",
remote_num, data[1], data[2], index, ati_remote_tbl[index].code);
-
+
if (ati_remote_tbl[index].kind == KIND_LITERAL) {
input_regs(dev, regs);
input_event(dev, ati_remote_tbl[index].type,
ati_remote_tbl[index].code,
ati_remote_tbl[index].value);
input_sync(dev);
-
+
ati_remote->old_jiffies = jiffies;
return;
}
-
+
if (ati_remote_tbl[index].kind == KIND_FILTERED) {
/* Filter duplicate events which happen "too close" together. */
- if ((ati_remote->old_data[0] == data[1]) &&
- (ati_remote->old_data[1] == data[2]) &&
- ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
+ if ((ati_remote->old_data[0] == data[1]) &&
+ (ati_remote->old_data[1] == data[2]) &&
+ ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
ati_remote->repeat_count++;
- }
- else {
+ } else {
ati_remote->repeat_count = 0;
}
-
+
ati_remote->old_data[0] = data[1];
ati_remote->old_data[1] = data[2];
ati_remote->old_jiffies = jiffies;
@@ -501,7 +488,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
if ((ati_remote->repeat_count > 0)
&& (ati_remote->repeat_count < 5))
return;
-
+
input_regs(dev, regs);
input_event(dev, ati_remote_tbl[index].type,
@@ -511,13 +498,13 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
input_sync(dev);
return;
- }
-
- /*
+ }
+
+ /*
* Other event kinds are from the directional control pad, and have an
* acceleration factor applied to them. Without this acceleration, the
* control pad is mostly unusable.
- *
+ *
* If elapsed time since last event is > 1/4 second, user "stopped",
* so reset acceleration. Otherwise, user is probably holding the control
* pad down, so we increase acceleration, ramping up over two seconds to
@@ -559,7 +546,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
input_report_rel(dev, REL_Y, acc);
break;
default:
- dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
+ dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
ati_remote_tbl[index].kind);
}
input_sync(dev);
@@ -586,12 +573,12 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs)
case -ESHUTDOWN:
dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n",
__FUNCTION__);
- return;
+ return;
default: /* error */
- dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
+ dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
__FUNCTION__, urb->status);
}
-
+
retval = usb_submit_urb(urb, SLAB_ATOMIC);
if (retval)
dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
@@ -603,8 +590,6 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs)
*/
static void ati_remote_delete(struct ati_remote *ati_remote)
{
- if (!ati_remote) return;
-
if (ati_remote->irq_urb)
usb_kill_urb(ati_remote->irq_urb);
@@ -614,16 +599,16 @@ static void ati_remote_delete(struct ati_remote *ati_remote)
input_unregister_device(&ati_remote->idev);
if (ati_remote->inbuf)
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+ usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
ati_remote->inbuf, ati_remote->inbuf_dma);
-
+
if (ati_remote->outbuf)
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+ usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
ati_remote->outbuf, ati_remote->outbuf_dma);
-
+
if (ati_remote->irq_urb)
usb_free_urb(ati_remote->irq_urb);
-
+
if (ati_remote->out_urb)
usb_free_urb(ati_remote->out_urb);
@@ -636,51 +621,52 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
int i;
idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
+ idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
BIT(BTN_SIDE) | BIT(BTN_EXTRA) );
idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
if (ati_remote_tbl[i].type == EV_KEY)
set_bit(ati_remote_tbl[i].code, idev->keybit);
-
+
idev->private = ati_remote;
idev->open = ati_remote_open;
idev->close = ati_remote_close;
-
+
idev->name = ati_remote->name;
idev->phys = ati_remote->phys;
-
- idev->id.bustype = BUS_USB;
+
+ idev->id.bustype = BUS_USB;
idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor);
idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct);
idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice);
+ idev->dev = &(ati_remote->udev->dev);
}
static int ati_remote_initialize(struct ati_remote *ati_remote)
{
struct usb_device *udev = ati_remote->udev;
int pipe, maxp;
-
+
init_waitqueue_head(&ati_remote->wait);
/* Set up irq_urb */
pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress);
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
-
- usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf,
- maxp, ati_remote_irq_in, ati_remote,
+
+ usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf,
+ maxp, ati_remote_irq_in, ati_remote,
ati_remote->endpoint_in->bInterval);
ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma;
ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
+
/* Set up out_urb */
pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress);
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
- usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf,
- maxp, ati_remote_irq_out, ati_remote,
+ usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf,
+ maxp, ati_remote_irq_out, ati_remote,
ati_remote->endpoint_out->bInterval);
ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma;
ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -688,11 +674,11 @@ static int ati_remote_initialize(struct ati_remote *ati_remote)
/* send initialization strings */
if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) ||
(ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
- dev_err(&ati_remote->interface->dev,
+ dev_err(&ati_remote->interface->dev,
"Initializing ati_remote hardware failed.\n");
return 1;
}
-
+
return 0;
}
@@ -769,7 +755,7 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
if (!strlen(ati_remote->name))
sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
- le16_to_cpu(ati_remote->udev->descriptor.idVendor),
+ le16_to_cpu(ati_remote->udev->descriptor.idVendor),
le16_to_cpu(ati_remote->udev->descriptor.idProduct));
/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
@@ -781,11 +767,11 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
ati_remote_input_init(ati_remote);
input_register_device(&ati_remote->idev);
- dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
+ dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
ati_remote->name, path);
usb_set_intfdata(interface, ati_remote);
-
+
error:
if (retval)
ati_remote_delete(ati_remote);
@@ -800,18 +786,14 @@ static void ati_remote_disconnect(struct usb_interface *interface)
{
struct ati_remote *ati_remote;
- down(&disconnect_sem);
-
ati_remote = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
if (!ati_remote) {
warn("%s - null device?\n", __FUNCTION__);
return;
}
-
- ati_remote_delete(ati_remote);
- up(&disconnect_sem);
+ ati_remote_delete(ati_remote);
}
/*
@@ -820,7 +802,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
static int __init ati_remote_init(void)
{
int result;
-
+
result = usb_register(&ati_remote_driver);
if (result)
err("usb_register error #%d\n", result);
@@ -838,8 +820,8 @@ static void __exit ati_remote_exit(void)
usb_deregister(&ati_remote_driver);
}
-/*
- * module specification
+/*
+ * module specification
*/
module_init(ati_remote_init);
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 740dec1f521..2350e7a5ad7 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -232,7 +232,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
report->size += parser->global.report_size * parser->global.report_count;
if (!parser->local.usage_index) /* Ignore padding fields */
- return 0;
+ return 0;
usages = max_t(int, parser->local.usage_index, parser->global.report_count);
@@ -765,7 +765,7 @@ static __inline__ __u32 s32ton(__s32 value, unsigned n)
static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
{
report += (offset >> 5) << 2; offset &= 31;
- return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1 << n) - 1);
+ return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1);
}
static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
@@ -1233,6 +1233,13 @@ int hid_wait_io(struct hid_device *hid)
return 0;
}
+static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,
+ ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
unsigned char type, void *buf, int size)
{
@@ -1301,10 +1308,6 @@ void hid_init_reports(struct hid_device *hid)
if (err)
warn("timeout initializing reports\n");
-
- usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
- HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
- hid->ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
}
#define USB_VENDOR_ID_WACOM 0x056a
@@ -1318,6 +1321,10 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0
#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F
+#define USB_VENDOR_ID_ACECAD 0x0460
+#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
+#define USB_DEVICE_ID_ACECAD_302 0x0008
+
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
@@ -1421,6 +1428,19 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
+#define USB_VENDOR_ID_LD 0x0f11
+#define USB_DEVICE_ID_CASSY 0x1000
+#define USB_DEVICE_ID_POCKETCASSY 0x1010
+#define USB_DEVICE_ID_MOBILECASSY 0x1020
+#define USB_DEVICE_ID_JWM 0x1080
+#define USB_DEVICE_ID_DMMP 0x1081
+#define USB_DEVICE_ID_UMIP 0x1090
+#define USB_DEVICE_ID_VIDEOCOM 0x1200
+#define USB_DEVICE_ID_COM3LAB 0x2000
+#define USB_DEVICE_ID_TELEPORT 0x2010
+#define USB_DEVICE_ID_NETWORKANALYSER 0x2020
+#define USB_DEVICE_ID_POWERCONTROL 0x2030
+
/*
* Alphabetically sorted blacklist by quirk type.
@@ -1456,6 +1476,17 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
@@ -1502,6 +1533,9 @@ static struct hid_blacklist {
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
+ { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
+
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
@@ -1590,6 +1624,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
return NULL;
}
+ hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
+
if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
dbg("reading report descriptor failed");
kfree(rdesc);
@@ -1635,7 +1671,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
/* Change the polling interval of mice. */
if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
interval = hid_mousepoll_interval;
-
+
if (endpoint->bEndpointAddress & USB_DIR_IN) {
if (hid->urbin)
continue;
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h
index 2b91705740a..52437e5e2e7 100644
--- a/drivers/usb/input/hid-debug.h
+++ b/drivers/usb/input/hid-debug.h
@@ -67,7 +67,7 @@ static const struct hid_usage_entry hid_usage_table[] = {
{0, 0x44, "Vbry"},
{0, 0x45, "Vbrz"},
{0, 0x46, "Vno"},
- {0, 0x80, "SystemControl"},
+ {0, 0x80, "SystemControl"},
{0, 0x81, "SystemPowerDown"},
{0, 0x82, "SystemSleep"},
{0, 0x83, "SystemWakeUp"},
@@ -347,7 +347,7 @@ __inline__ static void tab(int n) {
static void hid_dump_field(struct hid_field *field, int n) {
int j;
-
+
if (field->physical) {
tab(n);
printk("Physical(");
@@ -408,7 +408,7 @@ static void hid_dump_field(struct hid_field *field, int n) {
printk("%s", units[sys][i]);
if(nibble != 1) {
/* This is a _signed_ nibble(!) */
-
+
int val = nibble & 0x7;
if(nibble & 0x08)
val = -((0x7 & ~val) +1);
@@ -443,7 +443,7 @@ static void __attribute__((unused)) hid_dump_device(struct hid_device *device) {
struct list_head *list;
unsigned i,k;
static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
-
+
for (i = 0; i < HID_REPORT_TYPES; i++) {
report_enum = device->report_enum + i;
list = report_enum->report_list.next;
@@ -664,8 +664,8 @@ static char *keys[KEY_MAX + 1] = {
static char *relatives[REL_MAX + 1] = {
[REL_X] = "X", [REL_Y] = "Y",
[REL_Z] = "Z", [REL_HWHEEL] = "HWheel",
- [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel",
- [REL_MISC] = "Misc",
+ [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel",
+ [REL_MISC] = "Misc",
};
static char *absolutes[ABS_MAX + 1] = {
@@ -690,9 +690,9 @@ static char *misc[MSC_MAX + 1] = {
};
static char *leds[LED_MAX + 1] = {
- [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock",
+ [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock",
[LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose",
- [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep",
+ [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep",
[LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute",
[LED_MISC] = "Misc",
};
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 5553c3553e9..9ac1e909533 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -164,7 +164,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
- if (field->flags & HID_MAIN_ITEM_RELATIVE)
+ if (field->flags & HID_MAIN_ITEM_RELATIVE)
map_rel(usage->hid & 0xf);
else
map_abs(usage->hid & 0xf);
@@ -297,7 +297,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case HID_UP_MSVENDOR:
goto ignore;
-
+
case HID_UP_PID:
set_bit(EV_FF, input->evbit);
@@ -349,7 +349,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
goto ignore;
if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
- (usage->type == EV_REL) && (usage->code == REL_WHEEL))
+ (usage->type == EV_REL) && (usage->code == REL_WHEEL))
set_bit(REL_HWHEEL, bit);
if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
@@ -365,11 +365,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
a = field->logical_minimum = 0;
b = field->logical_maximum = 255;
}
-
+
if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
else input_set_abs_params(input, usage->code, a, b, 0, 0);
-
+
}
if (usage->hat_min < usage->hat_max || usage->hat_dir) {
@@ -420,7 +420,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
return;
}
- if (usage->hat_min < usage->hat_max || usage->hat_dir) {
+ if (usage->hat_min < usage->hat_max || usage->hat_dir) {
int hat_dir = usage->hat_dir;
if (!hat_dir)
hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
@@ -551,7 +551,7 @@ int hidinput_connect(struct hid_device *hid)
for (i = 0; i < hid->maxcollection; i++)
if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
hid->collection[i].type == HID_COLLECTION_PHYSICAL)
- if (IS_INPUT_APPLICATION(hid->collection[i].usage))
+ if (IS_INPUT_APPLICATION(hid->collection[i].usage))
break;
if (i == hid->maxcollection)
@@ -592,7 +592,7 @@ int hidinput_connect(struct hid_device *hid)
for (j = 0; j < report->field[i]->maxusage; j++)
hidinput_configure_usage(hidinput, report->field[i],
report->field[i]->usage + j);
-
+
if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
/* This will leave hidinput NULL, so that it
* allocates another one if we have more inputs on
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index 0d7404bab92..0c4c77aa31e 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -94,7 +94,7 @@ struct lgff_device {
isn't really necessary */
unsigned long flags[1]; /* Contains various information about the
- state of the driver for this device */
+ state of the driver for this device */
struct timer_list timer;
};
@@ -234,7 +234,7 @@ static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
kfree(ret);
return NULL;
}
- memset(ret->field[0]->value, 0, sizeof(s32[8]));
+ memset(ret->field[0]->value, 0, sizeof(s32[8]));
return ret;
}
@@ -295,11 +295,11 @@ static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
unsigned long flags;
if (type != EV_FF) return -EINVAL;
- if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
+ if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
if (value < 0) return -EINVAL;
spin_lock_irqsave(&lgff->lock, flags);
-
+
if (value > 0) {
if (test_bit(EFFECT_STARTED, effect->flags)) {
spin_unlock_irqrestore(&lgff->lock, flags);
@@ -345,7 +345,7 @@ static int hid_lgff_flush(struct input_dev *dev, struct file *file)
and perform ioctls on the same fd all at the same time */
if ( current->pid == lgff->effects[i].owner
&& test_bit(EFFECT_USED, lgff->effects[i].flags)) {
-
+
if (hid_lgff_erase(dev, i))
warn("erase effect %d failed", i);
}
@@ -378,7 +378,7 @@ static int hid_lgff_upload_effect(struct input_dev* input,
struct lgff_effect new;
int id;
unsigned long flags;
-
+
dbg("ioctl rumble");
if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
@@ -441,7 +441,7 @@ static void hid_lgff_timer(unsigned long timer_data)
spin_lock_irqsave(&lgff->lock, flags);
- for (i=0; i<LGFF_EFFECTS; ++i) {
+ for (i=0; i<LGFF_EFFECTS; ++i) {
struct lgff_effect* effect = lgff->effects +i;
if (test_bit(EFFECT_PLAYING, effect->flags)) {
@@ -491,7 +491,7 @@ static void hid_lgff_timer(unsigned long timer_data)
set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
}
}
- }
+ }
#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
@@ -524,5 +524,5 @@ static void hid_lgff_timer(unsigned long timer_data)
add_timer(&lgff->timer);
}
- spin_unlock_irqrestore(&lgff->lock, flags);
+ spin_unlock_irqrestore(&lgff->lock, flags);
}
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 6d9329c698d..c1b6b69bc4a 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -118,7 +118,7 @@ struct hid_item {
#define HID_MAIN_ITEM_CONSTANT 0x001
#define HID_MAIN_ITEM_VARIABLE 0x002
#define HID_MAIN_ITEM_RELATIVE 0x004
-#define HID_MAIN_ITEM_WRAP 0x008
+#define HID_MAIN_ITEM_WRAP 0x008
#define HID_MAIN_ITEM_NONLINEAR 0x010
#define HID_MAIN_ITEM_NO_PREFERRED 0x020
#define HID_MAIN_ITEM_NULL_STATE 0x040
@@ -172,14 +172,14 @@ struct hid_item {
#define HID_USAGE_PAGE 0xffff0000
#define HID_UP_UNDEFINED 0x00000000
-#define HID_UP_GENDESK 0x00010000
-#define HID_UP_KEYBOARD 0x00070000
-#define HID_UP_LED 0x00080000
-#define HID_UP_BUTTON 0x00090000
-#define HID_UP_ORDINAL 0x000a0000
+#define HID_UP_GENDESK 0x00010000
+#define HID_UP_KEYBOARD 0x00070000
+#define HID_UP_LED 0x00080000
+#define HID_UP_BUTTON 0x00090000
+#define HID_UP_ORDINAL 0x000a0000
#define HID_UP_CONSUMER 0x000c0000
-#define HID_UP_DIGITIZER 0x000d0000
-#define HID_UP_PID 0x000f0000
+#define HID_UP_DIGITIZER 0x000d0000
+#define HID_UP_PID 0x000f0000
#define HID_UP_HPVENDOR 0xff7f0000
#define HID_UP_MSVENDOR 0xff000000
@@ -406,7 +406,7 @@ struct hid_device { /* device report descriptor */
dma_addr_t outbuf_dma; /* Output buffer dma */
spinlock_t outlock; /* Output fifo spinlock */
- unsigned claimed; /* Claimed by hidinput, hiddev? */
+ unsigned claimed; /* Claimed by hidinput, hiddev? */
unsigned quirks; /* Various quirks the device can pull on us */
struct list_head inputs; /* The list of inputs */
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 96b7c906795..4c13331b5f4 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -95,7 +95,7 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
return NULL;
rinfo->report_id = ((struct hid_report *) list)->id;
break;
-
+
case HID_REPORT_ID_NEXT:
list = (struct list_head *)
report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK];
@@ -106,7 +106,7 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
return NULL;
rinfo->report_id = ((struct hid_report *) list)->id;
break;
-
+
default:
return NULL;
}
@@ -158,7 +158,7 @@ static void hiddev_send_event(struct hid_device *hid,
if (uref->field_index != HID_FIELD_INDEX_NONE ||
(list->flags & HIDDEV_FLAG_REPORT) != 0) {
list->buffer[list->head] = *uref;
- list->head = (list->head + 1) &
+ list->head = (list->head + 1) &
(HIDDEV_BUFFER_SIZE - 1);
kill_fasync(&list->fasync, SIGIO, POLL_IN);
}
@@ -179,9 +179,9 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
unsigned type = field->report_type;
struct hiddev_usage_ref uref;
- uref.report_type =
+ uref.report_type =
(type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
- ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
+ ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
uref.report_id = field->report->id;
uref.field_index = field->index;
@@ -199,9 +199,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
struct hiddev_usage_ref uref;
memset(&uref, 0, sizeof(uref));
- uref.report_type =
+ uref.report_type =
(type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
- ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
+ ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
uref.report_id = report->id;
uref.field_index = HID_FIELD_INDEX_NONE;
@@ -236,7 +236,7 @@ static int hiddev_release(struct inode * inode, struct file * file)
*listptr = (*listptr)->next;
if (!--list->hiddev->open) {
- if (list->hiddev->exist)
+ if (list->hiddev->exist)
hid_close(list->hiddev->hid);
else
kfree(list->hiddev);
@@ -303,7 +303,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
if (list->head == list->tail) {
add_wait_queue(&list->hiddev->wait, &wait);
set_current_state(TASK_INTERRUPTIBLE);
-
+
while (list->head == list->tail) {
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
@@ -317,7 +317,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
retval = -EIO;
break;
}
-
+
schedule();
}
@@ -329,7 +329,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
return retval;
- while (list->head != list->tail &&
+ while (list->head != list->tail &&
retval + event_size <= count) {
if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
if (list->buffer[list->tail].field_index !=
@@ -405,10 +405,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return -EINVAL;
for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type ==
+ if (hid->collection[i].type ==
HID_COLLECTION_APPLICATION && arg-- == 0)
break;
-
+
if (i == hid->maxcollection)
return -EINVAL;
@@ -562,7 +562,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
if (!uref_multi)
return -ENOMEM;
uref = &uref_multi->uref;
- if (copy_from_user(uref, user_arg, sizeof(*uref)))
+ if (copy_from_user(uref, user_arg, sizeof(*uref)))
goto fault;
rinfo.report_type = uref->report_type;
@@ -595,7 +595,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return -ENOMEM;
uref = &uref_multi->uref;
if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
- if (copy_from_user(uref_multi, user_arg,
+ if (copy_from_user(uref_multi, user_arg,
sizeof(*uref_multi)))
goto fault;
} else {
@@ -603,7 +603,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
goto fault;
}
- if (cmd != HIDIOCGUSAGE &&
+ if (cmd != HIDIOCGUSAGE &&
cmd != HIDIOCGUSAGES &&
uref->report_type == HID_REPORT_TYPE_INPUT)
goto inval;
@@ -651,16 +651,16 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return field->usage[uref->usage_index].collection_index;
case HIDIOCGUSAGES:
for (i = 0; i < uref_multi->num_values; i++)
- uref_multi->values[i] =
+ uref_multi->values[i] =
field->value[uref->usage_index + i];
- if (copy_to_user(user_arg, uref_multi,
+ if (copy_to_user(user_arg, uref_multi,
sizeof(*uref_multi)))
goto fault;
goto goodreturn;
case HIDIOCSUSAGES:
for (i = 0; i < uref_multi->num_values; i++)
- field->value[uref->usage_index + i] =
- uref_multi->values[i];
+ field->value[uref->usage_index + i] =
+ uref_multi->values[i];
goto goodreturn;
}
@@ -670,7 +670,7 @@ goodreturn:
fault:
kfree(uref_multi);
return -EFAULT;
-inval:
+inval:
kfree(uref_multi);
return -EINVAL;
@@ -734,7 +734,7 @@ static struct usb_class_driver hiddev_class = {
.name = "usb/hid/hiddev%d",
.fops = &hiddev_fops,
.mode = S_IFCHR | S_IRUGO | S_IWUSR,
- .minor_base = HIDDEV_MINOR_BASE,
+ .minor_base = HIDDEV_MINOR_BASE,
};
/*
@@ -747,7 +747,7 @@ int hiddev_connect(struct hid_device *hid)
int retval;
for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type ==
+ if (hid->collection[i].type ==
HID_COLLECTION_APPLICATION &&
!IS_INPUT_APPLICATION(hid->collection[i].usage))
break;
@@ -755,11 +755,11 @@ int hiddev_connect(struct hid_device *hid)
if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
return -1;
- if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
+ if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
return -1;
memset(hiddev, 0, sizeof(struct hiddev));
- retval = usb_register_dev(hid->intf, &hiddev_class);
+ retval = usb_register_dev(hid->intf, &hiddev_class);
if (retval) {
err("Not able to get a minor for this device.");
kfree(hiddev);
@@ -768,12 +768,12 @@ int hiddev_connect(struct hid_device *hid)
init_waitqueue_head(&hiddev->wait);
- hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
+ hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
hiddev->hid = hid;
hiddev->exist = 1;
- hid->minor = hid->intf->minor;
+ hid->minor = hid->intf->minor;
hid->hiddev = hiddev;
return 0;
@@ -818,7 +818,7 @@ void hiddev_disconnect(struct hid_device *hid)
/* We never attach in this manner, and rely on HID to connect us. This
* is why there is no disconnect routine defined in the usb_driver either.
*/
-static int hiddev_usbd_probe(struct usb_interface *intf,
+static int hiddev_usbd_probe(struct usb_interface *intf,
const struct usb_device_id *hiddev_info)
{
return -ENODEV;
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
new file mode 100644
index 00000000000..47dec6a1b34
--- /dev/null
+++ b/drivers/usb/input/itmtouch.c
@@ -0,0 +1,268 @@
+/******************************************************************************
+ * itmtouch.c -- Driver for ITM touchscreen panel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Based upon original work by Chris Collins <xfire-itmtouch@xware.cx>.
+ *
+ * Kudos to ITM for providing me with the datasheet for the panel,
+ * even though it was a day later than I had finished writing this
+ * driver.
+ *
+ * It has meant that I've been able to correct my interpretation of the
+ * protocol packets however.
+ *
+ * CC -- 2003/9/29
+ *
+ * History
+ * 1.0 & 1.1 2003 (CC) vojtech@suse.cz
+ * Original version for 2.4.x kernels
+ *
+ * 1.2 02/03/2005 (HCE) hc@mivu.no
+ * Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints.
+ * Unfortunately no calibration support at this time.
+ *
+ * 1.2.1 09/03/2005 (HCE) hc@mivu.no
+ * Code cleanup and adjusting syntax to start matching kernel standards
+ *
+ *****************************************************************************/
+
+#include <linux/config.h>
+
+#ifdef CONFIG_USB_DEBUG
+ #define DEBUG
+#else
+ #undef DEBUG
+#endif
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+
+/* only an 8 byte buffer necessary for a single packet */
+#define ITM_BUFSIZE 8
+#define PATH_SIZE 64
+
+#define USB_VENDOR_ID_ITMINC 0x0403
+#define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9
+
+#define DRIVER_AUTHOR "Hans-Christian Egtvedt <hc@mivu.no>"
+#define DRIVER_VERSION "v1.2.1"
+#define DRIVER_DESC "USB ITM Inc Touch Panel Driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE( DRIVER_LICENSE );
+
+struct itmtouch_dev {
+ struct usb_device *usbdev; /* usb device */
+ struct input_dev inputdev; /* input device */
+ struct urb *readurb; /* urb */
+ char rbuf[ITM_BUFSIZE]; /* data */
+ int users;
+ char name[128];
+ char phys[64];
+};
+
+static struct usb_device_id itmtouch_ids [] = {
+ { USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) },
+ { }
+};
+
+static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+ struct itmtouch_dev * itmtouch = urb->context;
+ unsigned char *data = urb->transfer_buffer;
+ struct input_dev *dev = &itmtouch->inputdev;
+ int retval;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ETIMEDOUT:
+ /* this urb is timing out */
+ dbg("%s - urb timed out - was the device unplugged?",
+ __FUNCTION__);
+ return;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __FUNCTION__, urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
+ goto exit;
+ }
+
+ input_regs(dev, regs);
+
+ /* if pressure has been released, then don't report X/Y */
+ if (data[7] & 0x20) {
+ input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F));
+ input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F));
+ }
+
+ input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F));
+ input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20);
+ input_sync(dev);
+
+exit:
+ retval = usb_submit_urb (urb, GFP_ATOMIC);
+ if (retval)
+ printk(KERN_ERR "%s - usb_submit_urb failed with result: %d",
+ __FUNCTION__, retval);
+}
+
+static int itmtouch_open(struct input_dev *input)
+{
+ struct itmtouch_dev *itmtouch = input->private;
+
+ itmtouch->readurb->dev = itmtouch->usbdev;
+
+ if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL))
+ return -EIO;
+
+ return 0;
+}
+
+static void itmtouch_close(struct input_dev *input)
+{
+ struct itmtouch_dev *itmtouch = input->private;
+
+ usb_kill_urb(itmtouch->readurb);
+}
+
+static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+ struct itmtouch_dev *itmtouch;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ unsigned int pipe;
+ unsigned int maxp;
+ char path[PATH_SIZE];
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+
+ if (!(itmtouch = kcalloc(1, sizeof(struct itmtouch_dev), GFP_KERNEL))) {
+ err("%s - Out of memory.", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ itmtouch->usbdev = udev;
+
+ itmtouch->inputdev.private = itmtouch;
+ itmtouch->inputdev.open = itmtouch_open;
+ itmtouch->inputdev.close = itmtouch_close;
+
+ usb_make_path(udev, path, PATH_SIZE);
+
+ itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+ itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
+ itmtouch->inputdev.name = itmtouch->name;
+ itmtouch->inputdev.phys = itmtouch->phys;
+ itmtouch->inputdev.id.bustype = BUS_USB;
+ itmtouch->inputdev.id.vendor = udev->descriptor.idVendor;
+ itmtouch->inputdev.id.product = udev->descriptor.idProduct;
+ itmtouch->inputdev.id.version = udev->descriptor.bcdDevice;
+ itmtouch->inputdev.dev = &intf->dev;
+
+ if (!strlen(itmtouch->name))
+ sprintf(itmtouch->name, "USB ITM touchscreen");
+
+ /* device limits */
+ /* as specified by the ITM datasheet, X and Y are 12bit,
+ * Z (pressure) is 8 bit. However, the fields are defined up
+ * to 14 bits for future possible expansion.
+ */
+ input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0);
+ input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0);
+ input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0);
+
+ /* initialise the URB so we can read from the transport stream */
+ pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
+ maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+
+ if (maxp > ITM_BUFSIZE)
+ maxp = ITM_BUFSIZE;
+
+ itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (!itmtouch->readurb) {
+ dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
+ kfree(itmtouch);
+ return -ENOMEM;
+ }
+
+ usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
+ maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
+
+ input_register_device(&itmtouch->inputdev);
+
+ printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path);
+ usb_set_intfdata(intf, itmtouch);
+
+ return 0;
+}
+
+static void itmtouch_disconnect(struct usb_interface *intf)
+{
+ struct itmtouch_dev *itmtouch = usb_get_intfdata(intf);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (itmtouch) {
+ input_unregister_device(&itmtouch->inputdev);
+ usb_kill_urb(itmtouch->readurb);
+ usb_free_urb(itmtouch->readurb);
+ kfree(itmtouch);
+ }
+}
+
+MODULE_DEVICE_TABLE(usb, itmtouch_ids);
+
+static struct usb_driver itmtouch_driver = {
+ .owner = THIS_MODULE,
+ .name = "itmtouch",
+ .probe = itmtouch_probe,
+ .disconnect = itmtouch_disconnect,
+ .id_table = itmtouch_ids,
+};
+
+static int __init itmtouch_init(void)
+{
+ info(DRIVER_DESC " " DRIVER_VERSION);
+ info(DRIVER_AUTHOR);
+ return usb_register(&itmtouch_driver);
+}
+
+static void __exit itmtouch_exit(void)
+{
+ usb_deregister(&itmtouch_driver);
+}
+
+module_init(itmtouch_init);
+module_exit(itmtouch_exit);
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
index a68c5b4e7b3..d2f0f90a9bc 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -36,7 +36,6 @@ struct kbtab {
struct input_dev dev;
struct usb_device *usbdev;
struct urb *irq;
- int open;
int x, y;
int button;
int pressure;
@@ -79,12 +78,12 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
/*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
- if( -1 == kb_pressure_click){
+ if (-1 == kb_pressure_click) {
input_report_abs(dev, ABS_PRESSURE, kbtab->pressure);
} else {
input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0);
};
-
+
input_sync(dev);
exit:
@@ -105,14 +104,9 @@ static int kbtab_open(struct input_dev *dev)
{
struct kbtab *kbtab = dev->private;
- if (kbtab->open++)
- return 0;
-
kbtab->irq->dev = kbtab->usbdev;
- if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) {
- kbtab->open--;
+ if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
return -EIO;
- }
return 0;
}
@@ -121,8 +115,7 @@ static void kbtab_close(struct input_dev *dev)
{
struct kbtab *kbtab = dev->private;
- if (!--kbtab->open)
- usb_kill_urb(kbtab->irq);
+ usb_kill_urb(kbtab->irq);
}
static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -161,7 +154,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
kbtab->dev.absmax[ABS_X] = 0x2000;
kbtab->dev.absmax[ABS_Y] = 0x1750;
kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
-
+
kbtab->dev.absfuzz[ABS_X] = 4;
kbtab->dev.absfuzz[ABS_Y] = 4;
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
new file mode 100644
index 00000000000..67dc9368520
--- /dev/null
+++ b/drivers/usb/input/keyspan_remote.c
@@ -0,0 +1,633 @@
+/*
+ * keyspan_remote: USB driver for the Keyspan DMR
+ *
+ * Copyright (C) 2005 Zymeta Corporation - Michael Downey (downey@zymeta.com)
+ *
+ * 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, version 2.
+ *
+ * This driver has been put together with the support of Innosys, Inc.
+ * and Keyspan, Inc the manufacturers of the Keyspan USB DMR product.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#define DRIVER_VERSION "v0.1"
+#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>"
+#define DRIVER_DESC "Driver for the USB Keyspan remote control."
+#define DRIVER_LICENSE "GPL"
+
+/* Parameters that can be passed to the driver. */
+static int debug;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
+
+/* Vendor and product ids */
+#define USB_KEYSPAN_VENDOR_ID 0x06CD
+#define USB_KEYSPAN_PRODUCT_UIA11 0x0202
+
+/* Defines for converting the data from the remote. */
+#define ZERO 0x18
+#define ZERO_MASK 0x1F /* 5 bits for a 0 */
+#define ONE 0x3C
+#define ONE_MASK 0x3F /* 6 bits for a 1 */
+#define SYNC 0x3F80
+#define SYNC_MASK 0x3FFF /* 14 bits for a SYNC sequence */
+#define STOP 0x00
+#define STOP_MASK 0x1F /* 5 bits for the STOP sequence */
+#define GAP 0xFF
+
+#define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */
+
+/* table of devices that work with this driver */
+static struct usb_device_id keyspan_table[] = {
+ { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
+ { } /* Terminating entry */
+};
+
+/* Structure to store all the real stuff that a remote sends to us. */
+struct keyspan_message {
+ u16 system;
+ u8 button;
+ u8 toggle;
+};
+
+/* Structure used for all the bit testing magic needed to be done. */
+struct bit_tester {
+ u32 tester;
+ int len;
+ int pos;
+ int bits_left;
+ u8 buffer[32];
+};
+
+/* Structure to hold all of our driver specific stuff */
+struct usb_keyspan {
+ char name[128];
+ char phys[64];
+ struct usb_device* udev;
+ struct input_dev input;
+ struct usb_interface* interface;
+ struct usb_endpoint_descriptor* in_endpoint;
+ struct urb* irq_urb;
+ int open;
+ dma_addr_t in_dma;
+ unsigned char* in_buffer;
+
+ /* variables used to parse messages from remote. */
+ struct bit_tester data;
+ int stage;
+ int toggle;
+};
+
+/*
+ * Table that maps the 31 possible keycodes to input keys.
+ * Currently there are 15 and 17 button models so RESERVED codes
+ * are blank areas in the mapping.
+ */
+static int keyspan_key_table[] = {
+ KEY_RESERVED, /* 0 is just a place holder. */
+ KEY_RESERVED,
+ KEY_STOP,
+ KEY_PLAYCD,
+ KEY_RESERVED,
+ KEY_PREVIOUSSONG,
+ KEY_REWIND,
+ KEY_FORWARD,
+ KEY_NEXTSONG,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_PAUSE,
+ KEY_VOLUMEUP,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_VOLUMEDOWN,
+ KEY_RESERVED,
+ KEY_UP,
+ KEY_RESERVED,
+ KEY_MUTE,
+ KEY_LEFT,
+ KEY_ENTER,
+ KEY_RIGHT,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_DOWN,
+ KEY_RESERVED,
+ KEY_KPASTERISK,
+ KEY_RESERVED,
+ KEY_MENU
+};
+
+static struct usb_driver keyspan_driver;
+
+/*
+ * Debug routine that prints out what we've received from the remote.
+ */
+static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
+{
+ char codes[4*RECV_SIZE];
+ int i;
+
+ for (i = 0; i < RECV_SIZE; i++) {
+ snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]);
+ }
+
+ dev_info(&dev->udev->dev, "%s\n", codes);
+}
+
+/*
+ * Routine that manages the bit_tester structure. It makes sure that there are
+ * at least bits_needed bits loaded into the tester.
+ */
+static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
+{
+ if (dev->data.bits_left >= bits_needed)
+ return(0);
+
+ /*
+ * Somehow we've missed the last message. The message will be repeated
+ * though so it's not too big a deal
+ */
+ if (dev->data.pos >= dev->data.len) {
+ dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
+ __FUNCTION__, dev->data.pos, dev->data.len);
+ return(-1);
+ }
+
+ /* Load as much as we can into the tester. */
+ while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) &&
+ (dev->data.pos < dev->data.len)) {
+ dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left);
+ dev->data.bits_left += 8;
+ }
+
+ return(0);
+}
+
+/*
+ * Routine that handles all the logic needed to parse out the message from the remote.
+ */
+static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
+{
+ int i;
+ int found = 0;
+ struct keyspan_message message;
+
+ switch(remote->stage) {
+ case 0:
+ /*
+ * In stage 0 we want to find the start of a message. The remote sends a 0xFF as filler.
+ * So the first byte that isn't a FF should be the start of a new message.
+ */
+ for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i);
+
+ if (i < RECV_SIZE) {
+ memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE);
+ remote->data.len = RECV_SIZE;
+ remote->data.pos = 0;
+ remote->data.tester = 0;
+ remote->data.bits_left = 0;
+ remote->stage = 1;
+ }
+ break;
+
+ case 1:
+ /*
+ * Stage 1 we should have 16 bytes and should be able to detect a
+ * SYNC. The SYNC is 14 bits, 7 0's and then 7 1's.
+ */
+ memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
+ remote->data.len += RECV_SIZE;
+
+ found = 0;
+ while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) {
+ for (i = 0; i < 8; ++i) {
+ if (keyspan_load_tester(remote, 14) != 0) {
+ remote->stage = 0;
+ return;
+ }
+
+ if ((remote->data.tester & SYNC_MASK) == SYNC) {
+ remote->data.tester = remote->data.tester >> 14;
+ remote->data.bits_left -= 14;
+ found = 1;
+ break;
+ } else {
+ remote->data.tester = remote->data.tester >> 1;
+ --remote->data.bits_left;
+ }
+ }
+ }
+
+ if (!found) {
+ remote->stage = 0;
+ remote->data.len = 0;
+ } else {
+ remote->stage = 2;
+ }
+ break;
+
+ case 2:
+ /*
+ * Stage 2 we should have 24 bytes which will be enough for a full
+ * message. We need to parse out the system code, button code,
+ * toggle code, and stop.
+ */
+ memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
+ remote->data.len += RECV_SIZE;
+
+ message.system = 0;
+ for (i = 0; i < 9; i++) {
+ keyspan_load_tester(remote, 6);
+
+ if ((remote->data.tester & ZERO_MASK) == ZERO) {
+ message.system = message.system << 1;
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else if ((remote->data.tester & ONE_MASK) == ONE) {
+ message.system = (message.system << 1) + 1;
+ remote->data.tester = remote->data.tester >> 6;
+ remote->data.bits_left -= 6;
+ } else {
+ err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
+ remote->stage = 0;
+ return;
+ }
+ }
+
+ message.button = 0;
+ for (i = 0; i < 5; i++) {
+ keyspan_load_tester(remote, 6);
+
+ if ((remote->data.tester & ZERO_MASK) == ZERO) {
+ message.button = message.button << 1;
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else if ((remote->data.tester & ONE_MASK) == ONE) {
+ message.button = (message.button << 1) + 1;
+ remote->data.tester = remote->data.tester >> 6;
+ remote->data.bits_left -= 6;
+ } else {
+ err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
+ remote->stage = 0;
+ return;
+ }
+ }
+
+ keyspan_load_tester(remote, 6);
+ if ((remote->data.tester & ZERO_MASK) == ZERO) {
+ message.toggle = 0;
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else if ((remote->data.tester & ONE_MASK) == ONE) {
+ message.toggle = 1;
+ remote->data.tester = remote->data.tester >> 6;
+ remote->data.bits_left -= 6;
+ } else {
+ err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
+ }
+
+ keyspan_load_tester(remote, 5);
+ if ((remote->data.tester & STOP_MASK) == STOP) {
+ remote->data.tester = remote->data.tester >> 5;
+ remote->data.bits_left -= 5;
+ } else {
+ err("Bad message recieved, no stop bit found.\n");
+ }
+
+ dev_dbg(&remote->udev,
+ "%s found valid message: system: %d, button: %d, toggle: %d\n",
+ __FUNCTION__, message.system, message.button, message.toggle);
+
+ if (message.toggle != remote->toggle) {
+ input_regs(&remote->input, regs);
+ input_report_key(&remote->input, keyspan_key_table[message.button], 1);
+ input_report_key(&remote->input, keyspan_key_table[message.button], 0);
+ input_sync(&remote->input);
+ remote->toggle = message.toggle;
+ }
+
+ remote->stage = 0;
+ break;
+ }
+}
+
+/*
+ * Routine for sending all the initialization messages to the remote.
+ */
+static int keyspan_setup(struct usb_device* dev)
+{
+ int retval = 0;
+
+ retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
+ if (retval) {
+ dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
+ __FUNCTION__, retval);
+ return(retval);
+ }
+
+ retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
+ if (retval) {
+ dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
+ __FUNCTION__, retval);
+ return(retval);
+ }
+
+ retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
+ if (retval) {
+ dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
+ __FUNCTION__, retval);
+ return(retval);
+ }
+
+ dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
+ return(retval);
+}
+
+/*
+ * Routine used to handle a new message that has come in.
+ */
+static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs)
+{
+ struct usb_keyspan *dev = urb->context;
+ int retval;
+
+ /* Check our status in case we need to bail out early. */
+ switch (urb->status) {
+ case 0:
+ break;
+
+ /* Device went away so don't keep trying to read from it. */
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ goto resubmit;
+ break;
+ }
+
+ if (debug)
+ keyspan_print(dev);
+
+ keyspan_check_data(dev, regs);
+
+resubmit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
+}
+
+static int keyspan_open(struct input_dev *dev)
+{
+ struct usb_keyspan *remote = dev->private;
+
+ if (remote->open++)
+ return 0;
+
+ remote->irq_urb->dev = remote->udev;
+ if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) {
+ remote->open--;
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void keyspan_close(struct input_dev *dev)
+{
+ struct usb_keyspan *remote = dev->private;
+
+ if (!--remote->open)
+ usb_kill_urb(remote->irq_urb);
+}
+
+/*
+ * Routine that sets up the driver to handle a specific USB device detected on the bus.
+ */
+static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+ int i;
+ int retval = -ENOMEM;
+ char path[64];
+ char *buf;
+ struct usb_keyspan *remote = NULL;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* See if the offered device matches what we can accept */
+ if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) ||
+ (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) )
+ return -ENODEV;
+
+ /* allocate memory for our device state and initialize it */
+ remote = kmalloc(sizeof(*remote), GFP_KERNEL);
+ if (remote == NULL) {
+ err("Out of memory\n");
+ goto error;
+ }
+ memset(remote, 0x00, sizeof(*remote));
+
+ remote->udev = udev;
+ remote->interface = interface;
+ remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
+
+ /* set up the endpoint information */
+ /* use only the first in interrupt endpoint */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!remote->in_endpoint &&
+ (endpoint->bEndpointAddress & USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+ /* we found our interrupt in endpoint */
+ remote->in_endpoint = endpoint;
+
+ remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+ if (!remote->in_buffer) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ }
+ }
+
+ if (!remote->in_endpoint) {
+ err("Could not find interrupt input endpoint.\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!remote->irq_urb) {
+ err("Failed to allocate urb.\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ retval = keyspan_setup(remote->udev);
+ if (retval) {
+ err("Failed to setup device.\n");
+ retval = -ENODEV;
+ goto error;
+ }
+
+ /*
+ * Setup the input system with the bits we are going to be reporting
+ */
+ remote->input.evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
+ for (i = 0; i < 32; ++i) {
+ if (keyspan_key_table[i] != KEY_RESERVED) {
+ set_bit(keyspan_key_table[i], remote->input.keybit);
+ }
+ }
+
+ remote->input.private = remote;
+ remote->input.open = keyspan_open;
+ remote->input.close = keyspan_close;
+
+ usb_make_path(remote->udev, path, 64);
+ sprintf(remote->phys, "%s/input0", path);
+
+ remote->input.name = remote->name;
+ remote->input.phys = remote->phys;
+ remote->input.id.bustype = BUS_USB;
+ remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor);
+ remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
+ remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
+
+ if (!(buf = kmalloc(63, GFP_KERNEL))) {
+ usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ kfree(remote);
+ return -ENOMEM;
+ }
+
+ if (remote->udev->descriptor.iManufacturer &&
+ usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
+ strcat(remote->name, buf);
+
+ if (remote->udev->descriptor.iProduct &&
+ usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
+ sprintf(remote->name, "%s %s", remote->name, buf);
+
+ if (!strlen(remote->name))
+ sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
+ remote->input.id.vendor, remote->input.id.product);
+
+ kfree(buf);
+
+ /*
+ * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
+ */
+ usb_fill_int_urb(remote->irq_urb,
+ remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress),
+ remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote,
+ remote->in_endpoint->bInterval);
+ remote->irq_urb->transfer_dma = remote->in_dma;
+ remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ /* we can register the device now, as it is ready */
+ input_register_device(&remote->input);
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, remote);
+
+ /* let the user know what node this device is now attached to */
+ info("connected: %s on %s", remote->name, path);
+ return 0;
+
+error:
+ /*
+ * In case of error we need to clean up any allocated buffers
+ */
+ if (remote->irq_urb)
+ usb_free_urb(remote->irq_urb);
+
+ if (remote->in_buffer)
+ usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+
+ if (remote)
+ kfree(remote);
+
+ return retval;
+}
+
+/*
+ * Routine called when a device is disconnected from the USB.
+ */
+static void keyspan_disconnect(struct usb_interface *interface)
+{
+ struct usb_keyspan *remote;
+
+ /* prevent keyspan_open() from racing keyspan_disconnect() */
+ lock_kernel();
+
+ remote = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ if (remote) { /* We have a valid driver structure so clean up everything we allocated. */
+ input_unregister_device(&remote->input);
+ usb_kill_urb(remote->irq_urb);
+ usb_free_urb(remote->irq_urb);
+ usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma);
+ kfree(remote);
+ }
+
+ unlock_kernel();
+
+ info("USB Keyspan now disconnected");
+}
+
+/*
+ * Standard driver set up sections
+ */
+static struct usb_driver keyspan_driver =
+{
+ .owner = THIS_MODULE,
+ .name = "keyspan_remote",
+ .probe = keyspan_probe,
+ .disconnect = keyspan_disconnect,
+ .id_table = keyspan_table
+};
+
+static int __init usb_keyspan_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&keyspan_driver);
+ if (result)
+ err("usb_register failed. Error number %d\n", result);
+
+ return result;
+}
+
+static void __exit usb_keyspan_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&keyspan_driver);
+}
+
+module_init(usb_keyspan_init);
+module_exit(usb_keyspan_exit);
+
+MODULE_DEVICE_TABLE(usb, keyspan_table);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index ab1a2a30ce7..09b5cc7c66d 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -42,9 +42,9 @@
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
- #define DEBUG
+ #define DEBUG
#else
- #undef DEBUG
+ #undef DEBUG
#endif
#include <linux/kernel.h>
@@ -93,275 +93,255 @@ module_param(raw_coordinates, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)");
struct mtouch_usb {
- unsigned char *data;
- dma_addr_t data_dma;
- struct urb *irq;
- struct usb_device *udev;
- struct input_dev input;
- int open;
- char name[128];
- char phys[64];
+ 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];
};
-static struct usb_device_id mtouchusb_devices [] = {
- { USB_DEVICE(0x0596, 0x0001) },
- { }
+static struct usb_device_id mtouchusb_devices[] = {
+ { USB_DEVICE(0x0596, 0x0001) },
+ { }
};
static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
{
- struct mtouch_usb *mtouch = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ETIMEDOUT:
- /* this urb is timing out */
- dbg("%s - urb timed out - was the device unplugged?",
- __FUNCTION__);
- return;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- input_regs(&mtouch->input, regs);
- input_report_key(&mtouch->input, BTN_TOUCH,
- MTOUCHUSB_GET_TOUCHED(mtouch->data));
- input_report_abs(&mtouch->input, ABS_X,
- MTOUCHUSB_GET_XC(mtouch->data));
- input_report_abs(&mtouch->input, ABS_Y,
+ struct mtouch_usb *mtouch = urb->context;
+ int retval;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ETIMEDOUT:
+ /* this urb is timing out */
+ dbg("%s - urb timed out - was the device unplugged?",
+ __FUNCTION__);
+ return;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d",
+ __FUNCTION__, urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d",
+ __FUNCTION__, urb->status);
+ goto exit;
+ }
+
+ input_regs(&mtouch->input, regs);
+ input_report_key(&mtouch->input, BTN_TOUCH,
+ MTOUCHUSB_GET_TOUCHED(mtouch->data));
+ input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
+ input_report_abs(&mtouch->input, ABS_Y,
(raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
- - MTOUCHUSB_GET_YC(mtouch->data));
- input_sync(&mtouch->input);
+ - MTOUCHUSB_GET_YC(mtouch->data));
+ input_sync(&mtouch->input);
exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result: %d",
- __FUNCTION__, retval);
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (retval)
+ err("%s - usb_submit_urb failed with result: %d",
+ __FUNCTION__, retval);
}
-static int mtouchusb_open (struct input_dev *input)
+static int mtouchusb_open(struct input_dev *input)
{
- struct mtouch_usb *mtouch = input->private;
+ struct mtouch_usb *mtouch = input->private;
- if (mtouch->open++)
- return 0;
+ mtouch->irq->dev = mtouch->udev;
- mtouch->irq->dev = mtouch->udev;
+ if (usb_submit_urb(mtouch->irq, GFP_ATOMIC))
+ return -EIO;
- if (usb_submit_urb (mtouch->irq, GFP_ATOMIC)) {
- mtouch->open--;
- return -EIO;
- }
-
- return 0;
+ return 0;
}
-static void mtouchusb_close (struct input_dev *input)
+static void mtouchusb_close(struct input_dev *input)
{
- struct mtouch_usb *mtouch = input->private;
+ struct mtouch_usb *mtouch = input->private;
- if (!--mtouch->open)
- usb_kill_urb (mtouch->irq);
+ usb_kill_urb(mtouch->irq);
}
static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch)
{
- dbg("%s - called", __FUNCTION__);
+ dbg("%s - called", __FUNCTION__);
- mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
- SLAB_ATOMIC, &mtouch->data_dma);
+ mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
+ SLAB_ATOMIC, &mtouch->data_dma);
- if (!mtouch->data)
- return -1;
+ if (!mtouch->data)
+ return -1;
- return 0;
+ return 0;
}
static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch)
{
- dbg("%s - called", __FUNCTION__);
+ dbg("%s - called", __FUNCTION__);
- if (mtouch->data)
- usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE,
- mtouch->data, mtouch->data_dma);
+ if (mtouch->data)
+ usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE,
+ mtouch->data, mtouch->data_dma);
}
static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- struct mtouch_usb *mtouch;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_device *udev = interface_to_usbdev (intf);
- char path[64];
- int nRet;
-
- dbg("%s - called", __FUNCTION__);
-
- dbg("%s - setting interface", __FUNCTION__);
- interface = intf->cur_altsetting;
-
- dbg("%s - setting endpoint", __FUNCTION__);
- endpoint = &interface->endpoint[0].desc;
-
- if (!(mtouch = kmalloc (sizeof (struct mtouch_usb), GFP_KERNEL))) {
- err("%s - Out of memory.", __FUNCTION__);
- return -ENOMEM;
- }
-
- memset(mtouch, 0, sizeof(struct mtouch_usb));
- mtouch->udev = udev;
-
- dbg("%s - allocating buffers", __FUNCTION__);
- if (mtouchusb_alloc_buffers(udev, mtouch)) {
- mtouchusb_free_buffers(udev, mtouch);
- kfree(mtouch);
- return -ENOMEM;
- }
-
- mtouch->input.private = mtouch;
- mtouch->input.open = mtouchusb_open;
- mtouch->input.close = mtouchusb_close;
-
- usb_make_path(udev, path, 64);
- sprintf(mtouch->phys, "%s/input0", path);
-
- mtouch->input.name = mtouch->name;
- mtouch->input.phys = mtouch->phys;
- mtouch->input.id.bustype = BUS_USB;
- mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
- mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
- mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
- mtouch->input.dev = &intf->dev;
-
- mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
- /* Used to Scale Compensated Data and Flip Y */
- mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
- mtouch->input.absmax[ABS_X] = raw_coordinates ? \
- MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
- mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
- mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
- mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
- mtouch->input.absmax[ABS_Y] = raw_coordinates ? \
- MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
- mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
- mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
+ struct mtouch_usb *mtouch;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ char path[64];
+ int nRet;
+
+ dbg("%s - called", __FUNCTION__);
+
+ dbg("%s - setting interface", __FUNCTION__);
+ interface = intf->cur_altsetting;
+
+ dbg("%s - setting endpoint", __FUNCTION__);
+ endpoint = &interface->endpoint[0].desc;
+
+ if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) {
+ err("%s - Out of memory.", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ memset(mtouch, 0, sizeof(struct mtouch_usb));
+ mtouch->udev = udev;
+
+ dbg("%s - allocating buffers", __FUNCTION__);
+ if (mtouchusb_alloc_buffers(udev, mtouch)) {
+ mtouchusb_free_buffers(udev, mtouch);
+ kfree(mtouch);
+ return -ENOMEM;
+ }
+
+ mtouch->input.private = mtouch;
+ mtouch->input.open = mtouchusb_open;
+ mtouch->input.close = mtouchusb_close;
+
+ usb_make_path(udev, path, 64);
+ sprintf(mtouch->phys, "%s/input0", path);
+
+ mtouch->input.name = mtouch->name;
+ mtouch->input.phys = mtouch->phys;
+ mtouch->input.id.bustype = BUS_USB;
+ mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+ mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
+ mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
+ mtouch->input.dev = &intf->dev;
+
+ mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+ mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
+ /* Used to Scale Compensated Data and Flip Y */
+ mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
+ mtouch->input.absmax[ABS_X] = raw_coordinates ?
+ MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
+ mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
+ mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
+ mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
+ mtouch->input.absmax[ABS_Y] = raw_coordinates ?
+ MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
+ mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
+ mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
if (udev->manufacturer)
strcat(mtouch->name, udev->manufacturer);
if (udev->product)
sprintf(mtouch->name, "%s %s", mtouch->name, udev->product);
- if (!strlen(mtouch->name))
- sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
- mtouch->input.id.vendor, mtouch->input.id.product);
-
- nRet = usb_control_msg(mtouch->udev,
- usb_rcvctrlpipe(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__, nRet);
-
- dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__);
- mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!mtouch->irq) {
- dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
- mtouchusb_free_buffers(udev, mtouch);
- kfree(mtouch);
- return -ENOMEM;
- }
-
- dbg("%s - usb_fill_int_urb", __FUNCTION__);
- usb_fill_int_urb(mtouch->irq,
- mtouch->udev,
- usb_rcvintpipe(mtouch->udev, 0x81),
- mtouch->data,
- MTOUCHUSB_REPORT_DATA_SIZE,
- mtouchusb_irq,
- mtouch,
- endpoint->bInterval);
-
- dbg("%s - input_register_device", __FUNCTION__);
- input_register_device(&mtouch->input);
-
- nRet = usb_control_msg(mtouch->udev,
- usb_rcvctrlpipe(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__, nRet);
-
- printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
- usb_set_intfdata(intf, mtouch);
-
- return 0;
+ if (!strlen(mtouch->name))
+ sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
+ mtouch->input.id.vendor, mtouch->input.id.product);
+
+ nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(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__, nRet);
+
+ dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__);
+ mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!mtouch->irq) {
+ dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
+ mtouchusb_free_buffers(udev, mtouch);
+ kfree(mtouch);
+ return -ENOMEM;
+ }
+
+ dbg("%s - usb_fill_int_urb", __FUNCTION__);
+ usb_fill_int_urb(mtouch->irq, mtouch->udev,
+ usb_rcvintpipe(mtouch->udev, 0x81),
+ mtouch->data, MTOUCHUSB_REPORT_DATA_SIZE,
+ mtouchusb_irq, mtouch, endpoint->bInterval);
+
+ dbg("%s - input_register_device", __FUNCTION__);
+ input_register_device(&mtouch->input);
+
+ nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(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__, nRet);
+
+ printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
+ usb_set_intfdata(intf, mtouch);
+
+ return 0;
}
static void mtouchusb_disconnect(struct usb_interface *intf)
{
- struct mtouch_usb *mtouch = usb_get_intfdata (intf);
-
- dbg("%s - called", __FUNCTION__);
- usb_set_intfdata(intf, NULL);
- if (mtouch) {
- dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
- usb_kill_urb(mtouch->irq);
- input_unregister_device(&mtouch->input);
- usb_free_urb(mtouch->irq);
- mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
- kfree(mtouch);
- }
+ struct mtouch_usb *mtouch = usb_get_intfdata(intf);
+
+ dbg("%s - called", __FUNCTION__);
+ usb_set_intfdata(intf, NULL);
+ if (mtouch) {
+ dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
+ usb_kill_urb(mtouch->irq);
+ input_unregister_device(&mtouch->input);
+ usb_free_urb(mtouch->irq);
+ mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
+ kfree(mtouch);
+ }
}
-MODULE_DEVICE_TABLE (usb, mtouchusb_devices);
+MODULE_DEVICE_TABLE(usb, mtouchusb_devices);
static struct usb_driver mtouchusb_driver = {
- .owner = THIS_MODULE,
- .name = "mtouchusb",
- .probe = mtouchusb_probe,
- .disconnect = mtouchusb_disconnect,
- .id_table = mtouchusb_devices,
+ .owner = THIS_MODULE,
+ .name = "mtouchusb",
+ .probe = mtouchusb_probe,
+ .disconnect = mtouchusb_disconnect,
+ .id_table = mtouchusb_devices,
};
-static int __init mtouchusb_init(void) {
- dbg("%s - called", __FUNCTION__);
- return usb_register(&mtouchusb_driver);
+static int __init mtouchusb_init(void)
+{
+ dbg("%s - called", __FUNCTION__);
+ return usb_register(&mtouchusb_driver);
}
-static void __exit mtouchusb_cleanup(void) {
- dbg("%s - called", __FUNCTION__);
- usb_deregister(&mtouchusb_driver);
+static void __exit mtouchusb_cleanup(void)
+{
+ dbg("%s - called", __FUNCTION__);
+ usb_deregister(&mtouchusb_driver);
}
module_init(mtouchusb_init);
module_exit(mtouchusb_cleanup);
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index 7fa2f9b9fb6..3975b309d55 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -10,7 +10,7 @@
* back to the host when polled by the USB controller.
*
* Testing with the knob I have has shown that it measures approximately 94 "clicks"
- * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was
+ * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was
* a variable speed cordless electric drill) has shown that the device can measure
* speeds of up to 7 clicks either clockwise or anticlockwise between pollings from
* the host. If it counts more than 7 clicks before it is polled, it will wrap back
@@ -120,9 +120,9 @@ exit:
/* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
static void powermate_sync_state(struct powermate_device *pm)
{
- if (pm->requires_update == 0)
+ if (pm->requires_update == 0)
return; /* no updates are required */
- if (pm->config->status == -EINPROGRESS)
+ if (pm->config->status == -EINPROGRESS)
return; /* an update is already in progress; it'll issue this update when it completes */
if (pm->requires_update & UPDATE_PULSE_ASLEEP){
@@ -142,7 +142,7 @@ static void powermate_sync_state(struct powermate_device *pm)
2: multiply the speed
the argument only has an effect for operations 0 and 2, and ranges between
1 (least effect) to 255 (maximum effect).
-
+
thus, several states are equivalent and are coalesced into one state.
we map this onto a range from 0 to 510, with:
@@ -151,7 +151,7 @@ static void powermate_sync_state(struct powermate_device *pm)
256 -- 510 -- use multiple (510 = fastest).
Only values of 'arg' quite close to 255 are particularly useful/spectacular.
- */
+ */
if (pm->pulse_speed < 255){
op = 0; // divide
arg = 255 - pm->pulse_speed;
@@ -199,14 +199,14 @@ static void powermate_config_complete(struct urb *urb, struct pt_regs *regs)
if (urb->status)
printk(KERN_ERR "powermate: config urb returned %d\n", urb->status);
-
+
spin_lock_irqsave(&pm->lock, flags);
powermate_sync_state(pm);
spin_unlock_irqrestore(&pm->lock, flags);
}
/* Set the LED up as described and begin the sync with the hardware if required */
-static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed,
+static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed,
int pulse_table, int pulse_asleep, int pulse_awake)
{
unsigned long flags;
@@ -229,7 +229,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
/* mark state updates which are required */
if (static_brightness != pm->static_brightness){
pm->static_brightness = static_brightness;
- pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
+ pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
}
if (pulse_asleep != pm->pulse_asleep){
pm->pulse_asleep = pulse_asleep;
@@ -246,7 +246,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
}
powermate_sync_state(pm);
-
+
spin_unlock_irqrestore(&pm->lock, flags);
}
@@ -257,19 +257,19 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig
struct powermate_device *pm = dev->private;
if (type == EV_MSC && code == MSC_PULSELED){
- /*
+ /*
bits 0- 7: 8 bits: LED brightness
bits 8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster.
bits 17-18: 2 bits: pulse table (0, 1, 2 valid)
bit 19: 1 bit : pulse whilst asleep?
bit 20: 1 bit : pulse constantly?
- */
+ */
int static_brightness = command & 0xFF; // bits 0-7
int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16
int pulse_table = (command >> 17) & 0x3; // bits 17-18
int pulse_asleep = (command >> 19) & 0x1; // bit 19
int pulse_awake = (command >> 20) & 0x1; // bit 20
-
+
powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake);
}
@@ -378,7 +378,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
switch (le16_to_cpu(udev->descriptor.idProduct)) {
case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
- default:
+ default:
pm->input.name = pm_name_soundknob;
printk(KERN_WARNING "powermate: unknown product id %04x\n",
le16_to_cpu(udev->descriptor.idProduct));
@@ -402,11 +402,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
usb_make_path(udev, path, 64);
snprintf(pm->phys, 64, "%s/input0", path);
printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys);
-
+
/* force an update of everything */
pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters
-
+
usb_set_intfdata(intf, pm);
return 0;
}
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index a71f1bbd0a1..386595ee21c 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -69,7 +69,6 @@ struct touchkit_usb {
struct urb *irq;
struct usb_device *udev;
struct input_dev input;
- int open;
char name[128];
char phys[64];
};
@@ -134,15 +133,10 @@ static int touchkit_open(struct input_dev *input)
{
struct touchkit_usb *touchkit = input->private;
- if (touchkit->open++)
- return 0;
-
touchkit->irq->dev = touchkit->udev;
- if (usb_submit_urb(touchkit->irq, GFP_ATOMIC)) {
- touchkit->open--;
+ if (usb_submit_urb(touchkit->irq, GFP_ATOMIC))
return -EIO;
- }
return 0;
}
@@ -151,8 +145,7 @@ static void touchkit_close(struct input_dev *input)
{
struct touchkit_usb *touchkit = input->private;
- if (!--touchkit->open)
- usb_kill_urb(touchkit->irq);
+ usb_kill_urb(touchkit->irq);
}
static int touchkit_alloc_buffers(struct usb_device *udev,
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 7038fb9d1ce..f35db1974c4 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -9,18 +9,18 @@
/*
* 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -72,7 +72,6 @@ struct usb_kbd {
unsigned char newleds;
char name[128];
char phys[64];
- int open;
unsigned char *new;
struct usb_ctrlrequest *cr;
@@ -166,7 +165,7 @@ static void usb_kbd_led(struct urb *urb, struct pt_regs *regs)
if (urb->status)
warn("led urb status %d received", urb->status);
-
+
if (*(kbd->leds) == kbd->newleds)
return;
@@ -180,14 +179,9 @@ static int usb_kbd_open(struct input_dev *dev)
{
struct usb_kbd *kbd = dev->private;
- if (kbd->open++)
- return 0;
-
kbd->irq->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->irq, GFP_KERNEL)) {
- kbd->open--;
+ if (usb_submit_urb(kbd->irq, GFP_KERNEL))
return -EIO;
- }
return 0;
}
@@ -196,8 +190,7 @@ static void usb_kbd_close(struct input_dev *dev)
{
struct usb_kbd *kbd = dev->private;
- if (!--kbd->open)
- usb_kill_urb(kbd->irq);
+ usb_kill_urb(kbd->irq);
}
static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
@@ -230,7 +223,7 @@ static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
}
-static int usb_kbd_probe(struct usb_interface *iface,
+static int usb_kbd_probe(struct usb_interface *iface,
const struct usb_device_id *id)
{
struct usb_device * dev = interface_to_usbdev(iface);
@@ -272,7 +265,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
for (i = 0; i < 255; i++)
set_bit(usb_kbd_keycode[i], kbd->dev.keybit);
clear_bit(0, kbd->dev.keybit);
-
+
kbd->dev.private = kbd;
kbd->dev.event = usb_kbd_event;
kbd->dev.open = usb_kbd_open;
@@ -294,7 +287,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
sprintf(kbd->phys, "%s/input0", path);
kbd->dev.name = kbd->name;
- kbd->dev.phys = kbd->phys;
+ kbd->dev.phys = kbd->phys;
kbd->dev.id.bustype = BUS_USB;
kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
@@ -329,7 +322,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
static void usb_kbd_disconnect(struct usb_interface *intf)
{
struct usb_kbd *kbd = usb_get_intfdata (intf);
-
+
usb_set_intfdata(intf, NULL);
if (kbd) {
usb_kill_urb(kbd->irq);
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 01155bbddd4..1ec41b5effe 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -9,18 +9,18 @@
/*
* 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
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -51,7 +51,6 @@ struct usb_mouse {
struct usb_device *usbdev;
struct input_dev dev;
struct urb *irq;
- int open;
signed char *data;
dma_addr_t data_dma;
@@ -101,14 +100,9 @@ static int usb_mouse_open(struct input_dev *dev)
{
struct usb_mouse *mouse = dev->private;
- if (mouse->open++)
- return 0;
-
mouse->irq->dev = mouse->usbdev;
- if (usb_submit_urb(mouse->irq, GFP_KERNEL)) {
- mouse->open--;
+ if (usb_submit_urb(mouse->irq, GFP_KERNEL))
return -EIO;
- }
return 0;
}
@@ -117,8 +111,7 @@ static void usb_mouse_close(struct input_dev *dev)
{
struct usb_mouse *mouse = dev->private;
- if (!--mouse->open)
- usb_kill_urb(mouse->irq);
+ usb_kill_urb(mouse->irq);
}
static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
@@ -132,19 +125,19 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
interface = intf->cur_altsetting;
- if (interface->desc.bNumEndpoints != 1)
+ if (interface->desc.bNumEndpoints != 1)
return -ENODEV;
endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & 0x80))
+ if (!(endpoint->bEndpointAddress & 0x80))
return -ENODEV;
- if ((endpoint->bmAttributes & 3) != 3)
+ if ((endpoint->bmAttributes & 3) != 3)
return -ENODEV;
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
- if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
+ if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
return -ENOMEM;
memset(mouse, 0, sizeof(struct usb_mouse));
@@ -209,7 +202,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
static void usb_mouse_disconnect(struct usb_interface *intf)
{
struct usb_mouse *mouse = usb_get_intfdata (intf);
-
+
usb_set_intfdata(intf, NULL);
if (mouse) {
usb_kill_urb(mouse->irq);
@@ -238,7 +231,7 @@ static struct usb_driver usb_mouse_driver = {
static int __init usb_mouse_init(void)
{
int retval = usb_register(&usb_mouse_driver);
- if (retval == 0)
+ if (retval == 0)
info(DRIVER_VERSION ":" DRIVER_DESC);
return retval;
}
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index fec04dda088..f6b34af66b3 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -9,7 +9,7 @@
* Copyright (c) 2000 Daniel Egger <egger@suse.de>
* Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
* Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
- * Copyright (c) 2002-2004 Ping Cheng <pingc@wacom.com>
+ * Copyright (c) 2002-2005 Ping Cheng <pingc@wacom.com>
*
* ChangeLog:
* v0.1 (vp) - Initial release
@@ -18,7 +18,7 @@
* v0.4 (sm) - Support for more Intuos models, menustrip
* relative mode, proximity.
* v0.5 (vp) - Big cleanup, nifty features removed,
- * they belong in userspace
+ * they belong in userspace
* v1.8 (vp) - Submit URB only when operating, moved to CVS,
* use input_report_key instead of report_btn and
* other cleanups
@@ -51,6 +51,9 @@
* - Cleanups here and there
* v1.30.1 (pi) - Added Graphire3 support
* v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
+ * v1.43 (pc) - Added support for Cintiq 21UX
+ - Fixed a Graphire bug
+ - Merged wacom_intuos3_irq into wacom_intuos_irq
*/
/*
@@ -72,7 +75,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.40"
+#define DRIVER_VERSION "v1.43"
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
#define DRIVER_LICENSE "GPL"
@@ -83,6 +86,16 @@ MODULE_LICENSE(DRIVER_LICENSE);
#define USB_VENDOR_ID_WACOM 0x056a
+enum {
+ PENPARTNER = 0,
+ GRAPHIRE,
+ PL,
+ INTUOS,
+ INTUOS3,
+ CINTIQ,
+ MAX_TYPE
+};
+
struct wacom_features {
char *name;
int pktlen;
@@ -102,7 +115,6 @@ struct wacom {
struct urb *irq;
struct wacom_features *features;
int tool[2];
- int open;
__u32 serial[2];
char phys[32];
};
@@ -149,7 +161,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
prox = data[1] & 0x40;
input_regs(dev, regs);
-
+
if (prox) {
pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -166,8 +178,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
if (!wacom->tool[0]) {
/* Going into proximity select tool */
wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
- }
- else {
+ } else {
/* was entered with stylus2 pressed */
if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
/* report out proximity for previous tool */
@@ -182,16 +193,15 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
wacom->tool[1] = BTN_TOOL_PEN;
}
input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
- input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14));
- input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14));
+ input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
+ input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
input_report_abs(dev, ABS_PRESSURE, pressure);
input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
/* Only allow the stylus2 button to be reported for the pen tool. */
input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
- }
- else {
+ } else {
/* report proximity-out of a (valid) tool */
if (wacom->tool[1] != BTN_TOOL_RUBBER) {
/* Unknown tool selected default to pen tool */
@@ -203,7 +213,7 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
wacom->tool[0] = prox; /* Save proximity state */
input_sync(dev);
-exit:
+ exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
err ("%s - usb_submit_urb failed with result %d",
@@ -232,20 +242,16 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
goto exit;
}
- if (data[0] != 2)
- {
+ if (data[0] != 2) {
printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
goto exit;
}
input_regs(dev, regs);
- if (data[1] & 0x04)
- {
+ if (data[1] & 0x04) {
input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
- }
- else
- {
+ } else {
input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
}
@@ -257,7 +263,7 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
input_sync(dev);
-exit:
+ exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
err ("%s - usb_submit_urb failed with result %d",
@@ -300,7 +306,7 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
input_sync(dev);
-exit:
+ exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
err ("%s - usb_submit_urb failed with result %d",
@@ -340,47 +346,47 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
input_regs(dev, regs);
- switch ((data[1] >> 5) & 3) {
+ if (data[1] & 0x10) { /* in prox */
- case 0: /* Pen */
- input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80);
- break;
+ switch ((data[1] >> 5) & 3) {
- case 1: /* Rubber */
- input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
- break;
-
- case 2: /* Mouse with wheel */
- input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
- input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
- /* fall through */
+ case 0: /* Pen */
+ wacom->tool[0] = BTN_TOOL_PEN;
+ break;
- case 3: /* Mouse without wheel */
- input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24);
- input_report_key(dev, BTN_LEFT, data[1] & 0x01);
- input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
- input_report_abs(dev, ABS_DISTANCE, data[7]);
+ case 1: /* Rubber */
+ wacom->tool[0] = BTN_TOOL_RUBBER;
+ break;
- input_report_abs(dev, ABS_X, x);
- input_report_abs(dev, ABS_Y, y);
+ case 2: /* Mouse with wheel */
+ input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
+ input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
+ /* fall through */
- input_sync(dev);
- goto exit;
+ case 3: /* Mouse without wheel */
+ wacom->tool[0] = BTN_TOOL_MOUSE;
+ input_report_key(dev, BTN_LEFT, data[1] & 0x01);
+ input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
+ input_report_abs(dev, ABS_DISTANCE, data[7]);
+ break;
+ }
}
if (data[1] & 0x80) {
input_report_abs(dev, ABS_X, x);
input_report_abs(dev, ABS_Y, y);
}
+ if (wacom->tool[0] != BTN_TOOL_MOUSE) {
+ input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
+ input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
+ input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
+ input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
+ }
- input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
- input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
- input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
- input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
-
+ input_report_key(dev, wacom->tool[0], data[1] & 0x10);
input_sync(dev);
-exit:
+ exit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
err ("%s - usb_submit_urb failed with result %d",
@@ -398,14 +404,13 @@ static int wacom_intuos_inout(struct urb *urb)
idx = data[1] & 0x01;
/* Enter report */
- if ((data[1] & 0xfc) == 0xc0)
- {
+ if ((data[1] & 0xfc) == 0xc0) {
/* serial number of the tool */
- wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) +
- ((__u32)data[4] << 20) + ((__u32)data[5] << 12) +
- ((__u32)data[6] << 4) + (data[7] >> 4);
+ wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
+ (data[4] << 20) + (data[5] << 12) +
+ (data[6] << 4) + (data[7] >> 4);
- switch (((__u32)data[2] << 4) | (data[3] >> 4)) {
+ switch ((data[2] << 4) | (data[3] >> 4)) {
case 0x812: /* Inking pen */
case 0x801: /* Intuos3 Inking pen */
case 0x012:
@@ -449,7 +454,7 @@ static int wacom_intuos_inout(struct urb *urb)
case 0x112:
case 0x913: /* Intuos3 Airbrush */
wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
- break; /* Airbrush */
+ break;
default: /* Unknown tool */
wacom->tool[idx] = BTN_TOOL_PEN;
}
@@ -478,9 +483,8 @@ static void wacom_intuos_general(struct urb *urb)
unsigned int t;
/* general pen packet */
- if ((data[1] & 0xb8) == 0xa0)
- {
- t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
+ if ((data[1] & 0xb8) == 0xa0) {
+ t = (data[6] << 2) | ((data[7] >> 6) & 3);
input_report_abs(dev, ABS_PRESSURE, t);
input_report_abs(dev, ABS_TILT_X,
((data[7] << 1) & 0x7e) | (data[8] >> 7));
@@ -491,10 +495,9 @@ static void wacom_intuos_general(struct urb *urb)
}
/* airbrush second packet */
- if ((data[1] & 0xbc) == 0xb4)
- {
+ if ((data[1] & 0xbc) == 0xb4) {
input_report_abs(dev, ABS_WHEEL,
- ((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
+ (data[6] << 2) | ((data[7] >> 6) & 3));
input_report_abs(dev, ABS_TILT_X,
((data[7] << 1) & 0x7e) | (data[8] >> 7));
input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
@@ -526,7 +529,7 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
goto exit;
}
- if (data[0] != 2 && data[0] != 5 && data[0] != 6) {
+ if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
goto exit;
}
@@ -536,107 +539,10 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
/* tool number */
idx = data[1] & 0x01;
- /* process in/out prox events */
- if (wacom_intuos_inout(urb)) goto exit;
-
- input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
- input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
- input_report_abs(dev, ABS_DISTANCE, data[9]);
-
- /* process general packets */
- wacom_intuos_general(urb);
-
- if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { /* 4D mouse or Lens cursor packets */
-
- if (data[1] & 0x02) { /* Rotation packet */
-
- t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
- input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2);
-
- } else {
-
- if ((data[1] & 0x10) == 0) { /* 4D mouse packets */
-
- input_report_key(dev, BTN_LEFT, data[8] & 0x01);
- input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
- input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
-
- input_report_key(dev, BTN_SIDE, data[8] & 0x20);
- input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
- t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
- input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
-
- } else {
- if (wacom->tool[idx] == BTN_TOOL_MOUSE) { /* 2D mouse packets */
- input_report_key(dev, BTN_LEFT, data[8] & 0x04);
- input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
- input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
- input_report_rel(dev, REL_WHEEL,
- (-(__u32)(data[8] & 0x01) + (__u32)((data[8] & 0x02) >> 1)));
- }
- else { /* Lens cursor packets */
- input_report_key(dev, BTN_LEFT, data[8] & 0x01);
- input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
- input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
- input_report_key(dev, BTN_SIDE, data[8] & 0x10);
- input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
- }
- }
- }
- }
-
- input_report_key(dev, wacom->tool[idx], 1);
- input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- input_sync(dev);
-
-exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = &wacom->dev;
- unsigned int t;
- int idx, retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- 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;
- }
-
- /* check for valid report */
- if (data[0] != 2 && data[0] != 5 && data[0] != 12)
- {
- printk(KERN_INFO "wacom_intuos3_irq: received unknown report #%d\n", data[0]);
- goto exit;
- }
-
- input_regs(dev, regs);
-
- /* tool index is always 0 here since there is no dual input tool */
- idx = data[1] & 0x01;
-
/* pad packets. Works as a second tool and is always in prox */
- if (data[0] == 12)
- {
+ if (data[0] == 12) {
/* initiate the pad as a device */
- if (wacom->tool[1] != BTN_TOOL_FINGER)
- {
+ if (wacom->tool[1] != BTN_TOOL_FINGER) {
wacom->tool[1] = BTN_TOOL_FINGER;
input_report_key(dev, wacom->tool[1], 1);
}
@@ -656,37 +562,78 @@ static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs)
}
/* process in/out prox events */
- if (wacom_intuos_inout(urb)) goto exit;
+ if (wacom_intuos_inout(urb))
+ goto exit;
- input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1));
- input_report_abs(dev, ABS_Y, ((__u32)data[4] << 9) | ((__u32)data[5] << 1) | (data[9] & 1));
- input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
+ /* Cintiq doesn't send data when RDY bit isn't set */
+ if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
+ return;
+
+ if (wacom->features->type >= INTUOS3) {
+ input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
+ input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
+ input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
+ } else {
+ input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
+ input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
+ input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
+ }
/* process general packets */
wacom_intuos_general(urb);
- if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0)
- {
- /* Marker pen rotation packet. Reported as wheel due to valuator limitation */
- if (data[1] & 0x02)
- {
- t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
- t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
- ((t-1) / 2 + 450)) : (450 - t / 2) ;
- input_report_abs(dev, ABS_WHEEL, t);
- }
+ /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
+ if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
+
+ if (data[1] & 0x02) {
+ /* Rotation packet */
+ if (wacom->features->type >= INTUOS3) {
+ /* I3 marker pen rotation reported as wheel
+ * due to valuator limitation
+ */
+ t = (data[6] << 3) | ((data[7] >> 5) & 7);
+ t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
+ ((t-1) / 2 + 450)) : (450 - t / 2) ;
+ input_report_abs(dev, ABS_WHEEL, t);
+ } else {
+ /* 4D mouse rotation packet */
+ t = (data[6] << 3) | ((data[7] >> 5) & 7);
+ input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
+ ((t - 1) / 2) : -t / 2);
+ }
- /* 2D mouse packets */
- if (wacom->tool[idx] == BTN_TOOL_MOUSE)
- {
+ } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
+ /* 4D mouse packet */
+ input_report_key(dev, BTN_LEFT, data[8] & 0x01);
+ input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
+ input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
+
+ input_report_key(dev, BTN_SIDE, data[8] & 0x20);
+ input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
+ t = (data[6] << 2) | ((data[7] >> 6) & 3);
+ input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
+
+ } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
+ /* 2D mouse packet */
input_report_key(dev, BTN_LEFT, data[8] & 0x04);
input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
- input_report_key(dev, BTN_SIDE, data[8] & 0x40);
- input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
- /* mouse wheel is positive when rolled backwards */
- input_report_rel(dev, REL_WHEEL, ((__u32)((data[8] & 0x02) >> 1)
- - (__u32)(data[8] & 0x01)));
+ input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1)
+ - (data[8] & 0x01));
+
+ /* I3 2D mouse side buttons */
+ if (wacom->features->type == INTUOS3) {
+ input_report_key(dev, BTN_SIDE, data[8] & 0x40);
+ input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
+ }
+
+ } else if (wacom->features->type < INTUOS3) {
+ /* Lens cursor packets */
+ input_report_key(dev, BTN_LEFT, data[8] & 0x01);
+ input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
+ input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
+ input_report_key(dev, BTN_SIDE, data[8] & 0x10);
+ input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
}
}
@@ -702,35 +649,36 @@ exit:
}
static struct wacom_features wacom_features[] = {
- { "Wacom Penpartner", 7, 5040, 3780, 255, 32, 0, wacom_penpartner_irq },
- { "Wacom Graphire", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq },
- { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq },
- { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, 1, wacom_graphire_irq },
- { "Wacom Graphire3", 8, 10208, 7424, 511, 32, 1, wacom_graphire_irq },
- { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, 1, wacom_graphire_irq },
- { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom PL400", 8, 5408, 4056, 255, 32, 3, wacom_pl_irq },
- { "Wacom PL500", 8, 6144, 4608, 255, 32, 3, wacom_pl_irq },
- { "Wacom PL600", 8, 6126, 4604, 255, 32, 3, wacom_pl_irq },
- { "Wacom PL600SX", 8, 6260, 5016, 255, 32, 3, wacom_pl_irq },
- { "Wacom PL550", 8, 6144, 4608, 511, 32, 3, wacom_pl_irq },
- { "Wacom PL800", 8, 7220, 5780, 511, 32, 3, wacom_pl_irq },
- { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq },
- { "Wacom Volito", 8, 5104, 3712, 511, 32, 1, wacom_graphire_irq },
- { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, 3, wacom_ptu_irq },
- { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, 4, wacom_intuos3_irq },
- { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, 4, wacom_intuos3_irq },
- { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, 4, wacom_intuos3_irq },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
- { }
+ { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_penpartner_irq },
+ { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_pl_irq },
+ { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_pl_irq },
+ { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_pl_irq },
+ { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq },
+ { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq },
+ { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq },
+ { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
+ { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
+ { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq },
+ { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq },
+ { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq },
+ { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq },
+ { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq },
+ { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
+ { }
};
static struct usb_device_id wacom_ids[] = {
@@ -761,6 +709,7 @@ static struct usb_device_id wacom_ids[] = {
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
+ { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
{ }
};
@@ -771,14 +720,9 @@ static int wacom_open(struct input_dev *dev)
{
struct wacom *wacom = dev->private;
- if (wacom->open++)
- return 0;
-
wacom->irq->dev = wacom->usbdev;
- if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
- wacom->open--;
+ if (usb_submit_urb(wacom->irq, GFP_KERNEL))
return -EIO;
- }
return 0;
}
@@ -787,8 +731,7 @@ static void wacom_close(struct input_dev *dev)
{
struct wacom *wacom = dev->private;
- if (!--wacom->open)
- usb_kill_urb(wacom->irq);
+ usb_kill_urb(wacom->irq);
}
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -823,32 +766,33 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
switch (wacom->features->type) {
- case 1:
+ case GRAPHIRE:
wacom->dev.evbit[0] |= BIT(EV_REL);
wacom->dev.relbit[0] |= BIT(REL_WHEEL);
wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+ wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
break;
- case 4: /* new functions for Intuos3 */
+ case INTUOS3:
+ case CINTIQ:
wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
/* fall through */
- case 2:
+ case INTUOS:
wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
wacom->dev.relbit[0] |= BIT(REL_WHEEL);
wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
+ wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
| BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE);
break;
- case 3:
- wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+ case PL:
+ wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
break;
}
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index d65edb22e54..a7fa1b17dcf 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -104,13 +104,12 @@ MODULE_DEVICE_TABLE (usb, xpad_table);
struct usb_xpad {
struct input_dev dev; /* input device interface */
struct usb_device *udev; /* usb device */
-
+
struct urb *irq_in; /* urb for interrupt in report */
unsigned char *idata; /* input data */
dma_addr_t idata_dma;
-
+
char phys[65]; /* physical device path */
- int open_count; /* reference count */
};
/*
@@ -128,35 +127,35 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
struct input_dev *dev = &xpad->dev;
input_regs(dev, regs);
-
+
/* left stick */
input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14]));
-
+
/* right stick */
input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16]));
input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18]));
-
+
/* triggers left/right */
input_report_abs(dev, ABS_Z, data[10]);
input_report_abs(dev, ABS_RZ, data[11]);
-
+
/* digital pad */
input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
-
+
/* start/back buttons and stick press left/right */
input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
input_report_key(dev, BTN_THUMBR, data[2] >> 7);
-
+
/* "analog" buttons A, B, X, Y */
input_report_key(dev, BTN_A, data[4]);
input_report_key(dev, BTN_B, data[5]);
input_report_key(dev, BTN_X, data[6]);
input_report_key(dev, BTN_Y, data[7]);
-
+
/* "analog" buttons black, white */
input_report_key(dev, BTN_C, data[8]);
input_report_key(dev, BTN_Z, data[9]);
@@ -168,7 +167,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
{
struct usb_xpad *xpad = urb->context;
int retval;
-
+
switch (urb->status) {
case 0:
/* success */
@@ -183,7 +182,7 @@ static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
goto exit;
}
-
+
xpad_process_packet(xpad, 0, xpad->idata, regs);
exit:
@@ -196,25 +195,19 @@ exit:
static int xpad_open (struct input_dev *dev)
{
struct usb_xpad *xpad = dev->private;
-
- if (xpad->open_count++)
- return 0;
-
+
xpad->irq_in->dev = xpad->udev;
- if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) {
- xpad->open_count--;
+ if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
return -EIO;
- }
-
+
return 0;
}
static void xpad_close (struct input_dev *dev)
{
struct usb_xpad *xpad = dev->private;
-
- if (!--xpad->open_count)
- usb_kill_urb(xpad->irq_in);
+
+ usb_kill_urb(xpad->irq_in);
}
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -224,19 +217,19 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_endpoint_descriptor *ep_irq_in;
char path[64];
int i;
-
+
for (i = 0; xpad_device[i].idVendor; i++) {
if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
(le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
break;
}
-
+
if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
err("cannot allocate memory for new pad");
return -ENOMEM;
}
memset(xpad, 0, sizeof(struct usb_xpad));
-
+
xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
SLAB_ATOMIC, &xpad->idata_dma);
if (!xpad->idata) {
@@ -251,18 +244,18 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
kfree(xpad);
return -ENOMEM;
}
-
+
ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
-
+
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
xpad, ep_irq_in->bInterval);
xpad->irq_in->transfer_dma = xpad->idata_dma;
xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
+
xpad->udev = udev;
-
+
xpad->dev.id.bustype = BUS_USB;
xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct);
@@ -273,21 +266,21 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
xpad->dev.phys = xpad->phys;
xpad->dev.open = xpad_open;
xpad->dev.close = xpad_close;
-
+
usb_make_path(udev, path, 64);
snprintf(xpad->phys, 64, "%s/input0", path);
-
+
xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
+
for (i = 0; xpad_btn[i] >= 0; i++)
set_bit(xpad_btn[i], xpad->dev.keybit);
-
+
for (i = 0; xpad_abs[i] >= 0; i++) {
-
+
signed short t = xpad_abs[i];
-
+
set_bit(t, xpad->dev.absbit);
-
+
switch (t) {
case ABS_X:
case ABS_Y:
@@ -310,11 +303,11 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
break;
}
}
-
+
input_register_device(&xpad->dev);
-
+
printk(KERN_INFO "input: %s on %s", xpad->dev.name, path);
-
+
usb_set_intfdata(intf, xpad);
return 0;
}
@@ -322,7 +315,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
static void xpad_disconnect(struct usb_interface *intf)
{
struct usb_xpad *xpad = usb_get_intfdata (intf);
-
+
usb_set_intfdata(intf, NULL);
if (xpad) {
usb_kill_urb(xpad->irq_in);