aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/input
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 11:51:43 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 11:51:43 -0700
commit393bfca19ecdce60a8d9a4d2577cac11ca924a25 (patch)
treea609269ca3332b8f2f7b2b4a2c96f7d824c0e639 /drivers/usb/input
parentdf6d3916f3b7b7e2067567a256dd4f0c1ea854a2 (diff)
parentba0acb5ee318901646f82c134cca2e4de0c43934 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
* master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: Input: move USB miscellaneous devices under drivers/input/misc Input: move USB mice under drivers/input/mouse Input: move USB gamepads under drivers/input/joystick Input: move USB touchscreens under drivers/input/touchscreen Input: move USB tablets under drivers/input/tablet Input: i8042 - fix AUX port detection with some chips Input: aaed2000_kbd - convert to use polldev library Input: drivers/usb/input - usb_buffer_free() cleanup Input: synaptics - don't complain about failed resets Input: pull input.h into uinpit.h Input: drivers/usb/input - fix sparse warnings (signedness) Input: evdev - fix some sparse warnings (signedness, shadowing) Input: drivers/joystick - fix various sparse warnings Input: force feedback - make sure effect is present before playing
Diffstat (limited to 'drivers/usb/input')
-rw-r--r--drivers/usb/input/Kconfig225
-rw-r--r--drivers/usb/input/Makefile24
-rw-r--r--drivers/usb/input/acecad.c289
-rw-r--r--drivers/usb/input/aiptek.c2236
-rw-r--r--drivers/usb/input/appletouch.c706
-rw-r--r--drivers/usb/input/ati_remote.c862
-rw-r--r--drivers/usb/input/ati_remote2.c545
-rw-r--r--drivers/usb/input/gtco.c1055
-rw-r--r--drivers/usb/input/kbtab.c226
-rw-r--r--drivers/usb/input/keyspan_remote.c592
-rw-r--r--drivers/usb/input/map_to_7segment.h189
-rw-r--r--drivers/usb/input/powermate.c465
-rw-r--r--drivers/usb/input/usbtouchscreen.c840
-rw-r--r--drivers/usb/input/wacom.h131
-rw-r--r--drivers/usb/input/wacom_sys.c318
-rw-r--r--drivers/usb/input/wacom_wac.c675
-rw-r--r--drivers/usb/input/wacom_wac.h49
-rw-r--r--drivers/usb/input/xpad.c433
-rw-r--r--drivers/usb/input/yealink.c1005
-rw-r--r--drivers/usb/input/yealink.h220
20 files changed, 0 insertions, 11085 deletions
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
deleted file mode 100644
index a792e42f58a..00000000000
--- a/drivers/usb/input/Kconfig
+++ /dev/null
@@ -1,225 +0,0 @@
-#
-# USB Input driver configuration
-#
-comment "USB Input Devices"
- depends on USB
-
-config USB_AIPTEK
- tristate "Aiptek 6000U/8000U tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Aiptek 6000U
- or Aiptek 8000U tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called aiptek.
-
-config USB_WACOM
- tristate "Wacom Intuos/Graphire tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Wacom Intuos
- or Graphire tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called wacom.
-
-config USB_ACECAD
- tristate "Acecad Flair tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the Acecad Flair
- tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called acecad.
-
-config USB_KBTAB
- tristate "KB Gear JamStudio tablet support"
- depends on USB && INPUT
- help
- Say Y here if you want to use the USB version of the KB Gear
- JamStudio tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called kbtab.
-
-config USB_POWERMATE
- tristate "Griffin PowerMate and Contour Jog support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use Griffin PowerMate or Contour Jog devices.
- These are aluminum dials which can measure clockwise and anticlockwise
- rotation. The dial also acts as a pushbutton. The base contains an LED
- which can be instructed to pulse or to switch to a particular intensity.
-
- You can download userspace tools from
- <http://sowerbutts.com/powermate/>.
-
- To compile this driver as a module, choose M here: the
- module will be called powermate.
-
-config USB_TOUCHSCREEN
- tristate "USB Touchscreen Driver"
- depends on USB && INPUT
- ---help---
- USB Touchscreen driver for:
- - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700)
- - PanJit TouchSet USB
- - 3M MicroTouch USB (EX II series)
- - ITM
- - some other eTurboTouch
- - Gunze AHL61
- - DMC TSC-10/25
-
- Have a look at <http://linux.chapter7.ch/touchkit/> for
- a usage description and the required user-space stuff.
-
- To compile this driver as a module, choose M here: the
- module will be called usbtouchscreen.
-
-config USB_TOUCHSCREEN_EGALAX
- default y
- bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_PANJIT
- default y
- bool "PanJit device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_3M
- default y
- bool "3M/Microtouch EX II series device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_ITM
- default y
- bool "ITM device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_ETURBO
- default y
- bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_GUNZE
- default y
- bool "Gunze AHL61 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_TOUCHSCREEN_DMC_TSC10
- default y
- bool "DMC TSC-10/25 device support" if EMBEDDED
- depends on USB_TOUCHSCREEN
-
-config USB_YEALINK
- tristate "Yealink usb-p1k voip phone"
- depends on USB && INPUT && EXPERIMENTAL
- ---help---
- Say Y here if you want to enable keyboard and LCD functions of the
- Yealink usb-p1k usb phones. The audio part is enabled by the generic
- usb sound driver, so you might want to enable that as well.
-
- For information about how to use these additional functions, see
- <file:Documentation/input/yealink.txt>.
-
- To compile this driver as a module, choose M here: the module will be
- called yealink.
-
-config USB_XPAD
- tristate "X-Box gamepad support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use the X-Box pad with your computer.
- Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV)
- and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
-
- For information about how to connect the X-Box pad to USB, see
- <file:Documentation/input/xpad.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called xpad.
-
-config USB_ATI_REMOTE
- tristate "ATI / X10 USB RF remote control"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an ATI or X10 "Lola" USB remote control.
- These are RF remotes with USB receivers.
- The ATI remote comes with many of ATI's All-In-Wonder video cards.
- The X10 "Lola" remote is available at:
- <http://www.x10.com/products/lola_sg1.htm>
- This driver provides mouse pointer, left and right mouse buttons,
- and maps all the other remote buttons to keypress events.
-
- To compile this driver as a module, choose M here: the module will be
- called ati_remote.
-
-config USB_ATI_REMOTE2
- tristate "ATI / Philips USB RF remote control"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an ATI or Philips USB RF remote control.
- These are RF remotes with USB receivers.
- ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
- and is also available as a separate product.
- This driver provides mouse pointer, left and right mouse buttons,
- and maps all the other remote buttons to keypress events.
-
- To compile this driver as a module, choose M here: the module will be
- called ati_remote2.
-
-config USB_KEYSPAN_REMOTE
- tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
- depends on USB && INPUT && EXPERIMENTAL
- ---help---
- Say Y here if you want to use a Keyspan DMR USB remote control.
- Currently only the UIA-11 type of receiver has been tested. The tag
- on the receiver that connects to the USB port should have a P/N that
- will tell you what type of DMR you have. The UIA-10 type is not
- supported at this time. This driver maps all buttons to keypress
- events.
-
- To compile this driver as a module, choose M here: the module will
- be called keyspan_remote.
-
-config USB_APPLETOUCH
- tristate "Apple USB Touchpad support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use an Apple USB Touchpad.
-
- These are the touchpads that can be found on post-February 2005
- Apple Powerbooks (prior models have a Synaptics touchpad connected
- to the ADB bus).
-
- This driver provides a basic mouse driver but can be interfaced
- with the synaptics X11 driver to provide acceleration and
- scrolling in X11.
-
- For further information, see
- <file:Documentation/input/appletouch.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called appletouch.
-
-config USB_GTCO
- tristate "GTCO CalComp/InterWrite USB Support"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use the USB version of the GTCO
- CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support"
- (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
- (CONFIG_INPUT_EVDEV) as well.
-
- To compile this driver as a module, choose M here: the
- module will be called gtco.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
deleted file mode 100644
index 284a0734e0c..00000000000
--- a/drivers/usb/input/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Makefile for the USB input drivers
-#
-
-# Multipart objects.
-wacom-objs := wacom_wac.o wacom_sys.o
-
-obj-$(CONFIG_USB_AIPTEK) += aiptek.o
-obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o
-obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o
-obj-$(CONFIG_USB_KBTAB) += kbtab.o
-obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o
-obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o
-obj-$(CONFIG_USB_POWERMATE) += powermate.o
-obj-$(CONFIG_USB_WACOM) += wacom.o
-obj-$(CONFIG_USB_ACECAD) += acecad.o
-obj-$(CONFIG_USB_YEALINK) += yealink.o
-obj-$(CONFIG_USB_XPAD) += xpad.o
-obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
-obj-$(CONFIG_USB_GTCO) += gtco.o
-
-ifeq ($(CONFIG_USB_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
deleted file mode 100644
index be8e9243c06..00000000000
--- a/drivers/usb/input/acecad.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (c) 2001-2005 Edouard TISSERANT <edouard.tisserant@wanadoo.fr>
- * Copyright (c) 2004-2005 Stephane VOLTZ <svoltz@numericable.fr>
- *
- * USB Acecad "Acecad Flair" tablet support
- *
- * Changelog:
- * v3.2 - Added sysfs support
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v3.2"
-#define DRIVER_DESC "USB Acecad Flair tablet driver"
-#define DRIVER_LICENSE "GPL"
-#define DRIVER_AUTHOR "Edouard TISSERANT <edouard.tisserant@wanadoo.fr>"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-#define USB_VENDOR_ID_ACECAD 0x0460
-#define USB_DEVICE_ID_FLAIR 0x0004
-#define USB_DEVICE_ID_302 0x0008
-
-struct usb_acecad {
- char name[128];
- char phys[64];
- struct usb_device *usbdev;
- struct input_dev *input;
- struct urb *irq;
-
- signed char *data;
- dma_addr_t data_dma;
-};
-
-static void usb_acecad_irq(struct urb *urb)
-{
- struct usb_acecad *acecad = urb->context;
- unsigned char *data = acecad->data;
- struct input_dev *dev = acecad->input;
- int prox, status;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- goto resubmit;
- }
-
- prox = (data[0] & 0x04) >> 2;
- input_report_key(dev, BTN_TOOL_PEN, prox);
-
- if (prox) {
- int x = data[1] | (data[2] << 8);
- int y = data[3] | (data[4] << 8);
- /* Pressure should compute the same way for flair and 302 */
- int pressure = data[5] | (data[6] << 8);
- int touch = data[0] & 0x01;
- int stylus = (data[0] & 0x10) >> 4;
- int stylus2 = (data[0] & 0x20) >> 5;
- input_report_abs(dev, ABS_X, x);
- input_report_abs(dev, ABS_Y, y);
- input_report_abs(dev, ABS_PRESSURE, pressure);
- input_report_key(dev, BTN_TOUCH, touch);
- input_report_key(dev, BTN_STYLUS, stylus);
- input_report_key(dev, BTN_STYLUS2, stylus2);
- }
-
- /* event termination */
- input_sync(dev);
-
-resubmit:
- status = usb_submit_urb(urb, GFP_ATOMIC);
- if (status)
- err("can't resubmit intr, %s-%s/input0, status %d",
- acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status);
-}
-
-static int usb_acecad_open(struct input_dev *dev)
-{
- struct usb_acecad *acecad = input_get_drvdata(dev);
-
- acecad->irq->dev = acecad->usbdev;
- if (usb_submit_urb(acecad->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usb_acecad_close(struct input_dev *dev)
-{
- struct usb_acecad *acecad = input_get_drvdata(dev);
-
- usb_kill_urb(acecad->irq);
-}
-
-static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface = intf->cur_altsetting;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_acecad *acecad;
- struct input_dev *input_dev;
- int pipe, maxp;
- int err = -ENOMEM;
-
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
-
- if (!usb_endpoint_is_int_in(endpoint))
- return -ENODEV;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!acecad || !input_dev) {
- err = -ENOMEM;
- goto fail1;
- }
-
- acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma);
- if (!acecad->data) {
- err= -ENOMEM;
- goto fail1;
- }
-
- acecad->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!acecad->irq) {
- err = -ENOMEM;
- goto fail2;
- }
-
- acecad->usbdev = dev;
- acecad->input = input_dev;
-
- if (dev->manufacturer)
- strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(acecad->name, " ", sizeof(acecad->name));
- strlcat(acecad->name, dev->product, sizeof(acecad->name));
- }
-
- usb_make_path(dev, acecad->phys, sizeof(acecad->phys));
- strlcat(acecad->phys, "/input0", sizeof(acecad->phys));
-
- input_dev->name = acecad->name;
- input_dev->phys = acecad->phys;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, acecad);
-
- input_dev->open = usb_acecad_open;
- input_dev->close = usb_acecad_close;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
- input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
-
- switch (id->driver_info) {
- case 0:
- input_dev->absmax[ABS_X] = 5000;
- input_dev->absmax[ABS_Y] = 3750;
- input_dev->absmax[ABS_PRESSURE] = 512;
- if (!strlen(acecad->name))
- snprintf(acecad->name, sizeof(acecad->name),
- "USB Acecad Flair Tablet %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
- break;
- case 1:
- input_dev->absmax[ABS_X] = 3000;
- input_dev->absmax[ABS_Y] = 2250;
- input_dev->absmax[ABS_PRESSURE] = 1024;
- if (!strlen(acecad->name))
- snprintf(acecad->name, sizeof(acecad->name),
- "USB Acecad 302 Tablet %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
- break;
- }
-
- input_dev->absfuzz[ABS_X] = 4;
- input_dev->absfuzz[ABS_Y] = 4;
-
- usb_fill_int_urb(acecad->irq, dev, pipe,
- acecad->data, maxp > 8 ? 8 : maxp,
- usb_acecad_irq, acecad, endpoint->bInterval);
- acecad->irq->transfer_dma = acecad->data_dma;
- acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- err = input_register_device(acecad->input);
- if (err)
- goto fail2;
-
- usb_set_intfdata(intf, acecad);
-
- return 0;
-
- fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
- fail1: input_free_device(input_dev);
- kfree(acecad);
- return err;
-}
-
-static void usb_acecad_disconnect(struct usb_interface *intf)
-{
- struct usb_acecad *acecad = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (acecad) {
- usb_kill_urb(acecad->irq);
- input_unregister_device(acecad->input);
- usb_free_urb(acecad->irq);
- usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
- kfree(acecad);
- }
-}
-
-static struct usb_device_id usb_acecad_id_table [] = {
- { USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_FLAIR), .driver_info = 0 },
- { USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_302), .driver_info = 1 },
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, usb_acecad_id_table);
-
-static struct usb_driver usb_acecad_driver = {
- .name = "usb_acecad",
- .probe = usb_acecad_probe,
- .disconnect = usb_acecad_disconnect,
- .id_table = usb_acecad_id_table,
-};
-
-static int __init usb_acecad_init(void)
-{
- int result = usb_register(&usb_acecad_driver);
- if (result == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
- return result;
-}
-
-static void __exit usb_acecad_exit(void)
-{
- usb_deregister(&usb_acecad_driver);
-}
-
-module_init(usb_acecad_init);
-module_exit(usb_acecad_exit);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
deleted file mode 100644
index cc0a498763d..00000000000
--- a/drivers/usb/input/aiptek.c
+++ /dev/null
@@ -1,2236 +0,0 @@
-/*
- * Native support for the Aiptek HyperPen USB Tablets
- * (4000U/5000U/6000U/8000U/12000U)
- *
- * Copyright (c) 2001 Chris Atenasio <chris@crud.net>
- * Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net>
- *
- * based on wacom.c by
- * Vojtech Pavlik <vojtech@suse.cz>
- * Andreas Bach Aaen <abach@stofanet.dk>
- * Clifford Wolf <clifford@clifford.at>
- * Sam Mosel <sam.mosel@computer.org>
- * James E. Blair <corvus@gnu.org>
- * Daniel Egger <egger@suse.de>
- *
- * Many thanks to Oliver Kuechemann for his support.
- *
- * ChangeLog:
- * v0.1 - Initial release
- * v0.2 - Hack to get around fake event 28's. (Bryan W. Headley)
- * v0.3 - Make URB dynamic (Bryan W. Headley, Jun-8-2002)
- * Released to Linux 2.4.19 and 2.5.x
- * v0.4 - Rewrote substantial portions of the code to deal with
- * corrected control sequences, timing, dynamic configuration,
- * support of 6000U - 12000U, procfs, and macro key support
- * (Jan-1-2003 - Feb-5-2003, Bryan W. Headley)
- * v1.0 - Added support for diagnostic messages, count of messages
- * received from URB - Mar-8-2003, Bryan W. Headley
- * v1.1 - added support for tablet resolution, changed DV and proximity
- * some corrections - Jun-22-2003, martin schneebacher
- * - Added support for the sysfs interface, deprecating the
- * procfs interface for 2.5.x kernel. Also added support for
- * Wheel command. Bryan W. Headley July-15-2003.
- * v1.2 - Reworked jitter timer as a kernel thread.
- * Bryan W. Headley November-28-2003/Jan-10-2004.
- * v1.3 - Repaired issue of kernel thread going nuts on single-processor
- * machines, introduced programmableDelay as a command line
- * parameter. Feb 7 2004, Bryan W. Headley.
- * v1.4 - Re-wire jitter so it does not require a thread. Courtesy of
- * Rene van Paassen. Added reporting of physical pointer device
- * (e.g., stylus, mouse in reports 2, 3, 4, 5. We don't know
- * for reports 1, 6.)
- * what physical device reports for reports 1, 6.) Also enabled
- * MOUSE and LENS tool button modes. Renamed "rubber" to "eraser".
- * Feb 20, 2004, Bryan W. Headley.
- * v1.5 - Added previousJitterable, so we don't do jitter delay when the
- * user is holding a button down for periods of time.
- *
- * NOTE:
- * This kernel driver is augmented by the "Aiptek" XFree86 input
- * driver for your X server, as well as the Gaiptek GUI Front-end
- * "Tablet Manager".
- * These three products are highly interactive with one another,
- * so therefore it's easier to document them all as one subsystem.
- * Please visit the project's "home page", located at,
- * http://aiptektablet.sourceforge.net.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-#include <asm/uaccess.h>
-#include <asm/unaligned.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.5 (May-15-2004)"
-#define DRIVER_AUTHOR "Bryan W. Headley/Chris Atenasio"
-#define DRIVER_DESC "Aiptek HyperPen USB Tablet Driver (Linux 2.6.x)"
-
-/*
- * Aiptek status packet:
- *
- * (returned as Report 1 - relative coordinates from mouse and stylus)
- *
- * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 0 0 1
- * byte1 0 0 0 0 0 BS2 BS Tip
- * byte2 X7 X6 X5 X4 X3 X2 X1 X0
- * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- *
- * (returned as Report 2 - absolute coordinates from the stylus)
- *
- * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 0 1 0
- * byte1 X7 X6 X5 X4 X3 X2 X1 X0
- * byte2 X15 X14 X13 X12 X11 X10 X9 X8
- * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- * byte4 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8
- * byte5 * * * BS2 BS1 Tip IR DV
- * byte6 P7 P6 P5 P4 P3 P2 P1 P0
- * byte7 P15 P14 P13 P12 P11 P10 P9 P8
- *
- * (returned as Report 3 - absolute coordinates from the mouse)
- *
- * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 0 1 0
- * byte1 X7 X6 X5 X4 X3 X2 X1 X0
- * byte2 X15 X14 X13 X12 X11 X10 X9 X8
- * byte3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- * byte4 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8
- * byte5 * * * BS2 BS1 Tip IR DV
- * byte6 P7 P6 P5 P4 P3 P2 P1 P0
- * byte7 P15 P14 P13 P12 P11 P10 P9 P8
- *
- * (returned as Report 4 - macrokeys from the stylus)
- *
- * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 1 0 0
- * byte1 0 0 0 BS2 BS Tip IR DV
- * byte2 0 0 0 0 0 0 1 0
- * byte3 0 0 0 K4 K3 K2 K1 K0
- * byte4 P7 P6 P5 P4 P3 P2 P1 P0
- * byte5 P15 P14 P13 P12 P11 P10 P9 P8
- *
- * (returned as Report 5 - macrokeys from the mouse)
- *
- * bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
- * byte0 0 0 0 0 0 1 0 0
- * byte1 0 0 0 BS2 BS Tip IR DV
- * byte2 0 0 0 0 0 0 1 0
- * byte3 0 0 0 K4 K3 K2 K1 K0
- * byte4 P7 P6 P5 P4 P3 P2 P1 P0
- * byte5 P15 P14 P13 P12 P11 P10 P9 P8
- *
- * IR: In Range = Proximity on
- * DV = Data Valid
- * BS = Barrel Switch (as in, macro keys)
- * BS2 also referred to as Tablet Pick
- *
- * Command Summary:
- *
- * Use report_type CONTROL (3)
- * Use report_id 2
- *
- * Command/Data Description Return Bytes Return Value
- * 0x10/0x00 SwitchToMouse 0
- * 0x10/0x01 SwitchToTablet 0
- * 0x18/0x04 SetResolution 0
- * 0x12/0xFF AutoGainOn 0
- * 0x17/0x00 FilterOn 0
- * 0x01/0x00 GetXExtension 2 MaxX
- * 0x01/0x01 GetYExtension 2 MaxY
- * 0x02/0x00 GetModelCode 2 ModelCode = LOBYTE
- * 0x03/0x00 GetODMCode 2 ODMCode
- * 0x08/0x00 GetPressureLevels 2 =512
- * 0x04/0x00 GetFirmwareVersion 2 Firmware Version
- * 0x11/0x02 EnableMacroKeys 0
- *
- * To initialize the tablet:
- *
- * (1) Send Resolution500LPI (Command)
- * (2) Query for Model code (Option Report)
- * (3) Query for ODM code (Option Report)
- * (4) Query for firmware (Option Report)
- * (5) Query for GetXExtension (Option Report)
- * (6) Query for GetYExtension (Option Report)
- * (7) Query for GetPressureLevels (Option Report)
- * (8) SwitchToTablet for Absolute coordinates, or
- * SwitchToMouse for Relative coordinates (Command)
- * (9) EnableMacroKeys (Command)
- * (10) FilterOn (Command)
- * (11) AutoGainOn (Command)
- *
- * (Step 9 can be omitted, but you'll then have no function keys.)
- */
-
-#define USB_VENDOR_ID_AIPTEK 0x08ca
-#define USB_REQ_GET_REPORT 0x01
-#define USB_REQ_SET_REPORT 0x09
-
- /* PointerMode codes
- */
-#define AIPTEK_POINTER_ONLY_MOUSE_MODE 0
-#define AIPTEK_POINTER_ONLY_STYLUS_MODE 1
-#define AIPTEK_POINTER_EITHER_MODE 2
-
-#define AIPTEK_POINTER_ALLOW_MOUSE_MODE(a) \
- (a == AIPTEK_POINTER_ONLY_MOUSE_MODE || \
- a == AIPTEK_POINTER_EITHER_MODE)
-#define AIPTEK_POINTER_ALLOW_STYLUS_MODE(a) \
- (a == AIPTEK_POINTER_ONLY_STYLUS_MODE || \
- a == AIPTEK_POINTER_EITHER_MODE)
-
- /* CoordinateMode code
- */
-#define AIPTEK_COORDINATE_RELATIVE_MODE 0
-#define AIPTEK_COORDINATE_ABSOLUTE_MODE 1
-
- /* XTilt and YTilt values
- */
-#define AIPTEK_TILT_MIN (-128)
-#define AIPTEK_TILT_MAX 127
-#define AIPTEK_TILT_DISABLE (-10101)
-
- /* Wheel values
- */
-#define AIPTEK_WHEEL_MIN 0
-#define AIPTEK_WHEEL_MAX 1024
-#define AIPTEK_WHEEL_DISABLE (-10101)
-
- /* ToolCode values, which BTW are 0x140 .. 0x14f
- * We have things set up such that if TOOL_BUTTON_FIRED_BIT is
- * not set, we'll send one instance of AIPTEK_TOOL_BUTTON_xxx.
- *
- * Whenever the user resets the value, TOOL_BUTTON_FIRED_BIT will
- * get reset.
- */
-#define TOOL_BUTTON(x) ((x) & 0x14f)
-#define TOOL_BUTTON_FIRED(x) ((x) & 0x200)
-#define TOOL_BUTTON_FIRED_BIT 0x200
- /* toolMode codes
- */
-#define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN
-#define AIPTEK_TOOL_BUTTON_PEN_MODE BTN_TOOL_PEN
-#define AIPTEK_TOOL_BUTTON_PENCIL_MODE BTN_TOOL_PENCIL
-#define AIPTEK_TOOL_BUTTON_BRUSH_MODE BTN_TOOL_BRUSH
-#define AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE BTN_TOOL_AIRBRUSH
-#define AIPTEK_TOOL_BUTTON_ERASER_MODE BTN_TOOL_RUBBER
-#define AIPTEK_TOOL_BUTTON_MOUSE_MODE BTN_TOOL_MOUSE
-#define AIPTEK_TOOL_BUTTON_LENS_MODE BTN_TOOL_LENS
-
- /* Diagnostic message codes
- */
-#define AIPTEK_DIAGNOSTIC_NA 0
-#define AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE 1
-#define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE 2
-#define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED 3
-
- /* Time to wait (in ms) to help mask hand jittering
- * when pressing the stylus buttons.
- */
-#define AIPTEK_JITTER_DELAY_DEFAULT 50
-
- /* Time to wait (in ms) in-between sending the tablet
- * a command and beginning the process of reading the return
- * sequence from the tablet.
- */
-#define AIPTEK_PROGRAMMABLE_DELAY_25 25
-#define AIPTEK_PROGRAMMABLE_DELAY_50 50
-#define AIPTEK_PROGRAMMABLE_DELAY_100 100
-#define AIPTEK_PROGRAMMABLE_DELAY_200 200
-#define AIPTEK_PROGRAMMABLE_DELAY_300 300
-#define AIPTEK_PROGRAMMABLE_DELAY_400 400
-#define AIPTEK_PROGRAMMABLE_DELAY_DEFAULT AIPTEK_PROGRAMMABLE_DELAY_400
-
- /* Mouse button programming
- */
-#define AIPTEK_MOUSE_LEFT_BUTTON 0x01
-#define AIPTEK_MOUSE_RIGHT_BUTTON 0x02
-#define AIPTEK_MOUSE_MIDDLE_BUTTON 0x04
-
- /* Stylus button programming
- */
-#define AIPTEK_STYLUS_LOWER_BUTTON 0x08
-#define AIPTEK_STYLUS_UPPER_BUTTON 0x10
-
- /* Length of incoming packet from the tablet
- */
-#define AIPTEK_PACKET_LENGTH 8
-
- /* We report in EV_MISC both the proximity and
- * whether the report came from the stylus, tablet mouse
- * or "unknown" -- Unknown when the tablet is in relative
- * mode, because we only get report 1's.
- */
-#define AIPTEK_REPORT_TOOL_UNKNOWN 0x10
-#define AIPTEK_REPORT_TOOL_STYLUS 0x20
-#define AIPTEK_REPORT_TOOL_MOUSE 0x40
-
-static int programmableDelay = AIPTEK_PROGRAMMABLE_DELAY_DEFAULT;
-static int jitterDelay = AIPTEK_JITTER_DELAY_DEFAULT;
-
-struct aiptek_features {
- int odmCode; /* Tablet manufacturer code */
- int modelCode; /* Tablet model code (not unique) */
- int firmwareCode; /* prom/eeprom version */
- char usbPath[64 + 1]; /* device's physical usb path */
- char inputPath[64 + 1]; /* input device path */
-};
-
-struct aiptek_settings {
- int pointerMode; /* stylus-, mouse-only or either */
- int coordinateMode; /* absolute/relative coords */
- int toolMode; /* pen, pencil, brush, etc. tool */
- int xTilt; /* synthetic xTilt amount */
- int yTilt; /* synthetic yTilt amount */
- int wheel; /* synthetic wheel amount */
- int stylusButtonUpper; /* stylus upper btn delivers... */
- int stylusButtonLower; /* stylus lower btn delivers... */
- int mouseButtonLeft; /* mouse left btn delivers... */
- int mouseButtonMiddle; /* mouse middle btn delivers... */
- int mouseButtonRight; /* mouse right btn delivers... */
- int programmableDelay; /* delay for tablet programming */
- int jitterDelay; /* delay for hand jittering */
-};
-
-struct aiptek {
- struct input_dev *inputdev; /* input device struct */
- struct usb_device *usbdev; /* usb device struct */
- struct urb *urb; /* urb for incoming reports */
- dma_addr_t data_dma; /* our dma stuffage */
- struct aiptek_features features; /* tablet's array of features */
- struct aiptek_settings curSetting; /* tablet's current programmable */
- struct aiptek_settings newSetting; /* ... and new param settings */
- unsigned int ifnum; /* interface number for IO */
- int diagnostic; /* tablet diagnostic codes */
- unsigned long eventCount; /* event count */
- int inDelay; /* jitter: in jitter delay? */
- unsigned long endDelay; /* jitter: time when delay ends */
- int previousJitterable; /* jitterable prev value */
- unsigned char *data; /* incoming packet data */
-};
-
-/*
- * Permit easy lookup of keyboard events to send, versus
- * the bitmap which comes from the tablet. This hides the
- * issue that the F_keys are not sequentially numbered.
- */
-static const int macroKeyEvents[] = {
- KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
- KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
- KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
- KEY_F18, KEY_F19, KEY_F20, KEY_F21, KEY_F22, KEY_F23,
- KEY_F24, KEY_STOP, KEY_AGAIN, KEY_PROPS, KEY_UNDO,
- KEY_FRONT, KEY_COPY, KEY_OPEN, KEY_PASTE, 0
-};
-
-/***********************************************************************
- * Relative reports deliver values in 2's complement format to
- * deal with negative offsets.
- */
-static int aiptek_convert_from_2s_complement(unsigned char c)
-{
- int ret;
- unsigned char b = c;
- int negate = 0;
-
- if ((b & 0x80) != 0) {
- b = ~b;
- b--;
- negate = 1;
- }
- ret = b;
- ret = (negate == 1) ? -ret : ret;
- return ret;
-}
-
-/***********************************************************************
- * aiptek_irq can receive one of six potential reports.
- * The documentation for each is in the body of the function.
- *
- * The tablet reports on several attributes per invocation of
- * aiptek_irq. Because the Linux Input Event system allows the
- * transmission of ONE attribute per input_report_xxx() call,
- * collation has to be done on the other end to reconstitute
- * a complete tablet report. Further, the number of Input Event reports
- * submitted varies, depending on what USB report type, and circumstance.
- * To deal with this, EV_MSC is used to indicate an 'end-of-report'
- * message. This has been an undocumented convention understood by the kernel
- * tablet driver and clients such as gpm and XFree86's tablet drivers.
- *
- * Of the information received from the tablet, the one piece I
- * cannot transmit is the proximity bit (without resorting to an EV_MSC
- * convention above.) I therefore have taken over REL_MISC and ABS_MISC
- * (for relative and absolute reports, respectively) for communicating
- * Proximity. Why two events? I thought it interesting to know if the
- * Proximity event occurred while the tablet was in absolute or relative
- * mode.
- *
- * Other tablets use the notion of a certain minimum stylus pressure
- * to infer proximity. While that could have been done, that is yet
- * another 'by convention' behavior, the documentation for which
- * would be spread between two (or more) pieces of software.
- *
- * EV_MSC usage was terminated for this purpose in Linux 2.5.x, and
- * replaced with the input_sync() method (which emits EV_SYN.)
- */
-
-static void aiptek_irq(struct urb *urb)
-{
- struct aiptek *aiptek = urb->context;
- unsigned char *data = aiptek->data;
- struct input_dev *inputdev = aiptek->inputdev;
- int jitterable = 0;
- int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
-
- switch (urb->status) {
- case 0:
- /* Success */
- break;
-
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* This urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
-
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- /* See if we are in a delay loop -- throw out report if true.
- */
- if (aiptek->inDelay == 1 && time_after(aiptek->endDelay, jiffies)) {
- goto exit;
- }
-
- aiptek->inDelay = 0;
- aiptek->eventCount++;
-
- /* Report 1 delivers relative coordinates with either a stylus
- * or the mouse. You do not know, however, which input
- * tool generated the event.
- */
- if (data[0] == 1) {
- if (aiptek->curSetting.coordinateMode ==
- AIPTEK_COORDINATE_ABSOLUTE_MODE) {
- aiptek->diagnostic =
- AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE;
- } else {
- x = aiptek_convert_from_2s_complement(data[2]);
- y = aiptek_convert_from_2s_complement(data[3]);
-
- /* jitterable keeps track of whether any button has been pressed.
- * We're also using it to remap the physical mouse button mask
- * to pseudo-settings. (We don't specifically care about it's
- * value after moving/transposing mouse button bitmasks, except
- * that a non-zero value indicates that one or more
- * mouse button was pressed.)
- */
- jitterable = data[5] & 0x07;
-
- left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
- right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
- middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
-
- input_report_key(inputdev, BTN_LEFT, left);
- input_report_key(inputdev, BTN_MIDDLE, middle);
- input_report_key(inputdev, BTN_RIGHT, right);
- input_report_rel(inputdev, REL_X, x);
- input_report_rel(inputdev, REL_Y, y);
- input_report_rel(inputdev, REL_MISC, 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
-
- /* Wheel support is in the form of a single-event
- * firing.
- */
- if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) {
- input_report_rel(inputdev, REL_WHEEL,
- aiptek->curSetting.wheel);
- aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
- }
- input_sync(inputdev);
- }
- }
- /* Report 2 is delivered only by the stylus, and delivers
- * absolute coordinates.
- */
- else if (data[0] == 2) {
- if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) {
- aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE;
- } else if (!AIPTEK_POINTER_ALLOW_STYLUS_MODE
- (aiptek->curSetting.pointerMode)) {
- aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;
- } else {
- x = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));
- y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
- z = le16_to_cpu(get_unaligned((__le16 *) (data + 6)));
-
- p = (data[5] & 0x01) != 0 ? 1 : 0;
- dv = (data[5] & 0x02) != 0 ? 1 : 0;
- tip = (data[5] & 0x04) != 0 ? 1 : 0;
-
- /* Use jitterable to re-arrange button masks
- */
- jitterable = data[5] & 0x18;
-
- bs = (data[5] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
- pck = (data[5] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
-
- /* dv indicates 'data valid' (e.g., the tablet is in sync
- * and has delivered a "correct" report) We will ignore
- * all 'bad' reports...
- */
- if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
- */
- if (TOOL_BUTTON_FIRED
- (aiptek->curSetting.toolMode) == 0) {
- input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
- 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
- }
-
- if (p != 0) {
- input_report_abs(inputdev, ABS_X, x);
- input_report_abs(inputdev, ABS_Y, y);
- input_report_abs(inputdev, ABS_PRESSURE, z);
-
- input_report_key(inputdev, BTN_TOUCH, tip);
- input_report_key(inputdev, BTN_STYLUS, bs);
- input_report_key(inputdev, BTN_STYLUS2, pck);
-
- if (aiptek->curSetting.xTilt !=
- AIPTEK_TILT_DISABLE) {
- input_report_abs(inputdev,
- ABS_TILT_X,
- aiptek->curSetting.xTilt);
- }
- if (aiptek->curSetting.yTilt != AIPTEK_TILT_DISABLE) {
- input_report_abs(inputdev,
- ABS_TILT_Y,
- aiptek->curSetting.yTilt);
- }
-
- /* Wheel support is in the form of a single-event
- * firing.
- */
- if (aiptek->curSetting.wheel !=
- AIPTEK_WHEEL_DISABLE) {
- input_report_abs(inputdev,
- ABS_WHEEL,
- aiptek->curSetting.wheel);
- aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
- }
- }
- input_report_abs(inputdev, ABS_MISC, p | AIPTEK_REPORT_TOOL_STYLUS);
- input_sync(inputdev);
- }
- }
- }
- /* Report 3's come from the mouse in absolute mode.
- */
- else if (data[0] == 3) {
- if (aiptek->curSetting.coordinateMode == AIPTEK_COORDINATE_RELATIVE_MODE) {
- aiptek->diagnostic = AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE;
- } else if (!AIPTEK_POINTER_ALLOW_MOUSE_MODE
- (aiptek->curSetting.pointerMode)) {
- aiptek->diagnostic = AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED;
- } else {
- x = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));
- y = le16_to_cpu(get_unaligned((__le16 *) (data + 3)));
-
- jitterable = data[5] & 0x1c;
-
- p = (data[5] & 0x01) != 0 ? 1 : 0;
- dv = (data[5] & 0x02) != 0 ? 1 : 0;
- left = (data[5] & aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
- right = (data[5] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
- middle = (data[5] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
-
- if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
- */
- if (TOOL_BUTTON_FIRED
- (aiptek->curSetting.toolMode) == 0) {
- input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
- 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
- }
-
- if (p != 0) {
- input_report_abs(inputdev, ABS_X, x);
- input_report_abs(inputdev, ABS_Y, y);
-
- input_report_key(inputdev, BTN_LEFT, left);
- input_report_key(inputdev, BTN_MIDDLE, middle);
- input_report_key(inputdev, BTN_RIGHT, right);
-
- /* Wheel support is in the form of a single-event
- * firing.
- */
- if (aiptek->curSetting.wheel != AIPTEK_WHEEL_DISABLE) {
- input_report_abs(inputdev,
- ABS_WHEEL,
- aiptek->curSetting.wheel);
- aiptek->curSetting.wheel = AIPTEK_WHEEL_DISABLE;
- }
- }
- input_report_rel(inputdev, REL_MISC, p | AIPTEK_REPORT_TOOL_MOUSE);
- input_sync(inputdev);
- }
- }
- }
- /* Report 4s come from the macro keys when pressed by stylus
- */
- else if (data[0] == 4) {
- jitterable = data[1] & 0x18;
-
- p = (data[1] & 0x01) != 0 ? 1 : 0;
- dv = (data[1] & 0x02) != 0 ? 1 : 0;
- tip = (data[1] & 0x04) != 0 ? 1 : 0;
- bs = (data[1] & aiptek->curSetting.stylusButtonLower) != 0 ? 1 : 0;
- pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
-
- macro = data[3];
- z = le16_to_cpu(get_unaligned((__le16 *) (data + 4)));
-
- if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
- */
- if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
- input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
- 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
- }
-
- if (p != 0) {
- input_report_key(inputdev, BTN_TOUCH, tip);
- input_report_key(inputdev, BTN_STYLUS, bs);
- input_report_key(inputdev, BTN_STYLUS2, pck);
- input_report_abs(inputdev, ABS_PRESSURE, z);
- }
-
- /* For safety, we're sending key 'break' codes for the
- * neighboring macro keys.
- */
- if (macro > 0) {
- input_report_key(inputdev,
- macroKeyEvents[macro - 1], 0);
- }
- if (macro < 25) {
- input_report_key(inputdev,
- macroKeyEvents[macro + 1], 0);
- }
- input_report_key(inputdev, macroKeyEvents[macro], p);
- input_report_abs(inputdev, ABS_MISC,
- p | AIPTEK_REPORT_TOOL_STYLUS);
- input_sync(inputdev);
- }
- }
- /* Report 5s come from the macro keys when pressed by mouse
- */
- else if (data[0] == 5) {
- jitterable = data[1] & 0x1c;
-
- p = (data[1] & 0x01) != 0 ? 1 : 0;
- dv = (data[1] & 0x02) != 0 ? 1 : 0;
- left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
- right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
- middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
- macro = data[3];
-
- if (dv != 0) {
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
- */
- if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
- input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.toolMode),
- 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
- }
-
- if (p != 0) {
- input_report_key(inputdev, BTN_LEFT, left);
- input_report_key(inputdev, BTN_MIDDLE, middle);
- input_report_key(inputdev, BTN_RIGHT, right);
- }
-
- /* For safety, we're sending key 'break' codes for the
- * neighboring macro keys.
- */
- if (macro > 0) {
- input_report_key(inputdev,
- macroKeyEvents[macro - 1], 0);
- }
- if (macro < 25) {
- input_report_key(inputdev,
- macroKeyEvents[macro + 1], 0);
- }
-
- input_report_key(inputdev, macroKeyEvents[macro], 1);
- input_report_rel(inputdev, ABS_MISC,
- p | AIPTEK_REPORT_TOOL_MOUSE);
- input_sync(inputdev);
- }
- }
- /* We have no idea which tool can generate a report 6. Theoretically,
- * neither need to, having been given reports 4 & 5 for such use.
- * However, report 6 is the 'official-looking' report for macroKeys;
- * reports 4 & 5 supposively are used to support unnamed, unknown
- * hat switches (which just so happen to be the macroKeys.)
- */
- else if (data[0] == 6) {
- macro = le16_to_cpu(get_unaligned((__le16 *) (data + 1)));
- if (macro > 0) {
- input_report_key(inputdev, macroKeyEvents[macro - 1],
- 0);
- }
- if (macro < 25) {
- input_report_key(inputdev, macroKeyEvents[macro + 1],
- 0);
- }
-
- /* If we've not already sent a tool_button_?? code, do
- * so now. Then set FIRED_BIT so it won't be resent unless
- * the user forces FIRED_BIT off.
- */
- if (TOOL_BUTTON_FIRED(aiptek->curSetting.toolMode) == 0) {
- input_report_key(inputdev,
- TOOL_BUTTON(aiptek->curSetting.
- toolMode), 1);
- aiptek->curSetting.toolMode |= TOOL_BUTTON_FIRED_BIT;
- }
-
- input_report_key(inputdev, macroKeyEvents[macro], 1);
- input_report_abs(inputdev, ABS_MISC,
- 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
- input_sync(inputdev);
- } else {
- dbg("Unknown report %d", data[0]);
- }
-
- /* Jitter may occur when the user presses a button on the stlyus
- * or the mouse. What we do to prevent that is wait 'x' milliseconds
- * following a 'jitterable' event, which should give the hand some time
- * stabilize itself.
- *
- * We just introduced aiptek->previousJitterable to carry forth the
- * notion that jitter occurs when the button state changes from on to off:
- * a person drawing, holding a button down is not subject to jittering.
- * With that in mind, changing from upper button depressed to lower button
- * WILL transition through a jitter delay.
- */
-
- if (aiptek->previousJitterable != jitterable &&
- aiptek->curSetting.jitterDelay != 0 && aiptek->inDelay != 1) {
- aiptek->endDelay = jiffies +
- ((aiptek->curSetting.jitterDelay * HZ) / 1000);
- aiptek->inDelay = 1;
- }
- aiptek->previousJitterable = jitterable;
-
-exit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval != 0) {
- err("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
- }
-}
-
-/***********************************************************************
- * These are the USB id's known so far. We do not identify them to
- * specific Aiptek model numbers, because there has been overlaps,
- * use, and reuse of id's in existing models. Certain models have
- * been known to use more than one ID, indicative perhaps of
- * manufacturing revisions. In any event, we consider these
- * IDs to not be model-specific nor unique.
- */
-static const struct usb_device_id aiptek_ids[] = {
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x01)},
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x10)},
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20)},
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x21)},
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x22)},
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x23)},
- {USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x24)},
- {}
-};
-
-MODULE_DEVICE_TABLE(usb, aiptek_ids);
-
-/***********************************************************************
- * Open an instance of the tablet driver.
- */
-static int aiptek_open(struct input_dev *inputdev)
-{
- struct aiptek *aiptek = input_get_drvdata(inputdev);
-
- aiptek->urb->dev = aiptek->usbdev;
- if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0)
- return -EIO;
-
- return 0;
-}
-
-/***********************************************************************
- * Close an instance of the tablet driver.
- */
-static void aiptek_close(struct input_dev *inputdev)
-{
- struct aiptek *aiptek = input_get_drvdata(inputdev);
-
- usb_kill_urb(aiptek->urb);
-}
-
-/***********************************************************************
- * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x,
- * where they were known as usb_set_report and usb_get_report.
- */
-static int
-aiptek_set_report(struct aiptek *aiptek,
- unsigned char report_type,
- unsigned char report_id, void *buffer, int size)
-{
- return usb_control_msg(aiptek->usbdev,
- usb_sndctrlpipe(aiptek->usbdev, 0),
- USB_REQ_SET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE |
- USB_DIR_OUT, (report_type << 8) + report_id,
- aiptek->ifnum, buffer, size, 5000);
-}
-
-static int
-aiptek_get_report(struct aiptek *aiptek,
- unsigned char report_type,
- unsigned char report_id, void *buffer, int size)
-{
- return usb_control_msg(aiptek->usbdev,
- usb_rcvctrlpipe(aiptek->usbdev, 0),
- USB_REQ_GET_REPORT,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE |
- USB_DIR_IN, (report_type << 8) + report_id,
- aiptek->ifnum, buffer, size, 5000);
-}
-
-/***********************************************************************
- * Send a command to the tablet.
- */
-static int
-aiptek_command(struct aiptek *aiptek, unsigned char command, unsigned char data)
-{
- const int sizeof_buf = 3 * sizeof(u8);
- int ret;
- u8 *buf;
-
- buf = kmalloc(sizeof_buf, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- buf[0] = 2;
- buf[1] = command;
- buf[2] = data;
-
- if ((ret =
- aiptek_set_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
- dbg("aiptek_program: failed, tried to send: 0x%02x 0x%02x",
- command, data);
- }
- kfree(buf);
- return ret < 0 ? ret : 0;
-}
-
-/***********************************************************************
- * Retrieve information from the tablet. Querying info is defined as first
- * sending the {command,data} sequence as a command, followed by a wait
- * (aka, "programmaticDelay") and then a "read" request.
- */
-static int
-aiptek_query(struct aiptek *aiptek, unsigned char command, unsigned char data)
-{
- const int sizeof_buf = 3 * sizeof(u8);
- int ret;
- u8 *buf;
-
- buf = kmalloc(sizeof_buf, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- buf[0] = 2;
- buf[1] = command;
- buf[2] = data;
-
- if (aiptek_command(aiptek, command, data) != 0) {
- kfree(buf);
- return -EIO;
- }
- msleep(aiptek->curSetting.programmableDelay);
-
- if ((ret =
- aiptek_get_report(aiptek, 3, 2, buf, sizeof_buf)) != sizeof_buf) {
- dbg("aiptek_query failed: returned 0x%02x 0x%02x 0x%02x",
- buf[0], buf[1], buf[2]);
- ret = -EIO;
- } else {
- ret = le16_to_cpu(get_unaligned((__le16 *) (buf + 1)));
- }
- kfree(buf);
- return ret;
-}
-
-/***********************************************************************
- * Program the tablet into either absolute or relative mode.
- * We also get information about the tablet's size.
- */
-static int aiptek_program_tablet(struct aiptek *aiptek)
-{
- int ret;
- /* Execute Resolution500LPI */
- if ((ret = aiptek_command(aiptek, 0x18, 0x04)) < 0)
- return ret;
-
- /* Query getModelCode */
- if ((ret = aiptek_query(aiptek, 0x02, 0x00)) < 0)
- return ret;
- aiptek->features.modelCode = ret & 0xff;
-
- /* Query getODMCode */
- if ((ret = aiptek_query(aiptek, 0x03, 0x00)) < 0)
- return ret;
- aiptek->features.odmCode = ret;
-
- /* Query getFirmwareCode */
- if ((ret = aiptek_query(aiptek, 0x04, 0x00)) < 0)
- return ret;
- aiptek->features.firmwareCode = ret;
-
- /* Query getXextension */
- if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
- return ret;
- aiptek->inputdev->absmin[ABS_X] = 0;
- aiptek->inputdev->absmax[ABS_X] = ret - 1;
-
- /* Query getYextension */
- if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
- return ret;
- aiptek->inputdev->absmin[ABS_Y] = 0;
- aiptek->inputdev->absmax[ABS_Y] = ret - 1;
-
- /* Query getPressureLevels */
- if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
- return ret;
- aiptek->inputdev->absmin[ABS_PRESSURE] = 0;
- aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;
-
- /* Depending on whether we are in absolute or relative mode, we will
- * do a switchToTablet(absolute) or switchToMouse(relative) command.
- */
- if (aiptek->curSetting.coordinateMode ==
- AIPTEK_COORDINATE_ABSOLUTE_MODE) {
- /* Execute switchToTablet */
- if ((ret = aiptek_command(aiptek, 0x10, 0x01)) < 0) {
- return ret;
- }
- } else {
- /* Execute switchToMouse */
- if ((ret = aiptek_command(aiptek, 0x10, 0x00)) < 0) {
- return ret;
- }
- }
-
- /* Enable the macro keys */
- if ((ret = aiptek_command(aiptek, 0x11, 0x02)) < 0)
- return ret;
-#if 0
- /* Execute FilterOn */
- if ((ret = aiptek_command(aiptek, 0x17, 0x00)) < 0)
- return ret;
-#endif
-
- /* Execute AutoGainOn */
- if ((ret = aiptek_command(aiptek, 0x12, 0xff)) < 0)
- return ret;
-
- /* Reset the eventCount, so we track events from last (re)programming
- */
- aiptek->diagnostic = AIPTEK_DIAGNOSTIC_NA;
- aiptek->eventCount = 0;
-
- return 0;
-}
-
-/***********************************************************************
- * Sysfs functions. Sysfs prefers that individually-tunable parameters
- * exist in their separate pseudo-files. Summary data that is immutable
- * may exist in a singular file so long as you don't define a writeable
- * interface.
- */
-
-/***********************************************************************
- * support the 'size' file -- display support
- */
-static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%dx%d\n",
- aiptek->inputdev->absmax[ABS_X] + 1,
- aiptek->inputdev->absmax[ABS_Y] + 1);
-}
-
-/* These structs define the sysfs files, param #1 is the name of the
- * file, param 2 is the file permissions, param 3 & 4 are to the
- * output generator and input parser routines. Absence of a routine is
- * permitted -- it only means can't either 'cat' the file, or send data
- * to it.
- */
-static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL);
-
-/***********************************************************************
- * support routines for the 'product_id' file
- */
-static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n",
- aiptek->inputdev->id.product);
-}
-
-static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
-
-/***********************************************************************
- * support routines for the 'vendor_id' file
- */
-static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
-}
-
-static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
-
-/***********************************************************************
- * support routines for the 'vendor' file
- */
-static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- int retval;
-
- if (aiptek == NULL)
- return 0;
-
- retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->manufacturer);
- return retval;
-}
-
-static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL);
-
-/***********************************************************************
- * support routines for the 'product' file
- */
-static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- int retval;
-
- if (aiptek == NULL)
- return 0;
-
- retval = snprintf(buf, PAGE_SIZE, "%s\n", aiptek->usbdev->product);
- return retval;
-}
-
-static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL);
-
-/***********************************************************************
- * support routines for the 'pointer_mode' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.pointerMode) {
- case AIPTEK_POINTER_ONLY_STYLUS_MODE:
- s = "stylus";
- break;
-
- case AIPTEK_POINTER_ONLY_MOUSE_MODE:
- s = "mouse";
- break;
-
- case AIPTEK_POINTER_EITHER_MODE:
- s = "either";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "stylus") == 0) {
- aiptek->newSetting.pointerMode =
- AIPTEK_POINTER_ONLY_STYLUS_MODE;
- } else if (strcmp(buf, "mouse") == 0) {
- aiptek->newSetting.pointerMode = AIPTEK_POINTER_ONLY_MOUSE_MODE;
- } else if (strcmp(buf, "either") == 0) {
- aiptek->newSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE;
- }
- return count;
-}
-
-static DEVICE_ATTR(pointer_mode,
- S_IRUGO | S_IWUGO,
- show_tabletPointerMode, store_tabletPointerMode);
-
-/***********************************************************************
- * support routines for the 'coordinate_mode' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.coordinateMode) {
- case AIPTEK_COORDINATE_ABSOLUTE_MODE:
- s = "absolute";
- break;
-
- case AIPTEK_COORDINATE_RELATIVE_MODE:
- s = "relative";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "absolute") == 0) {
- aiptek->newSetting.pointerMode =
- AIPTEK_COORDINATE_ABSOLUTE_MODE;
- } else if (strcmp(buf, "relative") == 0) {
- aiptek->newSetting.pointerMode =
- AIPTEK_COORDINATE_RELATIVE_MODE;
- }
- return count;
-}
-
-static DEVICE_ATTR(coordinate_mode,
- S_IRUGO | S_IWUGO,
- show_tabletCoordinateMode, store_tabletCoordinateMode);
-
-/***********************************************************************
- * support routines for the 'tool_mode' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (TOOL_BUTTON(aiptek->curSetting.toolMode)) {
- case AIPTEK_TOOL_BUTTON_MOUSE_MODE:
- s = "mouse";
- break;
-
- case AIPTEK_TOOL_BUTTON_ERASER_MODE:
- s = "eraser";
- break;
-
- case AIPTEK_TOOL_BUTTON_PENCIL_MODE:
- s = "pencil";
- break;
-
- case AIPTEK_TOOL_BUTTON_PEN_MODE:
- s = "pen";
- break;
-
- case AIPTEK_TOOL_BUTTON_BRUSH_MODE:
- s = "brush";
- break;
-
- case AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE:
- s = "airbrush";
- break;
-
- case AIPTEK_TOOL_BUTTON_LENS_MODE:
- s = "lens";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "mouse") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_MOUSE_MODE;
- } else if (strcmp(buf, "eraser") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_ERASER_MODE;
- } else if (strcmp(buf, "pencil") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PENCIL_MODE;
- } else if (strcmp(buf, "pen") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE;
- } else if (strcmp(buf, "brush") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_BRUSH_MODE;
- } else if (strcmp(buf, "airbrush") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_AIRBRUSH_MODE;
- } else if (strcmp(buf, "lens") == 0) {
- aiptek->newSetting.toolMode = AIPTEK_TOOL_BUTTON_LENS_MODE;
- }
-
- return count;
-}
-
-static DEVICE_ATTR(tool_mode,
- S_IRUGO | S_IWUGO,
- show_tabletToolMode, store_tabletToolMode);
-
-/***********************************************************************
- * support routines for the 'xtilt' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (aiptek->curSetting.xTilt == AIPTEK_TILT_DISABLE) {
- return snprintf(buf, PAGE_SIZE, "disable\n");
- } else {
- return snprintf(buf, PAGE_SIZE, "%d\n",
- aiptek->curSetting.xTilt);
- }
-}
-
-static ssize_t
-store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- int x;
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "disable") == 0) {
- aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
- } else {
- x = (int)simple_strtol(buf, NULL, 10);
- if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) {
- aiptek->newSetting.xTilt = x;
- }
- }
- return count;
-}
-
-static DEVICE_ATTR(xtilt,
- S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt);
-
-/***********************************************************************
- * support routines for the 'ytilt' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (aiptek->curSetting.yTilt == AIPTEK_TILT_DISABLE) {
- return snprintf(buf, PAGE_SIZE, "disable\n");
- } else {
- return snprintf(buf, PAGE_SIZE, "%d\n",
- aiptek->curSetting.yTilt);
- }
-}
-
-static ssize_t
-store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- int y;
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "disable") == 0) {
- aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
- } else {
- y = (int)simple_strtol(buf, NULL, 10);
- if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) {
- aiptek->newSetting.yTilt = y;
- }
- }
- return count;
-}
-
-static DEVICE_ATTR(ytilt,
- S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt);
-
-/***********************************************************************
- * support routines for the 'jitter' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.jitterDelay);
-}
-
-static ssize_t
-store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10);
- return count;
-}
-
-static DEVICE_ATTR(jitter,
- S_IRUGO | S_IWUGO,
- show_tabletJitterDelay, store_tabletJitterDelay);
-
-/***********************************************************************
- * support routines for the 'delay' file. Note that this file
- * both displays current setting and allows reprogramming.
- */
-static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%d\n",
- aiptek->curSetting.programmableDelay);
-}
-
-static ssize_t
-store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10);
- return count;
-}
-
-static DEVICE_ATTR(delay,
- S_IRUGO | S_IWUGO,
- show_tabletProgrammableDelay, store_tabletProgrammableDelay);
-
-/***********************************************************************
- * support routines for the 'input_path' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "/dev/input/%s\n",
- aiptek->features.inputPath);
-}
-
-static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL);
-
-/***********************************************************************
- * support routines for the 'event_count' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%ld\n", aiptek->eventCount);
-}
-
-static DEVICE_ATTR(event_count, S_IRUGO, show_tabletEventsReceived, NULL);
-
-/***********************************************************************
- * support routines for the 'diagnostic' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *retMsg;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->diagnostic) {
- case AIPTEK_DIAGNOSTIC_NA:
- retMsg = "no errors\n";
- break;
-
- case AIPTEK_DIAGNOSTIC_SENDING_RELATIVE_IN_ABSOLUTE:
- retMsg = "Error: receiving relative reports\n";
- break;
-
- case AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE:
- retMsg = "Error: receiving absolute reports\n";
- break;
-
- case AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED:
- if (aiptek->curSetting.pointerMode ==
- AIPTEK_POINTER_ONLY_MOUSE_MODE) {
- retMsg = "Error: receiving stylus reports\n";
- } else {
- retMsg = "Error: receiving mouse reports\n";
- }
- break;
-
- default:
- return 0;
- }
- return snprintf(buf, PAGE_SIZE, retMsg);
-}
-
-static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL);
-
-/***********************************************************************
- * support routines for the 'stylus_upper' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.stylusButtonUpper) {
- case AIPTEK_STYLUS_UPPER_BUTTON:
- s = "upper";
- break;
-
- case AIPTEK_STYLUS_LOWER_BUTTON:
- s = "lower";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "upper") == 0) {
- aiptek->newSetting.stylusButtonUpper =
- AIPTEK_STYLUS_UPPER_BUTTON;
- } else if (strcmp(buf, "lower") == 0) {
- aiptek->newSetting.stylusButtonUpper =
- AIPTEK_STYLUS_LOWER_BUTTON;
- }
- return count;
-}
-
-static DEVICE_ATTR(stylus_upper,
- S_IRUGO | S_IWUGO,
- show_tabletStylusUpper, store_tabletStylusUpper);
-
-/***********************************************************************
- * support routines for the 'stylus_lower' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.stylusButtonLower) {
- case AIPTEK_STYLUS_UPPER_BUTTON:
- s = "upper";
- break;
-
- case AIPTEK_STYLUS_LOWER_BUTTON:
- s = "lower";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "upper") == 0) {
- aiptek->newSetting.stylusButtonLower =
- AIPTEK_STYLUS_UPPER_BUTTON;
- } else if (strcmp(buf, "lower") == 0) {
- aiptek->newSetting.stylusButtonLower =
- AIPTEK_STYLUS_LOWER_BUTTON;
- }
- return count;
-}
-
-static DEVICE_ATTR(stylus_lower,
- S_IRUGO | S_IWUGO,
- show_tabletStylusLower, store_tabletStylusLower);
-
-/***********************************************************************
- * support routines for the 'mouse_left' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.mouseButtonLeft) {
- case AIPTEK_MOUSE_LEFT_BUTTON:
- s = "left";
- break;
-
- case AIPTEK_MOUSE_MIDDLE_BUTTON:
- s = "middle";
- break;
-
- case AIPTEK_MOUSE_RIGHT_BUTTON:
- s = "right";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "left") == 0) {
- aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON;
- } else if (strcmp(buf, "middle") == 0) {
- aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_MIDDLE_BUTTON;
- } else if (strcmp(buf, "right") == 0) {
- aiptek->newSetting.mouseButtonLeft = AIPTEK_MOUSE_RIGHT_BUTTON;
- }
- return count;
-}
-
-static DEVICE_ATTR(mouse_left,
- S_IRUGO | S_IWUGO,
- show_tabletMouseLeft, store_tabletMouseLeft);
-
-/***********************************************************************
- * support routines for the 'mouse_middle' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.mouseButtonMiddle) {
- case AIPTEK_MOUSE_LEFT_BUTTON:
- s = "left";
- break;
-
- case AIPTEK_MOUSE_MIDDLE_BUTTON:
- s = "middle";
- break;
-
- case AIPTEK_MOUSE_RIGHT_BUTTON:
- s = "right";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "left") == 0) {
- aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON;
- } else if (strcmp(buf, "middle") == 0) {
- aiptek->newSetting.mouseButtonMiddle =
- AIPTEK_MOUSE_MIDDLE_BUTTON;
- } else if (strcmp(buf, "right") == 0) {
- aiptek->newSetting.mouseButtonMiddle =
- AIPTEK_MOUSE_RIGHT_BUTTON;
- }
- return count;
-}
-
-static DEVICE_ATTR(mouse_middle,
- S_IRUGO | S_IWUGO,
- show_tabletMouseMiddle, store_tabletMouseMiddle);
-
-/***********************************************************************
- * support routines for the 'mouse_right' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
- char *s;
-
- if (aiptek == NULL)
- return 0;
-
- switch (aiptek->curSetting.mouseButtonRight) {
- case AIPTEK_MOUSE_LEFT_BUTTON:
- s = "left";
- break;
-
- case AIPTEK_MOUSE_MIDDLE_BUTTON:
- s = "middle";
- break;
-
- case AIPTEK_MOUSE_RIGHT_BUTTON:
- s = "right";
- break;
-
- default:
- s = "unknown";
- break;
- }
- return snprintf(buf, PAGE_SIZE, "%s\n", s);
-}
-
-static ssize_t
-store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (strcmp(buf, "left") == 0) {
- aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON;
- } else if (strcmp(buf, "middle") == 0) {
- aiptek->newSetting.mouseButtonRight =
- AIPTEK_MOUSE_MIDDLE_BUTTON;
- } else if (strcmp(buf, "right") == 0) {
- aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON;
- }
- return count;
-}
-
-static DEVICE_ATTR(mouse_right,
- S_IRUGO | S_IWUGO,
- show_tabletMouseRight, store_tabletMouseRight);
-
-/***********************************************************************
- * support routines for the 'wheel' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) {
- return snprintf(buf, PAGE_SIZE, "disable\n");
- } else {
- return snprintf(buf, PAGE_SIZE, "%d\n",
- aiptek->curSetting.wheel);
- }
-}
-
-static ssize_t
-store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10);
- return count;
-}
-
-static DEVICE_ATTR(wheel,
- S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel);
-
-/***********************************************************************
- * support routines for the 'execute' file. Note that this file
- * both displays current setting and allows for setting changing.
- */
-static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- /* There is nothing useful to display, so a one-line manual
- * is in order...
- */
- return snprintf(buf, PAGE_SIZE,
- "Write anything to this file to program your tablet.\n");
-}
-
-static ssize_t
-store_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- /* We do not care what you write to this file. Merely the action
- * of writing to this file triggers a tablet reprogramming.
- */
- memcpy(&aiptek->curSetting, &aiptek->newSetting,
- sizeof(struct aiptek_settings));
-
- if (aiptek_program_tablet(aiptek) < 0)
- return -EIO;
-
- return count;
-}
-
-static DEVICE_ATTR(execute,
- S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute);
-
-/***********************************************************************
- * support routines for the 'odm_code' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode);
-}
-
-static DEVICE_ATTR(odm_code, S_IRUGO, show_tabletODMCode, NULL);
-
-/***********************************************************************
- * support routines for the 'model_code' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode);
-}
-
-static DEVICE_ATTR(model_code, S_IRUGO, show_tabletModelCode, NULL);
-
-/***********************************************************************
- * support routines for the 'firmware_code' file. Note that this file
- * only displays current setting.
- */
-static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct aiptek *aiptek = dev_get_drvdata(dev);
-
- if (aiptek == NULL)
- return 0;
-
- return snprintf(buf, PAGE_SIZE, "%04x\n",
- aiptek->features.firmwareCode);
-}
-
-static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL);
-
-/***********************************************************************
- * This routine removes all existing sysfs files managed by this device
- * driver.
- */
-static void aiptek_delete_files(struct device *dev)
-{
- device_remove_file(dev, &dev_attr_size);
- device_remove_file(dev, &dev_attr_product_id);
- device_remove_file(dev, &dev_attr_vendor_id);
- device_remove_file(dev, &dev_attr_vendor);
- device_remove_file(dev, &dev_attr_product);
- device_remove_file(dev, &dev_attr_pointer_mode);
- device_remove_file(dev, &dev_attr_coordinate_mode);
- device_remove_file(dev, &dev_attr_tool_mode);
- device_remove_file(dev, &dev_attr_xtilt);
- device_remove_file(dev, &dev_attr_ytilt);
- device_remove_file(dev, &dev_attr_jitter);
- device_remove_file(dev, &dev_attr_delay);
- device_remove_file(dev, &dev_attr_input_path);
- device_remove_file(dev, &dev_attr_event_count);
- device_remove_file(dev, &dev_attr_diagnostic);
- device_remove_file(dev, &dev_attr_odm_code);
- device_remove_file(dev, &dev_attr_model_code);
- device_remove_file(dev, &dev_attr_firmware_code);
- device_remove_file(dev, &dev_attr_stylus_lower);
- device_remove_file(dev, &dev_attr_stylus_upper);
- device_remove_file(dev, &dev_attr_mouse_left);
- device_remove_file(dev, &dev_attr_mouse_middle);
- device_remove_file(dev, &dev_attr_mouse_right);
- device_remove_file(dev, &dev_attr_wheel);
- device_remove_file(dev, &dev_attr_execute);
-}
-
-/***********************************************************************
- * This routine creates the sysfs files managed by this device
- * driver.
- */
-static int aiptek_add_files(struct device *dev)
-{
- int ret;
-
- if ((ret = device_create_file(dev, &dev_attr_size)) ||
- (ret = device_create_file(dev, &dev_attr_product_id)) ||
- (ret = device_create_file(dev, &dev_attr_vendor_id)) ||
- (ret = device_create_file(dev, &dev_attr_vendor)) ||
- (ret = device_create_file(dev, &dev_attr_product)) ||
- (ret = device_create_file(dev, &dev_attr_pointer_mode)) ||
- (ret = device_create_file(dev, &dev_attr_coordinate_mode)) ||
- (ret = device_create_file(dev, &dev_attr_tool_mode)) ||
- (ret = device_create_file(dev, &dev_attr_xtilt)) ||
- (ret = device_create_file(dev, &dev_attr_ytilt)) ||
- (ret = device_create_file(dev, &dev_attr_jitter)) ||
- (ret = device_create_file(dev, &dev_attr_delay)) ||
- (ret = device_create_file(dev, &dev_attr_input_path)) ||
- (ret = device_create_file(dev, &dev_attr_event_count)) ||
- (ret = device_create_file(dev, &dev_attr_diagnostic)) ||
- (ret = device_create_file(dev, &dev_attr_odm_code)) ||
- (ret = device_create_file(dev, &dev_attr_model_code)) ||
- (ret = device_create_file(dev, &dev_attr_firmware_code)) ||
- (ret = device_create_file(dev, &dev_attr_stylus_lower)) ||
- (ret = device_create_file(dev, &dev_attr_stylus_upper)) ||
- (ret = device_create_file(dev, &dev_attr_mouse_left)) ||
- (ret = device_create_file(dev, &dev_attr_mouse_middle)) ||
- (ret = device_create_file(dev, &dev_attr_mouse_right)) ||
- (ret = device_create_file(dev, &dev_attr_wheel)) ||
- (ret = device_create_file(dev, &dev_attr_execute))) {
- err("aiptek: killing own sysfs device files\n");
- aiptek_delete_files(dev);
- }
- return ret;
-}
-
-/***********************************************************************
- * This routine is called when a tablet has been identified. It basically
- * sets up the tablet and the driver's internal structures.
- */
-static int
-aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *usbdev = interface_to_usbdev(intf);
- struct usb_endpoint_descriptor *endpoint;
- struct aiptek *aiptek;
- struct input_dev *inputdev;
- struct input_handle *inputhandle;
- struct list_head *node, *next;
- int i;
- int speeds[] = { 0,
- AIPTEK_PROGRAMMABLE_DELAY_50,
- AIPTEK_PROGRAMMABLE_DELAY_400,
- AIPTEK_PROGRAMMABLE_DELAY_25,
- AIPTEK_PROGRAMMABLE_DELAY_100,
- AIPTEK_PROGRAMMABLE_DELAY_200,
- AIPTEK_PROGRAMMABLE_DELAY_300
- };
- int err = -ENOMEM;
-
- /* programmableDelay is where the command-line specified
- * delay is kept. We make it the first element of speeds[],
- * so therefore, your override speed is tried first, then the
- * remainder. Note that the default value of 400ms will be tried
- * if you do not specify any command line parameter.
- */
- speeds[0] = programmableDelay;
-
- aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
- inputdev = input_allocate_device();
- if (!aiptek || !inputdev)
- goto fail1;
-
- aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
- GFP_ATOMIC, &aiptek->data_dma);
- if (!aiptek->data)
- goto fail1;
-
- aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!aiptek->urb)
- goto fail2;
-
- aiptek->inputdev = inputdev;
- aiptek->usbdev = usbdev;
- aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
- aiptek->inDelay = 0;
- aiptek->endDelay = 0;
- aiptek->previousJitterable = 0;
-
- /* Set up the curSettings struct. Said struct contains the current
- * programmable parameters. The newSetting struct contains changes
- * the user makes to the settings via the sysfs interface. Those
- * changes are not "committed" to curSettings until the user
- * writes to the sysfs/.../execute file.
- */
- aiptek->curSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE;
- aiptek->curSetting.coordinateMode = AIPTEK_COORDINATE_ABSOLUTE_MODE;
- aiptek->curSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE;
- aiptek->curSetting.xTilt = AIPTEK_TILT_DISABLE;
- aiptek->curSetting.yTilt = AIPTEK_TILT_DISABLE;
- aiptek->curSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON;
- aiptek->curSetting.mouseButtonMiddle = AIPTEK_MOUSE_MIDDLE_BUTTON;
- aiptek->curSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON;
- aiptek->curSetting.stylusButtonUpper = AIPTEK_STYLUS_UPPER_BUTTON;
- aiptek->curSetting.stylusButtonLower = AIPTEK_STYLUS_LOWER_BUTTON;
- aiptek->curSetting.jitterDelay = jitterDelay;
- aiptek->curSetting.programmableDelay = programmableDelay;
-
- /* Both structs should have equivalent settings
- */
- aiptek->newSetting = aiptek->curSetting;
-
- /* Determine the usb devices' physical path.
- * Asketh not why we always pretend we're using "../input0",
- * but I suspect this will have to be refactored one
- * day if a single USB device can be a keyboard & a mouse
- * & a tablet, and the inputX number actually will tell
- * us something...
- */
- usb_make_path(usbdev, aiptek->features.usbPath,
- sizeof(aiptek->features.usbPath));
- strlcat(aiptek->features.usbPath, "/input0",
- sizeof(aiptek->features.usbPath));
-
- /* Set up client data, pointers to open and close routines
- * for the input device.
- */
- inputdev->name = "Aiptek";
- inputdev->phys = aiptek->features.usbPath;
- usb_to_input_id(usbdev, &inputdev->id);
- inputdev->dev.parent = &intf->dev;
-
- input_set_drvdata(inputdev, aiptek);
-
- inputdev->open = aiptek_open;
- inputdev->close = aiptek_close;
-
- /* Now program the capacities of the tablet, in terms of being
- * an input device.
- */
- inputdev->evbit[0] |= BIT(EV_KEY)
- | BIT(EV_ABS)
- | BIT(EV_REL)
- | BIT(EV_MSC);
-
- inputdev->absbit[0] |= BIT(ABS_MISC);
-
- inputdev->relbit[0] |=
- (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
-
- inputdev->keybit[LONG(BTN_LEFT)] |=
- (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
-
- inputdev->keybit[LONG(BTN_DIGI)] |=
- (BIT(BTN_TOOL_PEN) |
- BIT(BTN_TOOL_RUBBER) |
- BIT(BTN_TOOL_PENCIL) |
- BIT(BTN_TOOL_AIRBRUSH) |
- BIT(BTN_TOOL_BRUSH) |
- BIT(BTN_TOOL_MOUSE) |
- BIT(BTN_TOOL_LENS) |
- BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
-
- inputdev->mscbit[0] = BIT(MSC_SERIAL);
-
- /* Programming the tablet macro keys needs to be done with a for loop
- * as the keycodes are discontiguous.
- */
- for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
- set_bit(macroKeyEvents[i], inputdev->keybit);
-
- /*
- * Program the input device coordinate capacities. We do not yet
- * know what maximum X, Y, and Z values are, so we're putting fake
- * values in. Later, we'll ask the tablet to put in the correct
- * values.
- */
- input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
- input_set_abs_params(inputdev, ABS_Y, 0, 2249, 0, 0);
- input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
- input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
- input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
- input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
-
- endpoint = &intf->altsetting[0].endpoint[0].desc;
-
- /* Go set up our URB, which is called when the tablet receives
- * input.
- */
- usb_fill_int_urb(aiptek->urb,
- aiptek->usbdev,
- usb_rcvintpipe(aiptek->usbdev,
- endpoint->bEndpointAddress),
- aiptek->data, 8, aiptek_irq, aiptek,
- endpoint->bInterval);
-
- aiptek->urb->transfer_dma = aiptek->data_dma;
- aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* Program the tablet. This sets the tablet up in the mode
- * specified in newSetting, and also queries the tablet's
- * physical capacities.
- *
- * Sanity check: if a tablet doesn't like the slow programmatic
- * delay, we often get sizes of 0x0. Let's use that as an indicator
- * to try faster delays, up to 25 ms. If that logic fails, well, you'll
- * have to explain to us how your tablet thinks it's 0x0, and yet that's
- * not an error :-)
- */
-
- for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
- aiptek->curSetting.programmableDelay = speeds[i];
- (void)aiptek_program_tablet(aiptek);
- if (aiptek->inputdev->absmax[ABS_X] > 0) {
- info("input: Aiptek using %d ms programming speed\n",
- aiptek->curSetting.programmableDelay);
- break;
- }
- }
-
- /* Register the tablet as an Input Device
- */
- err = input_register_device(aiptek->inputdev);
- if (err)
- goto fail2;
-
- /* We now will look for the evdev device which is mapped to
- * the tablet. The partial name is kept in the link list of
- * input_handles associated with this input device.
- * What identifies an evdev input_handler is that it begins
- * with 'event', continues with a digit, and that in turn
- * is mapped to input/eventN.
- */
- list_for_each_safe(node, next, &inputdev->h_list) {
- inputhandle = to_handle(node);
- if (strncmp(inputhandle->name, "event", 5) == 0) {
- strcpy(aiptek->features.inputPath, inputhandle->name);
- break;
- }
- }
-
- /* Associate this driver's struct with the usb interface.
- */
- usb_set_intfdata(intf, aiptek);
-
- /* Set up the sysfs files
- */
- aiptek_add_files(&intf->dev);
-
- /* Make sure the evdev module is loaded. Assuming evdev IS a module :-)
- */
- if (request_module("evdev") != 0)
- info("aiptek: error loading 'evdev' module");
-
- return 0;
-
- fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
- aiptek->data_dma);
- fail1: input_free_device(inputdev);
- kfree(aiptek);
- return err;
-}
-
-/***********************************************************************
- * Deal with tablet disconnecting from the system.
- */
-static void aiptek_disconnect(struct usb_interface *intf)
-{
- struct aiptek *aiptek = usb_get_intfdata(intf);
-
- /* Disassociate driver's struct with usb interface
- */
- usb_set_intfdata(intf, NULL);
- if (aiptek != NULL) {
- /* Free & unhook everything from the system.
- */
- usb_kill_urb(aiptek->urb);
- input_unregister_device(aiptek->inputdev);
- aiptek_delete_files(&intf->dev);
- usb_free_urb(aiptek->urb);
- usb_buffer_free(interface_to_usbdev(intf),
- AIPTEK_PACKET_LENGTH,
- aiptek->data, aiptek->data_dma);
- kfree(aiptek);
- }
-}
-
-static struct usb_driver aiptek_driver = {
- .name = "aiptek",
- .probe = aiptek_probe,
- .disconnect = aiptek_disconnect,
- .id_table = aiptek_ids,
-};
-
-static int __init aiptek_init(void)
-{
- int result = usb_register(&aiptek_driver);
- if (result == 0) {
- info(DRIVER_VERSION ": " DRIVER_AUTHOR);
- info(DRIVER_DESC);
- }
- return result;
-}
-
-static void __exit aiptek_exit(void)
-{
- usb_deregister(&aiptek_driver);
-}
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-module_param(programmableDelay, int, 0);
-MODULE_PARM_DESC(programmableDelay, "delay used during tablet programming");
-module_param(jitterDelay, int, 0);
-MODULE_PARM_DESC(jitterDelay, "stylus/mouse settlement delay");
-
-module_init(aiptek_init);
-module_exit(aiptek_exit);
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
deleted file mode 100644
index e3215267db1..00000000000
--- a/drivers/usb/input/appletouch.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
- *
- * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
- * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
- * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
- * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
- * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
- * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
- *
- * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb/input.h>
-
-/* Apple has powerbooks which have the keyboard with different Product IDs */
-#define APPLE_VENDOR_ID 0x05AC
-
-/* These names come from Info.plist in AppleUSBTrackpad.kext */
-#define FOUNTAIN_ANSI_PRODUCT_ID 0x020E
-#define FOUNTAIN_ISO_PRODUCT_ID 0x020F
-
-#define FOUNTAIN_TP_ONLY_PRODUCT_ID 0x030A
-
-#define GEYSER1_TP_ONLY_PRODUCT_ID 0x030B
-
-#define GEYSER_ANSI_PRODUCT_ID 0x0214
-#define GEYSER_ISO_PRODUCT_ID 0x0215
-#define GEYSER_JIS_PRODUCT_ID 0x0216
-
-/* MacBook devices */
-#define GEYSER3_ANSI_PRODUCT_ID 0x0217
-#define GEYSER3_ISO_PRODUCT_ID 0x0218
-#define GEYSER3_JIS_PRODUCT_ID 0x0219
-
-/*
- * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext
- * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables
- */
-#define GEYSER4_ANSI_PRODUCT_ID 0x021A
-#define GEYSER4_ISO_PRODUCT_ID 0x021B
-#define GEYSER4_JIS_PRODUCT_ID 0x021C
-
-#define ATP_DEVICE(prod) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
- USB_DEVICE_ID_MATCH_INT_CLASS | \
- USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
- .idVendor = APPLE_VENDOR_ID, \
- .idProduct = (prod), \
- .bInterfaceClass = 0x03, \
- .bInterfaceProtocol = 0x02
-
-/* table of devices that work with this driver */
-static struct usb_device_id atp_table [] = {
- { ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) },
- { ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) },
- { ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) },
-
- /* PowerBooks Oct 2005 */
- { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
-
- /* Core Duo MacBook & MacBook Pro */
- { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
-
- /* Core2 Duo MacBook & MacBook Pro */
- { ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) },
- { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) },
-
- /* Terminating entry */
- { }
-};
-MODULE_DEVICE_TABLE (usb, atp_table);
-
-/*
- * number of sensors. Note that only 16 instead of 26 X (horizontal)
- * sensors exist on 12" and 15" PowerBooks. All models have 16 Y
- * (vertical) sensors.
- */
-#define ATP_XSENSORS 26
-#define ATP_YSENSORS 16
-
-/* amount of fuzz this touchpad generates */
-#define ATP_FUZZ 16
-
-/* maximum pressure this driver will report */
-#define ATP_PRESSURE 300
-/*
- * multiplication factor for the X and Y coordinates.
- * We try to keep the touchpad aspect ratio while still doing only simple
- * arithmetics.
- * The factors below give coordinates like:
- * 0 <= x < 960 on 12" and 15" Powerbooks
- * 0 <= x < 1600 on 17" Powerbooks
- * 0 <= y < 646
- */
-#define ATP_XFACT 64
-#define ATP_YFACT 43
-
-/*
- * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
- * ignored.
- */
-#define ATP_THRESHOLD 5
-
-/* MacBook Pro (Geyser 3 & 4) initialization constants */
-#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1
-#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9
-#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300
-#define ATP_GEYSER3_MODE_REQUEST_INDEX 0
-#define ATP_GEYSER3_MODE_VENDOR_VALUE 0x04
-
-/* Structure to hold all of our device specific stuff */
-struct atp {
- char phys[64];
- struct usb_device * udev; /* usb device */
- struct urb * urb; /* usb request block */
- signed char * data; /* transferred data */
- int open; /* non-zero if opened */
- struct input_dev *input; /* input dev */
- int valid; /* are the sensors valid ? */
- int x_old; /* last reported x/y, */
- int y_old; /* used for smoothing */
- /* current value of the sensors */
- signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
- /* last value of the sensors */
- signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
- /* accumulated sensors */
- int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
- int overflowwarn; /* overflow warning printed? */
- int datalen; /* size of an USB urb transfer */
-};
-
-#define dbg_dump(msg, tab) \
- if (debug > 1) { \
- int i; \
- printk("appletouch: %s %lld", msg, (long long)jiffies); \
- for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
- printk(" %02x", tab[i]); \
- printk("\n"); \
- }
-
-#define dprintk(format, a...) \
- do { \
- if (debug) printk(format, ##a); \
- } while (0)
-
-MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
-MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
-MODULE_LICENSE("GPL");
-
-/*
- * Make the threshold a module parameter
- */
-static int threshold = ATP_THRESHOLD;
-module_param(threshold, int, 0644);
-MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value");
-
-static int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activate debugging output");
-
-/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
-static inline int atp_is_geyser_2(struct atp *dev)
-{
- u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
- return (productId == GEYSER_ANSI_PRODUCT_ID) ||
- (productId == GEYSER_ISO_PRODUCT_ID) ||
- (productId == GEYSER_JIS_PRODUCT_ID);
-}
-
-static inline int atp_is_geyser_3(struct atp *dev)
-{
- u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
-
- return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
- (productId == GEYSER3_ISO_PRODUCT_ID) ||
- (productId == GEYSER3_JIS_PRODUCT_ID) ||
- (productId == GEYSER4_ANSI_PRODUCT_ID) ||
- (productId == GEYSER4_ISO_PRODUCT_ID) ||
- (productId == GEYSER4_JIS_PRODUCT_ID);
-}
-
-static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
- int *z, int *fingers)
-{
- int i;
- /* values to calculate mean */
- int pcum = 0, psum = 0;
- int is_increasing = 0;
-
- *fingers = 0;
-
- for (i = 0; i < nb_sensors; i++) {
- if (xy_sensors[i] < threshold) {
- if (is_increasing)
- is_increasing = 0;
-
- continue;
- }
-
- /*
- * Makes the finger detection more versatile. For example,
- * two fingers with no gap will be detected. Also, my
- * tests show it less likely to have intermittent loss
- * of multiple finger readings while moving around (scrolling).
- *
- * Changes the multiple finger detection to counting humps on
- * sensors (transitions from nonincreasing to increasing)
- * instead of counting transitions from low sensors (no
- * finger reading) to high sensors (finger above
- * sensor)
- *
- * - Jason Parekh <jasonparekh@gmail.com>
- */
- if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
- (*fingers)++;
- is_increasing = 1;
- } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) {
- is_increasing = 0;
- }
-
- /*
- * Subtracts threshold so a high sensor that just passes the threshold
- * won't skew the calculated absolute coordinate. Fixes an issue
- * where slowly moving the mouse would occassionaly jump a number of
- * pixels (let me restate--slowly moving the mouse makes this issue
- * most apparent).
- */
- pcum += (xy_sensors[i] - threshold) * i;
- psum += (xy_sensors[i] - threshold);
- }
-
- if (psum > 0) {
- *z = psum;
- return pcum * fact / psum;
- }
-
- return 0;
-}
-
-static inline void atp_report_fingers(struct input_dev *input, int fingers)
-{
- input_report_key(input, BTN_TOOL_FINGER, fingers == 1);
- input_report_key(input, BTN_TOOL_DOUBLETAP, fingers == 2);
- input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
-}
-
-static void atp_complete(struct urb* urb)
-{
- int x, y, x_z, y_z, x_f, y_f;
- int retval, i, j;
- struct atp *dev = urb->context;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -EOVERFLOW:
- if(!dev->overflowwarn) {
- printk("appletouch: OVERFLOW with data "
- "length %d, actual length is %d\n",
- dev->datalen, dev->urb->actual_length);
- dev->overflowwarn = 1;
- }
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* This urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- /* drop incomplete datasets */
- if (dev->urb->actual_length != dev->datalen) {
- dprintk("appletouch: incomplete data package"
- " (first byte: %d, length: %d).\n",
- dev->data[0], dev->urb->actual_length);
- goto exit;
- }
-
- /* reorder the sensors values */
- if (atp_is_geyser_3(dev)) {
- memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
-
- /*
- * The values are laid out like this:
- * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
- * '-' is an unused value.
- */
-
- /* read X values */
- for (i = 0, j = 19; i < 20; i += 2, j += 3) {
- dev->xy_cur[i] = dev->data[j + 1];
- dev->xy_cur[i + 1] = dev->data[j + 2];
- }
- /* read Y values */
- for (i = 0, j = 1; i < 9; i += 2, j += 3) {
- dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
- dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
- }
- } else if (atp_is_geyser_2(dev)) {
- memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
-
- /*
- * The values are laid out like this:
- * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ...
- * '-' is an unused value.
- */
-
- /* read X values */
- for (i = 0, j = 19; i < 20; i += 2, j += 3) {
- dev->xy_cur[i] = dev->data[j];
- dev->xy_cur[i + 1] = dev->data[j + 1];
- }
-
- /* read Y values */
- for (i = 0, j = 1; i < 9; i += 2, j += 3) {
- dev->xy_cur[ATP_XSENSORS + i] = dev->data[j];
- dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 1];
- }
- } else {
- for (i = 0; i < 8; i++) {
- /* X values */
- dev->xy_cur[i ] = dev->data[5 * i + 2];
- dev->xy_cur[i + 8] = dev->data[5 * i + 4];
- dev->xy_cur[i + 16] = dev->data[5 * i + 42];
- if (i < 2)
- dev->xy_cur[i + 24] = dev->data[5 * i + 44];
-
- /* Y values */
- dev->xy_cur[i + 26] = dev->data[5 * i + 1];
- dev->xy_cur[i + 34] = dev->data[5 * i + 3];
- }
- }
-
- dbg_dump("sample", dev->xy_cur);
-
- if (!dev->valid) {
- /* first sample */
- dev->valid = 1;
- dev->x_old = dev->y_old = -1;
- memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
-
- if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
- goto exit;
-
- /* 17" Powerbooks have extra X sensors */
- for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
- if (!dev->xy_cur[i]) continue;
-
- printk("appletouch: 17\" model detected.\n");
- if(atp_is_geyser_2(dev))
- input_set_abs_params(dev->input, ABS_X, 0,
- (20 - 1) *
- ATP_XFACT - 1,
- ATP_FUZZ, 0);
- else
- input_set_abs_params(dev->input, ABS_X, 0,
- (ATP_XSENSORS - 1) *
- ATP_XFACT - 1,
- ATP_FUZZ, 0);
-
- break;
- }
-
- goto exit;
- }
-
- for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
- /* accumulate the change */
- signed char change = dev->xy_old[i] - dev->xy_cur[i];
- dev->xy_acc[i] -= change;
-
- /* prevent down drifting */
- if (dev->xy_acc[i] < 0)
- dev->xy_acc[i] = 0;
- }
-
- memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
-
- dbg_dump("accumulator", dev->xy_acc);
-
- x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
- ATP_XFACT, &x_z, &x_f);
- y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
- ATP_YFACT, &y_z, &y_f);
-
- if (x && y) {
- if (dev->x_old != -1) {
- x = (dev->x_old * 3 + x) >> 2;
- y = (dev->y_old * 3 + y) >> 2;
- dev->x_old = x;
- dev->y_old = y;
-
- if (debug > 1)
- printk("appletouch: X: %3d Y: %3d "
- "Xz: %3d Yz: %3d\n",
- x, y, x_z, y_z);
-
- input_report_key(dev->input, BTN_TOUCH, 1);
- input_report_abs(dev->input, ABS_X, x);
- input_report_abs(dev->input, ABS_Y, y);
- input_report_abs(dev->input, ABS_PRESSURE,
- min(ATP_PRESSURE, x_z + y_z));
- atp_report_fingers(dev->input, max(x_f, y_f));
- }
- dev->x_old = x;
- dev->y_old = y;
- }
- else if (!x && !y) {
-
- dev->x_old = dev->y_old = -1;
- input_report_key(dev->input, BTN_TOUCH, 0);
- input_report_abs(dev->input, ABS_PRESSURE, 0);
- atp_report_fingers(dev->input, 0);
-
- /* reset the accumulator on release */
- memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
- }
-
- input_report_key(dev->input, BTN_LEFT,
- !!dev->data[dev->datalen - 1]);
-
- input_sync(dev->input);
-
-exit:
- retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
- if (retval) {
- err("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
- }
-}
-
-static int atp_open(struct input_dev *input)
-{
- struct atp *dev = input_get_drvdata(input);
-
- if (usb_submit_urb(dev->urb, GFP_ATOMIC))
- return -EIO;
-
- dev->open = 1;
- return 0;
-}
-
-static void atp_close(struct input_dev *input)
-{
- struct atp *dev = input_get_drvdata(input);
-
- usb_kill_urb(dev->urb);
- dev->open = 0;
-}
-
-static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
-{
- struct atp *dev;
- struct input_dev *input_dev;
- struct usb_device *udev = interface_to_usbdev(iface);
- struct usb_host_interface *iface_desc;
- struct usb_endpoint_descriptor *endpoint;
- int int_in_endpointAddr = 0;
- int i, error = -ENOMEM;
-
- /* set up the endpoint information */
- /* use only the first interrupt-in endpoint */
- iface_desc = iface->cur_altsetting;
- for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
- endpoint = &iface_desc->endpoint[i].desc;
- if (!int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) {
- /* we found an interrupt in endpoint */
- int_in_endpointAddr = endpoint->bEndpointAddress;
- break;
- }
- }
- if (!int_in_endpointAddr) {
- err("Could not find int-in endpoint");
- return -EIO;
- }
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!dev || !input_dev) {
- err("Out of memory");
- goto err_free_devs;
- }
-
- dev->udev = udev;
- dev->input = input_dev;
- dev->overflowwarn = 0;
- if (atp_is_geyser_3(dev))
- dev->datalen = 64;
- else if (atp_is_geyser_2(dev))
- dev->datalen = 64;
- else
- dev->datalen = 81;
-
- if (atp_is_geyser_3(dev)) {
- /*
- * By default Geyser 3 device sends standard USB HID mouse
- * packets (Report ID 2). This code changes device mode, so it
- * sends raw sensor reports (Report ID 5).
- */
- char data[8];
- int size;
-
- size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- ATP_GEYSER3_MODE_READ_REQUEST_ID,
- USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ATP_GEYSER3_MODE_REQUEST_VALUE,
- ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
-
- if (size != 8) {
- err("Could not do mode read request from device"
- " (Geyser 3 mode)");
- goto err_free_devs;
- }
-
- /* Apply the mode switch */
- data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;
-
- size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ATP_GEYSER3_MODE_REQUEST_VALUE,
- ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
-
- if (size != 8) {
- err("Could not do mode write request to device"
- " (Geyser 3 mode)");
- goto err_free_devs;
- }
- printk("appletouch Geyser 3 inited.\n");
- }
-
- dev->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->urb)
- goto err_free_devs;
-
- dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL,
- &dev->urb->transfer_dma);
- if (!dev->data)
- goto err_free_urb;
-
- usb_fill_int_urb(dev->urb, udev,
- usb_rcvintpipe(udev, int_in_endpointAddr),
- dev->data, dev->datalen, atp_complete, dev, 1);
-
- usb_make_path(udev, dev->phys, sizeof(dev->phys));
- strlcat(dev->phys, "/input0", sizeof(dev->phys));
-
- input_dev->name = "appletouch";
- input_dev->phys = dev->phys;
- usb_to_input_id(dev->udev, &input_dev->id);
- input_dev->dev.parent = &iface->dev;
-
- input_set_drvdata(input_dev, dev);
-
- input_dev->open = atp_open;
- input_dev->close = atp_close;
-
- set_bit(EV_ABS, input_dev->evbit);
-
- if (atp_is_geyser_3(dev)) {
- /*
- * MacBook have 20 X sensors, 10 Y sensors
- */
- input_set_abs_params(input_dev, ABS_X, 0,
- ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
- input_set_abs_params(input_dev, ABS_Y, 0,
- ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
- } else if (atp_is_geyser_2(dev)) {
- /*
- * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
- * later.
- */
- input_set_abs_params(input_dev, ABS_X, 0,
- ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
- input_set_abs_params(input_dev, ABS_Y, 0,
- ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
- } else {
- /*
- * 12" and 15" Powerbooks only have 16 x sensors,
- * 17" models are detected later.
- */
- input_set_abs_params(input_dev, ABS_X, 0,
- (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
- input_set_abs_params(input_dev, ABS_Y, 0,
- (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
- }
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
-
- set_bit(EV_KEY, input_dev->evbit);
- set_bit(BTN_TOUCH, input_dev->keybit);
- set_bit(BTN_TOOL_FINGER, input_dev->keybit);
- set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
- set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
- set_bit(BTN_LEFT, input_dev->keybit);
-
- error = input_register_device(dev->input);
- if (error)
- goto err_free_buffer;
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(iface, dev);
-
- return 0;
-
- err_free_buffer:
- usb_buffer_free(dev->udev, dev->datalen,
- dev->data, dev->urb->transfer_dma);
- err_free_urb:
- usb_free_urb(dev->urb);
- err_free_devs:
- usb_set_intfdata(iface, NULL);
- kfree(dev);
- input_free_device(input_dev);
- return error;
-}
-
-static void atp_disconnect(struct usb_interface *iface)
-{
- struct atp *dev = usb_get_intfdata(iface);
-
- usb_set_intfdata(iface, NULL);
- if (dev) {
- usb_kill_urb(dev->urb);
- input_unregister_device(dev->input);
- usb_buffer_free(dev->udev, dev->datalen,
- dev->data, dev->urb->transfer_dma);
- usb_free_urb(dev->urb);
- kfree(dev);
- }
- printk(KERN_INFO "input: appletouch disconnected\n");
-}
-
-static int atp_suspend(struct usb_interface *iface, pm_message_t message)
-{
- struct atp *dev = usb_get_intfdata(iface);
- usb_kill_urb(dev->urb);
- dev->valid = 0;
- return 0;
-}
-
-static int atp_resume(struct usb_interface *iface)
-{
- struct atp *dev = usb_get_intfdata(iface);
- if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
- return -EIO;
-
- return 0;
-}
-
-static struct usb_driver atp_driver = {
- .name = "appletouch",
- .probe = atp_probe,
- .disconnect = atp_disconnect,
- .suspend = atp_suspend,
- .resume = atp_resume,
- .id_table = atp_table,
-};
-
-static int __init atp_init(void)
-{
- return usb_register(&atp_driver);
-}
-
-static void __exit atp_exit(void)
-{
- usb_deregister(&atp_driver);
-}
-
-module_init(atp_init);
-module_exit(atp_exit);
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
deleted file mode 100644
index 471aab20644..00000000000
--- a/drivers/usb/input/ati_remote.c
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * USB ATI Remote support
- *
- * Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
- * Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
- *
- * This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including
- * porting to the 2.6 kernel interfaces, along with other modification
- * to better match the style of the existing usb/input drivers. However, the
- * protocol and hardware handling is essentially unchanged from 2.1.1.
- *
- * The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by
- * Vojtech Pavlik.
- *
- * Changes:
- *
- * Feb 2004: Torrey Hoffman <thoffman@arnor.net>
- * Version 2.2.0
- * Jun 2004: Torrey Hoffman <thoffman@arnor.net>
- * Version 2.2.1
- * Added key repeat support contributed by:
- * Vincent Vanackere <vanackere@lif.univ-mrs.fr>
- * Added support for the "Lola" remote contributed by:
- * Seth Cohn <sethcohn@yahoo.com>
- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *
- * Hardware & software notes
- *
- * These remote controls are distributed by ATI as part of their
- * "All-In-Wonder" video card packages. The receiver self-identifies as a
- * "USB Receiver" with manufacturer "X10 Wireless Technology Inc".
- *
- * The "Lola" remote is available from X10. See:
- * http://www.x10.com/products/lola_sg1.htm
- * The Lola is similar to the ATI remote but has no mouse support, and slightly
- * different keys.
- *
- * It is possible to use multiple receivers and remotes on multiple computers
- * simultaneously by configuring them to use specific channels.
- *
- * The RF protocol used by the remote supports 16 distinct channels, 1 to 16.
- * Actually, it may even support more, at least in some revisions of the
- * hardware.
- *
- * Each remote can be configured to transmit on one channel as follows:
- * - Press and hold the "hand icon" button.
- * - When the red LED starts to blink, let go of the "hand icon" button.
- * - When it stops blinking, input the channel code as two digits, from 01
- * to 16, and press the hand icon again.
- *
- * The timing can be a little tricky. Try loading the module with debug=1
- * to have the kernel print out messages about the remote control number
- * and mask. Note: debugging prints remote numbers as zero-based hexadecimal.
- *
- * The driver has a "channel_mask" parameter. This bitmask specifies which
- * channels will be ignored by the module. To mask out channels, just add
- * all the 2^channel_number values together.
- *
- * For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote
- * ignore signals coming from remote controls transmitting on channel 4, but
- * accept all other channels.
- *
- * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be
- * ignored.
- *
- * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this
- * parameter are unused.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/usb/input.h>
-#include <linux/wait.h>
-#include <linux/jiffies.h>
-
-/*
- * Module and Version Information, Module Parameters
- */
-
-#define ATI_REMOTE_VENDOR_ID 0x0bc7
-#define ATI_REMOTE_PRODUCT_ID 0x004
-#define LOLA_REMOTE_PRODUCT_ID 0x002
-#define MEDION_REMOTE_PRODUCT_ID 0x006
-
-#define DRIVER_VERSION "2.2.1"
-#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>"
-#define DRIVER_DESC "ATI/X10 RF USB Remote Control"
-
-#define NAME_BUFSIZE 80 /* size of product name, path buffers */
-#define DATA_BUFSIZE 63 /* size of URB data buffers */
-
-/*
- * Duplicate event filtering time.
- * Sequential, identical KIND_FILTERED inputs with less than
- * FILTER_TIME milliseconds between them are considered as repeat
- * events. The hardware generates 5 events for the first keypress
- * and we have to take this into account for an accurate repeat
- * behaviour.
- */
-#define FILTER_TIME 60 /* msec */
-#define REPEAT_DELAY 500 /* msec */
-
-static unsigned long channel_mask;
-module_param(channel_mask, ulong, 0644);
-MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
-
-static int repeat_filter = FILTER_TIME;
-module_param(repeat_filter, int, 0644);
-MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec");
-
-static int repeat_delay = REPEAT_DELAY;
-module_param(repeat_delay, int, 0644);
-MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec");
-
-#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
-#undef err
-#define err(format, arg...) printk(KERN_ERR format , ## arg)
-
-static struct usb_device_id ati_remote_table[] = {
- { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
- { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
- { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) },
- {} /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, ati_remote_table);
-
-/* Get hi and low bytes of a 16-bits int */
-#define HI(a) ((unsigned char)((a) >> 8))
-#define LO(a) ((unsigned char)((a) & 0xff))
-
-#define SEND_FLAG_IN_PROGRESS 1
-#define SEND_FLAG_COMPLETE 2
-
-/* Device initialization strings */
-static char init1[] = { 0x01, 0x00, 0x20, 0x14 };
-static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
-
-struct ati_remote {
- struct input_dev *idev;
- struct usb_device *udev;
- struct usb_interface *interface;
-
- struct urb *irq_urb;
- struct urb *out_urb;
- struct usb_endpoint_descriptor *endpoint_in;
- struct usb_endpoint_descriptor *endpoint_out;
- unsigned char *inbuf;
- unsigned char *outbuf;
- dma_addr_t inbuf_dma;
- dma_addr_t outbuf_dma;
-
- unsigned char old_data[2]; /* Detect duplicate events */
- unsigned long old_jiffies;
- unsigned long acc_jiffies; /* handle acceleration */
- unsigned long first_jiffies;
-
- unsigned int repeat_count;
-
- char name[NAME_BUFSIZE];
- char phys[NAME_BUFSIZE];
-
- wait_queue_head_t wait;
- int send_flags;
-};
-
-/* "Kinds" of messages sent from the hardware to the driver. */
-#define KIND_END 0
-#define KIND_LITERAL 1 /* Simply pass to input system */
-#define KIND_FILTERED 2 /* Add artificial key-up events, drop keyrepeats */
-#define KIND_LU 3 /* Directional keypad diagonals - left up, */
-#define KIND_RU 4 /* right up, */
-#define KIND_LD 5 /* left down, */
-#define KIND_RD 6 /* right down */
-#define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/
-
-/* Translation table from hardware messages to input events. */
-static const struct {
- short kind;
- unsigned char data1, data2;
- int type;
- unsigned int code;
- int value;
-} ati_remote_tbl[] = {
- /* Directional control pad axes */
- {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */
- {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */
- {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */
- {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */
- /* Directional control pad diagonals */
- {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */
- {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */
- {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */
- {KIND_RD, 0x3b, 0x76, EV_REL, 0, 0}, /* right down */
-
- /* "Mouse button" buttons */
- {KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */
- {KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */
- {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */
- {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */
-
- /* Artificial "doubleclick" events are generated by the hardware.
- * They are mapped to the "side" and "extra" mouse buttons here. */
- {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
- {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
-
- /* keyboard. */
- {KIND_FILTERED, 0xd2, 0x0d, EV_KEY, KEY_1, 1},
- {KIND_FILTERED, 0xd3, 0x0e, EV_KEY, KEY_2, 1},
- {KIND_FILTERED, 0xd4, 0x0f, EV_KEY, KEY_3, 1},
- {KIND_FILTERED, 0xd5, 0x10, EV_KEY, KEY_4, 1},
- {KIND_FILTERED, 0xd6, 0x11, EV_KEY, KEY_5, 1},
- {KIND_FILTERED, 0xd7, 0x12, EV_KEY, KEY_6, 1},
- {KIND_FILTERED, 0xd8, 0x13, EV_KEY, KEY_7, 1},
- {KIND_FILTERED, 0xd9, 0x14, EV_KEY, KEY_8, 1},
- {KIND_FILTERED, 0xda, 0x15, EV_KEY, KEY_9, 1},
- {KIND_FILTERED, 0xdc, 0x17, EV_KEY, KEY_0, 1},
- {KIND_FILTERED, 0xc5, 0x00, EV_KEY, KEY_A, 1},
- {KIND_FILTERED, 0xc6, 0x01, EV_KEY, KEY_B, 1},
- {KIND_FILTERED, 0xde, 0x19, EV_KEY, KEY_C, 1},
- {KIND_FILTERED, 0xe0, 0x1b, EV_KEY, KEY_D, 1},
- {KIND_FILTERED, 0xe6, 0x21, EV_KEY, KEY_E, 1},
- {KIND_FILTERED, 0xe8, 0x23, EV_KEY, KEY_F, 1},
-
- /* "special" keys */
- {KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_KPENTER, 1}, /* "check" */
- {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_MENU, 1}, /* "menu" */
- {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1}, /* Power */
- {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_TV, 1}, /* TV */
- {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_DVD, 1}, /* DVD */
- {KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1}, /* WEB */
- {KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1}, /* "book" */
- {KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_EDIT, 1}, /* "hand" */
- {KIND_FILTERED, 0xe1, 0x1c, EV_KEY, KEY_COFFEE, 1}, /* "timer" */
- {KIND_FILTERED, 0xe5, 0x20, EV_KEY, KEY_FRONT, 1}, /* "max" */
- {KIND_FILTERED, 0xe2, 0x1d, EV_KEY, KEY_LEFT, 1}, /* left */
- {KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1}, /* right */
- {KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1}, /* down */
- {KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1}, /* up */
- {KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_OK, 1}, /* "OK" */
- {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_VOLUMEDOWN, 1}, /* VOL + */
- {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_VOLUMEUP, 1}, /* VOL - */
- {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_MUTE, 1}, /* MUTE */
- {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELUP, 1}, /* CH + */
- {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */
- {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_RECORD, 1}, /* ( o) red */
- {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */
- {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */
- {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */
- {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */
- {KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1}, /* ('') */
- {KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1}, /* (<-) */
- {KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1}, /* (>+) */
- {KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1}, /* PLAYING */
- {KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1}, /* TOP */
- {KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1}, /* END */
- {KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1}, /* SELECT */
-
- {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
-};
-
-/* Local function prototypes */
-static void ati_remote_dump (unsigned char *data, unsigned int actual_length);
-static int ati_remote_open (struct input_dev *inputdev);
-static void ati_remote_close (struct input_dev *inputdev);
-static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
-static void ati_remote_irq_out (struct urb *urb);
-static void ati_remote_irq_in (struct urb *urb);
-static void ati_remote_input_report (struct urb *urb);
-static int ati_remote_initialize (struct ati_remote *ati_remote);
-static int ati_remote_probe (struct usb_interface *interface, const struct usb_device_id *id);
-static void ati_remote_disconnect (struct usb_interface *interface);
-
-/* usb specific object to register with the usb subsystem */
-static struct usb_driver ati_remote_driver = {
- .name = "ati_remote",
- .probe = ati_remote_probe,
- .disconnect = ati_remote_disconnect,
- .id_table = ati_remote_table,
-};
-
-/*
- * ati_remote_dump_input
- */
-static void ati_remote_dump(unsigned char *data, unsigned int len)
-{
- if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00))
- warn("Weird byte 0x%02x", data[0]);
- else if (len == 4)
- warn("Weird key %02x %02x %02x %02x",
- data[0], data[1], data[2], data[3]);
- else
- warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...",
- len, data[0], data[1], data[2], data[3], data[4], data[5]);
-}
-
-/*
- * ati_remote_open
- */
-static int ati_remote_open(struct input_dev *inputdev)
-{
- struct ati_remote *ati_remote = input_get_drvdata(inputdev);
-
- /* On first open, submit the read urb which was set up previously. */
- ati_remote->irq_urb->dev = ati_remote->udev;
- if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
- dev_err(&ati_remote->interface->dev,
- "%s: usb_submit_urb failed!\n", __FUNCTION__);
- return -EIO;
- }
-
- return 0;
-}
-
-/*
- * ati_remote_close
- */
-static void ati_remote_close(struct input_dev *inputdev)
-{
- struct ati_remote *ati_remote = input_get_drvdata(inputdev);
-
- usb_kill_urb(ati_remote->irq_urb);
-}
-
-/*
- * ati_remote_irq_out
- */
-static void ati_remote_irq_out(struct urb *urb)
-{
- struct ati_remote *ati_remote = urb->context;
-
- if (urb->status) {
- dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
- __FUNCTION__, urb->status);
- return;
- }
-
- ati_remote->send_flags |= SEND_FLAG_COMPLETE;
- wmb();
- wake_up(&ati_remote->wait);
-}
-
-/*
- * ati_remote_sendpacket
- *
- * Used to send device initialization strings
- */
-static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigned char *data)
-{
- int retval = 0;
-
- /* Set up out_urb */
- memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd));
- ((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd);
-
- ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1;
- ati_remote->out_urb->dev = ati_remote->udev;
- ati_remote->send_flags = SEND_FLAG_IN_PROGRESS;
-
- retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC);
- if (retval) {
- dev_dbg(&ati_remote->interface->dev,
- "sendpacket: usb_submit_urb failed: %d\n", retval);
- return retval;
- }
-
- wait_event_timeout(ati_remote->wait,
- ((ati_remote->out_urb->status != -EINPROGRESS) ||
- (ati_remote->send_flags & SEND_FLAG_COMPLETE)),
- HZ);
- usb_kill_urb(ati_remote->out_urb);
-
- return retval;
-}
-
-/*
- * ati_remote_event_lookup
- */
-static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2)
-{
- int i;
-
- for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
- /*
- * Decide if the table entry matches the remote input.
- */
- if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) &&
- ((((ati_remote_tbl[i].data1 >> 4) -
- (d1 >> 4) + rem) & 0x0f) == 0x0f) &&
- (ati_remote_tbl[i].data2 == d2))
- return i;
-
- }
- return -1;
-}
-
-/*
- * ati_remote_compute_accel
- *
- * Implements acceleration curve for directional control pad
- * If elapsed time since last event is > 1/4 second, user "stopped",
- * so reset acceleration. Otherwise, user is probably holding the control
- * pad down, so we increase acceleration, ramping up over two seconds to
- * a maximum speed.
- */
-static int ati_remote_compute_accel(struct ati_remote *ati_remote)
-{
- static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
- unsigned long now = jiffies;
- int acc;
-
- if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) {
- acc = 1;
- ati_remote->acc_jiffies = now;
- }
- else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125)))
- acc = accel[0];
- else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250)))
- acc = accel[1];
- else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500)))
- acc = accel[2];
- else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000)))
- acc = accel[3];
- else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500)))
- acc = accel[4];
- else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000)))
- acc = accel[5];
- else
- acc = accel[6];
-
- return acc;
-}
-
-/*
- * ati_remote_report_input
- */
-static void ati_remote_input_report(struct urb *urb)
-{
- struct ati_remote *ati_remote = urb->context;
- unsigned char *data= ati_remote->inbuf;
- struct input_dev *dev = ati_remote->idev;
- int index, acc;
- int remote_num;
-
- /* Deal with strange looking inputs */
- if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
- ((data[3] & 0x0f) != 0x00) ) {
- ati_remote_dump(data, urb->actual_length);
- return;
- }
-
- /* Mask unwanted remote channels. */
- /* note: remote_num is 0-based, channel 1 on remote == 0 here */
- remote_num = (data[3] >> 4) & 0x0f;
- if (channel_mask & (1 << (remote_num + 1))) {
- dbginfo(&ati_remote->interface->dev,
- "Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n",
- remote_num, data[1], data[2], channel_mask);
- return;
- }
-
- /* Look up event code index in translation table */
- index = ati_remote_event_lookup(remote_num, data[1], data[2]);
- if (index < 0) {
- dev_warn(&ati_remote->interface->dev,
- "Unknown input from channel 0x%02x: data %02x,%02x\n",
- remote_num, data[1], data[2]);
- return;
- }
- dbginfo(&ati_remote->interface->dev,
- "channel 0x%02x; data %02x,%02x; index %d; keycode %d\n",
- remote_num, data[1], data[2], index, ati_remote_tbl[index].code);
-
- if (ati_remote_tbl[index].kind == KIND_LITERAL) {
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code,
- ati_remote_tbl[index].value);
- input_sync(dev);
-
- ati_remote->old_jiffies = jiffies;
- return;
- }
-
- if (ati_remote_tbl[index].kind == KIND_FILTERED) {
- unsigned long now = jiffies;
-
- /* Filter duplicate events which happen "too close" together. */
- if (ati_remote->old_data[0] == data[1] &&
- ati_remote->old_data[1] == data[2] &&
- time_before(now, ati_remote->old_jiffies +
- msecs_to_jiffies(repeat_filter))) {
- ati_remote->repeat_count++;
- } else {
- ati_remote->repeat_count = 0;
- ati_remote->first_jiffies = now;
- }
-
- ati_remote->old_data[0] = data[1];
- ati_remote->old_data[1] = data[2];
- ati_remote->old_jiffies = now;
-
- /* Ensure we skip at least the 4 first duplicate events (generated
- * by a single keypress), and continue skipping until repeat_delay
- * msecs have passed
- */
- if (ati_remote->repeat_count > 0 &&
- (ati_remote->repeat_count < 5 ||
- time_before(now, ati_remote->first_jiffies +
- msecs_to_jiffies(repeat_delay))))
- return;
-
-
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code, 1);
- input_sync(dev);
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code, 0);
- input_sync(dev);
-
- } else {
-
- /*
- * Other event kinds are from the directional control pad, and have an
- * acceleration factor applied to them. Without this acceleration, the
- * control pad is mostly unusable.
- */
- acc = ati_remote_compute_accel(ati_remote);
-
- switch (ati_remote_tbl[index].kind) {
- case KIND_ACCEL:
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code,
- ati_remote_tbl[index].value * acc);
- break;
- case KIND_LU:
- input_report_rel(dev, REL_X, -acc);
- input_report_rel(dev, REL_Y, -acc);
- break;
- case KIND_RU:
- input_report_rel(dev, REL_X, acc);
- input_report_rel(dev, REL_Y, -acc);
- break;
- case KIND_LD:
- input_report_rel(dev, REL_X, -acc);
- input_report_rel(dev, REL_Y, acc);
- break;
- case KIND_RD:
- input_report_rel(dev, REL_X, acc);
- input_report_rel(dev, REL_Y, acc);
- break;
- default:
- dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
- ati_remote_tbl[index].kind);
- }
- input_sync(dev);
-
- ati_remote->old_jiffies = jiffies;
- ati_remote->old_data[0] = data[1];
- ati_remote->old_data[1] = data[2];
- }
-}
-
-/*
- * ati_remote_irq_in
- */
-static void ati_remote_irq_in(struct urb *urb)
-{
- struct ati_remote *ati_remote = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0: /* success */
- ati_remote_input_report(urb);
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n",
- __FUNCTION__);
- return;
- default: /* error */
- dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
- __FUNCTION__, urb->status);
- }
-
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
- __FUNCTION__, retval);
-}
-
-/*
- * ati_remote_alloc_buffers
- */
-static int ati_remote_alloc_buffers(struct usb_device *udev,
- struct ati_remote *ati_remote)
-{
- ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
- &ati_remote->inbuf_dma);
- if (!ati_remote->inbuf)
- return -1;
-
- ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, GFP_ATOMIC,
- &ati_remote->outbuf_dma);
- if (!ati_remote->outbuf)
- return -1;
-
- ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ati_remote->irq_urb)
- return -1;
-
- ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!ati_remote->out_urb)
- return -1;
-
- return 0;
-}
-
-/*
- * ati_remote_free_buffers
- */
-static void ati_remote_free_buffers(struct ati_remote *ati_remote)
-{
- usb_free_urb(ati_remote->irq_urb);
- usb_free_urb(ati_remote->out_urb);
-
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->inbuf, ati_remote->inbuf_dma);
-
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->outbuf, ati_remote->outbuf_dma);
-}
-
-static void ati_remote_input_init(struct ati_remote *ati_remote)
-{
- struct input_dev *idev = ati_remote->idev;
- int i;
-
- idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
- BIT(BTN_SIDE) | BIT(BTN_EXTRA) );
- idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
- if (ati_remote_tbl[i].type == EV_KEY)
- set_bit(ati_remote_tbl[i].code, idev->keybit);
-
- input_set_drvdata(idev, ati_remote);
-
- idev->open = ati_remote_open;
- idev->close = ati_remote_close;
-
- idev->name = ati_remote->name;
- idev->phys = ati_remote->phys;
-
- usb_to_input_id(ati_remote->udev, &idev->id);
- idev->dev.parent = &ati_remote->udev->dev;
-}
-
-static int ati_remote_initialize(struct ati_remote *ati_remote)
-{
- struct usb_device *udev = ati_remote->udev;
- int pipe, maxp;
-
- init_waitqueue_head(&ati_remote->wait);
-
- /* Set up irq_urb */
- pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
-
- usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf,
- maxp, ati_remote_irq_in, ati_remote,
- ati_remote->endpoint_in->bInterval);
- ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma;
- ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* Set up out_urb */
- pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
-
- usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf,
- maxp, ati_remote_irq_out, ati_remote,
- ati_remote->endpoint_out->bInterval);
- ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma;
- ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* send initialization strings */
- if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) ||
- (ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
- dev_err(&ati_remote->interface->dev,
- "Initializing ati_remote hardware failed.\n");
- return -EIO;
- }
-
- return 0;
-}
-
-/*
- * ati_remote_probe
- */
-static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_host_interface *iface_host = interface->cur_altsetting;
- struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
- struct ati_remote *ati_remote;
- struct input_dev *input_dev;
- int err = -ENOMEM;
-
- if (iface_host->desc.bNumEndpoints != 2) {
- err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
- return -ENODEV;
- }
-
- endpoint_in = &iface_host->endpoint[0].desc;
- endpoint_out = &iface_host->endpoint[1].desc;
-
- if (!usb_endpoint_is_int_in(endpoint_in)) {
- err("%s: Unexpected endpoint_in\n", __FUNCTION__);
- return -ENODEV;
- }
- if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
- err("%s: endpoint_in message size==0? \n", __FUNCTION__);
- return -ENODEV;
- }
-
- ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ati_remote || !input_dev)
- goto fail1;
-
- /* Allocate URB buffers, URBs */
- if (ati_remote_alloc_buffers(udev, ati_remote))
- goto fail2;
-
- ati_remote->endpoint_in = endpoint_in;
- ati_remote->endpoint_out = endpoint_out;
- ati_remote->udev = udev;
- ati_remote->idev = input_dev;
- ati_remote->interface = interface;
-
- usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
- strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
-
- if (udev->manufacturer)
- strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
-
- if (udev->product)
- snprintf(ati_remote->name, sizeof(ati_remote->name),
- "%s %s", ati_remote->name, udev->product);
-
- if (!strlen(ati_remote->name))
- snprintf(ati_remote->name, sizeof(ati_remote->name),
- DRIVER_DESC "(%04x,%04x)",
- le16_to_cpu(ati_remote->udev->descriptor.idVendor),
- le16_to_cpu(ati_remote->udev->descriptor.idProduct));
-
- ati_remote_input_init(ati_remote);
-
- /* Device Hardware Initialization - fills in ati_remote->idev from udev. */
- err = ati_remote_initialize(ati_remote);
- if (err)
- goto fail3;
-
- /* Set up and register input device */
- err = input_register_device(ati_remote->idev);
- if (err)
- goto fail3;
-
- usb_set_intfdata(interface, ati_remote);
- return 0;
-
- fail3: usb_kill_urb(ati_remote->irq_urb);
- usb_kill_urb(ati_remote->out_urb);
- fail2: ati_remote_free_buffers(ati_remote);
- fail1: input_free_device(input_dev);
- kfree(ati_remote);
- return err;
-}
-
-/*
- * ati_remote_disconnect
- */
-static void ati_remote_disconnect(struct usb_interface *interface)
-{
- struct ati_remote *ati_remote;
-
- ati_remote = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
- if (!ati_remote) {
- warn("%s - null device?\n", __FUNCTION__);
- return;
- }
-
- usb_kill_urb(ati_remote->irq_urb);
- usb_kill_urb(ati_remote->out_urb);
- input_unregister_device(ati_remote->idev);
- ati_remote_free_buffers(ati_remote);
- kfree(ati_remote);
-}
-
-/*
- * ati_remote_init
- */
-static int __init ati_remote_init(void)
-{
- int result;
-
- result = usb_register(&ati_remote_driver);
- if (result)
- err("usb_register error #%d\n", result);
- else
- info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION);
-
- return result;
-}
-
-/*
- * ati_remote_exit
- */
-static void __exit ati_remote_exit(void)
-{
- usb_deregister(&ati_remote_driver);
-}
-
-/*
- * module specification
- */
-
-module_init(ati_remote_init);
-module_exit(ati_remote_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c
deleted file mode 100644
index a9032aa3465..00000000000
--- a/drivers/usb/input/ati_remote2.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * ati_remote2 - ATI/Philips USB RF remote driver
- *
- * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
- * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- */
-
-#include <linux/usb/input.h>
-
-#define DRIVER_DESC "ATI/Philips USB RF remote driver"
-#define DRIVER_VERSION "0.2"
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
-MODULE_LICENSE("GPL");
-
-/*
- * ATI Remote Wonder II Channel Configuration
- *
- * The remote control can by assigned one of sixteen "channels" in order to facilitate
- * the use of multiple remote controls within range of each other.
- * A remote's "channel" may be altered by pressing and holding the "PC" button for
- * approximately 3 seconds, after which the button will slowly flash the count of the
- * currently configured "channel", using the numeric keypad enter a number between 1 and
- * 16 and then the "PC" button again, the button will slowly flash the count of the
- * newly configured "channel".
- */
-
-static unsigned int channel_mask = 0xFFFF;
-module_param(channel_mask, uint, 0644);
-MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
-
-static unsigned int mode_mask = 0x1F;
-module_param(mode_mask, uint, 0644);
-MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
-
-static struct usb_device_id ati_remote2_id_table[] = {
- { USB_DEVICE(0x0471, 0x0602) }, /* ATI Remote Wonder II */
- { }
-};
-MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
-
-static struct {
- int hw_code;
- int key_code;
-} ati_remote2_key_table[] = {
- { 0x00, KEY_0 },
- { 0x01, KEY_1 },
- { 0x02, KEY_2 },
- { 0x03, KEY_3 },
- { 0x04, KEY_4 },
- { 0x05, KEY_5 },
- { 0x06, KEY_6 },
- { 0x07, KEY_7 },
- { 0x08, KEY_8 },
- { 0x09, KEY_9 },
- { 0x0c, KEY_POWER },
- { 0x0d, KEY_MUTE },
- { 0x10, KEY_VOLUMEUP },
- { 0x11, KEY_VOLUMEDOWN },
- { 0x20, KEY_CHANNELUP },
- { 0x21, KEY_CHANNELDOWN },
- { 0x28, KEY_FORWARD },
- { 0x29, KEY_REWIND },
- { 0x2c, KEY_PLAY },
- { 0x30, KEY_PAUSE },
- { 0x31, KEY_STOP },
- { 0x37, KEY_RECORD },
- { 0x38, KEY_DVD },
- { 0x39, KEY_TV },
- { 0x54, KEY_MENU },
- { 0x58, KEY_UP },
- { 0x59, KEY_DOWN },
- { 0x5a, KEY_LEFT },
- { 0x5b, KEY_RIGHT },
- { 0x5c, KEY_OK },
- { 0x78, KEY_A },
- { 0x79, KEY_B },
- { 0x7a, KEY_C },
- { 0x7b, KEY_D },
- { 0x7c, KEY_E },
- { 0x7d, KEY_F },
- { 0x82, KEY_ENTER },
- { 0x8e, KEY_VENDOR },
- { 0x96, KEY_COFFEE },
- { 0xa9, BTN_LEFT },
- { 0xaa, BTN_RIGHT },
- { 0xbe, KEY_QUESTION },
- { 0xd5, KEY_FRONT },
- { 0xd0, KEY_EDIT },
- { 0xf9, KEY_INFO },
- { (0x00 << 8) | 0x3f, KEY_PROG1 },
- { (0x01 << 8) | 0x3f, KEY_PROG2 },
- { (0x02 << 8) | 0x3f, KEY_PROG3 },
- { (0x03 << 8) | 0x3f, KEY_PROG4 },
- { (0x04 << 8) | 0x3f, KEY_PC },
- { 0, KEY_RESERVED }
-};
-
-struct ati_remote2 {
- struct input_dev *idev;
- struct usb_device *udev;
-
- struct usb_interface *intf[2];
- struct usb_endpoint_descriptor *ep[2];
- struct urb *urb[2];
- void *buf[2];
- dma_addr_t buf_dma[2];
-
- unsigned long jiffies;
- int mode;
-
- char name[64];
- char phys[64];
-};
-
-static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
-static void ati_remote2_disconnect(struct usb_interface *interface);
-
-static struct usb_driver ati_remote2_driver = {
- .name = "ati_remote2",
- .probe = ati_remote2_probe,
- .disconnect = ati_remote2_disconnect,
- .id_table = ati_remote2_id_table,
-};
-
-static int ati_remote2_open(struct input_dev *idev)
-{
- struct ati_remote2 *ar2 = input_get_drvdata(idev);
- int r;
-
- r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
- if (r) {
- dev_err(&ar2->intf[0]->dev,
- "%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
- return r;
- }
- r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
- if (r) {
- usb_kill_urb(ar2->urb[0]);
- dev_err(&ar2->intf[1]->dev,
- "%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
- return r;
- }
-
- return 0;
-}
-
-static void ati_remote2_close(struct input_dev *idev)
-{
- struct ati_remote2 *ar2 = input_get_drvdata(idev);
-
- usb_kill_urb(ar2->urb[0]);
- usb_kill_urb(ar2->urb[1]);
-}
-
-static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
-{
- struct input_dev *idev = ar2->idev;
- u8 *data = ar2->buf[0];
- int channel, mode;
-
- channel = data[0] >> 4;
-
- if (!((1 << channel) & channel_mask))
- return;
-
- mode = data[0] & 0x0F;
-
- if (mode > 4) {
- dev_err(&ar2->intf[0]->dev,
- "Unknown mode byte (%02x %02x %02x %02x)\n",
- data[3], data[2], data[1], data[0]);
- return;
- }
-
- if (!((1 << mode) & mode_mask))
- return;
-
- input_event(idev, EV_REL, REL_X, (s8) data[1]);
- input_event(idev, EV_REL, REL_Y, (s8) data[2]);
- input_sync(idev);
-}
-
-static int ati_remote2_lookup(unsigned int hw_code)
-{
- int i;
-
- for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
- if (ati_remote2_key_table[i].hw_code == hw_code)
- return i;
-
- return -1;
-}
-
-static void ati_remote2_input_key(struct ati_remote2 *ar2)
-{
- struct input_dev *idev = ar2->idev;
- u8 *data = ar2->buf[1];
- int channel, mode, hw_code, index;
-
- channel = data[0] >> 4;
-
- if (!((1 << channel) & channel_mask))
- return;
-
- mode = data[0] & 0x0F;
-
- if (mode > 4) {
- dev_err(&ar2->intf[1]->dev,
- "Unknown mode byte (%02x %02x %02x %02x)\n",
- data[3], data[2], data[1], data[0]);
- return;
- }
-
- hw_code = data[2];
- /*
- * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
- * Use the mode byte to figure out which one was pressed.
- */
- if (hw_code == 0x3f) {
- /*
- * For some incomprehensible reason the mouse pad generates
- * events which look identical to the events from the last
- * pressed mode key. Naturally we don't want to generate key
- * events for the mouse pad so we filter out any subsequent
- * events from the same mode key.
- */
- if (ar2->mode == mode)
- return;
-
- if (data[1] == 0)
- ar2->mode = mode;
-
- hw_code |= mode << 8;
- }
-
- if (!((1 << mode) & mode_mask))
- return;
-
- index = ati_remote2_lookup(hw_code);
- if (index < 0) {
- dev_err(&ar2->intf[1]->dev,
- "Unknown code byte (%02x %02x %02x %02x)\n",
- data[3], data[2], data[1], data[0]);
- return;
- }
-
- switch (data[1]) {
- case 0: /* release */
- break;
- case 1: /* press */
- ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]);
- break;
- case 2: /* repeat */
-
- /* No repeat for mouse buttons. */
- if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
- ati_remote2_key_table[index].key_code == BTN_RIGHT)
- return;
-
- if (!time_after_eq(jiffies, ar2->jiffies))
- return;
-
- ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]);
- break;
- default:
- dev_err(&ar2->intf[1]->dev,
- "Unknown state byte (%02x %02x %02x %02x)\n",
- data[3], data[2], data[1], data[0]);
- return;
- }
-
- input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
- input_sync(idev);
-}
-
-static void ati_remote2_complete_mouse(struct urb *urb)
-{
- struct ati_remote2 *ar2 = urb->context;
- int r;
-
- switch (urb->status) {
- case 0:
- ati_remote2_input_mouse(ar2);
- break;
- case -ENOENT:
- case -EILSEQ:
- case -ECONNRESET:
- case -ESHUTDOWN:
- dev_dbg(&ar2->intf[0]->dev,
- "%s(): urb status = %d\n", __FUNCTION__, urb->status);
- return;
- default:
- dev_err(&ar2->intf[0]->dev,
- "%s(): urb status = %d\n", __FUNCTION__, urb->status);
- }
-
- r = usb_submit_urb(urb, GFP_ATOMIC);
- if (r)
- dev_err(&ar2->intf[0]->dev,
- "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
-}
-
-static void ati_remote2_complete_key(struct urb *urb)
-{
- struct ati_remote2 *ar2 = urb->context;
- int r;
-
- switch (urb->status) {
- case 0:
- ati_remote2_input_key(ar2);
- break;
- case -ENOENT:
- case -EILSEQ:
- case -ECONNRESET:
- case -ESHUTDOWN:
- dev_dbg(&ar2->intf[1]->dev,
- "%s(): urb status = %d\n", __FUNCTION__, urb->status);
- return;
- default:
- dev_err(&ar2->intf[1]->dev,
- "%s(): urb status = %d\n", __FUNCTION__, urb->status);
- }
-
- r = usb_submit_urb(urb, GFP_ATOMIC);
- if (r)
- dev_err(&ar2->intf[1]->dev,
- "%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
-}
-
-static int ati_remote2_input_init(struct ati_remote2 *ar2)
-{
- struct input_dev *idev;
- int i, retval;
-
- idev = input_allocate_device();
- if (!idev)
- return -ENOMEM;
-
- ar2->idev = idev;
- input_set_drvdata(idev, ar2);
-
- idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
- idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
- idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
- set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
-
- idev->rep[REP_DELAY] = 250;
- idev->rep[REP_PERIOD] = 33;
-
- idev->open = ati_remote2_open;
- idev->close = ati_remote2_close;
-
- idev->name = ar2->name;
- idev->phys = ar2->phys;
-
- usb_to_input_id(ar2->udev, &idev->id);
- idev->dev.parent = &ar2->udev->dev;
-
- retval = input_register_device(idev);
- if (retval)
- input_free_device(idev);
-
- return retval;
-}
-
-static int ati_remote2_urb_init(struct ati_remote2 *ar2)
-{
- struct usb_device *udev = ar2->udev;
- int i, pipe, maxp;
-
- for (i = 0; i < 2; i++) {
- ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
- if (!ar2->buf[i])
- return -ENOMEM;
-
- ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
- if (!ar2->urb[i])
- return -ENOMEM;
-
- pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- maxp = maxp > 4 ? 4 : maxp;
-
- usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp,
- i ? ati_remote2_complete_key : ati_remote2_complete_mouse,
- ar2, ar2->ep[i]->bInterval);
- ar2->urb[i]->transfer_dma = ar2->buf_dma[i];
- ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- }
-
- return 0;
-}
-
-static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
-{
- int i;
-
- for (i = 0; i < 2; i++) {
- usb_free_urb(ar2->urb[i]);
-
- if (ar2->buf[i])
- usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
- }
-}
-
-static int ati_remote2_setup(struct ati_remote2 *ar2)
-{
- int r, i, channel;
-
- /*
- * Configure receiver to only accept input from remote "channel"
- * channel == 0 -> Accept input from any remote channel
- * channel == 1 -> Only accept input from remote channel 1
- * channel == 2 -> Only accept input from remote channel 2
- * ...
- * channel == 16 -> Only accept input from remote channel 16
- */
-
- channel = 0;
- for (i = 0; i < 16; i++) {
- if ((1 << i) & channel_mask) {
- if (!(~(1 << i) & 0xFFFF & channel_mask))
- channel = i + 1;
- break;
- }
- }
-
- r = usb_control_msg(ar2->udev, usb_sndctrlpipe(ar2->udev, 0),
- 0x20,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (r) {
- dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n",
- __FUNCTION__, r);
- return r;
- }
-
- return 0;
-}
-
-static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_host_interface *alt = interface->cur_altsetting;
- struct ati_remote2 *ar2;
- int r;
-
- if (alt->desc.bInterfaceNumber)
- return -ENODEV;
-
- ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL);
- if (!ar2)
- return -ENOMEM;
-
- ar2->udev = udev;
-
- ar2->intf[0] = interface;
- ar2->ep[0] = &alt->endpoint[0].desc;
-
- ar2->intf[1] = usb_ifnum_to_if(udev, 1);
- r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
- if (r)
- goto fail1;
- alt = ar2->intf[1]->cur_altsetting;
- ar2->ep[1] = &alt->endpoint[0].desc;
-
- r = ati_remote2_urb_init(ar2);
- if (r)
- goto fail2;
-
- r = ati_remote2_setup(ar2);
- if (r)
- goto fail2;
-
- usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
- strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
-
- strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
-
- r = ati_remote2_input_init(ar2);
- if (r)
- goto fail2;
-
- usb_set_intfdata(interface, ar2);
-
- return 0;
-
- fail2:
- ati_remote2_urb_cleanup(ar2);
-
- usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
- fail1:
- kfree(ar2);
-
- return r;
-}
-
-static void ati_remote2_disconnect(struct usb_interface *interface)
-{
- struct ati_remote2 *ar2;
- struct usb_host_interface *alt = interface->cur_altsetting;
-
- if (alt->desc.bInterfaceNumber)
- return;
-
- ar2 = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- input_unregister_device(ar2->idev);
-
- ati_remote2_urb_cleanup(ar2);
-
- usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
-
- kfree(ar2);
-}
-
-static int __init ati_remote2_init(void)
-{
- int r;
-
- r = usb_register(&ati_remote2_driver);
- if (r)
- printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r);
- else
- printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n");
-
- return r;
-}
-
-static void __exit ati_remote2_exit(void)
-{
- usb_deregister(&ati_remote2_driver);
-}
-
-module_init(ati_remote2_init);
-module_exit(ati_remote2_exit);
diff --git a/drivers/usb/input/gtco.c b/drivers/usb/input/gtco.c
deleted file mode 100644
index b2ca10f2fe0..00000000000
--- a/drivers/usb/input/gtco.c
+++ /dev/null
@@ -1,1055 +0,0 @@
-/* -*- linux-c -*-
-
-GTCO digitizer USB driver
-
-Use the err(), dbg() and info() macros from usb.h for system logging
-
-TO CHECK: Is pressure done right on report 5?
-
-Copyright (C) 2006 GTCO CalComp
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; version 2
-of the License.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation, and that the name of GTCO-CalComp not be used in advertising
-or publicity pertaining to distribution of the software without specific,
-written prior permission. GTCO-CalComp makes no representations about the
-suitability of this software for any purpose. It is provided "as is"
-without express or implied warranty.
-
-GTCO-CALCOMP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
-EVENT SHALL GTCO-CALCOMP BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-GTCO CalComp, Inc.
-7125 Riverwood Drive
-Columbia, MD 21046
-
-Jeremy Roberson jroberson@gtcocalcomp.com
-Scott Hill shill@gtcocalcomp.com
-*/
-
-
-
-/*#define DEBUG*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <asm/uaccess.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-
-
-#include <linux/version.h>
-#include <linux/usb/input.h>
-
-/* Version with a Major number of 2 is for kernel inclusion only. */
-#define GTCO_VERSION "2.00.0006"
-
-
-/* MACROS */
-
-#define VENDOR_ID_GTCO 0x078C
-#define PID_400 0x400
-#define PID_401 0x401
-#define PID_1000 0x1000
-#define PID_1001 0x1001
-#define PID_1002 0x1002
-
-/* Max size of a single report */
-#define REPORT_MAX_SIZE 10
-
-
-/* Bitmask whether pen is in range */
-#define MASK_INRANGE 0x20
-#define MASK_BUTTON 0x01F
-
-#define PATHLENGTH 64
-
-/* DATA STRUCTURES */
-
-/* Device table */
-static struct usb_device_id gtco_usbid_table [] = {
- { USB_DEVICE(VENDOR_ID_GTCO, PID_400) },
- { USB_DEVICE(VENDOR_ID_GTCO, PID_401) },
- { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) },
- { USB_DEVICE(VENDOR_ID_GTCO, PID_1001) },
- { USB_DEVICE(VENDOR_ID_GTCO, PID_1002) },
- { }
-};
-MODULE_DEVICE_TABLE (usb, gtco_usbid_table);
-
-
-/* Structure to hold all of our device specific stuff */
-struct gtco {
-
- struct input_dev *inputdevice; /* input device struct pointer */
- struct usb_device *usbdev; /* the usb device for this device */
- struct urb *urbinfo; /* urb for incoming reports */
- dma_addr_t buf_dma; /* dma addr of the data buffer*/
- unsigned char * buffer; /* databuffer for reports */
-
- char usbpath[PATHLENGTH];
- int openCount;
-
- /* Information pulled from Report Descriptor */
- u32 usage;
- u32 min_X;
- u32 max_X;
- u32 min_Y;
- u32 max_Y;
- s8 mintilt_X;
- s8 maxtilt_X;
- s8 mintilt_Y;
- s8 maxtilt_Y;
- u32 maxpressure;
- u32 minpressure;
-};
-
-
-
-/* Code for parsing the HID REPORT DESCRIPTOR */
-
-/* From HID1.11 spec */
-struct hid_descriptor
-{
- struct usb_descriptor_header header;
- __le16 bcdHID;
- u8 bCountryCode;
- u8 bNumDescriptors;
- u8 bDescriptorType;
- __le16 wDescriptorLength;
-} __attribute__ ((packed));
-
-
-#define HID_DESCRIPTOR_SIZE 9
-#define HID_DEVICE_TYPE 33
-#define REPORT_DEVICE_TYPE 34
-
-
-#define PREF_TAG(x) ((x)>>4)
-#define PREF_TYPE(x) ((x>>2)&0x03)
-#define PREF_SIZE(x) ((x)&0x03)
-
-#define TYPE_MAIN 0
-#define TYPE_GLOBAL 1
-#define TYPE_LOCAL 2
-#define TYPE_RESERVED 3
-
-#define TAG_MAIN_INPUT 0x8
-#define TAG_MAIN_OUTPUT 0x9
-#define TAG_MAIN_FEATURE 0xB
-#define TAG_MAIN_COL_START 0xA
-#define TAG_MAIN_COL_END 0xC
-
-#define TAG_GLOB_USAGE 0
-#define TAG_GLOB_LOG_MIN 1
-#define TAG_GLOB_LOG_MAX 2
-#define TAG_GLOB_PHYS_MIN 3
-#define TAG_GLOB_PHYS_MAX 4
-#define TAG_GLOB_UNIT_EXP 5
-#define TAG_GLOB_UNIT 6
-#define TAG_GLOB_REPORT_SZ 7
-#define TAG_GLOB_REPORT_ID 8
-#define TAG_GLOB_REPORT_CNT 9
-#define TAG_GLOB_PUSH 10
-#define TAG_GLOB_POP 11
-
-#define TAG_GLOB_MAX 12
-
-#define DIGITIZER_USAGE_TIP_PRESSURE 0x30
-#define DIGITIZER_USAGE_TILT_X 0x3D
-#define DIGITIZER_USAGE_TILT_Y 0x3E
-
-
-/*
- * This is an abbreviated parser for the HID Report Descriptor. We
- * know what devices we are talking to, so this is by no means meant
- * to be generic. We can make some safe assumptions:
- *
- * - We know there are no LONG tags, all short
- * - We know that we have no MAIN Feature and MAIN Output items
- * - We know what the IRQ reports are supposed to look like.
- *
- * The main purpose of this is to use the HID report desc to figure
- * out the mins and maxs of the fields in the IRQ reports. The IRQ
- * reports for 400/401 change slightly if the max X is bigger than 64K.
- *
- */
-static void parse_hid_report_descriptor(struct gtco *device, char * report,
- int length)
-{
- int x, i = 0;
-
- /* Tag primitive vars */
- __u8 prefix;
- __u8 size;
- __u8 tag;
- __u8 type;
- __u8 data = 0;
- __u16 data16 = 0;
- __u32 data32 = 0;
-
- /* For parsing logic */
- int inputnum = 0;
- __u32 usage = 0;
-
- /* Global Values, indexed by TAG */
- __u32 globalval[TAG_GLOB_MAX];
- __u32 oldval[TAG_GLOB_MAX];
-
- /* Debug stuff */
- char maintype = 'x';
- char globtype[12];
- int indent = 0;
- char indentstr[10] = "";
-
-
- dbg("======>>>>>>PARSE<<<<<<======");
-
- /* Walk this report and pull out the info we need */
- while (i < length) {
- prefix = report[i];
-
- /* Skip over prefix */
- i++;
-
- /* Determine data size and save the data in the proper variable */
- size = PREF_SIZE(prefix);
- switch (size) {
- case 1:
- data = report[i];
- break;
- case 2:
- data16 = le16_to_cpu(get_unaligned((__le16 *)&report[i]));
- break;
- case 3:
- size = 4;
- data32 = le32_to_cpu(get_unaligned((__le32 *)&report[i]));
- break;
- }
-
- /* Skip size of data */
- i += size;
-
- /* What we do depends on the tag type */
- tag = PREF_TAG(prefix);
- type = PREF_TYPE(prefix);
- switch (type) {
- case TYPE_MAIN:
- strcpy(globtype, "");
- switch (tag) {
-
- case TAG_MAIN_INPUT:
- /*
- * The INPUT MAIN tag signifies this is
- * information from a report. We need to
- * figure out what it is and store the
- * min/max values
- */
-
- maintype = 'I';
- if (data == 2)
- strcpy(globtype, "Variable");
- else if (data == 3)
- strcpy(globtype, "Var|Const");
-
- dbg("::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits",
- globalval[TAG_GLOB_REPORT_ID], inputnum,
- globalval[TAG_GLOB_LOG_MAX], globalval[TAG_GLOB_LOG_MAX],
- globalval[TAG_GLOB_LOG_MIN], globalval[TAG_GLOB_LOG_MIN],
- globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT]);
-
-
- /*
- We can assume that the first two input items
- are always the X and Y coordinates. After
- that, we look for everything else by
- local usage value
- */
- switch (inputnum) {
- case 0: /* X coord */
- dbg("GER: X Usage: 0x%x", usage);
- if (device->max_X == 0) {
- device->max_X = globalval[TAG_GLOB_LOG_MAX];
- device->min_X = globalval[TAG_GLOB_LOG_MIN];
- }
- break;
-
- case 1: /* Y coord */
- dbg("GER: Y Usage: 0x%x", usage);
- if (device->max_Y == 0) {
- device->max_Y = globalval[TAG_GLOB_LOG_MAX];
- device->min_Y = globalval[TAG_GLOB_LOG_MIN];
- }
- break;
-
- default:
- /* Tilt X */
- if (usage == DIGITIZER_USAGE_TILT_X) {
- if (device->maxtilt_X == 0) {
- device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX];
- device->mintilt_X = globalval[TAG_GLOB_LOG_MIN];
- }
- }
-
- /* Tilt Y */
- if (usage == DIGITIZER_USAGE_TILT_Y) {
- if (device->maxtilt_Y == 0) {
- device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX];
- device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN];
- }
- }
-
- /* Pressure */
- if (usage == DIGITIZER_USAGE_TIP_PRESSURE) {
- if (device->maxpressure == 0) {
- device->maxpressure = globalval[TAG_GLOB_LOG_MAX];
- device->minpressure = globalval[TAG_GLOB_LOG_MIN];
- }
- }
-
- break;
- }
-
- inputnum++;
- break;
-
- case TAG_MAIN_OUTPUT:
- maintype = 'O';
- break;
-
- case TAG_MAIN_FEATURE:
- maintype = 'F';
- break;
-
- case TAG_MAIN_COL_START:
- maintype = 'S';
-
- if (data == 0) {
- dbg("======>>>>>> Physical");
- strcpy(globtype, "Physical");
- } else
- dbg("======>>>>>>");
-
- /* Indent the debug output */
- indent++;
- for (x = 0; x < indent; x++)
- indentstr[x] = '-';
- indentstr[x] = 0;
-
- /* Save global tags */
- for (x = 0; x < TAG_GLOB_MAX; x++)
- oldval[x] = globalval[x];
-
- break;
-
- case TAG_MAIN_COL_END:
- dbg("<<<<<<======");
- maintype = 'E';
- indent--;
- for (x = 0; x < indent; x++)
- indentstr[x] = '-';
- indentstr[x] = 0;
-
- /* Copy global tags back */
- for (x = 0; x < TAG_GLOB_MAX; x++)
- globalval[x] = oldval[x];
-
- break;
- }
-
- switch (size) {
- case 1:
- dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
- indentstr, tag, maintype, size, globtype, data);
- break;
-
- case 2:
- dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
- indentstr, tag, maintype, size, globtype, data16);
- break;
-
- case 4:
- dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x",
- indentstr, tag, maintype, size, globtype, data32);
- break;
- }
- break;
-
- case TYPE_GLOBAL:
- switch (tag) {
- case TAG_GLOB_USAGE:
- /*
- * First time we hit the global usage tag,
- * it should tell us the type of device
- */
- if (device->usage == 0)
- device->usage = data;
-
- strcpy(globtype, "USAGE");
- break;
-
- case TAG_GLOB_LOG_MIN:
- strcpy(globtype, "LOG_MIN");
- break;
-
- case TAG_GLOB_LOG_MAX:
- strcpy(globtype, "LOG_MAX");
- break;
-
- case TAG_GLOB_PHYS_MIN:
- strcpy(globtype, "PHYS_MIN");
- break;
-
- case TAG_GLOB_PHYS_MAX:
- strcpy(globtype, "PHYS_MAX");
- break;
-
- case TAG_GLOB_UNIT_EXP:
- strcpy(globtype, "EXP");
- break;
-
- case TAG_GLOB_UNIT:
- strcpy(globtype, "UNIT");
- break;
-
- case TAG_GLOB_REPORT_SZ:
- strcpy(globtype, "REPORT_SZ");
- break;
-
- case TAG_GLOB_REPORT_ID:
- strcpy(globtype, "REPORT_ID");
- /* New report, restart numbering */
- inputnum = 0;
- break;
-
- case TAG_GLOB_REPORT_CNT:
- strcpy(globtype, "REPORT_CNT");
- break;
-
- case TAG_GLOB_PUSH:
- strcpy(globtype, "PUSH");
- break;
-
- case TAG_GLOB_POP:
- strcpy(globtype, "POP");
- break;
- }
-
- /* Check to make sure we have a good tag number
- so we don't overflow array */
- if (tag < TAG_GLOB_MAX) {
- switch (size) {
- case 1:
- dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
- indentstr, globtype, tag, size, data);
- globalval[tag] = data;
- break;
-
- case 2:
- dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
- indentstr, globtype, tag, size, data16);
- globalval[tag] = data16;
- break;
-
- case 4:
- dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",
- indentstr, globtype, tag, size, data32);
- globalval[tag] = data32;
- break;
- }
- } else {
- dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ",
- indentstr, tag, size);
- }
- break;
-
- case TYPE_LOCAL:
- switch (tag) {
- case TAG_GLOB_USAGE:
- strcpy(globtype, "USAGE");
- /* Always 1 byte */
- usage = data;
- break;
-
- case TAG_GLOB_LOG_MIN:
- strcpy(globtype, "MIN");
- break;
-
- case TAG_GLOB_LOG_MAX:
- strcpy(globtype, "MAX");
- break;
-
- default:
- strcpy(globtype, "UNKNOWN");
- break;
- }
-
- switch (size) {
- case 1:
- dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
- indentstr, tag, globtype, size, data);
- break;
-
- case 2:
- dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
- indentstr, tag, globtype, size, data16);
- break;
-
- case 4:
- dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x",
- indentstr, tag, globtype, size, data32);
- break;
- }
-
- break;
- }
- }
-}
-
-/* INPUT DRIVER Routines */
-
-/*
- * Called when opening the input device. This will submit the URB to
- * the usb system so we start getting reports
- */
-static int gtco_input_open(struct input_dev *inputdev)
-{
- struct gtco *device = input_get_drvdata(inputdev);
-
- device->urbinfo->dev = device->usbdev;
- if (usb_submit_urb(device->urbinfo, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-/*
- * Called when closing the input device. This will unlink the URB
- */
-static void gtco_input_close(struct input_dev *inputdev)
-{
- struct gtco *device = input_get_drvdata(inputdev);
-
- usb_kill_urb(device->urbinfo);
-}
-
-
-/*
- * Setup input device capabilities. Tell the input system what this
- * device is capable of generating.
- *
- * This information is based on what is read from the HID report and
- * placed in the struct gtco structure
- *
- */
-static void gtco_setup_caps(struct input_dev *inputdev)
-{
- struct gtco *device = input_get_drvdata(inputdev);
-
- /* Which events */
- inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
-
- /* Misc event menu block */
- inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ;
-
- /* Absolute values based on HID report info */
- input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X,
- 0, 0);
- input_set_abs_params(inputdev, ABS_Y, device->min_Y, device->max_Y,
- 0, 0);
-
- /* Proximity */
- input_set_abs_params(inputdev, ABS_DISTANCE, 0, 1, 0, 0);
-
- /* Tilt & pressure */
- input_set_abs_params(inputdev, ABS_TILT_X, device->mintilt_X,
- device->maxtilt_X, 0, 0);
- input_set_abs_params(inputdev, ABS_TILT_Y, device->mintilt_Y,
- device->maxtilt_Y, 0, 0);
- input_set_abs_params(inputdev, ABS_PRESSURE, device->minpressure,
- device->maxpressure, 0, 0);
-
- /* Transducer */
- input_set_abs_params(inputdev, ABS_MISC, 0, 0xFF, 0, 0);
-}
-
-/* USB Routines */
-
-/*
- * URB callback routine. Called when we get IRQ reports from the
- * digitizer.
- *
- * This bridges the USB and input device worlds. It generates events
- * on the input device based on the USB reports.
- */
-static void gtco_urb_callback(struct urb *urbinfo)
-{
- struct gtco *device = urbinfo->context;
- struct input_dev *inputdev;
- int rc;
- u32 val = 0;
- s8 valsigned = 0;
- char le_buffer[2];
-
- inputdev = device->inputdevice;
-
- /* Was callback OK? */
- if (urbinfo->status == -ECONNRESET ||
- urbinfo->status == -ENOENT ||
- urbinfo->status == -ESHUTDOWN) {
-
- /* Shutdown is occurring. Return and don't queue up any more */
- return;
- }
-
- if (urbinfo->status != 0) {
- /*
- * Some unknown error. Hopefully temporary. Just go and
- * requeue an URB
- */
- goto resubmit;
- }
-
- /*
- * Good URB, now process
- */
-
- /* PID dependent when we interpret the report */
- if (inputdev->id.product == PID_1000 ||
- inputdev->id.product == PID_1001 ||
- inputdev->id.product == PID_1002) {
-
- /*
- * Switch on the report ID
- * Conveniently, the reports have more information, the higher
- * the report number. We can just fall through the case
- * statements if we start with the highest number report
- */
- switch (device->buffer[0]) {
- case 5:
- /* Pressure is 9 bits */
- val = ((u16)(device->buffer[8]) << 1);
- val |= (u16)(device->buffer[7] >> 7);
- input_report_abs(inputdev, ABS_PRESSURE,
- device->buffer[8]);
-
- /* Mask out the Y tilt value used for pressure */
- device->buffer[7] = (u8)((device->buffer[7]) & 0x7F);
-
- /* Fall thru */
- case 4:
- /* Tilt */
-
- /* Sign extend these 7 bit numbers. */
- if (device->buffer[6] & 0x40)
- device->buffer[6] |= 0x80;
-
- if (device->buffer[7] & 0x40)
- device->buffer[7] |= 0x80;
-
-
- valsigned = (device->buffer[6]);
- input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned);
-
- valsigned = (device->buffer[7]);
- input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned);
-
- /* Fall thru */
- case 2:
- case 3:
- /* Convert buttons, only 5 bits possible */
- val = (device->buffer[5]) & MASK_BUTTON;
-
- /* We don't apply any meaning to the bitmask,
- just report */
- input_event(inputdev, EV_MSC, MSC_SERIAL, val);
-
- /* Fall thru */
- case 1:
- /* All reports have X and Y coords in the same place */
- val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[1]));
- input_report_abs(inputdev, ABS_X, val);
-
- val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[3]));
- input_report_abs(inputdev, ABS_Y, val);
-
- /* Ditto for proximity bit */
- val = device->buffer[5] & MASK_INRANGE ? 1 : 0;
- input_report_abs(inputdev, ABS_DISTANCE, val);
-
- /* Report 1 is an exception to how we handle buttons */
- /* Buttons are an index, not a bitmask */
- if (device->buffer[0] == 1) {
-
- /*
- * Convert buttons, 5 bit index
- * Report value of index set as one,
- * the rest as 0
- */
- val = device->buffer[5] & MASK_BUTTON;
- dbg("======>>>>>>REPORT 1: val 0x%X(%d)",
- val, val);
-
- /*
- * We don't apply any meaning to the button
- * index, just report it
- */
- input_event(inputdev, EV_MSC, MSC_SERIAL, val);
- }
- break;
-
- case 7:
- /* Menu blocks */
- input_event(inputdev, EV_MSC, MSC_SCAN,
- device->buffer[1]);
- break;
- }
- }
-
- /* Other pid class */
- if (inputdev->id.product == PID_400 ||
- inputdev->id.product == PID_401) {
-
- /* Report 2 */
- if (device->buffer[0] == 2) {
- /* Menu blocks */
- input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]);
- }
-
- /* Report 1 */
- if (device->buffer[0] == 1) {
- char buttonbyte;
-
- /* IF X max > 64K, we still a bit from the y report */
- if (device->max_X > 0x10000) {
-
- val = (u16)(((u16)(device->buffer[2] << 8)) | (u8)device->buffer[1]);
- val |= (u32)(((u8)device->buffer[3] & 0x1) << 16);
-
- input_report_abs(inputdev, ABS_X, val);
-
- le_buffer[0] = (u8)((u8)(device->buffer[3]) >> 1);
- le_buffer[0] |= (u8)((device->buffer[3] & 0x1) << 7);
-
- le_buffer[1] = (u8)(device->buffer[4] >> 1);
- le_buffer[1] |= (u8)((device->buffer[5] & 0x1) << 7);
-
- val = le16_to_cpu(get_unaligned((__le16 *)le_buffer));
- input_report_abs(inputdev, ABS_Y, val);
-
- /*
- * Shift the button byte right by one to
- * make it look like the standard report
- */
- buttonbyte = device->buffer[5] >> 1;
- } else {
-
- val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[1]));
- input_report_abs(inputdev, ABS_X, val);
-
- val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[3]));
- input_report_abs(inputdev, ABS_Y, val);
-
- buttonbyte = device->buffer[5];
- }
-
- /* BUTTONS and PROXIMITY */
- val = buttonbyte & MASK_INRANGE ? 1 : 0;
- input_report_abs(inputdev, ABS_DISTANCE, val);
-
- /* Convert buttons, only 4 bits possible */
- val = buttonbyte & 0x0F;
-#ifdef USE_BUTTONS
- for (i = 0; i < 5; i++)
- input_report_key(inputdev, BTN_DIGI + i, val & (1 << i));
-#else
- /* We don't apply any meaning to the bitmask, just report */
- input_event(inputdev, EV_MSC, MSC_SERIAL, val);
-#endif
-
- /* TRANSDUCER */
- input_report_abs(inputdev, ABS_MISC, device->buffer[6]);
- }
- }
-
- /* Everybody gets report ID's */
- input_event(inputdev, EV_MSC, MSC_RAW, device->buffer[0]);
-
- /* Sync it up */
- input_sync(inputdev);
-
- resubmit:
- rc = usb_submit_urb(urbinfo, GFP_ATOMIC);
- if (rc != 0)
- err("usb_submit_urb failed rc=0x%x", rc);
-}
-
-/*
- * The probe routine. This is called when the kernel find the matching USB
- * vendor/product. We do the following:
- *
- * - Allocate mem for a local structure to manage the device
- * - Request a HID Report Descriptor from the device and parse it to
- * find out the device parameters
- * - Create an input device and assign it attributes
- * - Allocate an URB so the device can talk to us when the input
- * queue is open
- */
-static int gtco_probe(struct usb_interface *usbinterface,
- const struct usb_device_id *id)
-{
-
- struct gtco *gtco;
- struct input_dev *input_dev;
- struct hid_descriptor *hid_desc;
- char *report = NULL;
- int result = 0, retry;
- int error;
- struct usb_endpoint_descriptor *endpoint;
-
- /* Allocate memory for device structure */
- gtco = kzalloc(sizeof(struct gtco), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!gtco || !input_dev) {
- err("No more memory");
- error = -ENOMEM;
- goto err_free_devs;
- }
-
- /* Set pointer to the input device */
- gtco->inputdevice = input_dev;
-
- /* Save interface information */
- gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface));
-
- /* Allocate some data for incoming reports */
- gtco->buffer = usb_buffer_alloc(gtco->usbdev, REPORT_MAX_SIZE,
- GFP_KERNEL, &gtco->buf_dma);
- if (!gtco->buffer) {
- err("No more memory for us buffers");
- error = -ENOMEM;
- goto err_free_devs;
- }
-
- /* Allocate URB for reports */
- gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL);
- if (!gtco->urbinfo) {
- err("Failed to allocate URB");
- return -ENOMEM;
- goto err_free_buf;
- }
-
- /*
- * The endpoint is always altsetting 0, we know this since we know
- * this device only has one interrupt endpoint
- */
- endpoint = &usbinterface->altsetting[0].endpoint[0].desc;
-
- /* Some debug */
- dbg("gtco # interfaces: %d", usbinterface->num_altsetting);
- dbg("num endpoints: %d", usbinterface->cur_altsetting->desc.bNumEndpoints);
- dbg("interface class: %d", usbinterface->cur_altsetting->desc.bInterfaceClass);
- dbg("endpoint: attribute:0x%x type:0x%x", endpoint->bmAttributes, endpoint->bDescriptorType);
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)
- dbg("endpoint: we have interrupt endpoint\n");
-
- dbg("endpoint extra len:%d ", usbinterface->altsetting[0].extralen);
-
- /*
- * Find the HID descriptor so we can find out the size of the
- * HID report descriptor
- */
- if (usb_get_extra_descriptor(usbinterface->cur_altsetting,
- HID_DEVICE_TYPE, &hid_desc) != 0){
- err("Can't retrieve exta USB descriptor to get hid report descriptor length");
- error = -EIO;
- goto err_free_urb;
- }
-
- dbg("Extra descriptor success: type:%d len:%d",
- hid_desc->bDescriptorType, hid_desc->wDescriptorLength);
-
- report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
- if (!report) {
- err("No more memory for report");
- error = -ENOMEM;
- goto err_free_urb;
- }
-
- /* Couple of tries to get reply */
- for (retry = 0; retry < 3; retry++) {
- result = usb_control_msg(gtco->usbdev,
- usb_rcvctrlpipe(gtco->usbdev, 0),
- USB_REQ_GET_DESCRIPTOR,
- USB_RECIP_INTERFACE | USB_DIR_IN,
- REPORT_DEVICE_TYPE << 8,
- 0, /* interface */
- report,
- hid_desc->wDescriptorLength,
- 5000); /* 5 secs */
-
- if (result == hid_desc->wDescriptorLength)
- break;
- }
-
- /* If we didn't get the report, fail */
- dbg("usb_control_msg result: :%d", result);
- if (result != hid_desc->wDescriptorLength) {
- err("Failed to get HID Report Descriptor of size: %d",
- hid_desc->wDescriptorLength);
- error = -EIO;
- goto err_free_urb;
- }
-
- /* Now we parse the report */
- parse_hid_report_descriptor(gtco, report, result);
-
- /* Now we delete it */
- kfree(report);
-
- /* Create a device file node */
- usb_make_path(gtco->usbdev, gtco->usbpath, sizeof(gtco->usbpath));
- strlcat(gtco->usbpath, "/input0", sizeof(gtco->usbpath));
-
- /* Set Input device functions */
- input_dev->open = gtco_input_open;
- input_dev->close = gtco_input_close;
-
- /* Set input device information */
- input_dev->name = "GTCO_CalComp";
- input_dev->phys = gtco->usbpath;
-
- input_set_drvdata(input_dev, gtco);
-
- /* Now set up all the input device capabilities */
- gtco_setup_caps(input_dev);
-
- /* Set input device required ID information */
- usb_to_input_id(gtco->usbdev, &input_dev->id);
- input_dev->dev.parent = &usbinterface->dev;
-
- /* Setup the URB, it will be posted later on open of input device */
- endpoint = &usbinterface->altsetting[0].endpoint[0].desc;
-
- usb_fill_int_urb(gtco->urbinfo,
- gtco->usbdev,
- usb_rcvintpipe(gtco->usbdev,
- endpoint->bEndpointAddress),
- gtco->buffer,
- REPORT_MAX_SIZE,
- gtco_urb_callback,
- gtco,
- endpoint->bInterval);
-
- gtco->urbinfo->transfer_dma = gtco->buf_dma;
- gtco->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* Save gtco pointer in USB interface gtco */
- usb_set_intfdata(usbinterface, gtco);
-
- /* All done, now register the input device */
- error = input_register_device(input_dev);
- if (error)
- goto err_free_urb;
-
- return 0;
-
- err_free_urb:
- usb_free_urb(gtco->urbinfo);
- err_free_buf:
- usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE,
- gtco->buffer, gtco->buf_dma);
- err_free_devs:
- kfree(report);
- input_free_device(input_dev);
- kfree(gtco);
- return error;
-}
-
-/*
- * This function is a standard USB function called when the USB device
- * is disconnected. We will get rid of the URV, de-register the input
- * device, and free up allocated memory
- */
-static void gtco_disconnect(struct usb_interface *interface)
-{
- /* Grab private device ptr */
- struct gtco *gtco = usb_get_intfdata(interface);
-
- /* Now reverse all the registration stuff */
- if (gtco) {
- input_unregister_device(gtco->inputdevice);
- usb_kill_urb(gtco->urbinfo);
- usb_free_urb(gtco->urbinfo);
- usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE,
- gtco->buffer, gtco->buf_dma);
- kfree(gtco);
- }
-
- info("gtco driver disconnected");
-}
-
-/* STANDARD MODULE LOAD ROUTINES */
-
-static struct usb_driver gtco_driverinfo_table = {
- .name = "gtco",
- .id_table = gtco_usbid_table,
- .probe = gtco_probe,
- .disconnect = gtco_disconnect,
-};
-
-/*
- * Register this module with the USB subsystem
- */
-static int __init gtco_init(void)
-{
- int error;
-
- error = usb_register(&gtco_driverinfo_table);
- if (error) {
- err("usb_register() failed rc=0x%x", error);
- return error;
- }
-
- printk("GTCO usb driver version: %s", GTCO_VERSION);
- return 0;
-}
-
-/*
- * Deregister this module with the USB subsystem
- */
-static void __exit gtco_exit(void)
-{
- usb_deregister(&gtco_driverinfo_table);
-}
-
-module_init(gtco_init);
-module_exit(gtco_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
deleted file mode 100644
index c4781b9d129..00000000000
--- a/drivers/usb/input/kbtab.c
+++ /dev/null
@@ -1,226 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-#include <asm/unaligned.h>
-
-/*
- * Version Information
- * v0.0.1 - Original, extremely basic version, 2.4.xx only
- * v0.0.2 - Updated, works with 2.5.62 and 2.4.20;
- * - added pressure-threshold modules param code from
- * Alex Perry <alex.perry@ieee.org>
- */
-
-#define DRIVER_VERSION "v0.0.2"
-#define DRIVER_AUTHOR "Josh Myer <josh@joshisanerd.com>"
-#define DRIVER_DESC "USB KB Gear JamStudio Tablet driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-#define USB_VENDOR_ID_KBGEAR 0x084e
-
-static int kb_pressure_click = 0x10;
-module_param(kb_pressure_click, int, 0);
-MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
-
-struct kbtab {
- signed char *data;
- dma_addr_t data_dma;
- struct input_dev *dev;
- struct usb_device *usbdev;
- struct urb *irq;
- int x, y;
- int button;
- int pressure;
- __u32 serial[2];
- char phys[32];
-};
-
-static void kbtab_irq(struct urb *urb)
-{
- struct kbtab *kbtab = urb->context;
- unsigned char *data = kbtab->data;
- struct input_dev *dev = kbtab->dev;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- goto exit;
- }
-
- kbtab->x = le16_to_cpu(get_unaligned((__le16 *) &data[1]));
- kbtab->y = le16_to_cpu(get_unaligned((__le16 *) &data[3]));
-
- kbtab->pressure = (data[5]);
-
- input_report_key(dev, BTN_TOOL_PEN, 1);
-
- input_report_abs(dev, ABS_X, kbtab->x);
- input_report_abs(dev, ABS_Y, kbtab->y);
-
- /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
- input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
-
- if (-1 == kb_pressure_click) {
- input_report_abs(dev, ABS_PRESSURE, kbtab->pressure);
- } else {
- input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0);
- };
-
- input_sync(dev);
-
- exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static struct usb_device_id kbtab_ids[] = {
- { USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, kbtab_ids);
-
-static int kbtab_open(struct input_dev *dev)
-{
- struct kbtab *kbtab = input_get_drvdata(dev);
-
- kbtab->irq->dev = kbtab->usbdev;
- if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void kbtab_close(struct input_dev *dev)
-{
- struct kbtab *kbtab = input_get_drvdata(dev);
-
- usb_kill_urb(kbtab->irq);
-}
-
-static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_endpoint_descriptor *endpoint;
- struct kbtab *kbtab;
- struct input_dev *input_dev;
- int error = -ENOMEM;
-
- kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!kbtab || !input_dev)
- goto fail1;
-
- kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
- if (!kbtab->data)
- goto fail1;
-
- kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!kbtab->irq)
- goto fail2;
-
- kbtab->usbdev = dev;
- kbtab->dev = input_dev;
-
- usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
- strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
-
- input_dev->name = "KB Gear Tablet";
- input_dev->phys = kbtab->phys;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, kbtab);
-
- input_dev->open = kbtab_open;
- input_dev->close = kbtab_close;
-
- input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
- input_dev->mscbit[0] |= BIT(MSC_SERIAL);
- input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
-
- endpoint = &intf->cur_altsetting->endpoint[0].desc;
-
- usb_fill_int_urb(kbtab->irq, dev,
- usb_rcvintpipe(dev, endpoint->bEndpointAddress),
- kbtab->data, 8,
- kbtab_irq, kbtab, endpoint->bInterval);
- kbtab->irq->transfer_dma = kbtab->data_dma;
- kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- error = input_register_device(kbtab->dev);
- if (error)
- goto fail3;
-
- usb_set_intfdata(intf, kbtab);
-
- return 0;
-
- fail3: usb_free_urb(kbtab->irq);
- fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
- fail1: input_free_device(input_dev);
- kfree(kbtab);
- return error;
-}
-
-static void kbtab_disconnect(struct usb_interface *intf)
-{
- struct kbtab *kbtab = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (kbtab) {
- usb_kill_urb(kbtab->irq);
- input_unregister_device(kbtab->dev);
- usb_free_urb(kbtab->irq);
- usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
- kfree(kbtab);
- }
-}
-
-static struct usb_driver kbtab_driver = {
- .name = "kbtab",
- .probe = kbtab_probe,
- .disconnect = kbtab_disconnect,
- .id_table = kbtab_ids,
-};
-
-static int __init kbtab_init(void)
-{
- int retval;
- retval = usb_register(&kbtab_driver);
- if (retval)
- goto out;
- info(DRIVER_VERSION ":" DRIVER_DESC);
-out:
- return retval;
-}
-
-static void __exit kbtab_exit(void)
-{
- usb_deregister(&kbtab_driver);
-}
-
-module_init(kbtab_init);
-module_exit(kbtab_exit);
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
deleted file mode 100644
index 1bffc9fa98c..00000000000
--- a/drivers/usb/input/keyspan_remote.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * keyspan_remote: USB driver for the Keyspan DMR
- *
- * Copyright (C) 2005 Zymeta Corporation - Michael Downey (downey@zymeta.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- * This driver has been put together with the support of Innosys, Inc.
- * and Keyspan, Inc the manufacturers of the Keyspan USB DMR product.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/usb/input.h>
-
-#define DRIVER_VERSION "v0.1"
-#define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>"
-#define DRIVER_DESC "Driver for the USB Keyspan remote control."
-#define DRIVER_LICENSE "GPL"
-
-/* Parameters that can be passed to the driver. */
-static int debug;
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
-
-/* Vendor and product ids */
-#define USB_KEYSPAN_VENDOR_ID 0x06CD
-#define USB_KEYSPAN_PRODUCT_UIA11 0x0202
-
-/* Defines for converting the data from the remote. */
-#define ZERO 0x18
-#define ZERO_MASK 0x1F /* 5 bits for a 0 */
-#define ONE 0x3C
-#define ONE_MASK 0x3F /* 6 bits for a 1 */
-#define SYNC 0x3F80
-#define SYNC_MASK 0x3FFF /* 14 bits for a SYNC sequence */
-#define STOP 0x00
-#define STOP_MASK 0x1F /* 5 bits for the STOP sequence */
-#define GAP 0xFF
-
-#define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */
-
-/* table of devices that work with this driver */
-static struct usb_device_id keyspan_table[] = {
- { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
- { } /* Terminating entry */
-};
-
-/* Structure to store all the real stuff that a remote sends to us. */
-struct keyspan_message {
- u16 system;
- u8 button;
- u8 toggle;
-};
-
-/* Structure used for all the bit testing magic needed to be done. */
-struct bit_tester {
- u32 tester;
- int len;
- int pos;
- int bits_left;
- u8 buffer[32];
-};
-
-/* Structure to hold all of our driver specific stuff */
-struct usb_keyspan {
- char name[128];
- char phys[64];
- struct usb_device* udev;
- struct input_dev *input;
- struct usb_interface* interface;
- struct usb_endpoint_descriptor* in_endpoint;
- struct urb* irq_urb;
- int open;
- dma_addr_t in_dma;
- unsigned char* in_buffer;
-
- /* variables used to parse messages from remote. */
- struct bit_tester data;
- int stage;
- int toggle;
-};
-
-/*
- * Table that maps the 31 possible keycodes to input keys.
- * Currently there are 15 and 17 button models so RESERVED codes
- * are blank areas in the mapping.
- */
-static const int keyspan_key_table[] = {
- KEY_RESERVED, /* 0 is just a place holder. */
- KEY_RESERVED,
- KEY_STOP,
- KEY_PLAYCD,
- KEY_RESERVED,
- KEY_PREVIOUSSONG,
- KEY_REWIND,
- KEY_FORWARD,
- KEY_NEXTSONG,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_PAUSE,
- KEY_VOLUMEUP,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_VOLUMEDOWN,
- KEY_RESERVED,
- KEY_UP,
- KEY_RESERVED,
- KEY_MUTE,
- KEY_LEFT,
- KEY_ENTER,
- KEY_RIGHT,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_DOWN,
- KEY_RESERVED,
- KEY_KPASTERISK,
- KEY_RESERVED,
- KEY_MENU
-};
-
-static struct usb_driver keyspan_driver;
-
-/*
- * Debug routine that prints out what we've received from the remote.
- */
-static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
-{
- char codes[4 * RECV_SIZE];
- int i;
-
- for (i = 0; i < RECV_SIZE; i++)
- snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]);
-
- dev_info(&dev->udev->dev, "%s\n", codes);
-}
-
-/*
- * Routine that manages the bit_tester structure. It makes sure that there are
- * at least bits_needed bits loaded into the tester.
- */
-static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
-{
- if (dev->data.bits_left >= bits_needed)
- return 0;
-
- /*
- * Somehow we've missed the last message. The message will be repeated
- * though so it's not too big a deal
- */
- if (dev->data.pos >= dev->data.len) {
- dev_dbg(&dev->udev->dev,
- "%s - Error ran out of data. pos: %d, len: %d\n",
- __FUNCTION__, dev->data.pos, dev->data.len);
- return -1;
- }
-
- /* Load as much as we can into the tester. */
- while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) &&
- (dev->data.pos < dev->data.len)) {
- dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left);
- dev->data.bits_left += 8;
- }
-
- return 0;
-}
-
-/*
- * Routine that handles all the logic needed to parse out the message from the remote.
- */
-static void keyspan_check_data(struct usb_keyspan *remote)
-{
- int i;
- int found = 0;
- struct keyspan_message message;
-
- switch(remote->stage) {
- case 0:
- /*
- * In stage 0 we want to find the start of a message. The remote sends a 0xFF as filler.
- * So the first byte that isn't a FF should be the start of a new message.
- */
- for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i);
-
- if (i < RECV_SIZE) {
- memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE);
- remote->data.len = RECV_SIZE;
- remote->data.pos = 0;
- remote->data.tester = 0;
- remote->data.bits_left = 0;
- remote->stage = 1;
- }
- break;
-
- case 1:
- /*
- * Stage 1 we should have 16 bytes and should be able to detect a
- * SYNC. The SYNC is 14 bits, 7 0's and then 7 1's.
- */
- memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
- remote->data.len += RECV_SIZE;
-
- found = 0;
- while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) {
- for (i = 0; i < 8; ++i) {
- if (keyspan_load_tester(remote, 14) != 0) {
- remote->stage = 0;
- return;
- }
-
- if ((remote->data.tester & SYNC_MASK) == SYNC) {
- remote->data.tester = remote->data.tester >> 14;
- remote->data.bits_left -= 14;
- found = 1;
- break;
- } else {
- remote->data.tester = remote->data.tester >> 1;
- --remote->data.bits_left;
- }
- }
- }
-
- if (!found) {
- remote->stage = 0;
- remote->data.len = 0;
- } else {
- remote->stage = 2;
- }
- break;
-
- case 2:
- /*
- * Stage 2 we should have 24 bytes which will be enough for a full
- * message. We need to parse out the system code, button code,
- * toggle code, and stop.
- */
- memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
- remote->data.len += RECV_SIZE;
-
- message.system = 0;
- for (i = 0; i < 9; i++) {
- keyspan_load_tester(remote, 6);
-
- if ((remote->data.tester & ZERO_MASK) == ZERO) {
- message.system = message.system << 1;
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else if ((remote->data.tester & ONE_MASK) == ONE) {
- message.system = (message.system << 1) + 1;
- remote->data.tester = remote->data.tester >> 6;
- remote->data.bits_left -= 6;
- } else {
- err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
- remote->stage = 0;
- return;
- }
- }
-
- message.button = 0;
- for (i = 0; i < 5; i++) {
- keyspan_load_tester(remote, 6);
-
- if ((remote->data.tester & ZERO_MASK) == ZERO) {
- message.button = message.button << 1;
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else if ((remote->data.tester & ONE_MASK) == ONE) {
- message.button = (message.button << 1) + 1;
- remote->data.tester = remote->data.tester >> 6;
- remote->data.bits_left -= 6;
- } else {
- err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
- remote->stage = 0;
- return;
- }
- }
-
- keyspan_load_tester(remote, 6);
- if ((remote->data.tester & ZERO_MASK) == ZERO) {
- message.toggle = 0;
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else if ((remote->data.tester & ONE_MASK) == ONE) {
- message.toggle = 1;
- remote->data.tester = remote->data.tester >> 6;
- remote->data.bits_left -= 6;
- } else {
- err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
- remote->stage = 0;
- return;
- }
-
- keyspan_load_tester(remote, 5);
- if ((remote->data.tester & STOP_MASK) == STOP) {
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else {
- err("Bad message recieved, no stop bit found.\n");
- }
-
- dev_dbg(&remote->udev->dev,
- "%s found valid message: system: %d, button: %d, toggle: %d\n",
- __FUNCTION__, message.system, message.button, message.toggle);
-
- if (message.toggle != remote->toggle) {
- input_report_key(remote->input, keyspan_key_table[message.button], 1);
- input_report_key(remote->input, keyspan_key_table[message.button], 0);
- input_sync(remote->input);
- remote->toggle = message.toggle;
- }
-
- remote->stage = 0;
- break;
- }
-}
-
-/*
- * Routine for sending all the initialization messages to the remote.
- */
-static int keyspan_setup(struct usb_device* dev)
-{
- int retval = 0;
-
- retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
- if (retval) {
- dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
- __FUNCTION__, retval);
- return(retval);
- }
-
- retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
- if (retval) {
- dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
- __FUNCTION__, retval);
- return(retval);
- }
-
- retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
- if (retval) {
- dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
- __FUNCTION__, retval);
- return(retval);
- }
-
- dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
- return(retval);
-}
-
-/*
- * Routine used to handle a new message that has come in.
- */
-static void keyspan_irq_recv(struct urb *urb)
-{
- struct usb_keyspan *dev = urb->context;
- int retval;
-
- /* Check our status in case we need to bail out early. */
- switch (urb->status) {
- case 0:
- break;
-
- /* Device went away so don't keep trying to read from it. */
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- return;
-
- default:
- goto resubmit;
- break;
- }
-
- if (debug)
- keyspan_print(dev);
-
- keyspan_check_data(dev);
-
-resubmit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
-}
-
-static int keyspan_open(struct input_dev *dev)
-{
- struct usb_keyspan *remote = input_get_drvdata(dev);
-
- remote->irq_urb->dev = remote->udev;
- if (usb_submit_urb(remote->irq_urb, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void keyspan_close(struct input_dev *dev)
-{
- struct usb_keyspan *remote = input_get_drvdata(dev);
-
- usb_kill_urb(remote->irq_urb);
-}
-
-static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface)
-{
-
- struct usb_endpoint_descriptor *endpoint;
- int i;
-
- for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
- endpoint = &iface->endpoint[i].desc;
-
- if (usb_endpoint_is_int_in(endpoint)) {
- /* we found our interrupt in endpoint */
- return endpoint;
- }
- }
-
- return NULL;
-}
-
-/*
- * Routine that sets up the driver to handle a specific USB device detected on the bus.
- */
-static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- struct usb_endpoint_descriptor *endpoint;
- struct usb_keyspan *remote;
- struct input_dev *input_dev;
- int i, error;
-
- endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
- if (!endpoint)
- return -ENODEV;
-
- remote = kzalloc(sizeof(*remote), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!remote || !input_dev) {
- error = -ENOMEM;
- goto fail1;
- }
-
- remote->udev = udev;
- remote->input = input_dev;
- remote->interface = interface;
- remote->in_endpoint = endpoint;
- remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
-
- remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
- if (!remote->in_buffer) {
- error = -ENOMEM;
- goto fail1;
- }
-
- remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!remote->irq_urb) {
- error = -ENOMEM;
- goto fail2;
- }
-
- error = keyspan_setup(udev);
- if (error) {
- error = -ENODEV;
- goto fail3;
- }
-
- if (udev->manufacturer)
- strlcpy(remote->name, udev->manufacturer, sizeof(remote->name));
-
- if (udev->product) {
- if (udev->manufacturer)
- strlcat(remote->name, " ", sizeof(remote->name));
- strlcat(remote->name, udev->product, sizeof(remote->name));
- }
-
- if (!strlen(remote->name))
- snprintf(remote->name, sizeof(remote->name),
- "USB Keyspan Remote %04x:%04x",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- usb_make_path(udev, remote->phys, sizeof(remote->phys));
- strlcat(remote->phys, "/input0", sizeof(remote->phys));
-
- input_dev->name = remote->name;
- input_dev->phys = remote->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->dev.parent = &interface->dev;
-
- input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
- for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
- if (keyspan_key_table[i] != KEY_RESERVED)
- set_bit(keyspan_key_table[i], input_dev->keybit);
-
- input_set_drvdata(input_dev, remote);
-
- input_dev->open = keyspan_open;
- input_dev->close = keyspan_close;
-
- /*
- * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
- */
- usb_fill_int_urb(remote->irq_urb,
- remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress),
- remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote,
- remote->in_endpoint->bInterval);
- remote->irq_urb->transfer_dma = remote->in_dma;
- remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* we can register the device now, as it is ready */
- error = input_register_device(remote->input);
- if (error)
- goto fail3;
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, remote);
-
- return 0;
-
- fail3: usb_free_urb(remote->irq_urb);
- fail2: usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
- fail1: kfree(remote);
- input_free_device(input_dev);
-
- return error;
-}
-
-/*
- * Routine called when a device is disconnected from the USB.
- */
-static void keyspan_disconnect(struct usb_interface *interface)
-{
- struct usb_keyspan *remote;
-
- remote = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
-
- if (remote) { /* We have a valid driver structure so clean up everything we allocated. */
- input_unregister_device(remote->input);
- usb_kill_urb(remote->irq_urb);
- usb_free_urb(remote->irq_urb);
- usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
- kfree(remote);
- }
-}
-
-/*
- * Standard driver set up sections
- */
-static struct usb_driver keyspan_driver =
-{
- .name = "keyspan_remote",
- .probe = keyspan_probe,
- .disconnect = keyspan_disconnect,
- .id_table = keyspan_table
-};
-
-static int __init usb_keyspan_init(void)
-{
- int result;
-
- /* register this driver with the USB subsystem */
- result = usb_register(&keyspan_driver);
- if (result)
- err("usb_register failed. Error number %d\n", result);
-
- return result;
-}
-
-static void __exit usb_keyspan_exit(void)
-{
- /* deregister this driver with the USB subsystem */
- usb_deregister(&keyspan_driver);
-}
-
-module_init(usb_keyspan_init);
-module_exit(usb_keyspan_exit);
-
-MODULE_DEVICE_TABLE(usb, keyspan_table);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/usb/input/map_to_7segment.h b/drivers/usb/input/map_to_7segment.h
deleted file mode 100644
index a424094d9fe..00000000000
--- a/drivers/usb/input/map_to_7segment.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * drivers/usb/input/map_to_7segment.h
- *
- * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef MAP_TO_7SEGMENT_H
-#define MAP_TO_7SEGMENT_H
-
-/* This file provides translation primitives and tables for the conversion
- * of (ASCII) characters to a 7-segments notation.
- *
- * The 7 segment's wikipedia notation below is used as standard.
- * See: http://en.wikipedia.org/wiki/Seven_segment_display
- *
- * Notation: +-a-+
- * f b
- * +-g-+
- * e c
- * +-d-+
- *
- * Usage:
- *
- * Register a map variable, and fill it with a character set:
- * static SEG7_DEFAULT_MAP(map_seg7);
- *
- *
- * Then use for conversion:
- * seg7 = map_to_seg7(&map_seg7, some_char);
- * ...
- *
- * In device drivers it is recommended, if required, to make the char map
- * accessible via the sysfs interface using the following scheme:
- *
- * static ssize_t show_map(struct device *dev, char *buf) {
- * memcpy(buf, &map_seg7, sizeof(map_seg7));
- * return sizeof(map_seg7);
- * }
- * static ssize_t store_map(struct device *dev, const char *buf, size_t cnt) {
- * if(cnt != sizeof(map_seg7))
- * return -EINVAL;
- * memcpy(&map_seg7, buf, cnt);
- * return cnt;
- * }
- * static DEVICE_ATTR(map_seg7, PERMS_RW, show_map, store_map);
- *
- * History:
- * 2005-05-31 RFC linux-kernel@vger.kernel.org
- */
-#include <linux/errno.h>
-
-
-#define BIT_SEG7_A 0
-#define BIT_SEG7_B 1
-#define BIT_SEG7_C 2
-#define BIT_SEG7_D 3
-#define BIT_SEG7_E 4
-#define BIT_SEG7_F 5
-#define BIT_SEG7_G 6
-#define BIT_SEG7_RESERVED 7
-
-struct seg7_conversion_map {
- unsigned char table[128];
-};
-
-static inline int map_to_seg7(struct seg7_conversion_map *map, int c)
-{
- return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL;
-}
-
-#define SEG7_CONVERSION_MAP(_name, _map) \
- struct seg7_conversion_map _name = { .table = { _map } }
-
-/*
- * It is recommended to use a facility that allows user space to redefine
- * custom character sets for LCD devices. Please use a sysfs interface
- * as described above.
- */
-#define MAP_TO_SEG7_SYSFS_FILE "map_seg7"
-
-/*******************************************************************************
- * ASCII conversion table
- ******************************************************************************/
-
-#define _SEG7(l,a,b,c,d,e,f,g) \
- ( a<<BIT_SEG7_A | b<<BIT_SEG7_B | c<<BIT_SEG7_C | d<<BIT_SEG7_D | \
- e<<BIT_SEG7_E | f<<BIT_SEG7_F | g<<BIT_SEG7_G )
-
-#define _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-
-#define _MAP_33_47_ASCII_SEG7_SYMBOL \
- _SEG7('!',0,0,0,0,1,1,0), _SEG7('"',0,1,0,0,0,1,0), _SEG7('#',0,1,1,0,1,1,0),\
- _SEG7('$',1,0,1,1,0,1,1), _SEG7('%',0,0,1,0,0,1,0), _SEG7('&',1,0,1,1,1,1,1),\
- _SEG7('\'',0,0,0,0,0,1,0),_SEG7('(',1,0,0,1,1,1,0), _SEG7(')',1,1,1,1,0,0,0),\
- _SEG7('*',0,1,1,0,1,1,1), _SEG7('+',0,1,1,0,0,0,1), _SEG7(',',0,0,0,0,1,0,0),\
- _SEG7('-',0,0,0,0,0,0,1), _SEG7('.',0,0,0,0,1,0,0), _SEG7('/',0,1,0,0,1,0,1),
-
-#define _MAP_48_57_ASCII_SEG7_NUMERIC \
- _SEG7('0',1,1,1,1,1,1,0), _SEG7('1',0,1,1,0,0,0,0), _SEG7('2',1,1,0,1,1,0,1),\
- _SEG7('3',1,1,1,1,0,0,1), _SEG7('4',0,1,1,0,0,1,1), _SEG7('5',1,0,1,1,0,1,1),\
- _SEG7('6',1,0,1,1,1,1,1), _SEG7('7',1,1,1,0,0,0,0), _SEG7('8',1,1,1,1,1,1,1),\
- _SEG7('9',1,1,1,1,0,1,1),
-
-#define _MAP_58_64_ASCII_SEG7_SYMBOL \
- _SEG7(':',0,0,0,1,0,0,1), _SEG7(';',0,0,0,1,0,0,1), _SEG7('<',1,0,0,0,0,1,1),\
- _SEG7('=',0,0,0,1,0,0,1), _SEG7('>',1,1,0,0,0,0,1), _SEG7('?',1,1,1,0,0,1,0),\
- _SEG7('@',1,1,0,1,1,1,1),
-
-#define _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
- _SEG7('A',1,1,1,0,1,1,1), _SEG7('B',1,1,1,1,1,1,1), _SEG7('C',1,0,0,1,1,1,0),\
- _SEG7('D',1,1,1,1,1,1,0), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
- _SEG7('G',1,1,1,1,0,1,1), _SEG7('H',0,1,1,0,1,1,1), _SEG7('I',0,1,1,0,0,0,0),\
- _SEG7('J',0,1,1,1,0,0,0), _SEG7('K',0,1,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
- _SEG7('M',1,1,1,0,1,1,0), _SEG7('N',1,1,1,0,1,1,0), _SEG7('O',1,1,1,1,1,1,0),\
- _SEG7('P',1,1,0,0,1,1,1), _SEG7('Q',1,1,1,1,1,1,0), _SEG7('R',1,1,1,0,1,1,1),\
- _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('U',0,1,1,1,1,1,0),\
- _SEG7('V',0,1,1,1,1,1,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
- _SEG7('Y',0,1,1,0,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
-
-#define _MAP_91_96_ASCII_SEG7_SYMBOL \
- _SEG7('[',1,0,0,1,1,1,0), _SEG7('\\',0,0,1,0,0,1,1),_SEG7(']',1,1,1,1,0,0,0),\
- _SEG7('^',1,1,0,0,0,1,0), _SEG7('_',0,0,0,1,0,0,0), _SEG7('`',0,1,0,0,0,0,0),
-
-#define _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
- _SEG7('A',1,1,1,0,1,1,1), _SEG7('b',0,0,1,1,1,1,1), _SEG7('c',0,0,0,1,1,0,1),\
- _SEG7('d',0,1,1,1,1,0,1), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\
- _SEG7('G',1,1,1,1,0,1,1), _SEG7('h',0,0,1,0,1,1,1), _SEG7('i',0,0,1,0,0,0,0),\
- _SEG7('j',0,0,1,1,0,0,0), _SEG7('k',0,0,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\
- _SEG7('M',1,1,1,0,1,1,0), _SEG7('n',0,0,1,0,1,0,1), _SEG7('o',0,0,1,1,1,0,1),\
- _SEG7('P',1,1,0,0,1,1,1), _SEG7('q',1,1,1,0,0,1,1), _SEG7('r',0,0,0,0,1,0,1),\
- _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('u',0,0,1,1,1,0,0),\
- _SEG7('v',0,0,1,1,1,0,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\
- _SEG7('y',0,1,1,1,0,1,1), _SEG7('Z',1,1,0,1,1,0,1),
-
-#define _MAP_123_126_ASCII_SEG7_SYMBOL \
- _SEG7('{',1,0,0,1,1,1,0), _SEG7('|',0,0,0,0,1,1,0), _SEG7('}',1,1,1,1,0,0,0),\
- _SEG7('~',1,0,0,0,0,0,0),
-
-/* Maps */
-
-/* This set tries to map as close as possible to the visible characteristics
- * of the ASCII symbol, lowercase and uppercase letters may differ in
- * presentation on the display.
- */
-#define MAP_ASCII7SEG_ALPHANUM \
- _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
- _MAP_33_47_ASCII_SEG7_SYMBOL \
- _MAP_48_57_ASCII_SEG7_NUMERIC \
- _MAP_58_64_ASCII_SEG7_SYMBOL \
- _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \
- _MAP_91_96_ASCII_SEG7_SYMBOL \
- _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
- _MAP_123_126_ASCII_SEG7_SYMBOL
-
-/* This set tries to map as close as possible to the symbolic characteristics
- * of the ASCII character for maximum discrimination.
- * For now this means all alpha chars are in lower case representations.
- * (This for example facilitates the use of hex numbers with uppercase input.)
- */
-#define MAP_ASCII7SEG_ALPHANUM_LC \
- _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \
- _MAP_33_47_ASCII_SEG7_SYMBOL \
- _MAP_48_57_ASCII_SEG7_NUMERIC \
- _MAP_58_64_ASCII_SEG7_SYMBOL \
- _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
- _MAP_91_96_ASCII_SEG7_SYMBOL \
- _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \
- _MAP_123_126_ASCII_SEG7_SYMBOL
-
-#define SEG7_DEFAULT_MAP(_name) \
- SEG7_CONVERSION_MAP(_name,MAP_ASCII7SEG_ALPHANUM)
-
-#endif /* MAP_TO_7SEGMENT_H */
-
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
deleted file mode 100644
index 4f93a760fae..00000000000
--- a/drivers/usb/input/powermate.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial.
- *
- * v1.1, (c)2002 William R Sowerbutts <will@sowerbutts.com>
- *
- * This device is a anodised aluminium knob which connects over USB. It can measure
- * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with
- * a spring for automatic release. The base contains a pair of LEDs which illuminate
- * the translucent base. It rotates without limit and reports its relative rotation
- * back to the host when polled by the USB controller.
- *
- * Testing with the knob I have has shown that it measures approximately 94 "clicks"
- * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was
- * a variable speed cordless electric drill) has shown that the device can measure
- * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from
- * the host. If it counts more than 7 clicks before it is polled, it will wrap back
- * to zero and start counting again. This was at quite high speed, however, almost
- * certainly faster than the human hand could turn it. Griffin say that it loses a
- * pulse or two on a direction change; the granularity is so fine that I never
- * noticed this in practice.
- *
- * The device's microcontroller can be programmed to set the LED to either a constant
- * intensity, or to a rhythmic pulsing. Several patterns and speeds are available.
- *
- * Griffin were very happy to provide documentation and free hardware for development.
- *
- * Some userspace tools are available on the web: http://sowerbutts.com/powermate/
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/usb/input.h>
-
-#define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */
-#define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */
-#define POWERMATE_PRODUCT_OLD 0x04AA /* Griffin soundKnob */
-
-#define CONTOUR_VENDOR 0x05f3 /* Contour Design, Inc. */
-#define CONTOUR_JOG 0x0240 /* Jog and Shuttle */
-
-/* these are the command codes we send to the device */
-#define SET_STATIC_BRIGHTNESS 0x01
-#define SET_PULSE_ASLEEP 0x02
-#define SET_PULSE_AWAKE 0x03
-#define SET_PULSE_MODE 0x04
-
-/* these refer to bits in the powermate_device's requires_update field. */
-#define UPDATE_STATIC_BRIGHTNESS (1<<0)
-#define UPDATE_PULSE_ASLEEP (1<<1)
-#define UPDATE_PULSE_AWAKE (1<<2)
-#define UPDATE_PULSE_MODE (1<<3)
-
-/* at least two versions of the hardware exist, with differing payload
- sizes. the first three bytes always contain the "interesting" data in
- the relevant format. */
-#define POWERMATE_PAYLOAD_SIZE_MAX 6
-#define POWERMATE_PAYLOAD_SIZE_MIN 3
-struct powermate_device {
- signed char *data;
- dma_addr_t data_dma;
- struct urb *irq, *config;
- struct usb_ctrlrequest *configcr;
- dma_addr_t configcr_dma;
- struct usb_device *udev;
- struct input_dev *input;
- spinlock_t lock;
- int static_brightness;
- int pulse_speed;
- int pulse_table;
- int pulse_asleep;
- int pulse_awake;
- int requires_update; // physical settings which are out of sync
- char phys[64];
-};
-
-static char pm_name_powermate[] = "Griffin PowerMate";
-static char pm_name_soundknob[] = "Griffin SoundKnob";
-
-static void powermate_config_complete(struct urb *urb);
-
-/* Callback for data arriving from the PowerMate over the USB interrupt pipe */
-static void powermate_irq(struct urb *urb)
-{
- struct powermate_device *pm = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- goto exit;
- }
-
- /* handle updates to device state */
- input_report_key(pm->input, BTN_0, pm->data[0] & 0x01);
- input_report_rel(pm->input, REL_DIAL, pm->data[1]);
- input_sync(pm->input);
-
-exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-/* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
-static void powermate_sync_state(struct powermate_device *pm)
-{
- if (pm->requires_update == 0)
- return; /* no updates are required */
- if (pm->config->status == -EINPROGRESS)
- return; /* an update is already in progress; it'll issue this update when it completes */
-
- if (pm->requires_update & UPDATE_PULSE_ASLEEP){
- pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP );
- pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 );
- pm->requires_update &= ~UPDATE_PULSE_ASLEEP;
- }else if (pm->requires_update & UPDATE_PULSE_AWAKE){
- pm->configcr->wValue = cpu_to_le16( SET_PULSE_AWAKE );
- pm->configcr->wIndex = cpu_to_le16( pm->pulse_awake ? 1 : 0 );
- pm->requires_update &= ~UPDATE_PULSE_AWAKE;
- }else if (pm->requires_update & UPDATE_PULSE_MODE){
- int op, arg;
- /* the powermate takes an operation and an argument for its pulse algorithm.
- the operation can be:
- 0: divide the speed
- 1: pulse at normal speed
- 2: multiply the speed
- the argument only has an effect for operations 0 and 2, and ranges between
- 1 (least effect) to 255 (maximum effect).
-
- thus, several states are equivalent and are coalesced into one state.
-
- we map this onto a range from 0 to 510, with:
- 0 -- 254 -- use divide (0 = slowest)
- 255 -- use normal speed
- 256 -- 510 -- use multiple (510 = fastest).
-
- Only values of 'arg' quite close to 255 are particularly useful/spectacular.
- */
- if (pm->pulse_speed < 255) {
- op = 0; // divide
- arg = 255 - pm->pulse_speed;
- } else if (pm->pulse_speed > 255) {
- op = 2; // multiply
- arg = pm->pulse_speed - 255;
- } else {
- op = 1; // normal speed
- arg = 0; // can be any value
- }
- pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
- pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
- pm->requires_update &= ~UPDATE_PULSE_MODE;
- } else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) {
- pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
- pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
- pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
- } else {
- printk(KERN_ERR "powermate: unknown update required");
- pm->requires_update = 0; /* fudge the bug */
- return;
- }
-
-/* printk("powermate: %04x %04x\n", pm->configcr->wValue, pm->configcr->wIndex); */
-
- pm->configcr->bRequestType = 0x41; /* vendor request */
- pm->configcr->bRequest = 0x01;
- pm->configcr->wLength = 0;
-
- usb_fill_control_urb(pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0),
- (void *) pm->configcr, NULL, 0,
- powermate_config_complete, pm);
- pm->config->setup_dma = pm->configcr_dma;
- pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP;
-
- if (usb_submit_urb(pm->config, GFP_ATOMIC))
- printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
-}
-
-/* Called when our asynchronous control message completes. We may need to issue another immediately */
-static void powermate_config_complete(struct urb *urb)
-{
- struct powermate_device *pm = urb->context;
- unsigned long flags;
-
- if (urb->status)
- printk(KERN_ERR "powermate: config urb returned %d\n", urb->status);
-
- spin_lock_irqsave(&pm->lock, flags);
- powermate_sync_state(pm);
- spin_unlock_irqrestore(&pm->lock, flags);
-}
-
-/* Set the LED up as described and begin the sync with the hardware if required */
-static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed,
- int pulse_table, int pulse_asleep, int pulse_awake)
-{
- unsigned long flags;
-
- if (pulse_speed < 0)
- pulse_speed = 0;
- if (pulse_table < 0)
- pulse_table = 0;
- if (pulse_speed > 510)
- pulse_speed = 510;
- if (pulse_table > 2)
- pulse_table = 2;
-
- pulse_asleep = !!pulse_asleep;
- pulse_awake = !!pulse_awake;
-
-
- spin_lock_irqsave(&pm->lock, flags);
-
- /* mark state updates which are required */
- if (static_brightness != pm->static_brightness) {
- pm->static_brightness = static_brightness;
- pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
- }
- if (pulse_asleep != pm->pulse_asleep) {
- pm->pulse_asleep = pulse_asleep;
- pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
- }
- if (pulse_awake != pm->pulse_awake) {
- pm->pulse_awake = pulse_awake;
- pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
- }
- if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) {
- pm->pulse_speed = pulse_speed;
- pm->pulse_table = pulse_table;
- pm->requires_update |= UPDATE_PULSE_MODE;
- }
-
- powermate_sync_state(pm);
-
- spin_unlock_irqrestore(&pm->lock, flags);
-}
-
-/* Callback from the Input layer when an event arrives from userspace to configure the LED */
-static int powermate_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int _value)
-{
- unsigned int command = (unsigned int)_value;
- struct powermate_device *pm = input_get_drvdata(dev);
-
- if (type == EV_MSC && code == MSC_PULSELED){
- /*
- bits 0- 7: 8 bits: LED brightness
- bits 8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster.
- bits 17-18: 2 bits: pulse table (0, 1, 2 valid)
- bit 19: 1 bit : pulse whilst asleep?
- bit 20: 1 bit : pulse constantly?
- */
- int static_brightness = command & 0xFF; // bits 0-7
- int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16
- int pulse_table = (command >> 17) & 0x3; // bits 17-18
- int pulse_asleep = (command >> 19) & 0x1; // bit 19
- int pulse_awake = (command >> 20) & 0x1; // bit 20
-
- powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake);
- }
-
- return 0;
-}
-
-static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
-{
- pm->data = usb_buffer_alloc(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- GFP_ATOMIC, &pm->data_dma);
- if (!pm->data)
- return -1;
-
- pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
- GFP_ATOMIC, &pm->configcr_dma);
- if (!pm->configcr)
- return -1;
-
- return 0;
-}
-
-static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm)
-{
- if (pm->data)
- usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX,
- pm->data, pm->data_dma);
- if (pm->configcr)
- usb_buffer_free(udev, sizeof(*(pm->configcr)),
- pm->configcr, pm->configcr_dma);
-}
-
-/* Called whenever a USB device matching one in our supported devices table is connected */
-static int powermate_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev (intf);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct powermate_device *pm;
- struct input_dev *input_dev;
- int pipe, maxp;
- int error = -ENOMEM;
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
- if (!usb_endpoint_is_int_in(endpoint))
- return -EIO;
-
- usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- 0, interface->desc.bInterfaceNumber, NULL, 0,
- USB_CTRL_SET_TIMEOUT);
-
- pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!pm || !input_dev)
- goto fail1;
-
- if (powermate_alloc_buffers(udev, pm))
- goto fail2;
-
- pm->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!pm->irq)
- goto fail2;
-
- pm->config = usb_alloc_urb(0, GFP_KERNEL);
- if (!pm->config)
- goto fail3;
-
- pm->udev = udev;
- pm->input = input_dev;
-
- usb_make_path(udev, pm->phys, sizeof(pm->phys));
- strlcpy(pm->phys, "/input0", sizeof(pm->phys));
-
- spin_lock_init(&pm->lock);
-
- switch (le16_to_cpu(udev->descriptor.idProduct)) {
- case POWERMATE_PRODUCT_NEW:
- input_dev->name = pm_name_powermate;
- break;
- case POWERMATE_PRODUCT_OLD:
- input_dev->name = pm_name_soundknob;
- break;
- default:
- input_dev->name = pm_name_soundknob;
- printk(KERN_WARNING "powermate: unknown product id %04x\n",
- le16_to_cpu(udev->descriptor.idProduct));
- }
-
- input_dev->phys = pm->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, pm);
-
- input_dev->event = powermate_input_event;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
- input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
- input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
- input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
-
- /* get a handle to the interrupt data pipe */
- pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-
- if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) {
- printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
- POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
- maxp = POWERMATE_PAYLOAD_SIZE_MAX;
- }
-
- usb_fill_int_urb(pm->irq, udev, pipe, pm->data,
- maxp, powermate_irq,
- pm, endpoint->bInterval);
- pm->irq->transfer_dma = pm->data_dma;
- pm->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* register our interrupt URB with the USB system */
- if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
- error = -EIO;
- goto fail4;
- }
-
- error = input_register_device(pm->input);
- if (error)
- goto fail5;
-
-
- /* force an update of everything */
- pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
- powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters
-
- usb_set_intfdata(intf, pm);
- return 0;
-
- fail5: usb_kill_urb(pm->irq);
- fail4: usb_free_urb(pm->config);
- fail3: usb_free_urb(pm->irq);
- fail2: powermate_free_buffers(udev, pm);
- fail1: input_free_device(input_dev);
- kfree(pm);
- return error;
-}
-
-/* Called when a USB device we've accepted ownership of is removed */
-static void powermate_disconnect(struct usb_interface *intf)
-{
- struct powermate_device *pm = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (pm) {
- pm->requires_update = 0;
- usb_kill_urb(pm->irq);
- input_unregister_device(pm->input);
- usb_free_urb(pm->irq);
- usb_free_urb(pm->config);
- powermate_free_buffers(interface_to_usbdev(intf), pm);
-
- kfree(pm);
- }
-}
-
-static struct usb_device_id powermate_devices [] = {
- { USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_NEW) },
- { USB_DEVICE(POWERMATE_VENDOR, POWERMATE_PRODUCT_OLD) },
- { USB_DEVICE(CONTOUR_VENDOR, CONTOUR_JOG) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, powermate_devices);
-
-static struct usb_driver powermate_driver = {
- .name = "powermate",
- .probe = powermate_probe,
- .disconnect = powermate_disconnect,
- .id_table = powermate_devices,
-};
-
-static int __init powermate_init(void)
-{
- return usb_register(&powermate_driver);
-}
-
-static void __exit powermate_cleanup(void)
-{
- usb_deregister(&powermate_driver);
-}
-
-module_init(powermate_init);
-module_exit(powermate_cleanup);
-
-MODULE_AUTHOR( "William R Sowerbutts" );
-MODULE_DESCRIPTION( "Griffin Technology, Inc PowerMate driver" );
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c
deleted file mode 100644
index e0829413336..00000000000
--- a/drivers/usb/input/usbtouchscreen.c
+++ /dev/null
@@ -1,840 +0,0 @@
-/******************************************************************************
- * usbtouchscreen.c
- * Driver for USB Touchscreens, supporting those devices:
- * - eGalax Touchkit
- * includes eTurboTouch CT-410/510/700
- * - 3M/Microtouch EX II series
- * - ITM
- * - PanJit TouchSet
- * - eTurboTouch
- * - Gunze AHL61
- * - DMC TSC-10/25
- *
- * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
- * Copyright (C) by Todd E. Johnson (mtouchusb.c)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Driver is based on touchkitusb.c
- * - ITM parts are from itmtouch.c
- * - 3M parts are from mtouchusb.c
- * - PanJit parts are from an unmerged driver by Lanslott Gish
- * - DMC TSC 10/25 are from Holger Schurig, with ideas from an unmerged
- * driver from Marius Vollmer
- *
- *****************************************************************************/
-
-//#define DEBUG
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb/input.h>
-
-
-#define DRIVER_VERSION "v0.5"
-#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
-#define DRIVER_DESC "USB Touchscreen Driver"
-
-static int swap_xy;
-module_param(swap_xy, bool, 0644);
-MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
-
-/* device specifc data/functions */
-struct usbtouch_usb;
-struct usbtouch_device_info {
- int min_xc, max_xc;
- int min_yc, max_yc;
- int min_press, max_press;
- int rept_size;
- int flags;
-
- void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
- int (*get_pkt_len) (unsigned char *pkt, int len);
- int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt);
- int (*init) (struct usbtouch_usb *usbtouch);
-};
-
-#define USBTOUCH_FLG_BUFFER 0x01
-
-
-/* a usbtouch device */
-struct usbtouch_usb {
- unsigned char *data;
- dma_addr_t data_dma;
- unsigned char *buffer;
- int buf_len;
- struct urb *irq;
- struct usb_device *udev;
- struct input_dev *input;
- struct usbtouch_device_info *type;
- char name[128];
- char phys[64];
-
- int x, y;
- int touch, press;
-};
-
-
-#if defined(CONFIG_USB_TOUCHSCREEN_EGALAX) || defined(CONFIG_USB_TOUCHSCREEN_ETURBO)
-#define MULTI_PACKET
-#endif
-
-#ifdef MULTI_PACKET
-static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
- unsigned char *pkt, int len);
-#endif
-
-/* device types */
-enum {
- DEVTPYE_DUMMY = -1,
- DEVTYPE_EGALAX,
- DEVTYPE_PANJIT,
- DEVTYPE_3M,
- DEVTYPE_ITM,
- DEVTYPE_ETURBO,
- DEVTYPE_GUNZE,
- DEVTYPE_DMC_TSC10,
-};
-
-static struct usb_device_id usbtouch_devices[] = {
-#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
- {USB_DEVICE(0x3823, 0x0001), .driver_info = DEVTYPE_EGALAX},
- {USB_DEVICE(0x3823, 0x0002), .driver_info = DEVTYPE_EGALAX},
- {USB_DEVICE(0x0123, 0x0001), .driver_info = DEVTYPE_EGALAX},
- {USB_DEVICE(0x0eef, 0x0001), .driver_info = DEVTYPE_EGALAX},
- {USB_DEVICE(0x0eef, 0x0002), .driver_info = DEVTYPE_EGALAX},
- {USB_DEVICE(0x1234, 0x0001), .driver_info = DEVTYPE_EGALAX},
- {USB_DEVICE(0x1234, 0x0002), .driver_info = DEVTYPE_EGALAX},
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
- {USB_DEVICE(0x134c, 0x0001), .driver_info = DEVTYPE_PANJIT},
- {USB_DEVICE(0x134c, 0x0002), .driver_info = DEVTYPE_PANJIT},
- {USB_DEVICE(0x134c, 0x0003), .driver_info = DEVTYPE_PANJIT},
- {USB_DEVICE(0x134c, 0x0004), .driver_info = DEVTYPE_PANJIT},
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_3M
- {USB_DEVICE(0x0596, 0x0001), .driver_info = DEVTYPE_3M},
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_ITM
- {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM},
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
- {USB_DEVICE(0x1234, 0x5678), .driver_info = DEVTYPE_ETURBO},
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
- {USB_DEVICE(0x0637, 0x0001), .driver_info = DEVTYPE_GUNZE},
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
- {USB_DEVICE(0x0afa, 0x03e8), .driver_info = DEVTYPE_DMC_TSC10},
-#endif
-
- {}
-};
-
-
-/*****************************************************************************
- * eGalax part
- */
-
-#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
-
-#define EGALAX_PKT_TYPE_MASK 0xFE
-#define EGALAX_PKT_TYPE_REPT 0x80
-#define EGALAX_PKT_TYPE_DIAG 0x0A
-
-static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
- return 0;
-
- dev->x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F);
- dev->y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F);
- dev->touch = pkt[0] & 0x01;
-
- return 1;
-}
-
-static int egalax_get_pkt_len(unsigned char *buf, int len)
-{
- switch (buf[0] & EGALAX_PKT_TYPE_MASK) {
- case EGALAX_PKT_TYPE_REPT:
- return 5;
-
- case EGALAX_PKT_TYPE_DIAG:
- if (len < 2)
- return -1;
-
- return buf[1] + 2;
- }
-
- return 0;
-}
-#endif
-
-
-/*****************************************************************************
- * PanJit Part
- */
-#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
-static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
- dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
- dev->touch = pkt[0] & 0x01;
-
- return 1;
-}
-#endif
-
-
-/*****************************************************************************
- * 3M/Microtouch Part
- */
-#ifdef CONFIG_USB_TOUCHSCREEN_3M
-
-#define MTOUCHUSB_ASYNC_REPORT 1
-#define MTOUCHUSB_RESET 7
-#define MTOUCHUSB_REQ_CTRLLR_ID 10
-
-static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- dev->x = (pkt[8] << 8) | pkt[7];
- dev->y = (pkt[10] << 8) | pkt[9];
- dev->touch = (pkt[2] & 0x40) ? 1 : 0;
-
- return 1;
-}
-
-static int mtouch_init(struct usbtouch_usb *usbtouch)
-{
- int ret, i;
-
- ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
- MTOUCHUSB_RESET,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
- dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
- __FUNCTION__, ret);
- if (ret < 0)
- return ret;
- msleep(150);
-
- for (i = 0; i < 3; i++) {
- ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
- MTOUCHUSB_ASYNC_REPORT,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
- dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
- __FUNCTION__, ret);
- if (ret >= 0)
- break;
- if (ret != -EPIPE)
- return ret;
- }
-
- return 0;
-}
-#endif
-
-
-/*****************************************************************************
- * ITM Part
- */
-#ifdef CONFIG_USB_TOUCHSCREEN_ITM
-static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- int touch;
- /*
- * ITM devices report invalid x/y data if not touched.
- * if the screen was touched before but is not touched any more
- * report touch as 0 with the last valid x/y data once. then stop
- * reporting data until touched again.
- */
- dev->press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F);
-
- touch = ~pkt[7] & 0x20;
- if (!touch) {
- if (dev->touch) {
- dev->touch = 0;
- return 1;
- }
-
- return 0;
- }
-
- dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F);
- dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F);
- dev->touch = touch;
-
- return 1;
-}
-#endif
-
-
-/*****************************************************************************
- * eTurboTouch part
- */
-#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
-static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- unsigned int shift;
-
- /* packets should start with sync */
- if (!(pkt[0] & 0x80))
- return 0;
-
- shift = (6 - (pkt[0] & 0x03));
- dev->x = ((pkt[3] << 7) | pkt[4]) >> shift;
- dev->y = ((pkt[1] << 7) | pkt[2]) >> shift;
- dev->touch = (pkt[0] & 0x10) ? 1 : 0;
-
- return 1;
-}
-
-static int eturbo_get_pkt_len(unsigned char *buf, int len)
-{
- if (buf[0] & 0x80)
- return 5;
- if (buf[0] == 0x01)
- return 3;
- return 0;
-}
-#endif
-
-
-/*****************************************************************************
- * Gunze part
- */
-#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
-static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80))
- return 0;
-
- dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F);
- dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F);
- dev->touch = pkt[0] & 0x20;
-
- return 1;
-}
-#endif
-
-/*****************************************************************************
- * DMC TSC-10/25 Part
- *
- * Documentation about the controller and it's protocol can be found at
- * http://www.dmccoltd.com/files/controler/tsc10usb_pi_e.pdf
- * http://www.dmccoltd.com/files/controler/tsc25_usb_e.pdf
- */
-#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
-
-/* supported data rates. currently using 130 */
-#define TSC10_RATE_POINT 0x50
-#define TSC10_RATE_30 0x40
-#define TSC10_RATE_50 0x41
-#define TSC10_RATE_80 0x42
-#define TSC10_RATE_100 0x43
-#define TSC10_RATE_130 0x44
-#define TSC10_RATE_150 0x45
-
-/* commands */
-#define TSC10_CMD_RESET 0x55
-#define TSC10_CMD_RATE 0x05
-#define TSC10_CMD_DATA1 0x01
-
-static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
-{
- struct usb_device *dev = usbtouch->udev;
- int ret;
- unsigned char buf[2];
-
- /* reset */
- buf[0] = buf[1] = 0xFF;
- ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
- TSC10_CMD_RESET,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
- if (ret < 0)
- return ret;
- if (buf[0] != 0x06 || buf[1] != 0x00)
- return -ENODEV;
-
- /* set coordinate output rate */
- buf[0] = buf[1] = 0xFF;
- ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
- TSC10_CMD_RATE,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- TSC10_RATE_150, 0, buf, 2, USB_CTRL_SET_TIMEOUT);
- if (ret < 0)
- return ret;
- if (buf[0] != 0x06 || buf[1] != 0x00)
- return -ENODEV;
-
- /* start sending data */
- ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
- TSC10_CMD_DATA1,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-
-static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
-{
- dev->x = ((pkt[2] & 0x03) << 8) | pkt[1];
- dev->y = ((pkt[4] & 0x03) << 8) | pkt[3];
- dev->touch = pkt[0] & 0x01;
-
- return 1;
-}
-#endif
-
-
-/*****************************************************************************
- * the different device descriptors
- */
-static struct usbtouch_device_info usbtouch_dev_info[] = {
-#ifdef CONFIG_USB_TOUCHSCREEN_EGALAX
- [DEVTYPE_EGALAX] = {
- .min_xc = 0x0,
- .max_xc = 0x07ff,
- .min_yc = 0x0,
- .max_yc = 0x07ff,
- .rept_size = 16,
- .flags = USBTOUCH_FLG_BUFFER,
- .process_pkt = usbtouch_process_multi,
- .get_pkt_len = egalax_get_pkt_len,
- .read_data = egalax_read_data,
- },
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_PANJIT
- [DEVTYPE_PANJIT] = {
- .min_xc = 0x0,
- .max_xc = 0x0fff,
- .min_yc = 0x0,
- .max_yc = 0x0fff,
- .rept_size = 8,
- .read_data = panjit_read_data,
- },
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_3M
- [DEVTYPE_3M] = {
- .min_xc = 0x0,
- .max_xc = 0x4000,
- .min_yc = 0x0,
- .max_yc = 0x4000,
- .rept_size = 11,
- .read_data = mtouch_read_data,
- .init = mtouch_init,
- },
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_ITM
- [DEVTYPE_ITM] = {
- .min_xc = 0x0,
- .max_xc = 0x0fff,
- .min_yc = 0x0,
- .max_yc = 0x0fff,
- .max_press = 0xff,
- .rept_size = 8,
- .read_data = itm_read_data,
- },
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_ETURBO
- [DEVTYPE_ETURBO] = {
- .min_xc = 0x0,
- .max_xc = 0x07ff,
- .min_yc = 0x0,
- .max_yc = 0x07ff,
- .rept_size = 8,
- .flags = USBTOUCH_FLG_BUFFER,
- .process_pkt = usbtouch_process_multi,
- .get_pkt_len = eturbo_get_pkt_len,
- .read_data = eturbo_read_data,
- },
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_GUNZE
- [DEVTYPE_GUNZE] = {
- .min_xc = 0x0,
- .max_xc = 0x0fff,
- .min_yc = 0x0,
- .max_yc = 0x0fff,
- .rept_size = 4,
- .read_data = gunze_read_data,
- },
-#endif
-
-#ifdef CONFIG_USB_TOUCHSCREEN_DMC_TSC10
- [DEVTYPE_DMC_TSC10] = {
- .min_xc = 0x0,
- .max_xc = 0x03ff,
- .min_yc = 0x0,
- .max_yc = 0x03ff,
- .rept_size = 5,
- .init = dmc_tsc10_init,
- .read_data = dmc_tsc10_read_data,
- },
-#endif
-};
-
-
-/*****************************************************************************
- * Generic Part
- */
-static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
- unsigned char *pkt, int len)
-{
- struct usbtouch_device_info *type = usbtouch->type;
-
- if (!type->read_data(usbtouch, pkt))
- return;
-
- input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);
-
- if (swap_xy) {
- input_report_abs(usbtouch->input, ABS_X, usbtouch->y);
- input_report_abs(usbtouch->input, ABS_Y, usbtouch->x);
- } else {
- input_report_abs(usbtouch->input, ABS_X, usbtouch->x);
- input_report_abs(usbtouch->input, ABS_Y, usbtouch->y);
- }
- if (type->max_press)
- input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press);
- input_sync(usbtouch->input);
-}
-
-
-#ifdef MULTI_PACKET
-static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
- unsigned char *pkt, int len)
-{
- unsigned char *buffer;
- int pkt_len, pos, buf_len, tmp;
-
- /* process buffer */
- if (unlikely(usbtouch->buf_len)) {
- /* try to get size */
- pkt_len = usbtouch->type->get_pkt_len(
- usbtouch->buffer, usbtouch->buf_len);
-
- /* drop? */
- if (unlikely(!pkt_len))
- goto out_flush_buf;
-
- /* need to append -pkt_len bytes before able to get size */
- if (unlikely(pkt_len < 0)) {
- int append = -pkt_len;
- if (unlikely(append > len))
- append = len;
- if (usbtouch->buf_len + append >= usbtouch->type->rept_size)
- goto out_flush_buf;
- memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, append);
- usbtouch->buf_len += append;
-
- pkt_len = usbtouch->type->get_pkt_len(
- usbtouch->buffer, usbtouch->buf_len);
- if (pkt_len < 0)
- return;
- }
-
- /* append */
- tmp = pkt_len - usbtouch->buf_len;
- if (usbtouch->buf_len + tmp >= usbtouch->type->rept_size)
- goto out_flush_buf;
- memcpy(usbtouch->buffer + usbtouch->buf_len, pkt, tmp);
- usbtouch_process_pkt(usbtouch, usbtouch->buffer, pkt_len);
-
- buffer = pkt + tmp;
- buf_len = len - tmp;
- } else {
- buffer = pkt;
- buf_len = len;
- }
-
- /* loop over the received packet, process */
- pos = 0;
- while (pos < buf_len) {
- /* get packet len */
- pkt_len = usbtouch->type->get_pkt_len(buffer + pos, len);
-
- /* unknown packet: drop everything */
- if (unlikely(!pkt_len))
- goto out_flush_buf;
-
- /* full packet: process */
- if (likely((pkt_len > 0) && (pkt_len <= buf_len - pos))) {
- usbtouch_process_pkt(usbtouch, buffer + pos, pkt_len);
- } else {
- /* incomplete packet: save in buffer */
- memcpy(usbtouch->buffer, buffer + pos, buf_len - pos);
- usbtouch->buf_len = buf_len - pos;
- return;
- }
- pos += pkt_len;
- }
-
-out_flush_buf:
- usbtouch->buf_len = 0;
- return;
-}
-#endif
-
-
-static void usbtouch_irq(struct urb *urb)
-{
- struct usbtouch_usb *usbtouch = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ETIME:
- /* this urb is timing out */
- dbg("%s - urb timed out - was the device unplugged?",
- __FUNCTION__);
- return;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- usbtouch->type->process_pkt(usbtouch, usbtouch->data, urb->actual_length);
-
-exit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- err("%s - usb_submit_urb failed with result: %d",
- __FUNCTION__, retval);
-}
-
-static int usbtouch_open(struct input_dev *input)
-{
- struct usbtouch_usb *usbtouch = input_get_drvdata(input);
-
- usbtouch->irq->dev = usbtouch->udev;
-
- if (usb_submit_urb(usbtouch->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usbtouch_close(struct input_dev *input)
-{
- struct usbtouch_usb *usbtouch = input_get_drvdata(input);
-
- usb_kill_urb(usbtouch->irq);
-}
-
-
-static void usbtouch_free_buffers(struct usb_device *udev,
- struct usbtouch_usb *usbtouch)
-{
- if (usbtouch->data)
- usb_buffer_free(udev, usbtouch->type->rept_size,
- usbtouch->data, usbtouch->data_dma);
- kfree(usbtouch->buffer);
-}
-
-
-static int usbtouch_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usbtouch_usb *usbtouch;
- struct input_dev *input_dev;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usbtouch_device_info *type;
- int err = -ENOMEM;
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
-
- usbtouch = kzalloc(sizeof(struct usbtouch_usb), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!usbtouch || !input_dev)
- goto out_free;
-
- type = &usbtouch_dev_info[id->driver_info];
- usbtouch->type = type;
- if (!type->process_pkt)
- type->process_pkt = usbtouch_process_pkt;
-
- usbtouch->data = usb_buffer_alloc(udev, type->rept_size,
- GFP_KERNEL, &usbtouch->data_dma);
- if (!usbtouch->data)
- goto out_free;
-
- if (type->flags & USBTOUCH_FLG_BUFFER) {
- usbtouch->buffer = kmalloc(type->rept_size, GFP_KERNEL);
- if (!usbtouch->buffer)
- goto out_free_buffers;
- }
-
- usbtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!usbtouch->irq) {
- dbg("%s - usb_alloc_urb failed: usbtouch->irq", __FUNCTION__);
- goto out_free_buffers;
- }
-
- usbtouch->udev = udev;
- usbtouch->input = input_dev;
-
- if (udev->manufacturer)
- strlcpy(usbtouch->name, udev->manufacturer, sizeof(usbtouch->name));
-
- if (udev->product) {
- if (udev->manufacturer)
- strlcat(usbtouch->name, " ", sizeof(usbtouch->name));
- strlcat(usbtouch->name, udev->product, sizeof(usbtouch->name));
- }
-
- if (!strlen(usbtouch->name))
- snprintf(usbtouch->name, sizeof(usbtouch->name),
- "USB Touchscreen %04x:%04x",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- usb_make_path(udev, usbtouch->phys, sizeof(usbtouch->phys));
- strlcpy(usbtouch->phys, "/input0", sizeof(usbtouch->phys));
-
- input_dev->name = usbtouch->name;
- input_dev->phys = usbtouch->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, usbtouch);
-
- input_dev->open = usbtouch_open;
- input_dev->close = usbtouch_close;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
- input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
- input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
- if (type->max_press)
- input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,
- type->max_press, 0, 0);
-
- usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
- usb_rcvintpipe(usbtouch->udev, endpoint->bEndpointAddress),
- usbtouch->data, type->rept_size,
- usbtouch_irq, usbtouch, endpoint->bInterval);
-
- usbtouch->irq->dev = usbtouch->udev;
- usbtouch->irq->transfer_dma = usbtouch->data_dma;
- usbtouch->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- /* device specific init */
- if (type->init) {
- err = type->init(usbtouch);
- if (err) {
- dbg("%s - type->init() failed, err: %d", __FUNCTION__, err);
- goto out_free_buffers;
- }
- }
-
- err = input_register_device(usbtouch->input);
- if (err) {
- dbg("%s - input_register_device failed, err: %d", __FUNCTION__, err);
- goto out_free_buffers;
- }
-
- usb_set_intfdata(intf, usbtouch);
-
- return 0;
-
-out_free_buffers:
- usbtouch_free_buffers(udev, usbtouch);
-out_free:
- input_free_device(input_dev);
- kfree(usbtouch);
- return err;
-}
-
-static void usbtouch_disconnect(struct usb_interface *intf)
-{
- struct usbtouch_usb *usbtouch = usb_get_intfdata(intf);
-
- dbg("%s - called", __FUNCTION__);
-
- if (!usbtouch)
- return;
-
- dbg("%s - usbtouch is initialized, cleaning up", __FUNCTION__);
- usb_set_intfdata(intf, NULL);
- usb_kill_urb(usbtouch->irq);
- input_unregister_device(usbtouch->input);
- usb_free_urb(usbtouch->irq);
- usbtouch_free_buffers(interface_to_usbdev(intf), usbtouch);
- kfree(usbtouch);
-}
-
-MODULE_DEVICE_TABLE(usb, usbtouch_devices);
-
-static struct usb_driver usbtouch_driver = {
- .name = "usbtouchscreen",
- .probe = usbtouch_probe,
- .disconnect = usbtouch_disconnect,
- .id_table = usbtouch_devices,
-};
-
-static int __init usbtouch_init(void)
-{
- return usb_register(&usbtouch_driver);
-}
-
-static void __exit usbtouch_cleanup(void)
-{
- usb_deregister(&usbtouch_driver);
-}
-
-module_init(usbtouch_init);
-module_exit(usbtouch_cleanup);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-MODULE_ALIAS("touchkitusb");
-MODULE_ALIAS("itmtouch");
-MODULE_ALIAS("mtouchusb");
diff --git a/drivers/usb/input/wacom.h b/drivers/usb/input/wacom.h
deleted file mode 100644
index d85abfc5ab5..00000000000
--- a/drivers/usb/input/wacom.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * drivers/usb/input/wacom.h
- *
- * USB Wacom Graphire and Wacom Intuos tablet support
- *
- * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
- * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk>
- * Copyright (c) 2000 Clifford Wolf <clifford@clifford.at>
- * Copyright (c) 2000 Sam Mosel <sam.mosel@computer.org>
- * Copyright (c) 2000 James E. Blair <corvus@gnu.org>
- * Copyright (c) 2000 Daniel Egger <egger@suse.de>
- * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com>
- * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be>
- * Copyright (c) 2002-2006 Ping Cheng <pingc@wacom.com>
- *
- * ChangeLog:
- * v0.1 (vp) - Initial release
- * v0.2 (aba) - Support for all buttons / combinations
- * v0.3 (vp) - Support for Intuos added
- * v0.4 (sm) - Support for more Intuos models, menustrip
- * relative mode, proximity.
- * v0.5 (vp) - Big cleanup, nifty features removed,
- * they belong in userspace
- * v1.8 (vp) - Submit URB only when operating, moved to CVS,
- * use input_report_key instead of report_btn and
- * other cleanups
- * v1.11 (vp) - Add URB ->dev setting for new kernels
- * v1.11 (jb) - Add support for the 4D Mouse & Lens
- * v1.12 (de) - Add support for two more inking pen IDs
- * v1.14 (vp) - Use new USB device id probing scheme.
- * Fix Wacom Graphire mouse wheel
- * v1.18 (vp) - Fix mouse wheel direction
- * Make mouse relative
- * v1.20 (fl) - Report tool id for Intuos devices
- * - Multi tools support
- * - Corrected Intuos protocol decoding (airbrush, 4D mouse, lens cursor...)
- * - Add PL models support
- * - Fix Wacom Graphire mouse wheel again
- * v1.21 (vp) - Removed protocol descriptions
- * - Added MISC_SERIAL for tool serial numbers
- * (gb) - Identify version on module load.
- * v1.21.1 (fl) - added Graphire2 support
- * v1.21.2 (fl) - added Intuos2 support
- * - added all the PL ids
- * v1.21.3 (fl) - added another eraser id from Neil Okamoto
- * - added smooth filter for Graphire from Peri Hankey
- * - added PenPartner support from Olaf van Es
- * - new tool ids from Ole Martin Bjoerndalen
- * v1.29 (pc) - Add support for more tablets
- * - Fix pressure reporting
- * v1.30 (vp) - Merge 2.4 and 2.5 drivers
- * - Since 2.5 now has input_sync(), remove MSC_SERIAL abuse
- * - Cleanups here and there
- * v1.30.1 (pi) - Added Graphire3 support
- * v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
- * v1.43 (pc) - Added support for Cintiq 21UX
- * - Fixed a Graphire bug
- * - Merged wacom_intuos3_irq into wacom_intuos_irq
- * v1.44 (pc) - Added support for Graphire4, Cintiq 710, Intuos3 6x11, etc.
- * - Report Device IDs
- * v1.45 (pc) - Added support for DTF 521, Intuos3 12x12 and 12x19
- * - Minor data report fix
- * v1.46 (pc) - Split wacom.c into wacom_sys.c and wacom_wac.c,
- * - where wacom_sys.c deals with system specific code,
- * - and wacom_wac.c deals with Wacom specific code
- * - Support Intuos3 4x6
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef WACOM_H
-#define WACOM_H
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb/input.h>
-#include <asm/unaligned.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.46"
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-#define USB_VENDOR_ID_WACOM 0x056a
-
-struct wacom {
- dma_addr_t data_dma;
- struct input_dev *dev;
- struct usb_device *usbdev;
- struct urb *irq;
- struct wacom_wac * wacom_wac;
- char phys[32];
-};
-
-struct wacom_combo {
- struct wacom * wacom;
- struct urb * urb;
-};
-
-extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
-extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data);
-extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data);
-extern void wacom_report_key(void *wcombo, unsigned int key_type, int key_data);
-extern void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value);
-extern void wacom_input_sync(void *wcombo);
-extern void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
-extern __u16 wacom_le16_to_cpu(unsigned char *data);
-extern __u16 wacom_be16_to_cpu(unsigned char *data);
-extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
-extern const struct usb_device_id * get_device_table(void);
-
-#endif
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c
deleted file mode 100644
index 1fe48208c2f..00000000000
--- a/drivers/usb/input/wacom_sys.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * drivers/usb/input/wacom_sys.c
- *
- * USB Wacom Graphire and Wacom Intuos tablet support - system specific code
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include "wacom.h"
-#include "wacom_wac.h"
-
-#define USB_REQ_GET_REPORT 0x01
-#define USB_REQ_SET_REPORT 0x09
-
-static int usb_get_report(struct usb_interface *intf, unsigned char type,
- unsigned char id, void *buf, int size)
-{
- return usb_control_msg(interface_to_usbdev(intf),
- usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
- USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
- buf, size, 100);
-}
-
-static int usb_set_report(struct usb_interface *intf, unsigned char type,
- unsigned char id, void *buf, int size)
-{
- return usb_control_msg(interface_to_usbdev(intf),
- usb_sndctrlpipe(interface_to_usbdev(intf), 0),
- USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
- buf, size, 1000);
-}
-
-static struct input_dev * get_input_dev(struct wacom_combo *wcombo)
-{
- return wcombo->wacom->dev;
-}
-
-static void wacom_sys_irq(struct urb *urb)
-{
- struct wacom *wacom = urb->context;
- struct wacom_combo wcombo;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- goto exit;
- }
-
- wcombo.wacom = wacom;
- wcombo.urb = urb;
-
- if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo))
- input_sync(get_input_dev(&wcombo));
-
- exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)
-{
- input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data);
- return;
-}
-
-void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data)
-{
- input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data);
- return;
-}
-
-void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data)
-{
- input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data);
- return;
-}
-
-void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value)
-{
- input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value);
- return;
-}
-
-__u16 wacom_be16_to_cpu(unsigned char *data)
-{
- __u16 value;
- value = be16_to_cpu(*(__be16 *) data);
- return value;
-}
-
-__u16 wacom_le16_to_cpu(unsigned char *data)
-{
- __u16 value;
- value = le16_to_cpu(*(__le16 *) data);
- return value;
-}
-
-void wacom_input_sync(void *wcombo)
-{
- input_sync(get_input_dev((struct wacom_combo *)wcombo));
- return;
-}
-
-static int wacom_open(struct input_dev *dev)
-{
- struct wacom *wacom = input_get_drvdata(dev);
-
- wacom->irq->dev = wacom->usbdev;
- if (usb_submit_urb(wacom->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void wacom_close(struct input_dev *dev)
-{
- struct wacom *wacom = input_get_drvdata(dev);
-
- usb_kill_urb(wacom->irq);
-}
-
-void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->evbit[0] |= BIT(EV_MSC);
- input_dev->mscbit[0] |= BIT(MSC_SERIAL);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4);
-}
-
-void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->evbit[0] |= BIT(EV_REL);
- input_dev->relbit[0] |= BIT(REL_WHEEL);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
- input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
-}
-
-void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
- input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
-}
-
-void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
- input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
-}
-
-void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
- input_dev->mscbit[0] |= BIT(MSC_SERIAL);
- input_dev->relbit[0] |= BIT(REL_WHEEL);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
- | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
- input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
- input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
- input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
- input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
- input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
- input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
-}
-
-void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
-}
-
-void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER);
-}
-
-static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_endpoint_descriptor *endpoint;
- struct wacom *wacom;
- struct wacom_wac *wacom_wac;
- struct input_dev *input_dev;
- int error = -ENOMEM;
- char rep_data[2], limit = 0;
-
- wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
- wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!wacom || !input_dev || !wacom_wac)
- goto fail1;
-
- wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
- if (!wacom_wac->data)
- goto fail1;
-
- wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!wacom->irq)
- goto fail2;
-
- wacom->usbdev = dev;
- wacom->dev = input_dev;
- usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
- strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
-
- wacom_wac->features = get_wacom_feature(id);
- BUG_ON(wacom_wac->features->pktlen > 10);
-
- input_dev->name = wacom_wac->features->name;
- wacom->wacom_wac = wacom_wac;
- usb_to_input_id(dev, &input_dev->id);
-
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, wacom);
-
- input_dev->open = wacom_open;
- input_dev->close = wacom_close;
-
- input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
- input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
- input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC);
-
- wacom_init_input_dev(input_dev, wacom_wac);
-
- endpoint = &intf->cur_altsetting->endpoint[0].desc;
-
- usb_fill_int_urb(wacom->irq, dev,
- usb_rcvintpipe(dev, endpoint->bEndpointAddress),
- wacom_wac->data, wacom_wac->features->pktlen,
- wacom_sys_irq, wacom, endpoint->bInterval);
- wacom->irq->transfer_dma = wacom->data_dma;
- wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- error = input_register_device(wacom->dev);
- if (error)
- goto fail3;
-
- /* Ask the tablet to report tablet data. Repeat until it succeeds */
- do {
- rep_data[0] = 2;
- rep_data[1] = 2;
- usb_set_report(intf, 3, 2, rep_data, 2);
- usb_get_report(intf, 3, 2, rep_data, 2);
- } while (rep_data[1] != 2 && limit++ < 5);
-
- usb_set_intfdata(intf, wacom);
- return 0;
-
- fail3: usb_free_urb(wacom->irq);
- fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
- fail1: input_free_device(input_dev);
- kfree(wacom);
- kfree(wacom_wac);
- return error;
-}
-
-static void wacom_disconnect(struct usb_interface *intf)
-{
- struct wacom *wacom = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (wacom) {
- usb_kill_urb(wacom->irq);
- input_unregister_device(wacom->dev);
- usb_free_urb(wacom->irq);
- usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
- kfree(wacom->wacom_wac);
- kfree(wacom);
- }
-}
-
-static struct usb_driver wacom_driver = {
- .name = "wacom",
- .probe = wacom_probe,
- .disconnect = wacom_disconnect,
-};
-
-static int __init wacom_init(void)
-{
- int result;
- wacom_driver.id_table = get_device_table();
- result = usb_register(&wacom_driver);
- if (result == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
- return result;
-}
-
-static void __exit wacom_exit(void)
-{
- usb_deregister(&wacom_driver);
-}
-
-module_init(wacom_init);
-module_exit(wacom_exit);
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c
deleted file mode 100644
index 4f3e9bc7177..00000000000
--- a/drivers/usb/input/wacom_wac.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * drivers/usb/input/wacom_wac.c
- *
- * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#include "wacom.h"
-#include "wacom_wac.h"
-
-static int wacom_penpartner_irq(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
-
- switch (data[0]) {
- case 1:
- if (data[5] & 0x80) {
- wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
- wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;
- wacom_report_key(wcombo, wacom->tool[0], 1);
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
- wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
- wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
- wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127);
- wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -127));
- wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40));
- } else {
- wacom_report_key(wcombo, wacom->tool[0], 0);
- wacom_report_abs(wcombo, ABS_MISC, 0); /* report tool id */
- wacom_report_abs(wcombo, ABS_PRESSURE, -1);
- wacom_report_key(wcombo, BTN_TOUCH, 0);
- }
- break;
- case 2:
- wacom_report_key(wcombo, BTN_TOOL_PEN, 1);
- wacom_report_abs(wcombo, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
- wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
- wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
- wacom_report_abs(wcombo, ABS_PRESSURE, (signed char)data[6] + 127);
- wacom_report_key(wcombo, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
- wacom_report_key(wcombo, BTN_STYLUS, (data[5] & 0x40));
- break;
- default:
- printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);
- return 0;
- }
- return 1;
-}
-
-static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
- int prox, id, pressure;
-
- if (data[0] != 2) {
- dbg("wacom_pl_irq: received unknown report #%d", data[0]);
- return 0;
- }
-
- prox = data[1] & 0x40;
-
- id = ERASER_DEVICE_ID;
- if (prox) {
-
- pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
- if (wacom->features->pressure_max > 255)
- pressure = (pressure << 1) | ((data[4] >> 6) & 1);
- pressure += (wacom->features->pressure_max + 1) / 2;
-
- /*
- * if going from out of proximity into proximity select between the eraser
- * and the pen based on the state of the stylus2 button, choose eraser if
- * pressed else choose pen. if not a proximity change from out to in, send
- * an out of proximity for previous tool then a in for new tool.
- */
- if (!wacom->tool[0]) {
- /* Eraser bit set for DTF */
- if (data[1] & 0x10)
- wacom->tool[1] = BTN_TOOL_RUBBER;
- else
- /* Going into proximity select tool */
- wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
- } else {
- /* was entered with stylus2 pressed */
- if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
- /* report out proximity for previous tool */
- wacom_report_key(wcombo, wacom->tool[1], 0);
- wacom_input_sync(wcombo);
- wacom->tool[1] = BTN_TOOL_PEN;
- return 0;
- }
- }
- if (wacom->tool[1] != BTN_TOOL_RUBBER) {
- /* Unknown tool selected default to pen tool */
- wacom->tool[1] = BTN_TOOL_PEN;
- id = STYLUS_DEVICE_ID;
- }
- wacom_report_key(wcombo, wacom->tool[1], prox); /* report in proximity for tool */
- wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
- wacom_report_abs(wcombo, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
- wacom_report_abs(wcombo, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
- wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-
- wacom_report_key(wcombo, BTN_TOUCH, data[4] & 0x08);
- wacom_report_key(wcombo, BTN_STYLUS, data[4] & 0x10);
- /* Only allow the stylus2 button to be reported for the pen tool. */
- wacom_report_key(wcombo, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
- } else {
- /* report proximity-out of a (valid) tool */
- if (wacom->tool[1] != BTN_TOOL_RUBBER) {
- /* Unknown tool selected default to pen tool */
- wacom->tool[1] = BTN_TOOL_PEN;
- }
- wacom_report_key(wcombo, wacom->tool[1], prox);
- }
-
- wacom->tool[0] = prox; /* Save proximity state */
- return 1;
-}
-
-static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
- int id;
-
- if (data[0] != 2) {
- printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
- return 0;
- }
-
- if (data[1] & 0x04) {
- wacom_report_key(wcombo, BTN_TOOL_RUBBER, data[1] & 0x20);
- wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x08);
- id = ERASER_DEVICE_ID;
- } else {
- wacom_report_key(wcombo, BTN_TOOL_PEN, data[1] & 0x20);
- wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
- id = STYLUS_DEVICE_ID;
- }
- wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
- wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
- wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
- wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
- wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
- wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
- return 1;
-}
-
-static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
- int x, y, id, rw;
-
- if (data[0] != 2) {
- dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
- return 0;
- }
-
- id = STYLUS_DEVICE_ID;
- if (data[1] & 0x80) { /* in prox */
-
- switch ((data[1] >> 5) & 3) {
-
- case 0: /* Pen */
- wacom->tool[0] = BTN_TOOL_PEN;
- break;
-
- case 1: /* Rubber */
- wacom->tool[0] = BTN_TOOL_RUBBER;
- id = ERASER_DEVICE_ID;
- break;
-
- case 2: /* Mouse with wheel */
- wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
- if (wacom->features->type == WACOM_G4) {
- rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
- wacom_report_rel(wcombo, REL_WHEEL, -rw);
- } else
- wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
- /* fall through */
-
- case 3: /* Mouse without wheel */
- wacom->tool[0] = BTN_TOOL_MOUSE;
- id = CURSOR_DEVICE_ID;
- wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
- wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
- if (wacom->features->type == WACOM_G4)
- wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
- else
- wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
- break;
- }
- x = wacom_le16_to_cpu(&data[2]);
- y = wacom_le16_to_cpu(&data[4]);
- wacom_report_abs(wcombo, ABS_X, x);
- wacom_report_abs(wcombo, ABS_Y, y);
- if (wacom->tool[0] != BTN_TOOL_MOUSE) {
- wacom_report_abs(wcombo, ABS_PRESSURE, data[6] | ((data[7] & 0x01) << 8));
- wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
- wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
- wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
- }
- wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */
- wacom_report_key(wcombo, wacom->tool[0], 1);
- } else if (!(data[1] & 0x90)) {
- wacom_report_abs(wcombo, ABS_X, 0);
- wacom_report_abs(wcombo, ABS_Y, 0);
- if (wacom->tool[0] == BTN_TOOL_MOUSE) {
- wacom_report_key(wcombo, BTN_LEFT, 0);
- wacom_report_key(wcombo, BTN_RIGHT, 0);
- wacom_report_abs(wcombo, ABS_DISTANCE, 0);
- } else {
- wacom_report_abs(wcombo, ABS_PRESSURE, 0);
- wacom_report_key(wcombo, BTN_TOUCH, 0);
- wacom_report_key(wcombo, BTN_STYLUS, 0);
- wacom_report_key(wcombo, BTN_STYLUS2, 0);
- }
- wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
- wacom_report_key(wcombo, wacom->tool[0], 0);
- }
-
- /* send pad data */
- if (wacom->features->type == WACOM_G4) {
- if (data[7] & 0xf8) {
- wacom_input_sync(wcombo); /* sync last event */
- wacom->id[1] = 1;
- wacom->serial[1] = (data[7] & 0xf8);
- wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
- wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
- rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
- wacom_report_rel(wcombo, REL_WHEEL, rw);
- wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
- wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
- } else if (wacom->id[1]) {
- wacom_input_sync(wcombo); /* sync last event */
- wacom->id[1] = 0;
- wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
- wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
- wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
- wacom_report_abs(wcombo, ABS_MISC, 0);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
- }
- }
- return 1;
-}
-
-static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
- int idx;
-
- /* tool number */
- idx = data[1] & 0x01;
-
- /* Enter report */
- if ((data[1] & 0xfc) == 0xc0) {
- /* serial number of the tool */
- wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
- (data[4] << 20) + (data[5] << 12) +
- (data[6] << 4) + (data[7] >> 4);
-
- wacom->id[idx] = (data[2] << 4) | (data[3] >> 4);
- switch (wacom->id[idx]) {
- case 0x812: /* Inking pen */
- case 0x801: /* Intuos3 Inking pen */
- case 0x012:
- wacom->tool[idx] = BTN_TOOL_PENCIL;
- break;
- case 0x822: /* Pen */
- case 0x842:
- case 0x852:
- case 0x823: /* Intuos3 Grip Pen */
- case 0x813: /* Intuos3 Classic Pen */
- case 0x885: /* Intuos3 Marker Pen */
- case 0x022:
- wacom->tool[idx] = BTN_TOOL_PEN;
- break;
- case 0x832: /* Stroke pen */
- case 0x032:
- wacom->tool[idx] = BTN_TOOL_BRUSH;
- break;
- case 0x007: /* Mouse 4D and 2D */
- case 0x09c:
- case 0x094:
- case 0x017: /* Intuos3 2D Mouse */
- wacom->tool[idx] = BTN_TOOL_MOUSE;
- break;
- case 0x096: /* Lens cursor */
- case 0x097: /* Intuos3 Lens cursor */
- wacom->tool[idx] = BTN_TOOL_LENS;
- break;
- case 0x82a: /* Eraser */
- case 0x85a:
- case 0x91a:
- case 0xd1a:
- case 0x0fa:
- case 0x82b: /* Intuos3 Grip Pen Eraser */
- case 0x81b: /* Intuos3 Classic Pen Eraser */
- case 0x91b: /* Intuos3 Airbrush Eraser */
- wacom->tool[idx] = BTN_TOOL_RUBBER;
- break;
- case 0xd12:
- case 0x912:
- case 0x112:
- case 0x913: /* Intuos3 Airbrush */
- wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
- break;
- default: /* Unknown tool */
- wacom->tool[idx] = BTN_TOOL_PEN;
- }
- return 1;
- }
-
- /* Exit report */
- if ((data[1] & 0xfe) == 0x80) {
- wacom_report_abs(wcombo, ABS_X, 0);
- wacom_report_abs(wcombo, ABS_Y, 0);
- wacom_report_abs(wcombo, ABS_DISTANCE, 0);
- if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
- wacom_report_key(wcombo, BTN_LEFT, 0);
- wacom_report_key(wcombo, BTN_MIDDLE, 0);
- wacom_report_key(wcombo, BTN_RIGHT, 0);
- wacom_report_key(wcombo, BTN_SIDE, 0);
- wacom_report_key(wcombo, BTN_EXTRA, 0);
- wacom_report_abs(wcombo, ABS_THROTTLE, 0);
- wacom_report_abs(wcombo, ABS_RZ, 0);
- } else {
- wacom_report_abs(wcombo, ABS_PRESSURE, 0);
- wacom_report_abs(wcombo, ABS_TILT_X, 0);
- wacom_report_abs(wcombo, ABS_TILT_Y, 0);
- wacom_report_key(wcombo, BTN_STYLUS, 0);
- wacom_report_key(wcombo, BTN_STYLUS2, 0);
- wacom_report_key(wcombo, BTN_TOUCH, 0);
- wacom_report_abs(wcombo, ABS_WHEEL, 0);
- }
- wacom_report_key(wcombo, wacom->tool[idx], 0);
- wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- return 2;
- }
- return 0;
-}
-
-static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
- unsigned int t;
-
- /* general pen packet */
- if ((data[1] & 0xb8) == 0xa0) {
- t = (data[6] << 2) | ((data[7] >> 6) & 3);
- wacom_report_abs(wcombo, ABS_PRESSURE, t);
- wacom_report_abs(wcombo, ABS_TILT_X,
- ((data[7] << 1) & 0x7e) | (data[8] >> 7));
- wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f);
- wacom_report_key(wcombo, BTN_STYLUS, data[1] & 2);
- wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 4);
- wacom_report_key(wcombo, BTN_TOUCH, t > 10);
- }
-
- /* airbrush second packet */
- if ((data[1] & 0xbc) == 0xb4) {
- wacom_report_abs(wcombo, ABS_WHEEL,
- (data[6] << 2) | ((data[7] >> 6) & 3));
- wacom_report_abs(wcombo, ABS_TILT_X,
- ((data[7] << 1) & 0x7e) | (data[8] >> 7));
- wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f);
- }
- return;
-}
-
-static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
-{
- unsigned char *data = wacom->data;
- unsigned int t;
- int idx, result;
-
- if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
- dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
- return 0;
- }
-
- /* tool number */
- idx = data[1] & 0x01;
-
- /* pad packets. Works as a second tool and is always in prox */
- if (data[0] == 12) {
- /* initiate the pad as a device */
- if (wacom->tool[1] != BTN_TOOL_FINGER)
- wacom->tool[1] = BTN_TOOL_FINGER;
-
- wacom_report_key(wcombo, BTN_0, (data[5] & 0x01));
- wacom_report_key(wcombo, BTN_1, (data[5] & 0x02));
- wacom_report_key(wcombo, BTN_2, (data[5] & 0x04));
- wacom_report_key(wcombo, BTN_3, (data[5] & 0x08));
- wacom_report_key(wcombo, BTN_4, (data[6] & 0x01));
- wacom_report_key(wcombo, BTN_5, (data[6] & 0x02));
- wacom_report_key(wcombo, BTN_6, (data[6] & 0x04));
- wacom_report_key(wcombo, BTN_7, (data[6] & 0x08));
- wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
- wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
-
- if((data[5] & 0x0f) | (data[6] & 0x0f) | (data[1] & 0x1f) |
- data[2] | (data[3] & 0x1f) | data[4])
- wacom_report_key(wcombo, wacom->tool[1], 1);
- else
- wacom_report_key(wcombo, wacom->tool[1], 0);
- wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff);
- return 1;
- }
-
- /* process in/out prox events */
- result = wacom_intuos_inout(wacom, wcombo);
- if (result)
- return result-1;
-
- /* Only large I3 and I1 & I2 support Lense Cursor */
- if((wacom->tool[idx] == BTN_TOOL_LENS)
- && ((wacom->features->type == INTUOS3)
- || (wacom->features->type == INTUOS3S)))
- return 0;
-
- /* Cintiq doesn't send data when RDY bit isn't set */
- if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
- return 0;
-
- if (wacom->features->type >= INTUOS3S) {
- wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
- wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
- wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
- } else {
- wacom_report_abs(wcombo, ABS_X, wacom_be16_to_cpu(&data[2]));
- wacom_report_abs(wcombo, ABS_Y, wacom_be16_to_cpu(&data[4]));
- wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
- }
-
- /* process general packets */
- wacom_intuos_general(wacom, wcombo);
-
- /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
- if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
-
- if (data[1] & 0x02) {
- /* Rotation packet */
- if (wacom->features->type >= INTUOS3S) {
- /* I3 marker pen rotation reported as wheel
- * due to valuator limitation
- */
- t = (data[6] << 3) | ((data[7] >> 5) & 7);
- t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
- ((t-1) / 2 + 450)) : (450 - t / 2) ;
- wacom_report_abs(wcombo, ABS_WHEEL, t);
- } else {
- /* 4D mouse rotation packet */
- t = (data[6] << 3) | ((data[7] >> 5) & 7);
- wacom_report_abs(wcombo, ABS_RZ, (data[7] & 0x20) ?
- ((t - 1) / 2) : -t / 2);
- }
-
- } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3S) {
- /* 4D mouse packet */
- wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01);
- wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
- wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04);
-
- wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x20);
- wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x10);
- t = (data[6] << 2) | ((data[7] >> 6) & 3);
- wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
-
- } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
- /* 2D mouse packet */
- wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04);
- wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08);
- wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10);
- wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01)
- - ((data[8] & 0x02) >> 1));
-
- /* I3 2D mouse side buttons */
- if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) {
- wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40);
- wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20);
- }
-
- } else if (wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L) {
- /* Lens cursor packets */
- wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01);
- wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02);
- wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x04);
- wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x10);
- wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x08);
- }
- }
-
- wacom_report_abs(wcombo, ABS_MISC, wacom->id[idx]); /* report tool id */
- wacom_report_key(wcombo, wacom->tool[idx], 1);
- wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- return 1;
-}
-
-int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
-{
- switch (wacom_wac->features->type) {
- case PENPARTNER:
- return (wacom_penpartner_irq(wacom_wac, wcombo));
- break;
- case PL:
- return (wacom_pl_irq(wacom_wac, wcombo));
- break;
- case WACOM_G4:
- case GRAPHIRE:
- return (wacom_graphire_irq(wacom_wac, wcombo));
- break;
- case PTU:
- return (wacom_ptu_irq(wacom_wac, wcombo));
- break;
- case INTUOS:
- case INTUOS3S:
- case INTUOS3:
- case INTUOS3L:
- case CINTIQ:
- return (wacom_intuos_irq(wacom_wac, wcombo));
- break;
- default:
- return 0;
- }
- return 0;
-}
-
-void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
-{
- switch (wacom_wac->features->type) {
- case WACOM_G4:
- input_dev_g4(input_dev, wacom_wac);
- /* fall through */
- case GRAPHIRE:
- input_dev_g(input_dev, wacom_wac);
- break;
- case INTUOS3:
- case INTUOS3L:
- case CINTIQ:
- input_dev_i3(input_dev, wacom_wac);
- /* fall through */
- case INTUOS3S:
- input_dev_i3s(input_dev, wacom_wac);
- case INTUOS:
- input_dev_i(input_dev, wacom_wac);
- break;
- case PL:
- case PTU:
- input_dev_pl(input_dev, wacom_wac);
- break;
- case PENPARTNER:
- input_dev_pt(input_dev, wacom_wac);
- break;
- }
- return;
-}
-
-static struct wacom_features wacom_features[] = {
- { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER },
- { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE },
- { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE },
- { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE },
- { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE },
- { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE },
- { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 },
- { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 },
- { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE },
- { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE },
- { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE },
- { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE },
- { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE },
- { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
- { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
- { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
- { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
- { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
- { "Wacom PL400", 8, 5408, 4056, 255, 0, PL },
- { "Wacom PL500", 8, 6144, 4608, 255, 0, PL },
- { "Wacom PL600", 8, 6126, 4604, 255, 0, PL },
- { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL },
- { "Wacom PL550", 8, 6144, 4608, 511, 0, PL },
- { "Wacom PL800", 8, 7220, 5780, 511, 0, PL },
- { "Wacom PL700", 8, 6758, 5406, 511, 0, PL },
- { "Wacom PL510", 8, 6282, 4762, 511, 0, PL },
- { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL },
- { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL },
- { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL },
- { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU },
- { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
- { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS },
- { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS },
- { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS },
- { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S },
- { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 },
- { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 },
- { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L },
- { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L },
- { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 },
- { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S },
- { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS },
- { }
-};
-
-static struct usb_device_id wacom_ids[] = {
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x15) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x63) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x64) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x37) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x38) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x39) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC0) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC4) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB3) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
- { }
-};
-
-const struct usb_device_id * get_device_table(void) {
- const struct usb_device_id * id_table = wacom_ids;
- return id_table;
-}
-
-struct wacom_features * get_wacom_feature(const struct usb_device_id * id) {
- int index = id - wacom_ids;
- struct wacom_features *wf = &wacom_features[index];
- return wf;
-}
-
-MODULE_DEVICE_TABLE(usb, wacom_ids);
diff --git a/drivers/usb/input/wacom_wac.h b/drivers/usb/input/wacom_wac.h
deleted file mode 100644
index a2302228724..00000000000
--- a/drivers/usb/input/wacom_wac.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * drivers/usb/input/wacom_wac.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef WACOM_WAC_H
-#define WACOM_WAC_H
-
-#define STYLUS_DEVICE_ID 0x02
-#define CURSOR_DEVICE_ID 0x06
-#define ERASER_DEVICE_ID 0x0A
-#define PAD_DEVICE_ID 0x0F
-
-enum {
- PENPARTNER = 0,
- GRAPHIRE,
- WACOM_G4,
- PTU,
- PL,
- INTUOS,
- INTUOS3S,
- INTUOS3,
- INTUOS3L,
- CINTIQ,
- MAX_TYPE
-};
-
-struct wacom_features {
- char *name;
- int pktlen;
- int x_max;
- int y_max;
- int pressure_max;
- int distance_max;
- int type;
-};
-
-struct wacom_wac {
- signed char *data;
- int tool[2];
- int id[2];
- __u32 serial[2];
- struct wacom_features *features;
-};
-
-#endif
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
deleted file mode 100644
index 8c8cd95a698..00000000000
--- a/drivers/usb/input/xpad.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * X-Box gamepad - v0.0.6
- *
- * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de>
- * 2004 Oliver Schwartz <Oliver.Schwartz@gmx.de>,
- * Steven Toth <steve@toth.demon.co.uk>,
- * Franz Lehner <franz@caos.at>,
- * Ivan Hawkes <blackhawk@ivanhawkes.com>
- * 2005 Dominic Cerquetti <binary1230@yahoo.com>
- * 2006 Adam Buchbinder <adam.buchbinder@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * This driver is based on:
- * - information from http://euc.jp/periphs/xbox-controller.ja.html
- * - the iForce driver drivers/char/joystick/iforce.c
- * - the skeleton-driver drivers/usb/usb-skeleton.c
- *
- * Thanks to:
- * - ITO Takayuki for providing essential xpad information on his website
- * - Vojtech Pavlik - iforce driver / input subsystem
- * - Greg Kroah-Hartman - usb-skeleton driver
- * - XBOX Linux project - extra USB id's
- *
- * TODO:
- * - fine tune axes (especially trigger axes)
- * - fix "analog" buttons (reported as digital now)
- * - get rumble working
- * - need USB IDs for other dance pads
- *
- * History:
- *
- * 2002-06-27 - 0.0.1 : first version, just said "XBOX HID controller"
- *
- * 2002-07-02 - 0.0.2 : basic working version
- * - all axes and 9 of the 10 buttons work (german InterAct device)
- * - the black button does not work
- *
- * 2002-07-14 - 0.0.3 : rework by Vojtech Pavlik
- * - indentation fixes
- * - usb + input init sequence fixes
- *
- * 2002-07-16 - 0.0.4 : minor changes, merge with Vojtech's v0.0.3
- * - verified the lack of HID and report descriptors
- * - verified that ALL buttons WORK
- * - fixed d-pad to axes mapping
- *
- * 2002-07-17 - 0.0.5 : simplified d-pad handling
- *
- * 2004-10-02 - 0.0.6 : DDR pad support
- * - borrowed from the XBOX linux kernel
- * - USB id's for commonly used dance pads are present
- * - dance pads will map D-PAD to buttons, not axes
- * - pass the module paramater 'dpad_to_buttons' to force
- * the D-PAD to map to buttons if your pad is not detected
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/usb/input.h>
-
-#define DRIVER_VERSION "v0.0.6"
-#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
-#define DRIVER_DESC "X-Box pad driver"
-
-#define XPAD_PKT_LEN 32
-
-/* xbox d-pads should map to buttons, as is required for DDR pads
- but we map them to axes when possible to simplify things */
-#define MAP_DPAD_TO_BUTTONS 0
-#define MAP_DPAD_TO_AXES 1
-#define MAP_DPAD_UNKNOWN -1
-
-static int dpad_to_buttons;
-module_param(dpad_to_buttons, bool, S_IRUGO);
-MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
-
-static const struct xpad_device {
- u16 idVendor;
- u16 idProduct;
- char *name;
- u8 dpad_mapping;
-} xpad_device[] = {
- { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES },
- { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES },
- { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES },
- { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES },
- { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS },
- { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES },
- { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES },
- { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES },
- { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES },
- { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES },
- { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS },
- { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS },
- { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
- { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES },
- { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES },
- { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES },
- { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES},
- { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES },
- { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES },
- { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES },
- { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES },
- { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES },
- { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS },
- { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS },
- { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES },
- { 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN }
-};
-
-static const signed short xpad_btn[] = {
- BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, /* "analog" buttons */
- BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR, /* start/back/sticks */
- -1 /* terminating entry */
-};
-
-/* only used if MAP_DPAD_TO_BUTTONS */
-static const signed short xpad_btn_pad[] = {
- BTN_LEFT, BTN_RIGHT, /* d-pad left, right */
- BTN_0, BTN_1, /* d-pad up, down (XXX names??) */
- -1 /* terminating entry */
-};
-
-static const signed short xpad_abs[] = {
- ABS_X, ABS_Y, /* left stick */
- ABS_RX, ABS_RY, /* right stick */
- ABS_Z, ABS_RZ, /* triggers left/right */
- -1 /* terminating entry */
-};
-
-/* only used if MAP_DPAD_TO_AXES */
-static const signed short xpad_abs_pad[] = {
- ABS_HAT0X, ABS_HAT0Y, /* d-pad axes */
- -1 /* terminating entry */
-};
-
-static struct usb_device_id xpad_table [] = {
- { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */
- { }
-};
-
-MODULE_DEVICE_TABLE (usb, xpad_table);
-
-struct usb_xpad {
- struct input_dev *dev; /* input device interface */
- struct usb_device *udev; /* usb device */
-
- struct urb *irq_in; /* urb for interrupt in report */
- unsigned char *idata; /* input data */
- dma_addr_t idata_dma;
-
- char phys[65]; /* physical device path */
-
- int dpad_mapping; /* map d-pad to buttons or to axes */
-};
-
-/*
- * xpad_process_packet
- *
- * Completes a request by converting the data into events for the
- * input subsystem.
- *
- * The used report descriptor was taken from ITO Takayukis website:
- * http://euc.jp/periphs/xbox-controller.ja.html
- */
-
-static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
-{
- struct input_dev *dev = xpad->dev;
-
- /* left stick */
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14]));
-
- /* right stick */
- input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16]));
- input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18]));
-
- /* triggers left/right */
- input_report_abs(dev, ABS_Z, data[10]);
- input_report_abs(dev, ABS_RZ, data[11]);
-
- /* digital pad */
- if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) {
- input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
- input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
- } else /* xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS */ {
- input_report_key(dev, BTN_LEFT, data[2] & 0x04);
- input_report_key(dev, BTN_RIGHT, data[2] & 0x08);
- input_report_key(dev, BTN_0, data[2] & 0x01); // up
- input_report_key(dev, BTN_1, data[2] & 0x02); // down
- }
-
- /* start/back buttons and stick press left/right */
- input_report_key(dev, BTN_START, data[2] & 0x10);
- input_report_key(dev, BTN_BACK, data[2] & 0x20);
- input_report_key(dev, BTN_THUMBL, data[2] & 0x40);
- input_report_key(dev, BTN_THUMBR, data[2] & 0x80);
-
- /* "analog" buttons A, B, X, Y */
- input_report_key(dev, BTN_A, data[4]);
- input_report_key(dev, BTN_B, data[5]);
- input_report_key(dev, BTN_X, data[6]);
- input_report_key(dev, BTN_Y, data[7]);
-
- /* "analog" buttons black, white */
- input_report_key(dev, BTN_C, data[8]);
- input_report_key(dev, BTN_Z, data[9]);
-
- input_sync(dev);
-}
-
-static void xpad_irq_in(struct urb *urb)
-{
- struct usb_xpad *xpad = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
- goto exit;
- }
-
- xpad_process_packet(xpad, 0, xpad->idata);
-
-exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static int xpad_open (struct input_dev *dev)
-{
- struct usb_xpad *xpad = input_get_drvdata(dev);
-
- xpad->irq_in->dev = xpad->udev;
- if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void xpad_close (struct input_dev *dev)
-{
- struct usb_xpad *xpad = input_get_drvdata(dev);
-
- usb_kill_urb(xpad->irq_in);
-}
-
-static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs)
-{
- set_bit(abs, input_dev->absbit);
-
- switch (abs) {
- case ABS_X:
- case ABS_Y:
- case ABS_RX:
- case ABS_RY: /* the two sticks */
- input_set_abs_params(input_dev, abs, -32768, 32767, 16, 128);
- break;
- case ABS_Z:
- case ABS_RZ: /* the triggers */
- input_set_abs_params(input_dev, abs, 0, 255, 0, 0);
- break;
- case ABS_HAT0X:
- case ABS_HAT0Y: /* the d-pad (only if MAP_DPAD_TO_AXES) */
- input_set_abs_params(input_dev, abs, -1, 1, 0, 0);
- break;
- }
-}
-
-static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev (intf);
- struct usb_xpad *xpad;
- struct input_dev *input_dev;
- struct usb_endpoint_descriptor *ep_irq_in;
- int i;
- int error = -ENOMEM;
-
- for (i = 0; xpad_device[i].idVendor; i++) {
- if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
- (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
- break;
- }
-
- xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!xpad || !input_dev)
- goto fail1;
-
- xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
- GFP_ATOMIC, &xpad->idata_dma);
- if (!xpad->idata)
- goto fail1;
-
- xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
- if (!xpad->irq_in)
- goto fail2;
-
- xpad->udev = udev;
- xpad->dpad_mapping = xpad_device[i].dpad_mapping;
- if (xpad->dpad_mapping == MAP_DPAD_UNKNOWN)
- xpad->dpad_mapping = dpad_to_buttons;
- xpad->dev = input_dev;
- usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
- strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
-
- input_dev->name = xpad_device[i].name;
- input_dev->phys = xpad->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, xpad);
-
- input_dev->open = xpad_open;
- input_dev->close = xpad_close;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
- /* set up buttons */
- for (i = 0; xpad_btn[i] >= 0; i++)
- set_bit(xpad_btn[i], input_dev->keybit);
- if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS)
- for (i = 0; xpad_btn_pad[i] >= 0; i++)
- set_bit(xpad_btn_pad[i], input_dev->keybit);
-
- /* set up axes */
- for (i = 0; xpad_abs[i] >= 0; i++)
- xpad_set_up_abs(input_dev, xpad_abs[i]);
- if (xpad->dpad_mapping == MAP_DPAD_TO_AXES)
- for (i = 0; xpad_abs_pad[i] >= 0; i++)
- xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
-
- ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
- usb_fill_int_urb(xpad->irq_in, udev,
- usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
- xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
- xpad, ep_irq_in->bInterval);
- xpad->irq_in->transfer_dma = xpad->idata_dma;
- xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- error = input_register_device(xpad->dev);
- if (error)
- goto fail3;
-
- usb_set_intfdata(intf, xpad);
- return 0;
-
- fail3: usb_free_urb(xpad->irq_in);
- fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
- fail1: input_free_device(input_dev);
- kfree(xpad);
- return error;
-
-}
-
-static void xpad_disconnect(struct usb_interface *intf)
-{
- struct usb_xpad *xpad = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (xpad) {
- usb_kill_urb(xpad->irq_in);
- input_unregister_device(xpad->dev);
- usb_free_urb(xpad->irq_in);
- usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
- xpad->idata, xpad->idata_dma);
- kfree(xpad);
- }
-}
-
-static struct usb_driver xpad_driver = {
- .name = "xpad",
- .probe = xpad_probe,
- .disconnect = xpad_disconnect,
- .id_table = xpad_table,
-};
-
-static int __init usb_xpad_init(void)
-{
- int result = usb_register(&xpad_driver);
- if (result == 0)
- info(DRIVER_DESC ":" DRIVER_VERSION);
- return result;
-}
-
-static void __exit usb_xpad_exit(void)
-{
- usb_deregister(&xpad_driver);
-}
-
-module_init(usb_xpad_init);
-module_exit(usb_xpad_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
deleted file mode 100644
index c54f1a5dcb4..00000000000
--- a/drivers/usb/input/yealink.c
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
- * drivers/usb/input/yealink.c
- *
- * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/*
- * Description:
- * Driver for the USB-P1K voip usb phone.
- * This device is produced by Yealink Network Technology Co Ltd
- * but may be branded under several names:
- * - Yealink usb-p1k
- * - Tiptel 115
- * - ...
- *
- * This driver is based on:
- * - the usbb2k-api http://savannah.nongnu.org/projects/usbb2k-api/
- * - information from http://memeteau.free.fr/usbb2k
- * - the xpad-driver drivers/usb/input/xpad.c
- *
- * Thanks to:
- * - Olivier Vandorpe, for providing the usbb2k-api.
- * - Martin Diehl, for spotting my memory allocation bug.
- *
- * History:
- * 20050527 henk First version, functional keyboard. Keyboard events
- * will pop-up on the ../input/eventX bus.
- * 20050531 henk Added led, LCD, dialtone and sysfs interface.
- * 20050610 henk Cleanups, make it ready for public consumption.
- * 20050630 henk Cleanups, fixes in response to comments.
- * 20050701 henk sysfs write serialisation, fix potential unload races
- * 20050801 henk Added ringtone, restructure USB
- * 20050816 henk Merge 2.6.13-rc6
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/rwsem.h>
-#include <linux/usb/input.h>
-
-#include "map_to_7segment.h"
-#include "yealink.h"
-
-#define DRIVER_VERSION "yld-20051230"
-#define DRIVER_AUTHOR "Henk Vergonet"
-#define DRIVER_DESC "Yealink phone driver"
-
-#define YEALINK_POLLING_FREQUENCY 10 /* in [Hz] */
-
-struct yld_status {
- u8 lcd[24];
- u8 led;
- u8 dialtone;
- u8 ringtone;
- u8 keynum;
-} __attribute__ ((packed));
-
-/*
- * Register the LCD segment and icon map
- */
-#define _LOC(k,l) { .a = (k), .m = (l) }
-#define _SEG(t, a, am, b, bm, c, cm, d, dm, e, em, f, fm, g, gm) \
- { .type = (t), \
- .u = { .s = { _LOC(a, am), _LOC(b, bm), _LOC(c, cm), \
- _LOC(d, dm), _LOC(e, em), _LOC(g, gm), \
- _LOC(f, fm) } } }
-#define _PIC(t, h, hm, n) \
- { .type = (t), \
- .u = { .p = { .name = (n), .a = (h), .m = (hm) } } }
-
-static const struct lcd_segment_map {
- char type;
- union {
- struct pictogram_map {
- u8 a,m;
- char name[10];
- } p;
- struct segment_map {
- u8 a,m;
- } s[7];
- } u;
-} lcdMap[] = {
-#include "yealink.h"
-};
-
-struct yealink_dev {
- struct input_dev *idev; /* input device */
- struct usb_device *udev; /* usb device */
-
- /* irq input channel */
- struct yld_ctl_packet *irq_data;
- dma_addr_t irq_dma;
- struct urb *urb_irq;
-
- /* control output channel */
- struct yld_ctl_packet *ctl_data;
- dma_addr_t ctl_dma;
- struct usb_ctrlrequest *ctl_req;
- dma_addr_t ctl_req_dma;
- struct urb *urb_ctl;
-
- char phys[64]; /* physical device path */
-
- u8 lcdMap[ARRAY_SIZE(lcdMap)]; /* state of LCD, LED ... */
- int key_code; /* last reported key */
-
- int stat_ix;
- union {
- struct yld_status s;
- u8 b[sizeof(struct yld_status)];
- } master, copy;
-};
-
-
-/*******************************************************************************
- * Yealink lcd interface
- ******************************************************************************/
-
-/*
- * Register a default 7 segment character set
- */
-static SEG7_DEFAULT_MAP(map_seg7);
-
- /* Display a char,
- * char '\9' and '\n' are placeholders and do not overwrite the original text.
- * A space will always hide an icon.
- */
-static int setChar(struct yealink_dev *yld, int el, int chr)
-{
- int i, a, m, val;
-
- if (el >= ARRAY_SIZE(lcdMap))
- return -EINVAL;
-
- if (chr == '\t' || chr == '\n')
- return 0;
-
- yld->lcdMap[el] = chr;
-
- if (lcdMap[el].type == '.') {
- a = lcdMap[el].u.p.a;
- m = lcdMap[el].u.p.m;
- if (chr != ' ')
- yld->master.b[a] |= m;
- else
- yld->master.b[a] &= ~m;
- return 0;
- }
-
- val = map_to_seg7(&map_seg7, chr);
- for (i = 0; i < ARRAY_SIZE(lcdMap[0].u.s); i++) {
- m = lcdMap[el].u.s[i].m;
-
- if (m == 0)
- continue;
-
- a = lcdMap[el].u.s[i].a;
- if (val & 1)
- yld->master.b[a] |= m;
- else
- yld->master.b[a] &= ~m;
- val = val >> 1;
- }
- return 0;
-};
-
-/*******************************************************************************
- * Yealink key interface
- ******************************************************************************/
-
-/* Map device buttons to internal key events.
- *
- * USB-P1K button layout:
- *
- * up
- * IN OUT
- * down
- *
- * pickup C hangup
- * 1 2 3
- * 4 5 6
- * 7 8 9
- * * 0 #
- *
- * The "up" and "down" keys, are symbolised by arrows on the button.
- * The "pickup" and "hangup" keys are symbolised by a green and red phone
- * on the button.
- */
-static int map_p1k_to_key(int scancode)
-{
- switch(scancode) { /* phone key: */
- case 0x23: return KEY_LEFT; /* IN */
- case 0x33: return KEY_UP; /* up */
- case 0x04: return KEY_RIGHT; /* OUT */
- case 0x24: return KEY_DOWN; /* down */
- case 0x03: return KEY_ENTER; /* pickup */
- case 0x14: return KEY_BACKSPACE; /* C */
- case 0x13: return KEY_ESC; /* hangup */
- case 0x00: return KEY_1; /* 1 */
- case 0x01: return KEY_2; /* 2 */
- case 0x02: return KEY_3; /* 3 */
- case 0x10: return KEY_4; /* 4 */
- case 0x11: return KEY_5; /* 5 */
- case 0x12: return KEY_6; /* 6 */
- case 0x20: return KEY_7; /* 7 */
- case 0x21: return KEY_8; /* 8 */
- case 0x22: return KEY_9; /* 9 */
- case 0x30: return KEY_KPASTERISK; /* * */
- case 0x31: return KEY_0; /* 0 */
- case 0x32: return KEY_LEFTSHIFT |
- KEY_3 << 8; /* # */
- }
- return -EINVAL;
-}
-
-/* Completes a request by converting the data into events for the
- * input subsystem.
- *
- * The key parameter can be cascaded: key2 << 8 | key1
- */
-static void report_key(struct yealink_dev *yld, int key)
-{
- struct input_dev *idev = yld->idev;
-
- if (yld->key_code >= 0) {
- /* old key up */
- input_report_key(idev, yld->key_code & 0xff, 0);
- if (yld->key_code >> 8)
- input_report_key(idev, yld->key_code >> 8, 0);
- }
-
- yld->key_code = key;
- if (key >= 0) {
- /* new valid key */
- input_report_key(idev, key & 0xff, 1);
- if (key >> 8)
- input_report_key(idev, key >> 8, 1);
- }
- input_sync(idev);
-}
-
-/*******************************************************************************
- * Yealink usb communication interface
- ******************************************************************************/
-
-static int yealink_cmd(struct yealink_dev *yld, struct yld_ctl_packet *p)
-{
- u8 *buf = (u8 *)p;
- int i;
- u8 sum = 0;
-
- for(i=0; i<USB_PKT_LEN-1; i++)
- sum -= buf[i];
- p->sum = sum;
- return usb_control_msg(yld->udev,
- usb_sndctrlpipe(yld->udev, 0),
- USB_REQ_SET_CONFIGURATION,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
- 0x200, 3,
- p, sizeof(*p),
- USB_CTRL_SET_TIMEOUT);
-}
-
-static u8 default_ringtone[] = {
- 0xEF, /* volume [0-255] */
- 0xFB, 0x1E, 0x00, 0x0C, /* 1250 [hz], 12/100 [s] */
- 0xFC, 0x18, 0x00, 0x0C, /* 1000 [hz], 12/100 [s] */
- 0xFB, 0x1E, 0x00, 0x0C,
- 0xFC, 0x18, 0x00, 0x0C,
- 0xFB, 0x1E, 0x00, 0x0C,
- 0xFC, 0x18, 0x00, 0x0C,
- 0xFB, 0x1E, 0x00, 0x0C,
- 0xFC, 0x18, 0x00, 0x0C,
- 0xFF, 0xFF, 0x01, 0x90, /* silent, 400/100 [s] */
- 0x00, 0x00 /* end of sequence */
-};
-
-static int yealink_set_ringtone(struct yealink_dev *yld, u8 *buf, size_t size)
-{
- struct yld_ctl_packet *p = yld->ctl_data;
- int ix, len;
-
- if (size <= 0)
- return -EINVAL;
-
- /* Set the ringtone volume */
- memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
- yld->ctl_data->cmd = CMD_RING_VOLUME;
- yld->ctl_data->size = 1;
- yld->ctl_data->data[0] = buf[0];
- yealink_cmd(yld, p);
-
- buf++;
- size--;
-
- p->cmd = CMD_RING_NOTE;
- ix = 0;
- while (size != ix) {
- len = size - ix;
- if (len > sizeof(p->data))
- len = sizeof(p->data);
- p->size = len;
- p->offset = cpu_to_be16(ix);
- memcpy(p->data, &buf[ix], len);
- yealink_cmd(yld, p);
- ix += len;
- }
- return 0;
-}
-
-/* keep stat_master & stat_copy in sync.
- */
-static int yealink_do_idle_tasks(struct yealink_dev *yld)
-{
- u8 val;
- int i, ix, len;
-
- ix = yld->stat_ix;
-
- memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
- yld->ctl_data->cmd = CMD_KEYPRESS;
- yld->ctl_data->size = 1;
- yld->ctl_data->sum = 0xff - CMD_KEYPRESS;
-
- /* If state update pointer wraps do a KEYPRESS first. */
- if (ix >= sizeof(yld->master)) {
- yld->stat_ix = 0;
- return 0;
- }
-
- /* find update candidates: copy != master */
- do {
- val = yld->master.b[ix];
- if (val != yld->copy.b[ix])
- goto send_update;
- } while (++ix < sizeof(yld->master));
-
- /* nothing todo, wait a bit and poll for a KEYPRESS */
- yld->stat_ix = 0;
- /* TODO how can we wait abit. ??
- * msleep_interruptible(1000 / YEALINK_POLLING_FREQUENCY);
- */
- return 0;
-
-send_update:
-
- /* Setup an appropriate update request */
- yld->copy.b[ix] = val;
- yld->ctl_data->data[0] = val;
-
- switch(ix) {
- case offsetof(struct yld_status, led):
- yld->ctl_data->cmd = CMD_LED;
- yld->ctl_data->sum = -1 - CMD_LED - val;
- break;
- case offsetof(struct yld_status, dialtone):
- yld->ctl_data->cmd = CMD_DIALTONE;
- yld->ctl_data->sum = -1 - CMD_DIALTONE - val;
- break;
- case offsetof(struct yld_status, ringtone):
- yld->ctl_data->cmd = CMD_RINGTONE;
- yld->ctl_data->sum = -1 - CMD_RINGTONE - val;
- break;
- case offsetof(struct yld_status, keynum):
- val--;
- val &= 0x1f;
- yld->ctl_data->cmd = CMD_SCANCODE;
- yld->ctl_data->offset = cpu_to_be16(val);
- yld->ctl_data->data[0] = 0;
- yld->ctl_data->sum = -1 - CMD_SCANCODE - val;
- break;
- default:
- len = sizeof(yld->master.s.lcd) - ix;
- if (len > sizeof(yld->ctl_data->data))
- len = sizeof(yld->ctl_data->data);
-
- /* Combine up to <len> consecutive LCD bytes in a singe request
- */
- yld->ctl_data->cmd = CMD_LCD;
- yld->ctl_data->offset = cpu_to_be16(ix);
- yld->ctl_data->size = len;
- yld->ctl_data->sum = -CMD_LCD - ix - val - len;
- for(i=1; i<len; i++) {
- ix++;
- val = yld->master.b[ix];
- yld->copy.b[ix] = val;
- yld->ctl_data->data[i] = val;
- yld->ctl_data->sum -= val;
- }
- }
- yld->stat_ix = ix + 1;
- return 1;
-}
-
-/* Decide on how to handle responses
- *
- * The state transition diagram is somethhing like:
- *
- * syncState<--+
- * | |
- * | idle
- * \|/ |
- * init --ok--> waitForKey --ok--> getKey
- * ^ ^ |
- * | +-------ok-------+
- * error,start
- *
- */
-static void urb_irq_callback(struct urb *urb)
-{
- struct yealink_dev *yld = urb->context;
- int ret;
-
- if (urb->status)
- err("%s - urb status %d", __FUNCTION__, urb->status);
-
- switch (yld->irq_data->cmd) {
- case CMD_KEYPRESS:
-
- yld->master.s.keynum = yld->irq_data->data[0];
- break;
-
- case CMD_SCANCODE:
- dbg("get scancode %x", yld->irq_data->data[0]);
-
- report_key(yld, map_p1k_to_key(yld->irq_data->data[0]));
- break;
-
- default:
- err("unexpected response %x", yld->irq_data->cmd);
- }
-
- yealink_do_idle_tasks(yld);
-
- ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
- if (ret)
- err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
-}
-
-static void urb_ctl_callback(struct urb *urb)
-{
- struct yealink_dev *yld = urb->context;
- int ret;
-
- if (urb->status)
- err("%s - urb status %d", __FUNCTION__, urb->status);
-
- switch (yld->ctl_data->cmd) {
- case CMD_KEYPRESS:
- case CMD_SCANCODE:
- /* ask for a response */
- ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
- break;
- default:
- /* send new command */
- yealink_do_idle_tasks(yld);
- ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
- }
-
- if (ret)
- err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
-}
-
-/*******************************************************************************
- * input event interface
- ******************************************************************************/
-
-/* TODO should we issue a ringtone on a SND_BELL event?
-static int input_ev(struct input_dev *dev, unsigned int type,
- unsigned int code, int value)
-{
-
- if (type != EV_SND)
- return -EINVAL;
-
- switch (code) {
- case SND_BELL:
- case SND_TONE:
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-*/
-
-static int input_open(struct input_dev *dev)
-{
- struct yealink_dev *yld = input_get_drvdata(dev);
- int i, ret;
-
- dbg("%s", __FUNCTION__);
-
- /* force updates to device */
- for (i = 0; i<sizeof(yld->master); i++)
- yld->copy.b[i] = ~yld->master.b[i];
- yld->key_code = -1; /* no keys pressed */
-
- yealink_set_ringtone(yld, default_ringtone, sizeof(default_ringtone));
-
- /* issue INIT */
- memset(yld->ctl_data, 0, sizeof(*(yld->ctl_data)));
- yld->ctl_data->cmd = CMD_INIT;
- yld->ctl_data->size = 10;
- yld->ctl_data->sum = 0x100-CMD_INIT-10;
- if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
- dbg("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, ret);
- return ret;
- }
- return 0;
-}
-
-static void input_close(struct input_dev *dev)
-{
- struct yealink_dev *yld = input_get_drvdata(dev);
-
- usb_kill_urb(yld->urb_ctl);
- usb_kill_urb(yld->urb_irq);
-}
-
-/*******************************************************************************
- * sysfs interface
- ******************************************************************************/
-
-static DECLARE_RWSEM(sysfs_rwsema);
-
-/* Interface to the 7-segments translation table aka. char set.
- */
-static ssize_t show_map(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- memcpy(buf, &map_seg7, sizeof(map_seg7));
- return sizeof(map_seg7);
-}
-
-static ssize_t store_map(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t cnt)
-{
- if (cnt != sizeof(map_seg7))
- return -EINVAL;
- memcpy(&map_seg7, buf, sizeof(map_seg7));
- return sizeof(map_seg7);
-}
-
-/* Interface to the LCD.
- */
-
-/* Reading /sys/../lineX will return the format string with its settings:
- *
- * Example:
- * cat ./line3
- * 888888888888
- * Linux Rocks!
- */
-static ssize_t show_line(struct device *dev, char *buf, int a, int b)
-{
- struct yealink_dev *yld;
- int i;
-
- down_read(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_read(&sysfs_rwsema);
- return -ENODEV;
- }
-
- for (i = a; i < b; i++)
- *buf++ = lcdMap[i].type;
- *buf++ = '\n';
- for (i = a; i < b; i++)
- *buf++ = yld->lcdMap[i];
- *buf++ = '\n';
- *buf = 0;
-
- up_read(&sysfs_rwsema);
- return 3 + ((b - a) << 1);
-}
-
-static ssize_t show_line1(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return show_line(dev, buf, LCD_LINE1_OFFSET, LCD_LINE2_OFFSET);
-}
-
-static ssize_t show_line2(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return show_line(dev, buf, LCD_LINE2_OFFSET, LCD_LINE3_OFFSET);
-}
-
-static ssize_t show_line3(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return show_line(dev, buf, LCD_LINE3_OFFSET, LCD_LINE4_OFFSET);
-}
-
-/* Writing to /sys/../lineX will set the coresponding LCD line.
- * - Excess characters are ignored.
- * - If less characters are written than allowed, the remaining digits are
- * unchanged.
- * - The '\n' or '\t' char is a placeholder, it does not overwrite the
- * original content.
- */
-static ssize_t store_line(struct device *dev, const char *buf, size_t count,
- int el, size_t len)
-{
- struct yealink_dev *yld;
- int i;
-
- down_write(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_write(&sysfs_rwsema);
- return -ENODEV;
- }
-
- if (len > count)
- len = count;
- for (i = 0; i < len; i++)
- setChar(yld, el++, buf[i]);
-
- up_write(&sysfs_rwsema);
- return count;
-}
-
-static ssize_t store_line1(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return store_line(dev, buf, count, LCD_LINE1_OFFSET, LCD_LINE1_SIZE);
-}
-
-static ssize_t store_line2(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return store_line(dev, buf, count, LCD_LINE2_OFFSET, LCD_LINE2_SIZE);
-}
-
-static ssize_t store_line3(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return store_line(dev, buf, count, LCD_LINE3_OFFSET, LCD_LINE3_SIZE);
-}
-
-/* Interface to visible and audible "icons", these include:
- * pictures on the LCD, the LED, and the dialtone signal.
- */
-
-/* Get a list of "switchable elements" with their current state. */
-static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct yealink_dev *yld;
- int i, ret = 1;
-
- down_read(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_read(&sysfs_rwsema);
- return -ENODEV;
- }
-
- for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
- if (lcdMap[i].type != '.')
- continue;
- ret += sprintf(&buf[ret], "%s %s\n",
- yld->lcdMap[i] == ' ' ? " " : "on",
- lcdMap[i].u.p.name);
- }
- up_read(&sysfs_rwsema);
- return ret;
-}
-
-/* Change the visibility of a particular element. */
-static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
- int chr)
-{
- struct yealink_dev *yld;
- int i;
-
- down_write(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_write(&sysfs_rwsema);
- return -ENODEV;
- }
-
- for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
- if (lcdMap[i].type != '.')
- continue;
- if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
- setChar(yld, i, chr);
- break;
- }
- }
-
- up_write(&sysfs_rwsema);
- return count;
-}
-
-static ssize_t show_icon(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return set_icon(dev, buf, count, buf[0]);
-}
-
-static ssize_t hide_icon(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return set_icon(dev, buf, count, ' ');
-}
-
-/* Upload a ringtone to the device.
- */
-
-/* Stores raw ringtone data in the phone */
-static ssize_t store_ringtone(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct yealink_dev *yld;
-
- down_write(&sysfs_rwsema);
- yld = dev_get_drvdata(dev);
- if (yld == NULL) {
- up_write(&sysfs_rwsema);
- return -ENODEV;
- }
-
- /* TODO locking with async usb control interface??? */
- yealink_set_ringtone(yld, (char *)buf, count);
- up_write(&sysfs_rwsema);
- return count;
-}
-
-#define _M444 S_IRUGO
-#define _M664 S_IRUGO|S_IWUSR|S_IWGRP
-#define _M220 S_IWUSR|S_IWGRP
-
-static DEVICE_ATTR(map_seg7 , _M664, show_map , store_map );
-static DEVICE_ATTR(line1 , _M664, show_line1 , store_line1 );
-static DEVICE_ATTR(line2 , _M664, show_line2 , store_line2 );
-static DEVICE_ATTR(line3 , _M664, show_line3 , store_line3 );
-static DEVICE_ATTR(get_icons , _M444, get_icons , NULL );
-static DEVICE_ATTR(show_icon , _M220, NULL , show_icon );
-static DEVICE_ATTR(hide_icon , _M220, NULL , hide_icon );
-static DEVICE_ATTR(ringtone , _M220, NULL , store_ringtone);
-
-static struct attribute *yld_attributes[] = {
- &dev_attr_line1.attr,
- &dev_attr_line2.attr,
- &dev_attr_line3.attr,
- &dev_attr_get_icons.attr,
- &dev_attr_show_icon.attr,
- &dev_attr_hide_icon.attr,
- &dev_attr_map_seg7.attr,
- &dev_attr_ringtone.attr,
- NULL
-};
-
-static struct attribute_group yld_attr_group = {
- .attrs = yld_attributes
-};
-
-/*******************************************************************************
- * Linux interface and usb initialisation
- ******************************************************************************/
-
-struct driver_info {
- char *name;
-};
-
-static const struct driver_info info_P1K = {
- .name = "Yealink usb-p1k",
-};
-
-static const struct usb_device_id usb_table [] = {
- {
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
- USB_DEVICE_ID_MATCH_INT_INFO,
- .idVendor = 0x6993,
- .idProduct = 0xb001,
- .bInterfaceClass = USB_CLASS_HID,
- .bInterfaceSubClass = 0,
- .bInterfaceProtocol = 0,
- .driver_info = (kernel_ulong_t)&info_P1K
- },
- { }
-};
-
-static int usb_cleanup(struct yealink_dev *yld, int err)
-{
- if (yld == NULL)
- return err;
-
- usb_kill_urb(yld->urb_irq); /* parameter validation in core/urb */
- usb_kill_urb(yld->urb_ctl); /* parameter validation in core/urb */
-
- if (yld->idev) {
- if (err)
- input_free_device(yld->idev);
- else
- input_unregister_device(yld->idev);
- }
- if (yld->ctl_req)
- usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
- yld->ctl_req, yld->ctl_req_dma);
- if (yld->ctl_data)
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->ctl_data, yld->ctl_dma);
- if (yld->irq_data)
- usb_buffer_free(yld->udev, USB_PKT_LEN,
- yld->irq_data, yld->irq_dma);
-
- usb_free_urb(yld->urb_irq); /* parameter validation in core/urb */
- usb_free_urb(yld->urb_ctl); /* parameter validation in core/urb */
- kfree(yld);
- return err;
-}
-
-static void usb_disconnect(struct usb_interface *intf)
-{
- struct yealink_dev *yld;
-
- down_write(&sysfs_rwsema);
- yld = usb_get_intfdata(intf);
- sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
- usb_set_intfdata(intf, NULL);
- up_write(&sysfs_rwsema);
-
- usb_cleanup(yld, 0);
-}
-
-static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev (intf);
- struct driver_info *nfo = (struct driver_info *)id->driver_info;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct yealink_dev *yld;
- struct input_dev *input_dev;
- int ret, pipe, i;
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
- if (!usb_endpoint_is_int_in(endpoint))
- return -ENODEV;
-
- yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
- if (!yld)
- return -ENOMEM;
-
- yld->udev = udev;
-
- yld->idev = input_dev = input_allocate_device();
- if (!input_dev)
- return usb_cleanup(yld, -ENOMEM);
-
- /* allocate usb buffers */
- yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- GFP_ATOMIC, &yld->irq_dma);
- if (yld->irq_data == NULL)
- return usb_cleanup(yld, -ENOMEM);
-
- yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- GFP_ATOMIC, &yld->ctl_dma);
- if (!yld->ctl_data)
- return usb_cleanup(yld, -ENOMEM);
-
- yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
- GFP_ATOMIC, &yld->ctl_req_dma);
- if (yld->ctl_req == NULL)
- return usb_cleanup(yld, -ENOMEM);
-
- /* allocate urb structures */
- yld->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
- if (yld->urb_irq == NULL)
- return usb_cleanup(yld, -ENOMEM);
-
- yld->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
- if (yld->urb_ctl == NULL)
- return usb_cleanup(yld, -ENOMEM);
-
- /* get a handle to the interrupt data pipe */
- pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
- ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- if (ret != USB_PKT_LEN)
- err("invalid payload size %d, expected %zd", ret, USB_PKT_LEN);
-
- /* initialise irq urb */
- usb_fill_int_urb(yld->urb_irq, udev, pipe, yld->irq_data,
- USB_PKT_LEN,
- urb_irq_callback,
- yld, endpoint->bInterval);
- yld->urb_irq->transfer_dma = yld->irq_dma;
- yld->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- yld->urb_irq->dev = udev;
-
- /* initialise ctl urb */
- yld->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
- USB_DIR_OUT;
- yld->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
- yld->ctl_req->wValue = cpu_to_le16(0x200);
- yld->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
- yld->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
-
- usb_fill_control_urb(yld->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
- (void *)yld->ctl_req, yld->ctl_data, USB_PKT_LEN,
- urb_ctl_callback, yld);
- yld->urb_ctl->setup_dma = yld->ctl_req_dma;
- yld->urb_ctl->transfer_dma = yld->ctl_dma;
- yld->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP |
- URB_NO_TRANSFER_DMA_MAP;
- yld->urb_ctl->dev = udev;
-
- /* find out the physical bus location */
- usb_make_path(udev, yld->phys, sizeof(yld->phys));
- strlcat(yld->phys, "/input0", sizeof(yld->phys));
-
- /* register settings for the input device */
- input_dev->name = nfo->name;
- input_dev->phys = yld->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->dev.parent = &intf->dev;
-
- input_set_drvdata(input_dev, yld);
-
- input_dev->open = input_open;
- input_dev->close = input_close;
- /* input_dev->event = input_ev; TODO */
-
- /* register available key events */
- input_dev->evbit[0] = BIT(EV_KEY);
- for (i = 0; i < 256; i++) {
- int k = map_p1k_to_key(i);
- if (k >= 0) {
- set_bit(k & 0xff, input_dev->keybit);
- if (k >> 8)
- set_bit(k >> 8, input_dev->keybit);
- }
- }
-
- ret = input_register_device(yld->idev);
- if (ret)
- return usb_cleanup(yld, ret);
-
- usb_set_intfdata(intf, yld);
-
- /* clear visible elements */
- for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
- setChar(yld, i, ' ');
-
- /* display driver version on LCD line 3 */
- store_line3(&intf->dev, NULL,
- DRIVER_VERSION, sizeof(DRIVER_VERSION));
-
- /* Register sysfs hooks (don't care about failure) */
- ret = sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
- return 0;
-}
-
-static struct usb_driver yealink_driver = {
- .name = "yealink",
- .probe = usb_probe,
- .disconnect = usb_disconnect,
- .id_table = usb_table,
-};
-
-static int __init yealink_dev_init(void)
-{
- int ret = usb_register(&yealink_driver);
- if (ret == 0)
- info(DRIVER_DESC ":" DRIVER_VERSION);
- return ret;
-}
-
-static void __exit yealink_dev_exit(void)
-{
- usb_deregister(&yealink_driver);
-}
-
-module_init(yealink_dev_init);
-module_exit(yealink_dev_exit);
-
-MODULE_DEVICE_TABLE (usb, usb_table);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/yealink.h b/drivers/usb/input/yealink.h
deleted file mode 100644
index 48af0be9cbd..00000000000
--- a/drivers/usb/input/yealink.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * drivers/usb/input/yealink.h
- *
- * Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef INPUT_YEALINK_H
-#define INPUT_YEALINK_H
-
-/* Using the control channel on interface 3 various aspects of the phone
- * can be controlled like LCD, LED, dialtone and the ringtone.
- */
-
-struct yld_ctl_packet {
- u8 cmd; /* command code, see below */
- u8 size; /* 1-11, size of used data bytes. */
- u16 offset; /* internal packet offset */
- u8 data[11];
- s8 sum; /* negative sum of 15 preceding bytes */
-} __attribute__ ((packed));
-
-#define USB_PKT_LEN sizeof(struct yld_ctl_packet)
-
-/* The following yld_ctl_packet's are available: */
-
-/* Init registers
- *
- * cmd 0x8e
- * size 10
- * offset 0
- * data 0,0,0,0....
- */
-#define CMD_INIT 0x8e
-
-/* Request key scan
- *
- * cmd 0x80
- * size 1
- * offset 0
- * data[0] on return returns the key number, if it changes there's a new
- * key pressed.
- */
-#define CMD_KEYPRESS 0x80
-
-/* Request scancode
- *
- * cmd 0x81
- * size 1
- * offset key number [0-1f]
- * data[0] on return returns the scancode
- */
-#define CMD_SCANCODE 0x81
-
-/* Set LCD
- *
- * cmd 0x04
- * size 1-11
- * offset 0-23
- * data segment bits
- */
-#define CMD_LCD 0x04
-
-/* Set led
- *
- * cmd 0x05
- * size 1
- * offset 0
- * data[0] 0 OFF / 1 ON
- */
-#define CMD_LED 0x05
-
-/* Set ringtone volume
- *
- * cmd 0x11
- * size 1
- * offset 0
- * data[0] 0-0xff volume
- */
-#define CMD_RING_VOLUME 0x11
-
-/* Set ringtone notes
- *
- * cmd 0x02
- * size 1-11
- * offset 0->
- * data binary representation LE16(-freq), LE16(duration) ....
- */
-#define CMD_RING_NOTE 0x02
-
-/* Sound ringtone via the speaker on the back
- *
- * cmd 0x03
- * size 1
- * offset 0
- * data[0] 0 OFF / 0x24 ON
- */
-#define CMD_RINGTONE 0x03
-
-/* Sound dial tone via the ear speaker
- *
- * cmd 0x09
- * size 1
- * offset 0
- * data[0] 0 OFF / 1 ON
- */
-#define CMD_DIALTONE 0x09
-
-#endif /* INPUT_YEALINK_H */
-
-
-#if defined(_SEG) && defined(_PIC)
-/* This table maps the LCD segments onto individual bit positions in the
- * yld_status struct.
- */
-
-/* LCD, each segment must be driven seperately.
- *
- * Layout:
- *
- * |[] [][] [][] [][] in |[][]
- * |[] M [][] D [][] : [][] out |[][]
- * store
- *
- * NEW REP SU MO TU WE TH FR SA
- *
- * [] [] [] [] [] [] [] [] [] [] [] []
- * [] [] [] [] [] [] [] [] [] [] [] []
- */
-
-/* Line 1
- * Format : 18.e8.M8.88...188
- * Icon names : M D : IN OUT STORE
- */
-#define LCD_LINE1_OFFSET 0
-#define LCD_LINE1_SIZE 17
-
-/* Note: first g then f => ! ! */
-/* _SEG( type a b c d e g f ) */
- _SEG('1', 0,0 , 22,2 , 22,2 , 0,0 , 0,0 , 0,0 , 0,0 ),
- _SEG('8', 20,1 , 20,2 , 20,4 , 20,8 , 21,4 , 21,2 , 21,1 ),
- _PIC('.', 22,1 , "M" ),
- _SEG('e', 18,1 , 18,2 , 18,4 , 18,1 , 19,2 , 18,1 , 19,1 ),
- _SEG('8', 16,1 , 16,2 , 16,4 , 16,8 , 17,4 , 17,2 , 17,1 ),
- _PIC('.', 15,8 , "D" ),
- _SEG('M', 14,1 , 14,2 , 14,4 , 14,1 , 15,4 , 15,2 , 15,1 ),
- _SEG('8', 12,1 , 12,2 , 12,4 , 12,8 , 13,4 , 13,2 , 13,1 ),
- _PIC('.', 11,8 , ":" ),
- _SEG('8', 10,1 , 10,2 , 10,4 , 10,8 , 11,4 , 11,2 , 11,1 ),
- _SEG('8', 8,1 , 8,2 , 8,4 , 8,8 , 9,4 , 9,2 , 9,1 ),
- _PIC('.', 7,1 , "IN" ),
- _PIC('.', 7,2 , "OUT" ),
- _PIC('.', 7,4 , "STORE" ),
- _SEG('1', 0,0 , 5,1 , 5,1 , 0,0 , 0,0 , 0,0 , 0,0 ),
- _SEG('8', 4,1 , 4,2 , 4,4 , 4,8 , 5,8 , 5,4 , 5,2 ),
- _SEG('8', 2,1 , 2,2 , 2,4 , 2,8 , 3,4 , 3,2 , 3,1 ),
-
-/* Line 2
- * Format : .........
- * Pict. name : NEW REP SU MO TU WE TH FR SA
- */
-#define LCD_LINE2_OFFSET LCD_LINE1_OFFSET + LCD_LINE1_SIZE
-#define LCD_LINE2_SIZE 9
-
- _PIC('.', 23,2 , "NEW" ),
- _PIC('.', 23,4 , "REP" ),
- _PIC('.', 1,8 , "SU" ),
- _PIC('.', 1,4 , "MO" ),
- _PIC('.', 1,2 , "TU" ),
- _PIC('.', 1,1 , "WE" ),
- _PIC('.', 0,1 , "TH" ),
- _PIC('.', 0,2 , "FR" ),
- _PIC('.', 0,4 , "SA" ),
-
-/* Line 3
- * Format : 888888888888
- */
-#define LCD_LINE3_OFFSET LCD_LINE2_OFFSET + LCD_LINE2_SIZE
-#define LCD_LINE3_SIZE 12
-
- _SEG('8', 22,16, 22,32, 22,64, 22,128, 23,128, 23,64, 23,32 ),
- _SEG('8', 20,16, 20,32, 20,64, 20,128, 21,128, 21,64, 21,32 ),
- _SEG('8', 18,16, 18,32, 18,64, 18,128, 19,128, 19,64, 19,32 ),
- _SEG('8', 16,16, 16,32, 16,64, 16,128, 17,128, 17,64, 17,32 ),
- _SEG('8', 14,16, 14,32, 14,64, 14,128, 15,128, 15,64, 15,32 ),
- _SEG('8', 12,16, 12,32, 12,64, 12,128, 13,128, 13,64, 13,32 ),
- _SEG('8', 10,16, 10,32, 10,64, 10,128, 11,128, 11,64, 11,32 ),
- _SEG('8', 8,16, 8,32, 8,64, 8,128, 9,128, 9,64, 9,32 ),
- _SEG('8', 6,16, 6,32, 6,64, 6,128, 7,128, 7,64, 7,32 ),
- _SEG('8', 4,16, 4,32, 4,64, 4,128, 5,128, 5,64, 5,32 ),
- _SEG('8', 2,16, 2,32, 2,64, 2,128, 3,128, 3,64, 3,32 ),
- _SEG('8', 0,16, 0,32, 0,64, 0,128, 1,128, 1,64, 1,32 ),
-
-/* Line 4
- *
- * The LED, DIALTONE and RINGTONE are implemented as icons and use the same
- * sysfs interface.
- */
-#define LCD_LINE4_OFFSET LCD_LINE3_OFFSET + LCD_LINE3_SIZE
-
- _PIC('.', offsetof(struct yld_status, led) , 0x01, "LED" ),
- _PIC('.', offsetof(struct yld_status, dialtone) , 0x01, "DIALTONE" ),
- _PIC('.', offsetof(struct yld_status, ringtone) , 0x24, "RINGTONE" ),
-
-#undef _SEG
-#undef _PIC
-#endif /* _SEG && _PIC */