aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/input')
-rw-r--r--drivers/usb/input/Kconfig30
-rw-r--r--drivers/usb/input/Makefile2
-rw-r--r--drivers/usb/input/acecad.c5
-rw-r--r--drivers/usb/input/appletouch.c5
-rw-r--r--drivers/usb/input/ati_remote.c8
-rw-r--r--drivers/usb/input/hid-core.c24
-rw-r--r--drivers/usb/input/hiddev.c2
-rw-r--r--drivers/usb/input/itmtouch.c2
-rw-r--r--drivers/usb/input/keyspan_remote.c3
-rw-r--r--drivers/usb/input/mtouchusb.c2
-rw-r--r--drivers/usb/input/powermate.c4
-rw-r--r--drivers/usb/input/touchkitusb.c2
-rw-r--r--drivers/usb/input/trancevibrator.c159
-rw-r--r--drivers/usb/input/usbmouse.c2
-rw-r--r--drivers/usb/input/usbtouchscreen.c285
-rw-r--r--drivers/usb/input/wacom.c1003
-rw-r--r--drivers/usb/input/wacom.h132
-rw-r--r--drivers/usb/input/wacom_sys.c315
-rw-r--r--drivers/usb/input/wacom_wac.c646
-rw-r--r--drivers/usb/input/wacom_wac.h48
-rw-r--r--drivers/usb/input/yealink.c2
21 files changed, 1565 insertions, 1116 deletions
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 650103bc9618..a102a58fe361 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -205,10 +205,12 @@ config USB_TOUCHSCREEN
205 depends on USB && INPUT 205 depends on USB && INPUT
206 ---help--- 206 ---help---
207 USB Touchscreen driver for: 207 USB Touchscreen driver for:
208 - eGalax Touchkit USB 208 - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
209 - PanJit TouchSet USB 209 - PanJit TouchSet USB
210 - 3M MicroTouch USB 210 - 3M MicroTouch USB (EX II series)
211 - ITM 211 - ITM
212 - some other eTurboTouch
213 - Gunze AHL61
212 214
213 Have a look at <http://linux.chapter7.ch/touchkit/> for 215 Have a look at <http://linux.chapter7.ch/touchkit/> for
214 a usage description and the required user-space stuff. 216 a usage description and the required user-space stuff.
@@ -218,7 +220,7 @@ config USB_TOUCHSCREEN
218 220
219config USB_TOUCHSCREEN_EGALAX 221config USB_TOUCHSCREEN_EGALAX
220 default y 222 default y
221 bool "eGalax device support" if EMBEDDED 223 bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
222 depends on USB_TOUCHSCREEN 224 depends on USB_TOUCHSCREEN
223 225
224config USB_TOUCHSCREEN_PANJIT 226config USB_TOUCHSCREEN_PANJIT
@@ -228,7 +230,7 @@ config USB_TOUCHSCREEN_PANJIT
228 230
229config USB_TOUCHSCREEN_3M 231config USB_TOUCHSCREEN_3M
230 default y 232 default y
231 bool "3M/Microtouch device support" if EMBEDDED 233 bool "3M/Microtouch EX II series device support" if EMBEDDED
232 depends on USB_TOUCHSCREEN 234 depends on USB_TOUCHSCREEN
233 235
234config USB_TOUCHSCREEN_ITM 236config USB_TOUCHSCREEN_ITM
@@ -236,6 +238,16 @@ config USB_TOUCHSCREEN_ITM
236 bool "ITM device support" if EMBEDDED 238 bool "ITM device support" if EMBEDDED
237 depends on USB_TOUCHSCREEN 239 depends on USB_TOUCHSCREEN
238 240
241config USB_TOUCHSCREEN_ETURBO
242 default y
243 bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
244 depends on USB_TOUCHSCREEN
245
246config USB_TOUCHSCREEN_GUNZE
247 default y
248 bool "Gunze AHL61 device support" if EMBEDDED
249 depends on USB_TOUCHSCREEN
250
239config USB_YEALINK 251config USB_YEALINK
240 tristate "Yealink usb-p1k voip phone" 252 tristate "Yealink usb-p1k voip phone"
241 depends on USB && INPUT && EXPERIMENTAL 253 depends on USB && INPUT && EXPERIMENTAL
@@ -326,3 +338,13 @@ config USB_APPLETOUCH
326 338
327 To compile this driver as a module, choose M here: the 339 To compile this driver as a module, choose M here: the
328 module will be called appletouch. 340 module will be called appletouch.
341
342config USB_TRANCEVIBRATOR
343 tristate "PlayStation 2 Trance Vibrator driver support"
344 depends on USB
345 help
346 Say Y here if you want to connect a PlayStation 2 Trance Vibrator
347 device to your computer's USB port.
348
349 To compile this driver as a module, choose M here: the
350 module will be called trancevibrator.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 764114529c56..48551be324ac 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -3,6 +3,7 @@
3# 3#
4 4
5# Multipart objects. 5# Multipart objects.
6wacom-objs := wacom_sys.o wacom_wac.o
6usbhid-objs := hid-core.o 7usbhid-objs := hid-core.o
7 8
8# Optional parts of multipart objects. 9# Optional parts of multipart objects.
@@ -44,6 +45,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o
44obj-$(CONFIG_USB_YEALINK) += yealink.o 45obj-$(CONFIG_USB_YEALINK) += yealink.o
45obj-$(CONFIG_USB_XPAD) += xpad.o 46obj-$(CONFIG_USB_XPAD) += xpad.o
46obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o 47obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
48obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
47 49
48ifeq ($(CONFIG_USB_DEBUG),y) 50ifeq ($(CONFIG_USB_DEBUG),y)
49EXTRA_CFLAGS += -DDEBUG 51EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index 18c10e150ef3..d83603ba40ae 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -141,10 +141,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
141 141
142 endpoint = &interface->endpoint[0].desc; 142 endpoint = &interface->endpoint[0].desc;
143 143
144 if (!(endpoint->bEndpointAddress & 0x80)) 144 if (!usb_endpoint_is_int_in(endpoint))
145 return -ENODEV;
146
147 if ((endpoint->bmAttributes & 3) != 3)
148 return -ENODEV; 145 return -ENODEV;
149 146
150 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); 147 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index 044faa07e297..0aa9cc2bfd69 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -436,10 +436,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
436 iface_desc = iface->cur_altsetting; 436 iface_desc = iface->cur_altsetting;
437 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { 437 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
438 endpoint = &iface_desc->endpoint[i].desc; 438 endpoint = &iface_desc->endpoint[i].desc;
439 if (!int_in_endpointAddr && 439 if (!int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) {
440 (endpoint->bEndpointAddress & USB_DIR_IN) &&
441 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
442 == USB_ENDPOINT_XFER_INT)) {
443 /* we found an interrupt in endpoint */ 440 /* we found an interrupt in endpoint */
444 int_in_endpointAddr = endpoint->bEndpointAddress; 441 int_in_endpointAddr = endpoint->bEndpointAddress;
445 break; 442 break;
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 3719fcb04b8f..3558d7ed99b9 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -732,12 +732,8 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
732 endpoint_in = &iface_host->endpoint[0].desc; 732 endpoint_in = &iface_host->endpoint[0].desc;
733 endpoint_out = &iface_host->endpoint[1].desc; 733 endpoint_out = &iface_host->endpoint[1].desc;
734 734
735 if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) { 735 if (!usb_endpoint_is_int_in(endpoint_in)) {
736 err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__); 736 err("%s: Unexpected endpoint_in\n", __FUNCTION__);
737 return -ENODEV;
738 }
739 if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
740 err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__);
741 return -ENODEV; 737 return -ENODEV;
742 } 738 }
743 if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { 739 if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 3305fb6079eb..2a3e9e9b4b3d 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1023,7 +1023,8 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
1023 return; 1023 return;
1024 case -EILSEQ: /* protocol error or unplug */ 1024 case -EILSEQ: /* protocol error or unplug */
1025 case -EPROTO: /* protocol error or unplug */ 1025 case -EPROTO: /* protocol error or unplug */
1026 case -ETIMEDOUT: /* NAK */ 1026 case -ETIME: /* protocol error or unplug */
1027 case -ETIMEDOUT: /* Should never happen, but... */
1027 clear_bit(HID_IN_RUNNING, &hid->iofl); 1028 clear_bit(HID_IN_RUNNING, &hid->iofl);
1028 hid_io_error(hid); 1029 hid_io_error(hid);
1029 return; 1030 return;
@@ -1535,13 +1536,17 @@ void hid_init_reports(struct hid_device *hid)
1535#define USB_VENDOR_ID_GLAB 0x06c2 1536#define USB_VENDOR_ID_GLAB 0x06c2
1536#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 1537#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
1537#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 1538#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
1538#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045
1539#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 1539#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040
1540#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044
1541#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045
1542#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051
1540#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 1543#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053
1544#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058
1541 1545
1542#define USB_VENDOR_ID_WISEGROUP 0x0925 1546#define USB_VENDOR_ID_WISEGROUP 0x0925
1543#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 1547#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
1544#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 1548#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
1549#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201
1545#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 1550#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
1546 1551
1547#define USB_VENDOR_ID_WISEGROUP_LTD 0x6677 1552#define USB_VENDOR_ID_WISEGROUP_LTD 0x6677
@@ -1591,6 +1596,10 @@ void hid_init_reports(struct hid_device *hid)
1591 1596
1592#define USB_VENDOR_ID_YEALINK 0x6993 1597#define USB_VENDOR_ID_YEALINK 0x6993
1593#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 1598#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
1599
1600#define USB_VENDOR_ID_ALCOR 0x058f
1601#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
1602
1594/* 1603/*
1595 * Alphabetically sorted blacklist by quirk type. 1604 * Alphabetically sorted blacklist by quirk type.
1596 */ 1605 */
@@ -1608,6 +1617,7 @@ static const struct hid_blacklist {
1608 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE }, 1617 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
1609 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE }, 1618 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
1610 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE }, 1619 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
1620 { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE },
1611 { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, 1621 { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
1612 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE }, 1622 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
1613 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE }, 1623 { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
@@ -1620,9 +1630,12 @@ static const struct hid_blacklist {
1620 { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, 1630 { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
1621 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, 1631 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
1622 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, 1632 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
1623 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE },
1624 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE }, 1633 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE },
1634 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT, HID_QUIRK_IGNORE },
1635 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE },
1636 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT, HID_QUIRK_IGNORE },
1625 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE }, 1637 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE },
1638 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL, HID_QUIRK_IGNORE },
1626 { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, 1639 { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
1627 { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, 1640 { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
1628 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, 1641 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE },
@@ -1690,7 +1703,11 @@ static const struct hid_blacklist {
1690 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, 1703 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
1691 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE }, 1704 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE },
1692 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE }, 1705 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
1706 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20, HID_QUIRK_IGNORE },
1707 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30, HID_QUIRK_IGNORE },
1693 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE }, 1708 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
1709 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108, HID_QUIRK_IGNORE },
1710 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118, HID_QUIRK_IGNORE },
1694 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE }, 1711 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
1695 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, 1712 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
1696 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, 1713 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
@@ -1701,6 +1718,7 @@ static const struct hid_blacklist {
1701 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, 1718 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
1702 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, 1719 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
1703 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, 1720 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
1721 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT, HID_QUIRK_IGNORE },
1704 { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE }, 1722 { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE },
1705 1723
1706 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, 1724 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index f6b839c257a7..a2b419d13740 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -722,7 +722,7 @@ inval:
722 return -EINVAL; 722 return -EINVAL;
723} 723}
724 724
725static struct file_operations hiddev_fops = { 725static const struct file_operations hiddev_fops = {
726 .owner = THIS_MODULE, 726 .owner = THIS_MODULE,
727 .read = hiddev_read, 727 .read = hiddev_read,
728 .write = hiddev_write, 728 .write = hiddev_write,
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index 86acb5f1907a..61966d719ca3 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -87,7 +87,7 @@ static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
87 case 0: 87 case 0:
88 /* success */ 88 /* success */
89 break; 89 break;
90 case -ETIMEDOUT: 90 case -ETIME:
91 /* this urb is timing out */ 91 /* this urb is timing out */
92 dbg("%s - urb timed out - was the device unplugged?", 92 dbg("%s - urb timed out - was the device unplugged?",
93 __FUNCTION__); 93 __FUNCTION__);
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 4723b310f277..a90359551575 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -420,8 +420,7 @@ static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_i
420 for (i = 0; i < iface->desc.bNumEndpoints; ++i) { 420 for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
421 endpoint = &iface->endpoint[i].desc; 421 endpoint = &iface->endpoint[i].desc;
422 422
423 if ((endpoint->bEndpointAddress & USB_DIR_IN) && 423 if (usb_endpoint_is_int_in(endpoint)) {
424 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
425 /* we found our interrupt in endpoint */ 424 /* we found our interrupt in endpoint */
426 return endpoint; 425 return endpoint;
427 } 426 }
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index a9ccda8810e0..5dce951f2751 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -107,7 +107,7 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
107 case 0: 107 case 0:
108 /* success */ 108 /* success */
109 break; 109 break;
110 case -ETIMEDOUT: 110 case -ETIME:
111 /* this urb is timing out */ 111 /* this urb is timing out */
112 dbg("%s - urb timed out - was the device unplugged?", 112 dbg("%s - urb timed out - was the device unplugged?",
113 __FUNCTION__); 113 __FUNCTION__);
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index b3c0d0c3eae9..f0f8db6810a2 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -313,9 +313,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
313 313
314 interface = intf->cur_altsetting; 314 interface = intf->cur_altsetting;
315 endpoint = &interface->endpoint[0].desc; 315 endpoint = &interface->endpoint[0].desc;
316 if (!(endpoint->bEndpointAddress & 0x80)) 316 if (!usb_endpoint_is_int_in(endpoint))
317 return -EIO;
318 if ((endpoint->bmAttributes & 3) != 3)
319 return -EIO; 317 return -EIO;
320 318
321 usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 319 usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 0149043ffb97..30b9f820e7a8 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -201,7 +201,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
201 case 0: 201 case 0:
202 /* success */ 202 /* success */
203 break; 203 break;
204 case -ETIMEDOUT: 204 case -ETIME:
205 /* this urb is timing out */ 205 /* this urb is timing out */
206 dbg("%s - urb timed out - was the device unplugged?", 206 dbg("%s - urb timed out - was the device unplugged?",
207 __FUNCTION__); 207 __FUNCTION__);
diff --git a/drivers/usb/input/trancevibrator.c b/drivers/usb/input/trancevibrator.c
new file mode 100644
index 000000000000..33cd91d11eca
--- /dev/null
+++ b/drivers/usb/input/trancevibrator.c
@@ -0,0 +1,159 @@
1/*
2 * PlayStation 2 Trance Vibrator driver
3 *
4 * Copyright (C) 2006 Sam Hocevar <sam@zoy.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21/* Standard include files */
22#include <linux/kernel.h>
23#include <linux/errno.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/usb.h>
27
28/* Version Information */
29#define DRIVER_VERSION "v1.1"
30#define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org"
31#define DRIVER_DESC "PlayStation 2 Trance Vibrator driver"
32
33#define TRANCEVIBRATOR_VENDOR_ID 0x0b49 /* ASCII Corporation */
34#define TRANCEVIBRATOR_PRODUCT_ID 0x064f /* Trance Vibrator */
35
36static struct usb_device_id id_table [] = {
37 { USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
38 { },
39};
40MODULE_DEVICE_TABLE (usb, id_table);
41
42/* Driver-local specific stuff */
43struct trancevibrator {
44 struct usb_device *udev;
45 unsigned int speed;
46};
47
48static ssize_t show_speed(struct device *dev, struct device_attribute *attr,
49 char *buf)
50{
51 struct usb_interface *intf = to_usb_interface(dev);
52 struct trancevibrator *tv = usb_get_intfdata(intf);
53
54 return sprintf(buf, "%d\n", tv->speed);
55}
56
57static ssize_t set_speed(struct device *dev, struct device_attribute *attr,
58 const char *buf, size_t count)
59{
60 struct usb_interface *intf = to_usb_interface(dev);
61 struct trancevibrator *tv = usb_get_intfdata(intf);
62 int temp, retval;
63
64 temp = simple_strtoul(buf, NULL, 10);
65 if (temp > 255)
66 temp = 255;
67 else if (temp < 0)
68 temp = 0;
69 tv->speed = temp;
70
71 dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
72
73 /* Set speed */
74 retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0),
75 0x01, /* vendor request: set speed */
76 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
77 tv->speed, /* speed value */
78 0, NULL, 0, USB_CTRL_GET_TIMEOUT);
79 if (retval) {
80 dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
81 return retval;
82 }
83 return count;
84}
85
86static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed);
87
88static int tv_probe(struct usb_interface *interface,
89 const struct usb_device_id *id)
90{
91 struct usb_device *udev = interface_to_usbdev(interface);
92 struct trancevibrator *dev;
93 int retval;
94
95 dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL);
96 if (dev == NULL) {
97 dev_err(&interface->dev, "Out of memory\n");
98 retval = -ENOMEM;
99 goto error;
100 }
101
102 dev->udev = usb_get_dev(udev);
103 usb_set_intfdata(interface, dev);
104 retval = device_create_file(&interface->dev, &dev_attr_speed);
105 if (retval)
106 goto error_create_file;
107
108 return 0;
109
110error_create_file:
111 usb_put_dev(udev);
112 usb_set_intfdata(interface, NULL);
113error:
114 kfree(dev);
115 return retval;
116}
117
118static void tv_disconnect(struct usb_interface *interface)
119{
120 struct trancevibrator *dev;
121
122 dev = usb_get_intfdata (interface);
123 usb_set_intfdata(interface, NULL);
124 device_remove_file(&interface->dev, &dev_attr_speed);
125 usb_put_dev(dev->udev);
126 kfree(dev);
127}
128
129/* USB subsystem object */
130static struct usb_driver tv_driver = {
131 .name = "trancevibrator",
132 .probe = tv_probe,
133 .disconnect = tv_disconnect,
134 .id_table = id_table,
135};
136
137static int __init tv_init(void)
138{
139 int retval = usb_register(&tv_driver);
140 if (retval) {
141 err("usb_register failed. Error number %d", retval);
142 return retval;
143 }
144
145 info(DRIVER_VERSION ":" DRIVER_DESC);
146 return 0;
147}
148
149static void __exit tv_exit(void)
150{
151 usb_deregister(&tv_driver);
152}
153
154module_init (tv_init);
155module_exit (tv_exit);
156
157MODULE_AUTHOR(DRIVER_AUTHOR);
158MODULE_DESCRIPTION(DRIVER_DESC);
159MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 446935b671d9..0fb792be95ef 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -218,7 +218,7 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
218 218
219static struct usb_device_id usb_mouse_id_table [] = { 219static struct usb_device_id usb_mouse_id_table [] = {
220 { USB_INTERFACE_INFO(3, 1, 2) }, 220 { USB_INTERFACE_INFO(3, 1, 2) },
221 { } /* Terminating entry */ 221 { } /* Terminating entry */
222}; 222};
223 223
224MODULE_DEVICE_TABLE (usb, usb_mouse_id_table); 224MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c
index a338bf4c2d78..4640d1000d83 100644
--- a/drivers/usb/input/usbtouchscreen.c
+++ b/drivers/usb/input/usbtouchscreen.c
@@ -2,9 +2,12 @@
2 * usbtouchscreen.c 2 * usbtouchscreen.c
3 * Driver for USB Touchscreens, supporting those devices: 3 * Driver for USB Touchscreens, supporting those devices:
4 * - eGalax Touchkit 4 * - eGalax Touchkit
5 * - 3M/Microtouch 5 * includes eTurboTouch CT-410/510/700
6 * - 3M/Microtouch EX II series
6 * - ITM 7 * - ITM
7 * - PanJit TouchSet 8 * - PanJit TouchSet
9 * - eTurboTouch
10 * - Gunze AHL61
8 * 11 *
9 * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch> 12 * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
10 * Copyright (C) by Todd E. Johnson (mtouchusb.c) 13 * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -42,7 +45,7 @@
42#include <linux/usb/input.h> 45#include <linux/usb/input.h>
43 46
44 47
45#define DRIVER_VERSION "v0.3" 48#define DRIVER_VERSION "v0.4"
46#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>" 49#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
47#define DRIVER_DESC "USB Touchscreen Driver" 50#define DRIVER_DESC "USB Touchscreen Driver"
48 51
@@ -60,6 +63,7 @@ struct usbtouch_device_info {
60 int flags; 63 int flags;
61 64
62 void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len); 65 void (*process_pkt) (struct usbtouch_usb *usbtouch, struct pt_regs *regs, unsigned char *pkt, int len);
66 int (*get_pkt_len) (unsigned char *pkt, int len);
63 int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); 67 int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press);
64 int (*init) (struct usbtouch_usb *usbtouch); 68 int (*init) (struct usbtouch_usb *usbtouch);
65}; 69};
@@ -81,8 +85,16 @@ struct usbtouch_usb {
81 char phys[64]; 85 char phys[64];
82}; 86};
83 87
84static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, 88
85 struct pt_regs *regs, unsigned char *pkt, int len); 89#if defined(CONFIG_USB_TOUCHSCREEN_EGALAX) || defined(CONFIG_USB_TOUCHSCREEN_ETURBO)
90#define MULTI_PACKET
91#endif
92
93#ifdef MULTI_PACKET
94static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
95 struct pt_regs *regs,
96 unsigned char *pkt, int len);
97#endif
86 98
87/* device types */ 99/* device types */
88enum { 100enum {
@@ -91,14 +103,19 @@ enum {
91 DEVTYPE_PANJIT, 103 DEVTYPE_PANJIT,
92 DEVTYPE_3M, 104 DEVTYPE_3M,
93 DEVTYPE_ITM, 105 DEVTYPE_ITM,
106 DEVTYPE_ETURBO,
107 DEVTYPE_GUNZE,
94}; 108};
95 109
96static struct usb_device_id usbtouch_devices[] = { 110static struct usb_device_id usbtouch_devices[] = {
97#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX 111#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
98 {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX}, 112 {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
113 {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX},
99 {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX}, 114 {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
100 {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX}, 115 {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX},
101 {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX}, 116 {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX},
117 {USB_DEVICE(0x1234, 0x0001), .driver_info = DEVTYPE_EGALAX},
118 {USB_DEVICE(0x1234, 0x0002), .driver_info = DEVTYPE_EGALAX},
102#endif 119#endif
103 120
104#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT 121#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
@@ -116,6 +133,14 @@ static struct usb_device_id usbtouch_devices[] = {
116 {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, 133 {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
117#endif 134#endif
118 135
136#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
137 {USB_DEVICE(0x1234, 0x5678), .driver_info = DEVTYPE_ETURBO},
138#endif
139
140#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
141 {USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE},
142#endif
143
119 {} 144 {}
120}; 145};
121 146
@@ -140,82 +165,23 @@ static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int
140 *touch = pkt[0] & 0x01; 165 *touch = pkt[0] & 0x01;
141 166
142 return 1; 167 return 1;
143
144} 168}
145 169
146static int egalax_get_pkt_len(unsigned char *buf) 170static int egalax_get_pkt_len(unsigned char *buf, int len)
147{ 171{
148 switch (buf[0] & EGALAX_PKT_TYPE_MASK) { 172 switch (buf[0] & EGALAX_PKT_TYPE_MASK) {
149 case EGALAX_PKT_TYPE_REPT: 173 case EGALAX_PKT_TYPE_REPT:
150 return 5; 174 return 5;
151 175
152 case EGALAX_PKT_TYPE_DIAG: 176 case EGALAX_PKT_TYPE_DIAG:
177 if (len < 2)
178 return -1;
179
153 return buf[1] + 2; 180 return buf[1] + 2;
154 } 181 }
155 182
156 return 0; 183 return 0;
157} 184}
158
159static void egalax_process(struct usbtouch_usb *usbtouch, struct pt_regs *regs,
160 unsigned char *pkt, int len)
161{
162 unsigned char *buffer;
163 int pkt_len, buf_len, pos;
164
165 /* if the buffer contains data, append */
166 if (unlikely(usbtouch->buf_len)) {
167 int tmp;
168
169 /* if only 1 byte in buffer, add another one to get length */
170 if (usbtouch->buf_len == 1)
171 usbtouch->buffer[1] = pkt[0];
172
173 pkt_len = egalax_get_pkt_len(usbtouch->buffer);
174
175 /* unknown packet: drop everything */
176 if (!pkt_len)
177 return;
178
179 /* append, process */
180 tmp = pkt_len - usbtouch->buf_len;
181 memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
182 usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len);
183
184 buffer = pkt + tmp;
185 buf_len = len - tmp;
186 } else {
187 buffer = pkt;
188 buf_len = len;
189 }
190
191 /* only one byte left in buffer */
192 if (unlikely(buf_len == 1)) {
193 usbtouch->buffer[0] = buffer[0];
194 usbtouch->buf_len = 1;
195 return;
196 }
197
198 /* loop over the buffer */
199 pos = 0;
200 while (pos < buf_len) {
201 /* get packet len */
202 pkt_len = egalax_get_pkt_len(buffer + pos);
203
204 /* unknown packet: drop everything */
205 if (unlikely(!pkt_len))
206 return;
207
208 /* full packet: process */
209 if (likely(pkt_len <= buf_len)) {
210 usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len);
211 } else {
212 /* incomplete packet: save in buffer */
213 memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
214 usbtouch->buf_len = buf_len - pos;
215 }
216 pos += pkt_len;
217 }
218}
219#endif 185#endif
220 186
221 187
@@ -254,7 +220,7 @@ static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int
254 220
255static int mtouch_init(struct usbtouch_usb *usbtouch) 221static int mtouch_init(struct usbtouch_usb *usbtouch)
256{ 222{
257 int ret; 223 int ret, i;
258 224
259 ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), 225 ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
260 MTOUCHUSB_RESET, 226 MTOUCHUSB_RESET,
@@ -264,15 +230,20 @@ static int mtouch_init(struct usbtouch_usb *usbtouch)
264 __FUNCTION__, ret); 230 __FUNCTION__, ret);
265 if (ret < 0) 231 if (ret < 0)
266 return ret; 232 return ret;
267 233 msleep(150);
268 ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0), 234
269 MTOUCHUSB_ASYNC_REPORT, 235 for (i = 0; i < 3; i++) {
270 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 236 ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
271 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); 237 MTOUCHUSB_ASYNC_REPORT,
272 dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", 238 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
273 __FUNCTION__, ret); 239 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
274 if (ret < 0) 240 dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
275 return ret; 241 __FUNCTION__, ret);
242 if (ret >= 0)
243 break;
244 if (ret != -EPIPE)
245 return ret;
246 }
276 247
277 return 0; 248 return 0;
278} 249}
@@ -296,6 +267,54 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr
296 267
297 268
298/***************************************************************************** 269/*****************************************************************************
270 * eTurboTouch part
271 */
272#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
273static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
274{
275 unsigned int shift;
276
277 /* packets should start with sync */
278 if (!(pkt[0] & 0x80))
279 return 0;
280
281 shift = (6 - (pkt[0] & 0x03));
282 *x = ((pkt[3] << 7) | pkt[4]) >> shift;
283 *y = ((pkt[1] << 7) | pkt[2]) >> shift;
284 *touch = (pkt[0] & 0x10) ? 1 : 0;
285
286 return 1;
287}
288
289static int eturbo_get_pkt_len(unsigned char *buf, int len)
290{
291 if (buf[0] & 0x80)
292 return 5;
293 if (buf[0] == 0x01)
294 return 3;
295 return 0;
296}
297#endif
298
299
300/*****************************************************************************
301 * Gunze part
302 */
303#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
304static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press)
305{
306 if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80))
307 return 0;
308
309 *x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F);
310 *y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F);
311 *touch = pkt[0] & 0x20;
312
313 return 1;
314}
315#endif
316
317/*****************************************************************************
299 * the different device descriptors 318 * the different device descriptors
300 */ 319 */
301static struct usbtouch_device_info usbtouch_dev_info[] = { 320static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -307,7 +326,8 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
307 .max_yc = 0x07ff, 326 .max_yc = 0x07ff,
308 .rept_size = 16, 327 .rept_size = 16,
309 .flags = USBTOUCH_FLG_BUFFER, 328 .flags = USBTOUCH_FLG_BUFFER,
310 .process_pkt = egalax_process, 329 .process_pkt = usbtouch_process_multi,
330 .get_pkt_len = egalax_get_pkt_len,
311 .read_data = egalax_read_data, 331 .read_data = egalax_read_data,
312 }, 332 },
313#endif 333#endif
@@ -346,6 +366,31 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
346 .read_data = itm_read_data, 366 .read_data = itm_read_data,
347 }, 367 },
348#endif 368#endif
369
370#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
371 [DEVTYPE_ETURBO] = {
372 .min_xc = 0x0,
373 .max_xc = 0x07ff,
374 .min_yc = 0x0,
375 .max_yc = 0x07ff,
376 .rept_size = 8,
377 .flags = USBTOUCH_FLG_BUFFER,
378 .process_pkt = usbtouch_process_multi,
379 .get_pkt_len = eturbo_get_pkt_len,
380 .read_data = eturbo_read_data,
381 },
382#endif
383
384#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
385 [DEVTYPE_GUNZE] = {
386 .min_xc = 0x0,
387 .max_xc = 0x0fff,
388 .min_yc = 0x0,
389 .max_yc = 0x0fff,
390 .rept_size = 4,
391 .read_data = gunze_read_data,
392 },
393#endif
349}; 394};
350 395
351 396
@@ -377,6 +422,83 @@ static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
377} 422}
378 423
379 424
425#ifdef MULTI_PACKET
426static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
427 struct pt_regs *regs,
428 unsigned char *pkt, int len)
429{
430 unsigned char *buffer;
431 int pkt_len, pos, buf_len, tmp;
432
433 /* process buffer */
434 if (unlikely(usbtouch->buf_len)) {
435 /* try to get size */
436 pkt_len = usbtouch->type->get_pkt_len(
437 usbtouch->buffer, usbtouch->buf_len);
438
439 /* drop? */
440 if (unlikely(!pkt_len))
441 goto out_flush_buf;
442
443 /* need to append -pkt_len bytes before able to get size */
444 if (unlikely(pkt_len < 0)) {
445 int append = -pkt_len;
446 if (unlikely(append > len))
447 append = len;
448 if (usbtouch->buf_len + append >= usbtouch->type->rept_size)
449 goto out_flush_buf;
450 memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, append);
451 usbtouch->buf_len += append;
452
453 pkt_len = usbtouch->type->get_pkt_len(
454 usbtouch->buffer, usbtouch->buf_len);
455 if (pkt_len < 0)
456 return;
457 }
458
459 /* append */
460 tmp = pkt_len - usbtouch->buf_len;
461 if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size)
462 goto out_flush_buf;
463 memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
464 usbtouch_process_pkt(usbtouch, regs, usbtouch->buffer, pkt_len);
465
466 buffer = pkt + tmp;
467 buf_len = len - tmp;
468 } else {
469 buffer = pkt;
470 buf_len = len;
471 }
472
473 /* loop over the received packet, process */
474 pos = 0;
475 while (pos < buf_len) {
476 /* get packet len */
477 pkt_len = usbtouch->type->get_pkt_len(buffer + pos, len);
478
479 /* unknown packet: drop everything */
480 if (unlikely(!pkt_len))
481 goto out_flush_buf;
482
483 /* full packet: process */
484 if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) {
485 usbtouch_process_pkt(usbtouch, regs, buffer + pos, pkt_len);
486 } else {
487 /* incomplete packet: save in buffer */
488 memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
489 usbtouch->buf_len = buf_len - pos;
490 return;
491 }
492 pos += pkt_len;
493 }
494
495out_flush_buf:
496 usbtouch->buf_len = 0;
497 return;
498}
499#endif
500
501
380static void usbtouch_irq(struct urb *urb, struct pt_regs *regs) 502static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
381{ 503{
382 struct usbtouch_usb *usbtouch = urb->context; 504 struct usbtouch_usb *usbtouch = urb->context;
@@ -386,7 +508,7 @@ static void usbtouch_irq(struct urb *urb, struct pt_regs *regs)
386 case 0: 508 case 0:
387 /* success */ 509 /* success */
388 break; 510 break;
389 case -ETIMEDOUT: 511 case -ETIME:
390 /* this urb is timing out */ 512 /* this urb is timing out */
391 dbg("%s - urb timed out - was the device unplugged?", 513 dbg("%s - urb timed out - was the device unplugged?",
392 __FUNCTION__); 514 __FUNCTION__);
@@ -452,7 +574,7 @@ static int usbtouch_probe(struct usb_interface *intf,
452 struct usb_endpoint_descriptor *endpoint; 574 struct usb_endpoint_descriptor *endpoint;
453 struct usb_device *udev = interface_to_usbdev(intf); 575 struct usb_device *udev = interface_to_usbdev(intf);
454 struct usbtouch_device_info *type; 576 struct usbtouch_device_info *type;
455 int err; 577 int err = -ENOMEM;
456 578
457 interface = intf->cur_altsetting; 579 interface = intf->cur_altsetting;
458 endpoint = &interface->endpoint[0].desc; 580 endpoint = &interface->endpoint[0].desc;
@@ -526,6 +648,7 @@ static int usbtouch_probe(struct usb_interface *intf,
526 usbtouch->data, type->rept_size, 648 usbtouch->data, type->rept_size,
527 usbtouch_irq, usbtouch, endpoint->bInterval); 649 usbtouch_irq, usbtouch, endpoint->bInterval);
528 650
651 usbtouch->irq->dev = usbtouch->udev;
529 usbtouch->irq->transfer_dma = usbtouch->data_dma; 652 usbtouch->irq->transfer_dma = usbtouch->data_dma;
530 usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 653 usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
531 654
@@ -553,7 +676,7 @@ out_free_buffers:
553out_free: 676out_free:
554 input_free_device(input_dev); 677 input_free_device(input_dev);
555 kfree(usbtouch); 678 kfree(usbtouch);
556 return -ENOMEM; 679 return err;
557} 680}
558 681
559static void usbtouch_disconnect(struct usb_interface *intf) 682static void usbtouch_disconnect(struct usb_interface *intf)
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
deleted file mode 100644
index 369461a70b72..000000000000
--- a/drivers/usb/input/wacom.c
+++ /dev/null
@@ -1,1003 +0,0 @@
1/*
2 * USB Wacom Graphire and Wacom Intuos tablet support
3 *
4 * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
5 * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
6 * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
7 * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
8 * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
9 * Copyright (c) 2000 Daniel Egger <egger@suse.de>
10 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
11 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
12 * Copyright (c) 2002-2006 Ping Cheng <pingc@wacom.com>
13 *
14 * ChangeLog:
15 * v0.1 (vp) - Initial release
16 * v0.2 (aba) - Support for all buttons / combinations
17 * v0.3 (vp) - Support for Intuos added
18 * v0.4 (sm) - Support for more Intuos models, menustrip
19 * relative mode, proximity.
20 * v0.5 (vp) - Big cleanup, nifty features removed,
21 * they belong in userspace
22 * v1.8 (vp) - Submit URB only when operating, moved to CVS,
23 * use input_report_key instead of report_btn and
24 * other cleanups
25 * v1.11 (vp) - Add URB ->dev setting for new kernels
26 * v1.11 (jb) - Add support for the 4D Mouse & Lens
27 * v1.12 (de) - Add support for two more inking pen IDs
28 * v1.14 (vp) - Use new USB device id probing scheme.
29 * Fix Wacom Graphire mouse wheel
30 * v1.18 (vp) - Fix mouse wheel direction
31 * Make mouse relative
32 * v1.20 (fl) - Report tool id for Intuos devices
33 * - Multi tools support
34 * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...)
35 * - Add PL models support
36 * - Fix Wacom Graphire mouse wheel again
37 * v1.21 (vp) - Removed protocol descriptions
38 * - Added MISC_SERIAL for tool serial numbers
39 * (gb) - Identify version on module load.
40 * v1.21.1 (fl) - added Graphire2 support
41 * v1.21.2 (fl) - added Intuos2 support
42 * - added all the PL ids
43 * v1.21.3 (fl) - added another eraser id from Neil Okamoto
44 * - added smooth filter for Graphire from Peri Hankey
45 * - added PenPartner support from Olaf van Es
46 * - new tool ids from Ole Martin Bjoerndalen
47 * v1.29 (pc) - Add support for more tablets
48 * - Fix pressure reporting
49 * v1.30 (vp) - Merge 2.4 and 2.5 drivers
50 * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
51 * - Cleanups here and there
52 * v1.30.1 (pi) - Added Graphire3 support
53 * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
54 * v1.43 (pc) - Added support for Cintiq 21UX
55 * - Fixed a Graphire bug
56 * - Merged wacom_intuos3_irq into wacom_intuos_irq
57 * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc.
58 * - Report Device IDs
59 * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19
60 * - Minor data report fix
61 */
62
63/*
64 * This program is free software; you can redistribute it and/or modify
65 * it under the terms of the GNU General Public License as published by
66 * the Free Software Foundation; either version 2 of the License, or
67 * (at your option) any later version.
68 */
69
70#include <linux/kernel.h>
71#include <linux/slab.h>
72#include <linux/module.h>
73#include <linux/init.h>
74#include <linux/usb/input.h>
75#include <asm/unaligned.h>
76
77/*
78 * Version Information
79 */
80#define DRIVER_VERSION "v1.45"
81#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
82#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
83#define DRIVER_LICENSE "GPL"
84
85MODULE_AUTHOR(DRIVER_AUTHOR);
86MODULE_DESCRIPTION(DRIVER_DESC);
87MODULE_LICENSE(DRIVER_LICENSE);
88
89#define USB_VENDOR_ID_WACOM 0x056a
90#define STYLUS_DEVICE_ID 0x02
91#define CURSOR_DEVICE_ID 0x06
92#define ERASER_DEVICE_ID 0x0A
93
94enum {
95 PENPARTNER = 0,
96 GRAPHIRE,
97 WACOM_G4,
98 PL,
99 INTUOS,
100 INTUOS3,
101 INTUOS312,
102 INTUOS319,
103 CINTIQ,
104 MAX_TYPE
105};
106
107struct wacom_features {
108 char *name;
109 int pktlen;
110 int x_max;
111 int y_max;
112 int pressure_max;
113 int distance_max;
114 int type;
115 usb_complete_t irq;
116};
117
118struct wacom {
119 signed char *data;
120 dma_addr_t data_dma;
121 struct input_dev *dev;
122 struct usb_device *usbdev;
123 struct urb *irq;
124 struct wacom_features *features;
125 int tool[2];
126 int id[2];
127 __u32 serial[2];
128 char phys[32];
129};
130
131#define USB_REQ_GET_REPORT 0x01
132#define USB_REQ_SET_REPORT 0x09
133
134static int usb_get_report(struct usb_interface *intf, unsigned char type,
135 unsigned char id, void *buf, int size)
136{
137 return usb_control_msg(interface_to_usbdev(intf),
138 usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
139 USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
140 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
141 buf, size, 100);
142}
143
144static int usb_set_report(struct usb_interface *intf, unsigned char type,
145 unsigned char id, void *buf, int size)
146{
147 return usb_control_msg(interface_to_usbdev(intf),
148 usb_sndctrlpipe(interface_to_usbdev(intf), 0),
149 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
150 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
151 buf, size, 1000);
152}
153
154static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
155{
156 struct wacom *wacom = urb->context;
157 unsigned char *data = wacom->data;
158 struct input_dev *dev = wacom->dev;
159 int prox, pressure, id;
160 int retval;
161
162 switch (urb->status) {
163 case 0:
164 /* success */
165 break;
166 case -ECONNRESET:
167 case -ENOENT:
168 case -ESHUTDOWN:
169 /* this urb is terminated, clean up */
170 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
171 return;
172 default:
173 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
174 goto exit;
175 }
176
177 if (data[0] != 2) {
178 dbg("wacom_pl_irq: received unknown report #%d", data[0]);
179 goto exit;
180 }
181
182 prox = data[1] & 0x40;
183
184 input_regs(dev, regs);
185
186 id = ERASER_DEVICE_ID;
187 if (prox) {
188
189 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
190 if (wacom->features->pressure_max > 255)
191 pressure = (pressure << 1) | ((data[4] >> 6) & 1);
192 pressure += (wacom->features->pressure_max + 1) / 2;
193
194 /*
195 * if going from out of proximity into proximity select between the eraser
196 * and the pen based on the state of the stylus2 button, choose eraser if
197 * pressed else choose pen. if not a proximity change from out to in, send
198 * an out of proximity for previous tool then a in for new tool.
199 */
200 if (!wacom->tool[0]) {
201 /* Eraser bit set for DTF */
202 if (data[1] & 0x10)
203 wacom->tool[1] = BTN_TOOL_RUBBER;
204 else
205 /* Going into proximity select tool */
206 wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
207 } else {
208 /* was entered with stylus2 pressed */
209 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
210 /* report out proximity for previous tool */
211 input_report_key(dev, wacom->tool[1], 0);
212 input_sync(dev);
213 wacom->tool[1] = BTN_TOOL_PEN;
214 goto exit;
215 }
216 }
217 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
218 /* Unknown tool selected default to pen tool */
219 wacom->tool[1] = BTN_TOOL_PEN;
220 id = STYLUS_DEVICE_ID;
221 }
222 input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
223 input_report_abs(dev, ABS_MISC, id); /* report tool id */
224 input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
225 input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
226 input_report_abs(dev, ABS_PRESSURE, pressure);
227
228 input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
229 input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
230 /* Only allow the stylus2 button to be reported for the pen tool. */
231 input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
232 } else {
233 /* report proximity-out of a (valid) tool */
234 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
235 /* Unknown tool selected default to pen tool */
236 wacom->tool[1] = BTN_TOOL_PEN;
237 }
238 input_report_key(dev, wacom->tool[1], prox);
239 }
240
241 wacom->tool[0] = prox; /* Save proximity state */
242 input_sync(dev);
243
244 exit:
245 retval = usb_submit_urb (urb, GFP_ATOMIC);
246 if (retval)
247 err ("%s - usb_submit_urb failed with result %d",
248 __FUNCTION__, retval);
249}
250
251static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
252{
253 struct wacom *wacom = urb->context;
254 unsigned char *data = wacom->data;
255 struct input_dev *dev = wacom->dev;
256 int retval, id;
257
258 switch (urb->status) {
259 case 0:
260 /* success */
261 break;
262 case -ECONNRESET:
263 case -ENOENT:
264 case -ESHUTDOWN:
265 /* this urb is terminated, clean up */
266 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
267 return;
268 default:
269 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
270 goto exit;
271 }
272
273 if (data[0] != 2) {
274 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
275 goto exit;
276 }
277
278 input_regs(dev, regs);
279 if (data[1] & 0x04) {
280 input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
281 input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
282 id = ERASER_DEVICE_ID;
283 } else {
284 input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
285 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
286 id = STYLUS_DEVICE_ID;
287 }
288 input_report_abs(dev, ABS_MISC, id); /* report tool id */
289 input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2]));
290 input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4]));
291 input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
292 input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
293 input_report_key(dev, BTN_STYLUS2, data[1] & 0x10);
294
295 input_sync(dev);
296
297 exit:
298 retval = usb_submit_urb (urb, GFP_ATOMIC);
299 if (retval)
300 err ("%s - usb_submit_urb failed with result %d",
301 __FUNCTION__, retval);
302}
303
304static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
305{
306 struct wacom *wacom = urb->context;
307 unsigned char *data = wacom->data;
308 struct input_dev *dev = wacom->dev;
309 int retval;
310
311 switch (urb->status) {
312 case 0:
313 /* success */
314 break;
315 case -ECONNRESET:
316 case -ENOENT:
317 case -ESHUTDOWN:
318 /* this urb is terminated, clean up */
319 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
320 return;
321 default:
322 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
323 goto exit;
324 }
325
326 if (data[0] != 2) {
327 printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);
328 goto exit;
329 }
330
331 input_regs(dev, regs);
332 input_report_key(dev, BTN_TOOL_PEN, 1);
333 input_report_abs(dev, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
334 input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1]));
335 input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3]));
336 input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127);
337 input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
338 input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
339 input_sync(dev);
340
341 exit:
342 retval = usb_submit_urb (urb, GFP_ATOMIC);
343 if (retval)
344 err ("%s - usb_submit_urb failed with result %d",
345 __FUNCTION__, retval);
346}
347
348static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
349{
350 struct wacom *wacom = urb->context;
351 unsigned char *data = wacom->data;
352 struct input_dev *dev = wacom->dev;
353 int x, y, id, rw;
354 int retval;
355
356 switch (urb->status) {
357 case 0:
358 /* success */
359 break;
360 case -ECONNRESET:
361 case -ENOENT:
362 case -ESHUTDOWN:
363 /* this urb is terminated, clean up */
364 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
365 return;
366 default:
367 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
368 goto exit;
369 }
370
371 if (data[0] == 99) return; /* for Volito tablets */
372
373 if (data[0] != 2) {
374 dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
375 goto exit;
376 }
377
378 input_regs(dev, regs);
379
380 id = STYLUS_DEVICE_ID;
381 if (data[1] & 0x10) { /* in prox */
382
383 switch ((data[1] >> 5) & 3) {
384
385 case 0: /* Pen */
386 wacom->tool[0] = BTN_TOOL_PEN;
387 break;
388
389 case 1: /* Rubber */
390 wacom->tool[0] = BTN_TOOL_RUBBER;
391 id = ERASER_DEVICE_ID;
392 break;
393
394 case 2: /* Mouse with wheel */
395 input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
396 if (wacom->features->type == WACOM_G4) {
397 rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
398 input_report_rel(dev, REL_WHEEL, -rw);
399 } else
400 input_report_rel(dev, REL_WHEEL, -(signed char) data[6]);
401 /* fall through */
402
403 case 3: /* Mouse without wheel */
404 wacom->tool[0] = BTN_TOOL_MOUSE;
405 id = CURSOR_DEVICE_ID;
406 input_report_key(dev, BTN_LEFT, data[1] & 0x01);
407 input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
408 if (wacom->features->type == WACOM_G4)
409 input_report_abs(dev, ABS_DISTANCE, data[6]);
410 else
411 input_report_abs(dev, ABS_DISTANCE, data[7]);
412 break;
413 }
414 }
415
416 if (data[1] & 0x90) {
417 x = le16_to_cpu(*(__le16 *) &data[2]);
418 y = le16_to_cpu(*(__le16 *) &data[4]);
419 input_report_abs(dev, ABS_X, x);
420 input_report_abs(dev, ABS_Y, y);
421 if (wacom->tool[0] != BTN_TOOL_MOUSE) {
422 input_report_abs(dev, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
423 input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
424 input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
425 input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
426 }
427 }
428
429 if (data[1] & 0x10)
430 input_report_abs(dev, ABS_MISC, id); /* report tool id */
431 else
432 input_report_abs(dev, ABS_MISC, 0); /* reset tool id */
433 input_report_key(dev, wacom->tool[0], data[1] & 0x10);
434 input_sync(dev);
435
436 /* send pad data */
437 if (wacom->features->type == WACOM_G4) {
438 if ((wacom->serial[1] & 0xc0) != (data[7] & 0xf8)) {
439 wacom->id[1] = 1;
440 wacom->serial[1] = (data[7] & 0xf8);
441 input_report_key(dev, BTN_0, (data[7] & 0x40));
442 input_report_key(dev, BTN_4, (data[7] & 0x80));
443 rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
444 input_report_rel(dev, REL_WHEEL, rw);
445 input_report_key(dev, BTN_TOOL_FINGER, 0xf0);
446 input_event(dev, EV_MSC, MSC_SERIAL, 0xf0);
447 } else if (wacom->id[1]) {
448 wacom->id[1] = 0;
449 input_report_key(dev, BTN_TOOL_FINGER, 0);
450 input_event(dev, EV_MSC, MSC_SERIAL, 0xf0);
451 }
452 input_sync(dev);
453 }
454 exit:
455 retval = usb_submit_urb (urb, GFP_ATOMIC);
456 if (retval)
457 err ("%s - usb_submit_urb failed with result %d",
458 __FUNCTION__, retval);
459}
460
461static int wacom_intuos_inout(struct urb *urb)
462{
463 struct wacom *wacom = urb->context;
464 unsigned char *data = wacom->data;
465 struct input_dev *dev = wacom->dev;
466 int idx;
467
468 /* tool number */
469 idx = data[1] & 0x01;
470
471 /* Enter report */
472 if ((data[1] & 0xfc) == 0xc0) {
473 /* serial number of the tool */
474 wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
475 (data[4] << 20) + (data[5] << 12) +
476 (data[6] << 4) + (data[7] >> 4);
477
478 wacom->id[idx] = (data[2] << 4) | (data[3] >> 4);
479 switch (wacom->id[idx]) {
480 case 0x812: /* Inking pen */
481 case 0x801: /* Intuos3 Inking pen */
482 case 0x012:
483 wacom->tool[idx] = BTN_TOOL_PENCIL;
484 break;
485 case 0x822: /* Pen */
486 case 0x842:
487 case 0x852:
488 case 0x823: /* Intuos3 Grip Pen */
489 case 0x813: /* Intuos3 Classic Pen */
490 case 0x885: /* Intuos3 Marker Pen */
491 case 0x022:
492 wacom->tool[idx] = BTN_TOOL_PEN;
493 break;
494 case 0x832: /* Stroke pen */
495 case 0x032:
496 wacom->tool[idx] = BTN_TOOL_BRUSH;
497 break;
498 case 0x007: /* Mouse 4D and 2D */
499 case 0x09c:
500 case 0x094:
501 case 0x017: /* Intuos3 2D Mouse */
502 wacom->tool[idx] = BTN_TOOL_MOUSE;
503 break;
504 case 0x096: /* Lens cursor */
505 case 0x097: /* Intuos3 Lens cursor */
506 wacom->tool[idx] = BTN_TOOL_LENS;
507 break;
508 case 0x82a: /* Eraser */
509 case 0x85a:
510 case 0x91a:
511 case 0xd1a:
512 case 0x0fa:
513 case 0x82b: /* Intuos3 Grip Pen Eraser */
514 case 0x81b: /* Intuos3 Classic Pen Eraser */
515 case 0x91b: /* Intuos3 Airbrush Eraser */
516 wacom->tool[idx] = BTN_TOOL_RUBBER;
517 break;
518 case 0xd12:
519 case 0x912:
520 case 0x112:
521 case 0x913: /* Intuos3 Airbrush */
522 wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
523 break;
524 default: /* Unknown tool */
525 wacom->tool[idx] = BTN_TOOL_PEN;
526 }
527 if(!((wacom->tool[idx] == BTN_TOOL_LENS) &&
528 ((wacom->features->type == INTUOS312)
529 || (wacom->features->type == INTUOS319)))) {
530 input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */
531 input_report_key(dev, wacom->tool[idx], 1);
532 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
533 input_sync(dev);
534 }
535 return 1;
536 }
537
538 /* Exit report */
539 if ((data[1] & 0xfe) == 0x80) {
540 input_report_key(dev, wacom->tool[idx], 0);
541 input_report_abs(dev, ABS_MISC, 0); /* reset tool id */
542 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
543 input_sync(dev);
544 return 1;
545 }
546
547 if((wacom->tool[idx] == BTN_TOOL_LENS) && ((wacom->features->type == INTUOS312)
548 || (wacom->features->type == INTUOS319)))
549 return 1;
550 else
551 return 0;
552}
553
554static void wacom_intuos_general(struct urb *urb)
555{
556 struct wacom *wacom = urb->context;
557 unsigned char *data = wacom->data;
558 struct input_dev *dev = wacom->dev;
559 unsigned int t;
560
561 /* general pen packet */
562 if ((data[1] & 0xb8) == 0xa0) {
563 t = (data[6] << 2) | ((data[7] >> 6) & 3);
564 input_report_abs(dev, ABS_PRESSURE, t);
565 input_report_abs(dev, ABS_TILT_X,
566 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
567 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
568 input_report_key(dev, BTN_STYLUS, data[1] & 2);
569 input_report_key(dev, BTN_STYLUS2, data[1] & 4);
570 input_report_key(dev, BTN_TOUCH, t > 10);
571 }
572
573 /* airbrush second packet */
574 if ((data[1] & 0xbc) == 0xb4) {
575 input_report_abs(dev, ABS_WHEEL,
576 (data[6] << 2) | ((data[7] >> 6) & 3));
577 input_report_abs(dev, ABS_TILT_X,
578 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
579 input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
580 }
581 return;
582}
583
584static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
585{
586 struct wacom *wacom = urb->context;
587 unsigned char *data = wacom->data;
588 struct input_dev *dev = wacom->dev;
589 unsigned int t;
590 int idx;
591 int retval;
592
593 switch (urb->status) {
594 case 0:
595 /* success */
596 break;
597 case -ECONNRESET:
598 case -ENOENT:
599 case -ESHUTDOWN:
600 /* this urb is terminated, clean up */
601 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
602 return;
603 default:
604 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
605 goto exit;
606 }
607
608 if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
609 dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
610 goto exit;
611 }
612
613 input_regs(dev, regs);
614
615 /* tool number */
616 idx = data[1] & 0x01;
617
618 /* pad packets. Works as a second tool and is always in prox */
619 if (data[0] == 12) {
620 /* initiate the pad as a device */
621 if (wacom->tool[1] != BTN_TOOL_FINGER)
622 wacom->tool[1] = BTN_TOOL_FINGER;
623
624 input_report_key(dev, BTN_0, (data[5] & 0x01));
625 input_report_key(dev, BTN_1, (data[5] & 0x02));
626 input_report_key(dev, BTN_2, (data[5] & 0x04));
627 input_report_key(dev, BTN_3, (data[5] & 0x08));
628 input_report_key(dev, BTN_4, (data[6] & 0x01));
629 input_report_key(dev, BTN_5, (data[6] & 0x02));
630 input_report_key(dev, BTN_6, (data[6] & 0x04));
631 input_report_key(dev, BTN_7, (data[6] & 0x08));
632 input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
633 input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
634
635 if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2])
636 input_report_key(dev, wacom->tool[1], 1);
637 else
638 input_report_key(dev, wacom->tool[1], 0);
639 input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff);
640 input_sync(dev);
641 goto exit;
642 }
643
644 /* process in/out prox events */
645 if (wacom_intuos_inout(urb))
646 goto exit;
647
648 /* Cintiq doesn't send data when RDY bit isn't set */
649 if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
650 goto exit;
651
652 if (wacom->features->type >= INTUOS3) {
653 input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
654 input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
655 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
656 } else {
657 input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
658 input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
659 input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
660 }
661
662 /* process general packets */
663 wacom_intuos_general(urb);
664
665 /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
666 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
667
668 if (data[1] & 0x02) {
669 /* Rotation packet */
670 if (wacom->features->type >= INTUOS3) {
671 /* I3 marker pen rotation reported as wheel
672 * due to valuator limitation
673 */
674 t = (data[6] << 3) | ((data[7] >> 5) & 7);
675 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
676 ((t-1) / 2 + 450)) : (450 - t / 2) ;
677 input_report_abs(dev, ABS_WHEEL, t);
678 } else {
679 /* 4D mouse rotation packet */
680 t = (data[6] << 3) | ((data[7] >> 5) & 7);
681 input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
682 ((t - 1) / 2) : -t / 2);
683 }
684
685 } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
686 /* 4D mouse packet */
687 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
688 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
689 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
690
691 input_report_key(dev, BTN_SIDE, data[8] & 0x20);
692 input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
693 t = (data[6] << 2) | ((data[7] >> 6) & 3);
694 input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
695
696 } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
697 /* 2D mouse packet */
698 input_report_key(dev, BTN_LEFT, data[8] & 0x04);
699 input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
700 input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
701 input_report_rel(dev, REL_WHEEL, (data[8] & 0x01)
702 - ((data[8] & 0x02) >> 1));
703
704 /* I3 2D mouse side buttons */
705 if (wacom->features->type == INTUOS3) {
706 input_report_key(dev, BTN_SIDE, data[8] & 0x40);
707 input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
708 }
709
710 } else if (wacom->features->type < INTUOS3) {
711 /* Lens cursor packets */
712 input_report_key(dev, BTN_LEFT, data[8] & 0x01);
713 input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
714 input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
715 input_report_key(dev, BTN_SIDE, data[8] & 0x10);
716 input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
717 }
718 }
719
720 input_report_abs(dev, ABS_MISC, wacom->id[idx]); /* report tool id */
721 input_report_key(dev, wacom->tool[idx], 1);
722 input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
723 input_sync(dev);
724
725exit:
726 retval = usb_submit_urb (urb, GFP_ATOMIC);
727 if (retval)
728 err ("%s - usb_submit_urb failed with result %d",
729 __FUNCTION__, retval);
730}
731
732static struct wacom_features wacom_features[] = {
733 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_penpartner_irq },
734 { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
735 { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
736 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
737 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
738 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq },
739 { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_graphire_irq },
740 { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_graphire_irq },
741 { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
742 { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq },
743 { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
744 { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 32, GRAPHIRE, wacom_graphire_irq },
745 { "Wacom PenPartner2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq },
746 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
747 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
748 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
749 { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
750 { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
751 { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_pl_irq },
752 { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_pl_irq },
753 { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_pl_irq },
754 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq },
755 { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq },
756 { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq },
757 { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_pl_irq },
758 { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq },
759 { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_pl_irq },
760 { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_pl_irq },
761 { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_pl_irq },
762 { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq },
763 { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
764 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
765 { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
766 { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
767 { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
768 { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq },
769 { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq },
770 { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq },
771 { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS312, wacom_intuos_irq },
772 { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS319, wacom_intuos_irq },
773 { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_intuos_irq },
774 { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq },
775 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
776 { }
777};
778
779static struct usb_device_id wacom_ids[] = {
780 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) },
781 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) },
782 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) },
783 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) },
784 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) },
785 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
786 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) },
787 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
788 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
789 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
790 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
791 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
792 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
793 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
794 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
795 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
796 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) },
797 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) },
798 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) },
799 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) },
800 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) },
801 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) },
802 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) },
803 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) },
804 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
805 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
806 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
807 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
808 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC3) },
809 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
810 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
811 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
812 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) },
813 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) },
814 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) },
815 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
816 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
817 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
818 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) },
819 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) },
820 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
821 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
822 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
823 { }
824};
825
826MODULE_DEVICE_TABLE(usb, wacom_ids);
827
828static int wacom_open(struct input_dev *dev)
829{
830 struct wacom *wacom = dev->private;
831
832 wacom->irq->dev = wacom->usbdev;
833 if (usb_submit_urb(wacom->irq, GFP_KERNEL))
834 return -EIO;
835
836 return 0;
837}
838
839static void wacom_close(struct input_dev *dev)
840{
841 struct wacom *wacom = dev->private;
842
843 usb_kill_urb(wacom->irq);
844}
845
846static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
847{
848 struct usb_device *dev = interface_to_usbdev(intf);
849 struct usb_endpoint_descriptor *endpoint;
850 struct wacom *wacom;
851 struct input_dev *input_dev;
852 char rep_data[2], limit = 0;
853
854 wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
855 input_dev = input_allocate_device();
856 if (!wacom || !input_dev)
857 goto fail1;
858
859 wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
860 if (!wacom->data)
861 goto fail1;
862
863 wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
864 if (!wacom->irq)
865 goto fail2;
866
867 wacom->usbdev = dev;
868 wacom->dev = input_dev;
869 usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
870 strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
871
872 wacom->features = wacom_features + (id - wacom_ids);
873 if (wacom->features->pktlen > 10)
874 BUG();
875
876 input_dev->name = wacom->features->name;
877 usb_to_input_id(dev, &input_dev->id);
878
879 input_dev->cdev.dev = &intf->dev;
880 input_dev->private = wacom;
881 input_dev->open = wacom_open;
882 input_dev->close = wacom_close;
883
884 input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
885 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
886 input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0);
887 input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
888 input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
889 input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC);
890
891 switch (wacom->features->type) {
892 case WACOM_G4:
893 input_dev->evbit[0] |= BIT(EV_MSC);
894 input_dev->mscbit[0] |= BIT(MSC_SERIAL);
895 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
896 input_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);
897 /* fall through */
898
899 case GRAPHIRE:
900 input_dev->evbit[0] |= BIT(EV_REL);
901 input_dev->relbit[0] |= BIT(REL_WHEEL);
902 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
903 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
904 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
905 break;
906
907 case INTUOS3:
908 case INTUOS312:
909 case INTUOS319:
910 case CINTIQ:
911 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
912 input_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);
913 input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
914 input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
915 /* fall through */
916
917 case INTUOS:
918 input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
919 input_dev->mscbit[0] |= BIT(MSC_SERIAL);
920 input_dev->relbit[0] |= BIT(REL_WHEEL);
921 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
922 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
923 | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
924 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
925 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
926 input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
927 input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
928 input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
929 input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
930 break;
931
932 case PL:
933 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
934 break;
935 }
936
937 endpoint = &intf->cur_altsetting->endpoint[0].desc;
938
939 if (wacom->features->pktlen > 10)
940 BUG();
941
942 usb_fill_int_urb(wacom->irq, dev,
943 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
944 wacom->data, wacom->features->pktlen,
945 wacom->features->irq, wacom, endpoint->bInterval);
946 wacom->irq->transfer_dma = wacom->data_dma;
947 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
948
949 input_register_device(wacom->dev);
950
951 /* Ask the tablet to report tablet data. Repeat until it succeeds */
952 do {
953 rep_data[0] = 2;
954 rep_data[1] = 2;
955 usb_set_report(intf, 3, 2, rep_data, 2);
956 usb_get_report(intf, 3, 2, rep_data, 2);
957 } while (rep_data[1] != 2 && limit++ < 5);
958
959 usb_set_intfdata(intf, wacom);
960 return 0;
961
962fail2: usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
963fail1: input_free_device(input_dev);
964 kfree(wacom);
965 return -ENOMEM;
966}
967
968static void wacom_disconnect(struct usb_interface *intf)
969{
970 struct wacom *wacom = usb_get_intfdata (intf);
971
972 usb_set_intfdata(intf, NULL);
973 if (wacom) {
974 usb_kill_urb(wacom->irq);
975 input_unregister_device(wacom->dev);
976 usb_free_urb(wacom->irq);
977 usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma);
978 kfree(wacom);
979 }
980}
981
982static struct usb_driver wacom_driver = {
983 .name = "wacom",
984 .probe = wacom_probe,
985 .disconnect = wacom_disconnect,
986 .id_table = wacom_ids,
987};
988
989static int __init wacom_init(void)
990{
991 int result = usb_register(&wacom_driver);
992 if (result == 0)
993 info(DRIVER_VERSION ":" DRIVER_DESC);
994 return result;
995}
996
997static void __exit wacom_exit(void)
998{
999 usb_deregister(&wacom_driver);
1000}
1001
1002module_init(wacom_init);
1003module_exit(wacom_exit);
diff --git a/drivers/usb/input/wacom.h b/drivers/usb/input/wacom.h
new file mode 100644
index 000000000000..832737b658cf
--- /dev/null
+++ b/drivers/usb/input/wacom.h
@@ -0,0 +1,132 @@
1/*
2 * drivers/usb/input/wacom.h
3 *
4 * USB Wacom Graphire and Wacom Intuos tablet support
5 *
6 * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
7 * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
8 * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
9 * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
10 * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
11 * Copyright (c) 2000 Daniel Egger <egger@suse.de>
12 * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
13 * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
14 * Copyright (c) 2002-2006 Ping Cheng <pingc@wacom.com>
15 *
16 * ChangeLog:
17 * v0.1 (vp) - Initial release
18 * v0.2 (aba) - Support for all buttons / combinations
19 * v0.3 (vp) - Support for Intuos added
20 * v0.4 (sm) - Support for more Intuos models, menustrip
21 * relative mode, proximity.
22 * v0.5 (vp) - Big cleanup, nifty features removed,
23 * they belong in userspace
24 * v1.8 (vp) - Submit URB only when operating, moved to CVS,
25 * use input_report_key instead of report_btn and
26 * other cleanups
27 * v1.11 (vp) - Add URB ->dev setting for new kernels
28 * v1.11 (jb) - Add support for the 4D Mouse & Lens
29 * v1.12 (de) - Add support for two more inking pen IDs
30 * v1.14 (vp) - Use new USB device id probing scheme.
31 * Fix Wacom Graphire mouse wheel
32 * v1.18 (vp) - Fix mouse wheel direction
33 * Make mouse relative
34 * v1.20 (fl) - Report tool id for Intuos devices
35 * - Multi tools support
36 * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...)
37 * - Add PL models support
38 * - Fix Wacom Graphire mouse wheel again
39 * v1.21 (vp) - Removed protocol descriptions
40 * - Added MISC_SERIAL for tool serial numbers
41 * (gb) - Identify version on module load.
42 * v1.21.1 (fl) - added Graphire2 support
43 * v1.21.2 (fl) - added Intuos2 support
44 * - added all the PL ids
45 * v1.21.3 (fl) - added another eraser id from Neil Okamoto
46 * - added smooth filter for Graphire from Peri Hankey
47 * - added PenPartner support from Olaf van Es
48 * - new tool ids from Ole Martin Bjoerndalen
49 * v1.29 (pc) - Add support for more tablets
50 * - Fix pressure reporting
51 * v1.30 (vp) - Merge 2.4 and 2.5 drivers
52 * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
53 * - Cleanups here and there
54 * v1.30.1 (pi) - Added Graphire3 support
55 * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
56 * v1.43 (pc) - Added support for Cintiq 21UX
57 * - Fixed a Graphire bug
58 * - Merged wacom_intuos3_irq into wacom_intuos_irq
59 * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc.
60 * - Report Device IDs
61 * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19
62 * - Minor data report fix
63 * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
64 * - where wacom_sys.c deals with system specific code,
65 * - and wacom_wac.c deals with Wacom specific code
66 */
67
68/*
69 * This program is free software; you can redistribute it and/or modify
70 * it under the terms of the GNU General Public License as published by
71 * the Free Software Foundation; either version 2 of the License, or
72 * (at your option) any later version.
73 */
74#ifndef WACOM_H
75#define WACOM_H
76#include <linux/kernel.h>
77#include <linux/slab.h>
78#include <linux/module.h>
79#include <linux/init.h>
80#include <linux/usb/input.h>
81#include <asm/unaligned.h>
82
83/*
84 * Version Information
85 */
86#define DRIVER_VERSION "v1.46"
87#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
88#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
89#define DRIVER_LICENSE "GPL"
90
91MODULE_AUTHOR(DRIVER_AUTHOR);
92MODULE_DESCRIPTION(DRIVER_DESC);
93MODULE_LICENSE(DRIVER_LICENSE);
94
95#define USB_VENDOR_ID_WACOM 0x056a
96
97struct wacom {
98 dma_addr_t data_dma;
99 struct input_dev *dev;
100 struct usb_device *usbdev;
101 struct urb *irq;
102 struct wacom_wac * wacom_wac;
103 char phys[32];
104};
105
106struct wacom_combo {
107 struct wacom * wacom;
108 struct urb * urb;
109 struct pt_regs *regs;
110};
111
112extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
113extern void wacom_sys_irq(struct urb *urb, struct pt_regs *regs);
114extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data);
115extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data);
116extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data);
117extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value);
118extern void wacom_input_regs(void *wcombo);
119extern void wacom_input_sync(void *wcombo);
120extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
121extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
122extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
123extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
124extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
125extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
126extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
127extern __u16 wacom_le16_to_cpu(unsigned char *data);
128extern __u16 wacom_be16_to_cpu(unsigned char *data);
129extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
130extern const struct usb_device_id * get_device_table(void);
131
132#endif
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c
new file mode 100644
index 000000000000..7c3b52bdd9d6
--- /dev/null
+++ b/drivers/usb/input/wacom_sys.c
@@ -0,0 +1,315 @@
1/*
2 * drivers/usb/input/wacom_sys.c
3 *
4 * USB Wacom Graphire and Wacom Intuos tablet support - system specific code
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include "wacom.h"
15#include "wacom_wac.h"
16
17#define USB_REQ_GET_REPORT 0x01
18#define USB_REQ_SET_REPORT 0x09
19
20static int usb_get_report(struct usb_interface *intf, unsigned char type,
21 unsigned char id, void *buf, int size)
22{
23 return usb_control_msg(interface_to_usbdev(intf),
24 usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
25 USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
26 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
27 buf, size, 100);
28}
29
30static int usb_set_report(struct usb_interface *intf, unsigned char type,
31 unsigned char id, void *buf, int size)
32{
33 return usb_control_msg(interface_to_usbdev(intf),
34 usb_sndctrlpipe(interface_to_usbdev(intf), 0),
35 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
36 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
37 buf, size, 1000);
38}
39
40static struct input_dev * get_input_dev(struct wacom_combo *wcombo)
41{
42 return wcombo->wacom->dev;
43}
44
45void wacom_sys_irq(struct urb *urb, struct pt_regs *regs)
46{
47 struct wacom *wacom = urb->context;
48 struct wacom_combo wcombo;
49 int retval;
50
51 switch (urb->status) {
52 case 0:
53 /* success */
54 break;
55 case -ECONNRESET:
56 case -ENOENT:
57 case -ESHUTDOWN:
58 /* this urb is terminated, clean up */
59 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
60 return;
61 default:
62 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
63 goto exit;
64 }
65
66 wcombo.wacom = wacom;
67 wcombo.urb = urb;
68 wcombo.regs = regs;
69
70 if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo))
71 input_sync(get_input_dev(&wcombo));
72
73 exit:
74 retval = usb_submit_urb (urb, GFP_ATOMIC);
75 if (retval)
76 err ("%s - usb_submit_urb failed with result %d",
77 __FUNCTION__, retval);
78}
79
80void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)
81{
82 input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data);
83 return;
84}
85
86void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data)
87{
88 input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data);
89 return;
90}
91
92void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data)
93{
94 input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data);
95 return;
96}
97
98void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value)
99{
100 input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value);
101 return;
102}
103
104__u16 wacom_be16_to_cpu(unsigned char *data)
105{
106 __u16 value;
107 value = be16_to_cpu(*(__be16 *) data);
108 return value;
109}
110
111__u16 wacom_le16_to_cpu(unsigned char *data)
112{
113 __u16 value;
114 value = be16_to_cpu(*(__be16 *) data);
115 return value;
116}
117
118void wacom_input_regs(void *wcombo)
119{
120 input_regs(get_input_dev((struct wacom_combo *)wcombo), ((struct wacom_combo *)wcombo)->regs);
121 return;
122}
123
124void wacom_input_sync(void *wcombo)
125{
126 input_sync(get_input_dev((struct wacom_combo *)wcombo));
127 return;
128}
129
130static int wacom_open(struct input_dev *dev)
131{
132 struct wacom *wacom = dev->private;
133
134 wacom->irq->dev = wacom->usbdev;
135 if (usb_submit_urb(wacom->irq, GFP_KERNEL))
136 return -EIO;
137
138 return 0;
139}
140
141static void wacom_close(struct input_dev *dev)
142{
143 struct wacom *wacom = dev->private;
144
145 usb_kill_urb(wacom->irq);
146}
147
148void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
149{
150 input_dev->evbit[0] |= BIT(EV_MSC);
151 input_dev->mscbit[0] |= BIT(MSC_SERIAL);
152 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
153 input_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);
154}
155
156void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
157{
158 input_dev->evbit[0] |= BIT(EV_REL);
159 input_dev->relbit[0] |= BIT(REL_WHEEL);
160 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
161 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
162 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
163}
164
165void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
166{
167 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
168 input_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);
169 input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
170 input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
171}
172
173void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
174{
175 input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
176 input_dev->mscbit[0] |= BIT(MSC_SERIAL);
177 input_dev->relbit[0] |= BIT(REL_WHEEL);
178 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
179 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
180 | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
181 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
182 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
183 input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
184 input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
185 input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
186 input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
187}
188
189void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
190{
191 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
192}
193
194void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
195{
196 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER);
197}
198
199static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
200{
201 struct usb_device *dev = interface_to_usbdev(intf);
202 struct usb_endpoint_descriptor *endpoint;
203 struct wacom *wacom;
204 struct wacom_wac *wacom_wac;
205 struct input_dev *input_dev;
206 char rep_data[2], limit = 0;
207
208 wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
209 wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
210 input_dev = input_allocate_device();
211 if (!wacom || !input_dev || !wacom_wac)
212 goto fail1;
213
214 wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
215 if (!wacom_wac->data)
216 goto fail1;
217
218 wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
219 if (!wacom->irq)
220 goto fail2;
221
222 wacom->usbdev = dev;
223 wacom->dev = input_dev;
224 usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
225 strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
226
227 wacom_wac->features = get_wacom_feature(id);
228 if (wacom_wac->features->pktlen > 10)
229 BUG();
230
231 input_dev->name = wacom_wac->features->name;
232 wacom->wacom_wac = wacom_wac;
233 usb_to_input_id(dev, &input_dev->id);
234
235 input_dev->cdev.dev = &intf->dev;
236 input_dev->private = wacom;
237 input_dev->open = wacom_open;
238 input_dev->close = wacom_close;
239
240 input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
241 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
242 input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
243 input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
244 input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
245 input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC);
246
247 wacom_init_input_dev(input_dev, wacom_wac);
248
249 endpoint = &intf->cur_altsetting->endpoint[0].desc;
250
251 usb_fill_int_urb(wacom->irq, dev,
252 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
253 wacom_wac->data, wacom_wac->features->pktlen,
254 wacom_wac->features->irq, wacom, endpoint->bInterval);
255 wacom->irq->transfer_dma = wacom->data_dma;
256 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
257
258 input_register_device(wacom->dev);
259
260 /* Ask the tablet to report tablet data. Repeat until it succeeds */
261 do {
262 rep_data[0] = 2;
263 rep_data[1] = 2;
264 usb_set_report(intf, 3, 2, rep_data, 2);
265 usb_get_report(intf, 3, 2, rep_data, 2);
266 } while (rep_data[1] != 2 && limit++ < 5);
267
268 usb_set_intfdata(intf, wacom);
269 return 0;
270
271fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
272fail1: input_free_device(input_dev);
273 kfree(wacom);
274 kfree(wacom_wac);
275 return -ENOMEM;
276}
277
278static void wacom_disconnect(struct usb_interface *intf)
279{
280 struct wacom *wacom = usb_get_intfdata (intf);
281
282 usb_set_intfdata(intf, NULL);
283 if (wacom) {
284 usb_kill_urb(wacom->irq);
285 input_unregister_device(wacom->dev);
286 usb_free_urb(wacom->irq);
287 usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
288 kfree(wacom);
289 kfree(wacom->wacom_wac);
290 }
291}
292
293static struct usb_driver wacom_driver = {
294 .name = "wacom",
295 .probe = wacom_probe,
296 .disconnect = wacom_disconnect,
297};
298
299static int __init wacom_init(void)
300{
301 int result;
302 wacom_driver.id_table = get_device_table();
303 result = usb_register(&wacom_driver);
304 if (result == 0)
305 info(DRIVER_VERSION ":" DRIVER_DESC);
306 return result;
307}
308
309static void __exit wacom_exit(void)
310{
311 usb_deregister(&wacom_driver);
312}
313
314module_init(wacom_init);
315module_exit(wacom_exit);
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c
new file mode 100644
index 000000000000..85d458c98b6e
--- /dev/null
+++ b/drivers/usb/input/wacom_wac.c
@@ -0,0 +1,646 @@
1/*
2 * drivers/usb/input/wacom_wac.c
3 *
4 * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code
5 *
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 */
14#include "wacom.h"
15#include "wacom_wac.h"
16
17static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
18{
19 unsigned char *data = wacom->data;
20
21 switch (data[0]) {
22 case 1:
23 wacom_input_regs(wcombo);
24 if (data[5] & 0x80) {
25 wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
26 wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;
27 wacom_report_key(wcombo, wacom->tool[0], 1);
28 wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
29 wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
30 wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
31 wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127);
32 wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -127));
33 wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40));
34 } else {
35 wacom_report_key(wcombo, wacom->tool[0], 0);
36 wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */
37 wacom_report_abs(wcombo, ABS_PRESSURE, -1);
38 wacom_report_key(wcombo, BTN_TOUCH, 0);
39 }
40 break;
41 case 2:
42 wacom_input_regs(wcombo);
43 wacom_report_key(wcombo, BTN_TOOL_PEN, 1);
44 wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
45 wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
46 wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
47 wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127);
48 wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
49 wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40));
50 break;
51 default:
52 printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);
53 return 0;
54 }
55 return 1;
56}
57
58static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
59{
60 unsigned char *data = wacom->data;
61 int prox, id, pressure;
62
63 if (data[0] != 2) {
64 dbg("wacom_pl_irq: received unknown report #%d", data[0]);
65 return 0;
66 }
67
68 prox = data[1] & 0x40;
69
70 wacom_input_regs(wcombo);
71
72 id = ERASER_DEVICE_ID;
73 if (prox) {
74
75 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
76 if (wacom->features->pressure_max > 255)
77 pressure = (pressure << 1) | ((data[4] >> 6) & 1);
78 pressure += (wacom->features->pressure_max + 1) / 2;
79
80 /*
81 * if going from out of proximity into proximity select between the eraser
82 * and the pen based on the state of the stylus2 button, choose eraser if
83 * pressed else choose pen. if not a proximity change from out to in, send
84 * an out of proximity for previous tool then a in for new tool.
85 */
86 if (!wacom->tool[0]) {
87 /* Eraser bit set for DTF */
88 if (data[1] & 0x10)
89 wacom->tool[1] = BTN_TOOL_RUBBER;
90 else
91 /* Going into proximity select tool */
92 wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
93 } else {
94 /* was entered with stylus2 pressed */
95 if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
96 /* report out proximity for previous tool */
97 wacom_report_key(wcombo, wacom->tool[1], 0);
98 wacom_input_sync(wcombo);
99 wacom->tool[1] = BTN_TOOL_PEN;
100 return 0;
101 }
102 }
103 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
104 /* Unknown tool selected default to pen tool */
105 wacom->tool[1] = BTN_TOOL_PEN;
106 id = STYLUS_DEVICE_ID;
107 }
108 wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */
109 wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
110 wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
111 wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
112 wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
113
114 wacom_report_key(wcombo, BTN_TOUCH, data[4] & 0x08);
115 wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10);
116 /* Only allow the stylus2 button to be reported for the pen tool. */
117 wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
118 } else {
119 /* report proximity-out of a (valid) tool */
120 if (wacom->tool[1] != BTN_TOOL_RUBBER) {
121 /* Unknown tool selected default to pen tool */
122 wacom->tool[1] = BTN_TOOL_PEN;
123 }
124 wacom_report_key(wcombo, wacom->tool[1], prox);
125 }
126
127 wacom->tool[0] = prox; /* Save proximity state */
128 return 1;
129}
130
131static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
132{
133 unsigned char *data = wacom->data;
134 int id;
135
136 if (data[0] != 2) {
137 printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
138 return 0;
139 }
140
141 wacom_input_regs(wcombo);
142 if (data[1] & 0x04) {
143 wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20);
144 wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08);
145 id = ERASER_DEVICE_ID;
146 } else {
147 wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20);
148 wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
149 id = STYLUS_DEVICE_ID;
150 }
151 wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
152 wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
153 wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
154 wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
155 wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
156 wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
157 return 1;
158}
159
160static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
161{
162 unsigned char *data = wacom->data;
163 int x, y, id, rw;
164
165 if (data[0] != 2) {
166 dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
167 return 0;
168 }
169
170 wacom_input_regs(wcombo);
171
172 id = STYLUS_DEVICE_ID;
173 if (data[1] & 0x10) { /* in prox */
174
175 switch ((data[1] >> 5) & 3) {
176
177 case 0: /* Pen */
178 wacom->tool[0] = BTN_TOOL_PEN;
179 break;
180
181 case 1: /* Rubber */
182 wacom->tool[0] = BTN_TOOL_RUBBER;
183 id = ERASER_DEVICE_ID;
184 break;
185
186 case 2: /* Mouse with wheel */
187 wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
188 if (wacom->features->type == WACOM_G4) {
189 rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
190 wacom_report_rel(wcombo, REL_WHEEL, -rw);
191 } else
192 wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
193 /* fall through */
194
195 case 3: /* Mouse without wheel */
196 wacom->tool[0] = BTN_TOOL_MOUSE;
197 id = CURSOR_DEVICE_ID;
198 wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
199 wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
200 if (wacom->features->type == WACOM_G4)
201 wacom_report_abs(wcombo, ABS_DISTANCE, data[6]);
202 else
203 wacom_report_abs(wcombo, ABS_DISTANCE, data[7]);
204 break;
205 }
206 }
207
208 if (data[1] & 0x90) {
209 x = wacom_le16_to_cpu(&data[2]);
210 y = wacom_le16_to_cpu(&data[4]);
211 wacom_report_abs(wcombo, ABS_X, x);
212 wacom_report_abs(wcombo, ABS_Y, y);
213 if (wacom->tool[0] != BTN_TOOL_MOUSE) {
214 wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
215 wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
216 wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
217 wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
218 }
219 }
220
221 if (data[1] & 0x10)
222 wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
223 else
224 wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
225 wacom_report_key(wcombo, wacom->tool[0], data[1] & 0x10);
226 wacom_input_sync(wcombo);
227
228 /* send pad data */
229 if (wacom->features->type == WACOM_G4) {
230 if ( (wacom->serial[1] & 0xc0) != (data[7] & 0xf8) ) {
231 wacom->id[1] = 1;
232 wacom->serial[1] = (data[7] & 0xf8);
233 wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
234 wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
235 rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
236 wacom_report_rel(wcombo, REL_WHEEL, rw);
237 wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
238 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
239 } else if (wacom->id[1]) {
240 wacom->id[1] = 0;
241 wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
242 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
243 }
244 }
245 return 1;
246}
247
248static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
249{
250 unsigned char *data = wacom->data;
251 int idx;
252
253 /* tool number */
254 idx = data[1] & 0x01;
255
256 /* Enter report */
257 if ((data[1] & 0xfc) == 0xc0) {
258 /* serial number of the tool */
259 wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
260 (data[4] << 20) + (data[5] << 12) +
261 (data[6] << 4) + (data[7] >> 4);
262
263 wacom->id[idx] = (data[2] << 4) | (data[3] >> 4);
264 switch (wacom->id[idx]) {
265 case 0x812: /* Inking pen */
266 case 0x801: /* Intuos3 Inking pen */
267 case 0x012:
268 wacom->tool[idx] = BTN_TOOL_PENCIL;
269 break;
270 case 0x822: /* Pen */
271 case 0x842:
272 case 0x852:
273 case 0x823: /* Intuos3 Grip Pen */
274 case 0x813: /* Intuos3 Classic Pen */
275 case 0x885: /* Intuos3 Marker Pen */
276 case 0x022:
277 wacom->tool[idx] = BTN_TOOL_PEN;
278 break;
279 case 0x832: /* Stroke pen */
280 case 0x032:
281 wacom->tool[idx] = BTN_TOOL_BRUSH;
282 break;
283 case 0x007: /* Mouse 4D and 2D */
284 case 0x09c:
285 case 0x094:
286 case 0x017: /* Intuos3 2D Mouse */
287 wacom->tool[idx] = BTN_TOOL_MOUSE;
288 break;
289 case 0x096: /* Lens cursor */
290 case 0x097: /* Intuos3 Lens cursor */
291 wacom->tool[idx] = BTN_TOOL_LENS;
292 break;
293 case 0x82a: /* Eraser */
294 case 0x85a:
295 case 0x91a:
296 case 0xd1a:
297 case 0x0fa:
298 case 0x82b: /* Intuos3 Grip Pen Eraser */
299 case 0x81b: /* Intuos3 Classic Pen Eraser */
300 case 0x91b: /* Intuos3 Airbrush Eraser */
301 wacom->tool[idx] = BTN_TOOL_RUBBER;
302 break;
303 case 0xd12:
304 case 0x912:
305 case 0x112:
306 case 0x913: /* Intuos3 Airbrush */
307 wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
308 break;
309 default: /* Unknown tool */
310 wacom->tool[idx] = BTN_TOOL_PEN;
311 }
312 /* only large I3 support Lens Cursor */
313 if(!((wacom->tool[idx] == BTN_TOOL_LENS) &&
314 (wacom->features->type == INTUOS3))) {
315 wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
316 wacom_report_key(wcombo, wacom->tool[idx], 1);
317 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
318 return 2;
319 }
320 return 1;
321 }
322
323 /* Exit report */
324 if ((data[1] & 0xfe) == 0x80) {
325 wacom_report_key(wcombo, wacom->tool[idx], 0);
326 wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
327 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
328 return 2;
329 }
330 return 0;
331}
332
333static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo)
334{
335 unsigned char *data = wacom->data;
336 unsigned int t;
337
338 /* general pen packet */
339 if ((data[1] & 0xb8) == 0xa0) {
340 t = (data[6] << 2) | ((data[7] >> 6) & 3);
341 wacom_report_abs(wcombo, ABS_PRESSURE, t);
342 wacom_report_abs(wcombo, ABS_TILT_X,
343 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
344 wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f);
345 wacom_report_key(wcombo, BTN_STYLUS, data[1] & 2);
346 wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 4);
347 wacom_report_key(wcombo, BTN_TOUCH, t > 10);
348 }
349
350 /* airbrush second packet */
351 if ((data[1] & 0xbc) == 0xb4) {
352 wacom_report_abs(wcombo, ABS_WHEEL,
353 (data[6] << 2) | ((data[7] >> 6) & 3));
354 wacom_report_abs(wcombo, ABS_TILT_X,
355 ((data[7] << 1) & 0x7e) | (data[8] >> 7));
356 wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f);
357 }
358 return;
359}
360
361static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
362{
363 unsigned char *data = wacom->data;
364 unsigned int t;
365 int idx, result;
366
367 if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
368 dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
369 return 0;
370 }
371
372 wacom_input_regs(wcombo);
373
374 /* tool number */
375 idx = data[1] & 0x01;
376
377 /* pad packets. Works as a second tool and is always in prox */
378 if (data[0] == 12) {
379 /* initiate the pad as a device */
380 if (wacom->tool[1] != BTN_TOOL_FINGER)
381 wacom->tool[1] = BTN_TOOL_FINGER;
382
383 wacom_report_key(wcombo, BTN_0, (data[5] & 0x01));
384 wacom_report_key(wcombo, BTN_1, (data[5] & 0x02));
385 wacom_report_key(wcombo, BTN_2, (data[5] & 0x04));
386 wacom_report_key(wcombo, BTN_3, (data[5] & 0x08));
387 wacom_report_key(wcombo, BTN_4, (data[6] & 0x01));
388 wacom_report_key(wcombo, BTN_5, (data[6] & 0x02));
389 wacom_report_key(wcombo, BTN_6, (data[6] & 0x04));
390 wacom_report_key(wcombo, BTN_7, (data[6] & 0x08));
391 wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
392 wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
393
394 if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) | data[2])
395 wacom_report_key(wcombo, wacom->tool[1], 1);
396 else
397 wacom_report_key(wcombo, wacom->tool[1], 0);
398 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff);
399 return 1;
400 }
401
402 /* process in/out prox events */
403 result = wacom_intuos_inout(wacom, wcombo);
404 if (result)
405 return result-1;
406
407 /* Cintiq doesn't send data when RDY bit isn't set */
408 if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
409 return 0;
410
411 if (wacom->features->type >= INTUOS3) {
412 wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
413 wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
414 wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
415 } else {
416 wacom_report_abs(wcombo, ABS_X, wacom_be16_to_cpu(&data[2]));
417 wacom_report_abs(wcombo, ABS_Y, wacom_be16_to_cpu(&data[4]));
418 wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
419 }
420
421 /* process general packets */
422 wacom_intuos_general(wacom, wcombo);
423
424 /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
425 if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
426
427 if (data[1] & 0x02) {
428 /* Rotation packet */
429 if (wacom->features->type >= INTUOS3) {
430 /* I3 marker pen rotation reported as wheel
431 * due to valuator limitation
432 */
433 t = (data[6] << 3) | ((data[7] >> 5) & 7);
434 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
435 ((t-1) / 2 + 450)) : (450 - t / 2) ;
436 wacom_report_abs(wcombo, ABS_WHEEL, t);
437 } else {
438 /* 4D mouse rotation packet */
439 t = (data[6] << 3) | ((data[7] >> 5) & 7);
440 wacom_report_abs(wcombo, ABS_RZ, (data[7] & 0x20) ?
441 ((t - 1) / 2) : -t / 2);
442 }
443
444 } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
445 /* 4D mouse packet */
446 wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01);
447 wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
448 wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04);
449
450 wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x20);
451 wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x10);
452 t = (data[6] << 2) | ((data[7] >> 6) & 3);
453 wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
454
455 } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
456 /* 2D mouse packet */
457 wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04);
458 wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08);
459 wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10);
460 wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01)
461 - ((data[8] & 0x02) >> 1));
462
463 /* I3 2D mouse side buttons */
464 if (wacom->features->type == INTUOS3) {
465 wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40);
466 wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20);
467 }
468
469 } else if (wacom->features->type < INTUOS3) {
470 /* Lens cursor packets */
471 wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01);
472 wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
473 wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04);
474 wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x10);
475 wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x08);
476 }
477 }
478
479 wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
480 wacom_report_key(wcombo, wacom->tool[idx], 1);
481 wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
482 return 1;
483}
484
485int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
486{
487 switch (wacom_wac->features->type) {
488 case PENPARTNER:
489 return (wacom_penpartner_irq(wacom_wac, wcombo));
490 break;
491 case PL:
492 return (wacom_pl_irq(wacom_wac, wcombo));
493 break;
494 case WACOM_G4:
495 case GRAPHIRE:
496 return (wacom_graphire_irq(wacom_wac, wcombo));
497 break;
498 case PTU:
499 return (wacom_ptu_irq(wacom_wac, wcombo));
500 break;
501 case INTUOS:
502 case INTUOS3:
503 case INTUOS3L:
504 case CINTIQ:
505 return (wacom_intuos_irq(wacom_wac, wcombo));
506 break;
507 default:
508 return 0;
509 }
510 return 0;
511}
512
513void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
514{
515 switch (wacom_wac->features->type) {
516 case WACOM_G4:
517 input_dev_g4(input_dev, wacom_wac);
518 /* fall through */
519 case GRAPHIRE:
520 input_dev_g(input_dev, wacom_wac);
521 break;
522 case INTUOS3:
523 case INTUOS3L:
524 case CINTIQ:
525 input_dev_i3(input_dev, wacom_wac);
526 /* fall through */
527 case INTUOS:
528 input_dev_i(input_dev, wacom_wac);
529 break;
530 case PL:
531 case PTU:
532 input_dev_pl(input_dev, wacom_wac);
533 break;
534 case PENPARTNER:
535 input_dev_pt(input_dev, wacom_wac);
536 break;
537 }
538 return;
539}
540
541static struct wacom_features wacom_features[] = {
542 { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_sys_irq },
543 { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_sys_irq },
544 { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_sys_irq },
545 { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_sys_irq },
546 { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_sys_irq },
547 { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_sys_irq },
548 { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_sys_irq },
549 { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_sys_irq },
550 { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_sys_irq },
551 { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_sys_irq },
552 { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_sys_irq },
553 { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 32, GRAPHIRE, wacom_sys_irq },
554 { "Wacom PenPartner2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_sys_irq },
555 { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_sys_irq},
556 { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq },
557 { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_sys_irq },
558 { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_sys_irq },
559 { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_sys_irq},
560 { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_sys_irq },
561 { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_sys_irq },
562 { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_sys_irq },
563 { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_sys_irq },
564 { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_sys_irq },
565 { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_sys_irq },
566 { "Wacom PL700", 8, 6758, 5406, 511, 32, PL, wacom_sys_irq },
567 { "Wacom PL510", 8, 6282, 4762, 511, 32, PL, wacom_sys_irq },
568 { "Wacom DTU710", 8, 34080, 27660, 511, 32, PL, wacom_sys_irq },
569 { "Wacom DTF521", 8, 6282, 4762, 511, 32, PL, wacom_sys_irq },
570 { "Wacom DTF720", 8, 6858, 5506, 511, 32, PL, wacom_sys_irq },
571 { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PTU, wacom_sys_irq },
572 { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_sys_irq },
573 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq },
574 { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_sys_irq },
575 { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_sys_irq },
576 { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_sys_irq },
577 { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_sys_irq },
578 { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_sys_irq },
579 { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_sys_irq },
580 { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 15, INTUOS3L, wacom_sys_irq },
581 { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 15, INTUOS3L, wacom_sys_irq },
582 { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 15, INTUOS3, wacom_sys_irq },
583 { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_sys_irq },
584 { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_sys_irq },
585 { }
586};
587
588static struct usb_device_id wacom_ids[] = {
589 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) },
590 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) },
591 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) },
592 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) },
593 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) },
594 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
595 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) },
596 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
597 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
598 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
599 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
600 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
601 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
602 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
603 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
604 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
605 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) },
606 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) },
607 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) },
608 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) },
609 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) },
610 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) },
611 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) },
612 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) },
613 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
614 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
615 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
616 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
617 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) },
618 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
619 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
620 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
621 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) },
622 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) },
623 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) },
624 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
625 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
626 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
627 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) },
628 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) },
629 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
630 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
631 { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
632 { }
633};
634
635const struct usb_device_id * get_device_table(void) {
636 const struct usb_device_id * id_table = wacom_ids;
637 return id_table;
638}
639
640struct wacom_features * get_wacom_feature(const struct usb_device_id * id) {
641 int index = id - wacom_ids;
642 struct wacom_features *wf = &wacom_features[index];
643 return wf;
644}
645
646MODULE_DEVICE_TABLE(usb, wacom_ids);
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/usb/input/wacom_wac.h
new file mode 100644
index 000000000000..ceae7bf59d9f
--- /dev/null
+++ b/drivers/usb/input/wacom_wac.h
@@ -0,0 +1,48 @@
1/*
2 * drivers/usb/input/wacom_wac.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#ifndef WACOM_WAC_H
10#define WACOM_WAC_H
11
12#define STYLUS_DEVICE_ID 0x02
13#define CURSOR_DEVICE_ID 0x06
14#define ERASER_DEVICE_ID 0x0A
15
16enum {
17 PENPARTNER = 0,
18 GRAPHIRE,
19 WACOM_G4,
20 PTU,
21 PL,
22 INTUOS,
23 INTUOS3,
24 INTUOS3L,
25 CINTIQ,
26 MAX_TYPE
27};
28
29struct wacom_features {
30 char *name;
31 int pktlen;
32 int x_max;
33 int y_max;
34 int pressure_max;
35 int distance_max;
36 int type;
37 usb_complete_t irq;
38};
39
40struct wacom_wac {
41 signed char *data;
42 int tool[2];
43 int id[2];
44 __u32 serial[2];
45 struct wacom_features *features;
46};
47
48#endif
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 7b45fd3de911..7291e7a2717b 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -971,7 +971,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
971 DRIVER_VERSION, sizeof(DRIVER_VERSION)); 971 DRIVER_VERSION, sizeof(DRIVER_VERSION));
972 972
973 /* Register sysfs hooks (don't care about failure) */ 973 /* Register sysfs hooks (don't care about failure) */
974 sysfs_create_group(&intf->dev.kobj, &yld_attr_group); 974 ret = sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
975 return 0; 975 return 0;
976} 976}
977 977