aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/input')
-rw-r--r--drivers/usb/input/Kconfig308
-rw-r--r--drivers/usb/input/Makefile44
-rw-r--r--drivers/usb/input/acecad.c285
-rw-r--r--drivers/usb/input/aiptek.c2249
-rw-r--r--drivers/usb/input/appletouch.c475
-rw-r--r--drivers/usb/input/ati_remote.c835
-rw-r--r--drivers/usb/input/fixp-arith.h90
-rw-r--r--drivers/usb/input/hid-core.c1957
-rw-r--r--drivers/usb/input/hid-debug.h742
-rw-r--r--drivers/usb/input/hid-ff.c94
-rw-r--r--drivers/usb/input/hid-input.c687
-rw-r--r--drivers/usb/input/hid-lgff.c525
-rw-r--r--drivers/usb/input/hid-tmff.c464
-rw-r--r--drivers/usb/input/hid.h517
-rw-r--r--drivers/usb/input/hiddev.c844
-rw-r--r--drivers/usb/input/itmtouch.c280
-rw-r--r--drivers/usb/input/kbtab.c224
-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/mtouchusb.c344
-rw-r--r--drivers/usb/input/pid.c297
-rw-r--r--drivers/usb/input/pid.h62
-rw-r--r--drivers/usb/input/powermate.c466
-rw-r--r--drivers/usb/input/touchkitusb.c296
-rw-r--r--drivers/usb/input/usbkbd.c369
-rw-r--r--drivers/usb/input/usbmouse.c250
-rw-r--r--drivers/usb/input/wacom.c882
-rw-r--r--drivers/usb/input/xpad.c344
-rw-r--r--drivers/usb/input/yealink.c1017
-rw-r--r--drivers/usb/input/yealink.h220
30 files changed, 0 insertions, 15948 deletions
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
deleted file mode 100644
index 1e53934907c..00000000000
--- a/drivers/usb/input/Kconfig
+++ /dev/null
@@ -1,308 +0,0 @@
-#
-# USB Input driver configuration
-#
-comment "USB Input Devices"
- depends on USB
-
-config USB_HID
- tristate "USB Human Interface Device (full HID) support"
- depends on USB
- ---help---
- Say Y here if you want full HID support to connect keyboards,
- mice, joysticks, graphic tablets, or any other HID based devices
- to your computer via USB. You also need to select HID Input layer
- support (below) if you want to use keyboards, mice, joysticks and
- the like ... as well as Uninterruptible Power Supply (UPS) and
- monitor control devices.
-
- You can't use this driver and the HIDBP (Boot Protocol) keyboard
- and mouse drivers at the same time. More information is available:
- <file:Documentation/input/input.txt>.
-
- If unsure, say Y.
-
- To compile this driver as a module, choose M here: the
- module will be called usbhid.
-
-comment "Input core support is needed for USB HID input layer or HIDBP support"
- depends on USB_HID && INPUT=n
-
-config USB_HIDINPUT
- bool "HID input layer support"
- default y
- depends on INPUT && USB_HID
- help
- Say Y here if you want to use a USB keyboard, mouse or joystick,
- or any other HID input device.
-
- If unsure, say Y.
-
-config HID_FF
- bool "Force feedback support (EXPERIMENTAL)"
- depends on USB_HIDINPUT && EXPERIMENTAL
- help
- Say Y here is you want force feedback support for a few HID devices.
- See below for a list of supported devices.
-
- See <file:Documentation/input/ff.txt> for a description of the force
- feedback API.
-
- If unsure, say N.
-
-config HID_PID
- bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
- depends on HID_FF
- help
- Say Y here if you have a PID-compliant joystick and wish to enable force
- feedback for it. The Microsoft Sidewinder Force Feedback 2 is one such
- device.
-
-config LOGITECH_FF
- bool "Logitech WingMan *3D support"
- depends on HID_FF
- help
- Say Y here if you have one of these devices:
- - Logitech WingMan Cordless RumblePad
- - Logitech WingMan Force 3D
- and if you want to enable force feedback for them.
- Note: if you say N here, this device will still be supported, but without
- force feedback.
-
-config THRUSTMASTER_FF
- bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
- depends on HID_FF && EXPERIMENTAL
- help
- Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
- and want to enable force feedback support for it.
- Note: if you say N here, this device will still be supported, but without
- force feedback.
-
-config USB_HIDDEV
- bool "/dev/hiddev raw HID device support"
- depends on USB_HID
- help
- Say Y here if you want to support HID devices (from the USB
- specification standpoint) that aren't strictly user interface
- devices, like monitor controls and Uninterruptable Power Supplies.
-
- This module supports these devices separately using a separate
- event interface on /dev/usb/hiddevX (char 180:96 to 180:111).
-
- If unsure, say Y.
-
-menu "USB HID Boot Protocol drivers"
- depends on USB!=n && USB_HID!=y
-
-config USB_KBD
- tristate "USB HIDBP Keyboard (simple Boot) support"
- depends on USB && INPUT
- ---help---
- Say Y here only if you are absolutely sure that you don't want
- to use the generic HID driver for your USB keyboard and prefer
- to use the keyboard in its limited Boot Protocol mode instead.
-
- This is almost certainly not what you want. This is mostly
- useful for embedded applications or simple keyboards.
-
- To compile this driver as a module, choose M here: the
- module will be called usbkbd.
-
- If even remotely unsure, say N.
-
-config USB_MOUSE
- tristate "USB HIDBP Mouse (simple Boot) support"
- depends on USB && INPUT
- ---help---
- Say Y here only if you are absolutely sure that you don't want
- to use the generic HID driver for your USB mouse and prefer
- to use the mouse in its limited Boot Protocol mode instead.
-
- This is almost certainly not what you want. This is mostly
- useful for embedded applications or simple mice.
-
- To compile this driver as a module, choose M here: the
- module will be called usbmouse.
-
- If even remotely unsure, say N.
-
-endmenu
-
-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_MTOUCH
- tristate "MicroTouch USB Touchscreen Driver"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use a MicroTouch (Now 3M) USB
- Touchscreen controller.
-
- See <file:Documentation/usb/mtouch.txt> for additional information.
-
- To compile this driver as a module, choose M here: the
- module will be called mtouchusb.
-
-config USB_ITMTOUCH
- tristate "ITM Touch USB Touchscreen Driver"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use a ITM Touch USB
- Touchscreen controller.
-
- This touchscreen is used in LG 1510SF monitors.
-
- To compile this driver as a module, choose M here: the
- module will be called itmtouch.
-
-config USB_EGALAX
- tristate "eGalax TouchKit USB Touchscreen Driver"
- depends on USB && INPUT
- ---help---
- Say Y here if you want to use a eGalax TouchKit USB
- Touchscreen controller.
-
- The driver has been tested on a Xenarc 700TSV monitor
- with eGalax touchscreen.
-
- 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 touchkitusb.
-
-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_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.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
deleted file mode 100644
index 5e03b93f29f..00000000000
--- a/drivers/usb/input/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Makefile for the USB input drivers
-#
-
-# Multipart objects.
-usbhid-objs := hid-core.o
-
-# Optional parts of multipart objects.
-
-ifeq ($(CONFIG_USB_HIDDEV),y)
- usbhid-objs += hiddev.o
-endif
-ifeq ($(CONFIG_USB_HIDINPUT),y)
- usbhid-objs += hid-input.o
-endif
-ifeq ($(CONFIG_HID_PID),y)
- usbhid-objs += pid.o
-endif
-ifeq ($(CONFIG_LOGITECH_FF),y)
- usbhid-objs += hid-lgff.o
-endif
-ifeq ($(CONFIG_THRUSTMASTER_FF),y)
- usbhid-objs += hid-tmff.o
-endif
-ifeq ($(CONFIG_HID_FF),y)
- usbhid-objs += hid-ff.o
-endif
-
-obj-$(CONFIG_USB_AIPTEK) += aiptek.o
-obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o
-obj-$(CONFIG_USB_HID) += usbhid.o
-obj-$(CONFIG_USB_KBD) += usbkbd.o
-obj-$(CONFIG_USB_KBTAB) += kbtab.o
-obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o
-obj-$(CONFIG_USB_MOUSE) += usbmouse.o
-obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o
-obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o
-obj-$(CONFIG_USB_EGALAX) += touchkitusb.o
-obj-$(CONFIG_USB_POWERMATE) += powermate.o
-obj-$(CONFIG_USB_WACOM) += wacom.o
-obj-$(CONFIG_USB_ACECAD) += acecad.o
-obj-$(CONFIG_USB_YEALINK) += yealink.o
-obj-$(CONFIG_USB_XPAD) += xpad.o
-obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
deleted file mode 100644
index a32558b4048..00000000000
--- a/drivers/usb/input/acecad.c
+++ /dev/null
@@ -1,285 +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/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.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 pt_regs *regs)
-{
- 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 = dev->private;
-
- acecad->irq->dev = acecad->usbdev;
- if (usb_submit_urb(acecad->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usb_acecad_close(struct input_dev *dev)
-{
- struct usb_acecad *acecad = dev->private;
-
- usb_kill_urb(acecad->irq);
-}
-
-static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface = intf->cur_altsetting;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_acecad *acecad;
- struct input_dev *input_dev;
- int pipe, maxp;
-
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
-
- if (!(endpoint->bEndpointAddress & 0x80))
- return -ENODEV;
-
- if ((endpoint->bmAttributes & 3) != 3)
- return -ENODEV;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!acecad || !input_dev)
- goto fail1;
-
- acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
- if (!acecad->data)
- goto fail1;
-
- acecad->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!acecad->irq)
- goto fail2;
-
- 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->cdev.dev = &intf->dev;
- input_dev->private = 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;
-
- input_register_device(acecad->input);
-
- 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 -ENOMEM;
-}
-
-static void usb_acecad_disconnect(struct usb_interface *intf)
-{
- struct usb_acecad *acecad = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
- if (acecad) {
- usb_kill_urb(acecad->irq);
- input_unregister_device(acecad->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 = {
- .owner = THIS_MODULE,
- .name = "usb_acecad",
- .probe = usb_acecad_probe,
- .disconnect = usb_acecad_disconnect,
- .id_table = usb_acecad_id_table,
-};
-
-static int __init usb_acecad_init(void)
-{
- int result = usb_register(&usb_acecad_driver);
- if (result == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
- return result;
-}
-
-static void __exit usb_acecad_exit(void)
-{
- usb_deregister(&usb_acecad_driver);
-}
-
-module_init(usb_acecad_init);
-module_exit(usb_acecad_exit);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
deleted file mode 100644
index 1c3b472a3bc..00000000000
--- a/drivers/usb/input/aiptek.c
+++ /dev/null
@@ -1,2249 +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/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-#include <linux/sched.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 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 pt_regs *regs)
-{
- 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 {
- input_regs(inputdev, regs);
-
- 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 {
- input_regs(inputdev, regs);
-
- 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 {
- input_regs(inputdev, regs);
- 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) {
- input_regs(inputdev, regs);
-
- /* 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) {
- input_regs(inputdev, regs);
-
- /* 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)));
- input_regs(inputdev, regs);
-
- 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 = inputdev->private;
-
- 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 = inputdev->private;
-
- 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
- };
-
- /* 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,
- SLAB_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->cdev.dev = &intf->dev;
- inputdev->private = 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 < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++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_X, 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 < sizeof(speeds) / sizeof(speeds[0]); ++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
- */
- input_register_device(aiptek->inputdev);
-
- /* 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 -ENOMEM;
-}
-
-/* Forward declaration */
-static void aiptek_disconnect(struct usb_interface *intf);
-
-static struct usb_driver aiptek_driver = {
- .owner = THIS_MODULE,
- .name = "aiptek",
- .probe = aiptek_probe,
- .disconnect = aiptek_disconnect,
- .id_table = aiptek_ids,
-};
-
-/***********************************************************************
- * 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 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 15840db092a..00000000000
--- a/drivers/usb/input/appletouch.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Apple USB Touchpad (for post-February 2005 PowerBooks) 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)
- *
- * 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/config.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/input.h>
-#include <linux/usb_input.h>
-
-/* Apple has powerbooks which have the keyboard with different Product IDs */
-#define APPLE_VENDOR_ID 0x05AC
-
-#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(0x020E) },
- { ATP_DEVICE(0x020F) },
- { ATP_DEVICE(0x030A) },
- { ATP_DEVICE(0x030B) },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE (usb, atp_table);
-
-/* size of a USB urb transfer */
-#define ATP_DATASIZE 81
-
-/*
- * 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
-
-/* 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];
-};
-
-#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");
-MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
-MODULE_LICENSE("GPL");
-
-static int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activate debugging output");
-
-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;
-
- *fingers = 0;
-
- for (i = 0; i < nb_sensors; i++) {
- if (xy_sensors[i] < ATP_THRESHOLD)
- continue;
- if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD))
- (*fingers)++;
- pcum += xy_sensors[i] * i;
- psum += xy_sensors[i];
- }
-
- 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, struct pt_regs* regs)
-{
- int x, y, x_z, y_z, x_f, y_f;
- int retval, i;
- struct atp *dev = urb->context;
-
- 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;
- }
-
- /* drop incomplete datasets */
- if (dev->urb->actual_length != ATP_DATASIZE) {
- dprintk("appletouch: incomplete data package.\n");
- goto exit;
- }
-
- /* reorder the sensors values */
- 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));
-
- /* 17" Powerbooks have 10 extra X sensors */
- for (i = 16; i < ATP_XSENSORS; i++)
- if (dev->xy_cur[i]) {
- printk("appletouch: 17\" model detected.\n");
- 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[80]);
-
- 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->private;
-
- 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->private;
-
- 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, retval = -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 &&
- (endpoint->bEndpointAddress & USB_DIR_IN) &&
- ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_INT)) {
- /* 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->urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->urb) {
- retval = -ENOMEM;
- goto err_free_devs;
- }
-
- dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
- &dev->urb->transfer_dma);
- if (!dev->data) {
- retval = -ENOMEM;
- goto err_free_urb;
- }
-
- usb_fill_int_urb(dev->urb, udev,
- usb_rcvintpipe(udev, int_in_endpointAddr),
- dev->data, ATP_DATASIZE, 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->cdev.dev = &iface->dev;
-
- input_dev->private = dev;
- input_dev->open = atp_open;
- input_dev->close = atp_close;
-
- set_bit(EV_ABS, input_dev->evbit);
-
- /*
- * 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);
-
- input_register_device(dev->input);
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(iface, dev);
-
- return 0;
-
- err_free_urb:
- usb_free_urb(dev->urb);
- err_free_devs:
- usb_set_intfdata(iface, NULL);
- kfree(dev);
- input_free_device(input_dev);
- return retval;
-}
-
-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_free_urb(dev->urb);
- usb_buffer_free(dev->udev, ATP_DATASIZE,
- dev->data, dev->urb->transfer_dma);
- 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 = {
- .owner = THIS_MODULE,
- .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 9a2a47db949..00000000000
--- a/drivers/usb/input/ati_remote.c
+++ /dev/null
@@ -1,835 +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/config.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-#include <linux/wait.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 */
-
-static unsigned long channel_mask;
-module_param(channel_mask, ulong, 0444);
-MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
-
-static int debug;
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
-
-#define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
-#undef err
-#define err(format, arg...) printk(KERN_ERR format , ## arg)
-
-static struct usb_device_id ati_remote_table[] = {
- { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
- { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
- { 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 };
-
-/* Acceleration curve for directional control pad */
-static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
-
-/* Duplicate event filtering time.
- * Sequential, identical KIND_FILTERED inputs with less than
- * FILTER_TIME jiffies between them are considered as repeat
- * events. The hardware generates 5 events for the first keypress
- * and we have to take this into account for an accurate repeat
- * behaviour.
- * (HZ / 20) == 50 ms and works well for me.
- */
-#define FILTER_TIME (HZ / 20)
-
-static DECLARE_MUTEX(disconnect_sem);
-
-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 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 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, struct pt_regs *regs);
-static void ati_remote_irq_in (struct urb *urb, struct pt_regs *regs);
-static void ati_remote_input_report (struct urb *urb, struct pt_regs *regs);
-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 = {
- .owner = THIS_MODULE,
- .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 = inputdev->private;
-
- /* 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 = inputdev->private;
-
- usb_kill_urb(ati_remote->irq_urb);
-}
-
-/*
- * ati_remote_irq_out
- */
-static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs)
-{
- struct ati_remote *ati_remote = urb->context;
-
- if (urb->status) {
- dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
- __FUNCTION__, urb->status);
- return;
- }
-
- ati_remote->send_flags |= SEND_FLAG_COMPLETE;
- wmb();
- wake_up(&ati_remote->wait);
-}
-
-/*
- * 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_report_input
- */
-static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
-{
- struct ati_remote *ati_remote = urb->context;
- unsigned char *data= ati_remote->inbuf;
- struct input_dev *dev = ati_remote->idev;
- 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_regs(dev, regs);
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code,
- ati_remote_tbl[index].value);
- input_sync(dev);
-
- ati_remote->old_jiffies = jiffies;
- return;
- }
-
- if (ati_remote_tbl[index].kind == KIND_FILTERED) {
- /* Filter duplicate events which happen "too close" together. */
- if ((ati_remote->old_data[0] == data[1]) &&
- (ati_remote->old_data[1] == data[2]) &&
- ((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
- ati_remote->repeat_count++;
- } else {
- ati_remote->repeat_count = 0;
- }
-
- ati_remote->old_data[0] = data[1];
- ati_remote->old_data[1] = data[2];
- ati_remote->old_jiffies = jiffies;
-
- if ((ati_remote->repeat_count > 0)
- && (ati_remote->repeat_count < 5))
- return;
-
-
- input_regs(dev, regs);
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code, 1);
- input_event(dev, ati_remote_tbl[index].type,
- ati_remote_tbl[index].code, 0);
- input_sync(dev);
-
- return;
- }
-
- /*
- * Other event kinds are from the directional control pad, and have an
- * acceleration factor applied to them. Without this acceleration, the
- * control pad is mostly unusable.
- *
- * If elapsed time since last event is > 1/4 second, user "stopped",
- * so reset acceleration. Otherwise, user is probably holding the control
- * pad down, so we increase acceleration, ramping up over two seconds to
- * a maximum speed. The acceleration curve is #defined above.
- */
- if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) {
- acc = 1;
- ati_remote->acc_jiffies = jiffies;
- }
- else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3)) acc = accel[0];
- else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2)) acc = accel[1];
- else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1)) acc = accel[2];
- else if ((jiffies - ati_remote->acc_jiffies) < HZ ) acc = accel[3];
- else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4];
- else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1)) acc = accel[5];
- else acc = accel[6];
-
- input_regs(dev, regs);
- 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 pt_regs *regs)
-{
- struct ati_remote *ati_remote = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0: /* success */
- ati_remote_input_report(urb, regs);
- 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, SLAB_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, SLAB_ATOMIC,
- &ati_remote->inbuf_dma);
- if (!ati_remote->inbuf)
- return -1;
-
- ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_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)
-{
- if (ati_remote->irq_urb)
- usb_free_urb(ati_remote->irq_urb);
-
- if (ati_remote->out_urb)
- usb_free_urb(ati_remote->out_urb);
-
- if (ati_remote->inbuf)
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->inbuf, ati_remote->inbuf_dma);
-
- if (ati_remote->outbuf)
- usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
- ati_remote->inbuf, 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);
-
- idev->private = 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->cdev.dev = &ati_remote->udev->dev;
-}
-
-static int ati_remote_initialize(struct ati_remote *ati_remote)
-{
- struct usb_device *udev = ati_remote->udev;
- int pipe, maxp;
-
- init_waitqueue_head(&ati_remote->wait);
-
- /* Set up irq_urb */
- pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
- maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
-
- usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf,
- maxp, ati_remote_irq_in, ati_remote,
- 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 (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) {
- err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__);
- return -ENODEV;
- }
- if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
- err("%s: Unexpected endpoint_in->bmAttributes\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 */
- input_register_device(ati_remote->idev);
-
- 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/fixp-arith.h b/drivers/usb/input/fixp-arith.h
deleted file mode 100644
index 26ca5b890a6..00000000000
--- a/drivers/usb/input/fixp-arith.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _FIXP_ARITH_H
-#define _FIXP_ARITH_H
-
-/*
- * $$
- *
- * Simplistic fixed-point arithmetics.
- * Hmm, I'm probably duplicating some code :(
- *
- * Copyright (c) 2002 Johann Deneux
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <deneux@ifrance.com>
- */
-
-#include <linux/types.h>
-
-// The type representing fixed-point values
-typedef s16 fixp_t;
-
-#define FRAC_N 8
-#define FRAC_MASK ((1<<FRAC_N)-1)
-
-// Not to be used directly. Use fixp_{cos,sin}
-static fixp_t cos_table[45] = {
- 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8,
- 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD,
- 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1,
- 0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078,
- 0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035,
- 0x002C, 0x0023, 0x001A, 0x0011, 0x0008
-};
-
-
-/* a: 123 -> 123.0 */
-static inline fixp_t fixp_new(s16 a)
-{
- return a<<FRAC_N;
-}
-
-/* a: 0xFFFF -> -1.0
- 0x8000 -> 1.0
- 0x0000 -> 0.0
-*/
-static inline fixp_t fixp_new16(s16 a)
-{
- return ((s32)a)>>(16-FRAC_N);
-}
-
-static inline fixp_t fixp_cos(unsigned int degrees)
-{
- int quadrant = (degrees / 90) & 3;
- unsigned int i = degrees % 90;
-
- if (quadrant == 1 || quadrant == 3) {
- i = 89 - i;
- }
-
- i >>= 1;
-
- return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
-}
-
-static inline fixp_t fixp_sin(unsigned int degrees)
-{
- return -fixp_cos(degrees + 90);
-}
-
-static inline fixp_t fixp_mult(fixp_t a, fixp_t b)
-{
- return ((s32)(a*b))>>FRAC_N;
-}
-
-#endif
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
deleted file mode 100644
index 79ddce4555a..00000000000
--- a/drivers/usb/input/hid-core.c
+++ /dev/null
@@ -1,1957 +0,0 @@
-/*
- * USB HID support for Linux
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
- */
-
-/*
- * 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 <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/spinlock.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-#include <linux/input.h>
-#include <linux/wait.h>
-
-#undef DEBUG
-#undef DEBUG_DATA
-
-#include <linux/usb.h>
-
-#include "hid.h"
-#include <linux/hiddev.h>
-
-/*
- * Version Information
- */
-
-#define DRIVER_VERSION "v2.6"
-#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik"
-#define DRIVER_DESC "USB HID core driver"
-#define DRIVER_LICENSE "GPL"
-
-static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
- "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
-/*
- * Module parameters.
- */
-
-static unsigned int hid_mousepoll_interval;
-module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
-MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
-
-/*
- * Register a new report for a device.
- */
-
-static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
-{
- struct hid_report_enum *report_enum = device->report_enum + type;
- struct hid_report *report;
-
- if (report_enum->report_id_hash[id])
- return report_enum->report_id_hash[id];
-
- if (!(report = kmalloc(sizeof(struct hid_report), GFP_KERNEL)))
- return NULL;
- memset(report, 0, sizeof(struct hid_report));
-
- if (id != 0)
- report_enum->numbered = 1;
-
- report->id = id;
- report->type = type;
- report->size = 0;
- report->device = device;
- report_enum->report_id_hash[id] = report;
-
- list_add_tail(&report->list, &report_enum->report_list);
-
- return report;
-}
-
-/*
- * Register a new field for this report.
- */
-
-static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values)
-{
- struct hid_field *field;
-
- if (report->maxfield == HID_MAX_FIELDS) {
- dbg("too many fields in report");
- return NULL;
- }
-
- if (!(field = kmalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
- + values * sizeof(unsigned), GFP_KERNEL))) return NULL;
-
- memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
- + values * sizeof(unsigned));
-
- field->index = report->maxfield++;
- report->field[field->index] = field;
- field->usage = (struct hid_usage *)(field + 1);
- field->value = (unsigned *)(field->usage + usages);
- field->report = report;
-
- return field;
-}
-
-/*
- * Open a collection. The type/usage is pushed on the stack.
- */
-
-static int open_collection(struct hid_parser *parser, unsigned type)
-{
- struct hid_collection *collection;
- unsigned usage;
-
- usage = parser->local.usage[0];
-
- if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
- dbg("collection stack overflow");
- return -1;
- }
-
- if (parser->device->maxcollection == parser->device->collection_size) {
- collection = kmalloc(sizeof(struct hid_collection) *
- parser->device->collection_size * 2, GFP_KERNEL);
- if (collection == NULL) {
- dbg("failed to reallocate collection array");
- return -1;
- }
- memcpy(collection, parser->device->collection,
- sizeof(struct hid_collection) *
- parser->device->collection_size);
- memset(collection + parser->device->collection_size, 0,
- sizeof(struct hid_collection) *
- parser->device->collection_size);
- kfree(parser->device->collection);
- parser->device->collection = collection;
- parser->device->collection_size *= 2;
- }
-
- parser->collection_stack[parser->collection_stack_ptr++] =
- parser->device->maxcollection;
-
- collection = parser->device->collection +
- parser->device->maxcollection++;
- collection->type = type;
- collection->usage = usage;
- collection->level = parser->collection_stack_ptr - 1;
-
- if (type == HID_COLLECTION_APPLICATION)
- parser->device->maxapplication++;
-
- return 0;
-}
-
-/*
- * Close a collection.
- */
-
-static int close_collection(struct hid_parser *parser)
-{
- if (!parser->collection_stack_ptr) {
- dbg("collection stack underflow");
- return -1;
- }
- parser->collection_stack_ptr--;
- return 0;
-}
-
-/*
- * Climb up the stack, search for the specified collection type
- * and return the usage.
- */
-
-static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type)
-{
- int n;
- for (n = parser->collection_stack_ptr - 1; n >= 0; n--)
- if (parser->device->collection[parser->collection_stack[n]].type == type)
- return parser->device->collection[parser->collection_stack[n]].usage;
- return 0; /* we know nothing about this usage type */
-}
-
-/*
- * Add a usage to the temporary parser table.
- */
-
-static int hid_add_usage(struct hid_parser *parser, unsigned usage)
-{
- if (parser->local.usage_index >= HID_MAX_USAGES) {
- dbg("usage index exceeded");
- return -1;
- }
- parser->local.usage[parser->local.usage_index] = usage;
- parser->local.collection_index[parser->local.usage_index] =
- parser->collection_stack_ptr ?
- parser->collection_stack[parser->collection_stack_ptr - 1] : 0;
- parser->local.usage_index++;
- return 0;
-}
-
-/*
- * Register a new field for this report.
- */
-
-static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags)
-{
- struct hid_report *report;
- struct hid_field *field;
- int usages;
- unsigned offset;
- int i;
-
- if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) {
- dbg("hid_register_report failed");
- return -1;
- }
-
- if (parser->global.logical_maximum < parser->global.logical_minimum) {
- dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum);
- return -1;
- }
-
- offset = report->size;
- report->size += parser->global.report_size * parser->global.report_count;
-
- if (!parser->local.usage_index) /* Ignore padding fields */
- return 0;
-
- usages = max_t(int, parser->local.usage_index, parser->global.report_count);
-
- if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL)
- return 0;
-
- field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
- field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
- field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
-
- for (i = 0; i < usages; i++) {
- int j = i;
- /* Duplicate the last usage we parsed if we have excess values */
- if (i >= parser->local.usage_index)
- j = parser->local.usage_index - 1;
- field->usage[i].hid = parser->local.usage[j];
- field->usage[i].collection_index =
- parser->local.collection_index[j];
- }
-
- field->maxusage = usages;
- field->flags = flags;
- field->report_offset = offset;
- field->report_type = report_type;
- field->report_size = parser->global.report_size;
- field->report_count = parser->global.report_count;
- field->logical_minimum = parser->global.logical_minimum;
- field->logical_maximum = parser->global.logical_maximum;
- field->physical_minimum = parser->global.physical_minimum;
- field->physical_maximum = parser->global.physical_maximum;
- field->unit_exponent = parser->global.unit_exponent;
- field->unit = parser->global.unit;
-
- return 0;
-}
-
-/*
- * Read data value from item.
- */
-
-static __inline__ __u32 item_udata(struct hid_item *item)
-{
- switch (item->size) {
- case 1: return item->data.u8;
- case 2: return item->data.u16;
- case 4: return item->data.u32;
- }
- return 0;
-}
-
-static __inline__ __s32 item_sdata(struct hid_item *item)
-{
- switch (item->size) {
- case 1: return item->data.s8;
- case 2: return item->data.s16;
- case 4: return item->data.s32;
- }
- return 0;
-}
-
-/*
- * Process a global item.
- */
-
-static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
-{
- switch (item->tag) {
-
- case HID_GLOBAL_ITEM_TAG_PUSH:
-
- if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) {
- dbg("global enviroment stack overflow");
- return -1;
- }
-
- memcpy(parser->global_stack + parser->global_stack_ptr++,
- &parser->global, sizeof(struct hid_global));
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_POP:
-
- if (!parser->global_stack_ptr) {
- dbg("global enviroment stack underflow");
- return -1;
- }
-
- memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr,
- sizeof(struct hid_global));
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
- parser->global.usage_page = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
- parser->global.logical_minimum = item_sdata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
- if (parser->global.logical_minimum < 0)
- parser->global.logical_maximum = item_sdata(item);
- else
- parser->global.logical_maximum = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
- parser->global.physical_minimum = item_sdata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
- if (parser->global.physical_minimum < 0)
- parser->global.physical_maximum = item_sdata(item);
- else
- parser->global.physical_maximum = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
- parser->global.unit_exponent = item_sdata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_UNIT:
- parser->global.unit = item_udata(item);
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
- if ((parser->global.report_size = item_udata(item)) > 32) {
- dbg("invalid report_size %d", parser->global.report_size);
- return -1;
- }
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
- if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) {
- dbg("invalid report_count %d", parser->global.report_count);
- return -1;
- }
- return 0;
-
- case HID_GLOBAL_ITEM_TAG_REPORT_ID:
- if ((parser->global.report_id = item_udata(item)) == 0) {
- dbg("report_id 0 is invalid");
- return -1;
- }
- return 0;
-
- default:
- dbg("unknown global tag 0x%x", item->tag);
- return -1;
- }
-}
-
-/*
- * Process a local item.
- */
-
-static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
-{
- __u32 data;
- unsigned n;
-
- if (item->size == 0) {
- dbg("item data expected for local item");
- return -1;
- }
-
- data = item_udata(item);
-
- switch (item->tag) {
-
- case HID_LOCAL_ITEM_TAG_DELIMITER:
-
- if (data) {
- /*
- * We treat items before the first delimiter
- * as global to all usage sets (branch 0).
- * In the moment we process only these global
- * items and the first delimiter set.
- */
- if (parser->local.delimiter_depth != 0) {
- dbg("nested delimiters");
- return -1;
- }
- parser->local.delimiter_depth++;
- parser->local.delimiter_branch++;
- } else {
- if (parser->local.delimiter_depth < 1) {
- dbg("bogus close delimiter");
- return -1;
- }
- parser->local.delimiter_depth--;
- }
- return 1;
-
- case HID_LOCAL_ITEM_TAG_USAGE:
-
- if (parser->local.delimiter_branch > 1) {
- dbg("alternative usage ignored");
- return 0;
- }
-
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- return hid_add_usage(parser, data);
-
- case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
-
- if (parser->local.delimiter_branch > 1) {
- dbg("alternative usage ignored");
- return 0;
- }
-
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- parser->local.usage_minimum = data;
- return 0;
-
- case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
-
- if (parser->local.delimiter_branch > 1) {
- dbg("alternative usage ignored");
- return 0;
- }
-
- if (item->size <= 2)
- data = (parser->global.usage_page << 16) + data;
-
- for (n = parser->local.usage_minimum; n <= data; n++)
- if (hid_add_usage(parser, n)) {
- dbg("hid_add_usage failed\n");
- return -1;
- }
- return 0;
-
- default:
-
- dbg("unknown local item tag 0x%x", item->tag);
- return 0;
- }
- return 0;
-}
-
-/*
- * Process a main item.
- */
-
-static int hid_parser_main(struct hid_parser *parser, struct hid_item *item)
-{
- __u32 data;
- int ret;
-
- data = item_udata(item);
-
- switch (item->tag) {
- case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
- ret = open_collection(parser, data & 0xff);
- break;
- case HID_MAIN_ITEM_TAG_END_COLLECTION:
- ret = close_collection(parser);
- break;
- case HID_MAIN_ITEM_TAG_INPUT:
- ret = hid_add_field(parser, HID_INPUT_REPORT, data);
- break;
- case HID_MAIN_ITEM_TAG_OUTPUT:
- ret = hid_add_field(parser, HID_OUTPUT_REPORT, data);
- break;
- case HID_MAIN_ITEM_TAG_FEATURE:
- ret = hid_add_field(parser, HID_FEATURE_REPORT, data);
- break;
- default:
- dbg("unknown main item tag 0x%x", item->tag);
- ret = 0;
- }
-
- memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */
-
- return ret;
-}
-
-/*
- * Process a reserved item.
- */
-
-static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item)
-{
- dbg("reserved item type, tag 0x%x", item->tag);
- return 0;
-}
-
-/*
- * Free a report and all registered fields. The field->usage and
- * field->value table's are allocated behind the field, so we need
- * only to free(field) itself.
- */
-
-static void hid_free_report(struct hid_report *report)
-{
- unsigned n;
-
- for (n = 0; n < report->maxfield; n++)
- kfree(report->field[n]);
- kfree(report);
-}
-
-/*
- * Free a device structure, all reports, and all fields.
- */
-
-static void hid_free_device(struct hid_device *device)
-{
- unsigned i,j;
-
- hid_ff_exit(device);
-
- for (i = 0; i < HID_REPORT_TYPES; i++) {
- struct hid_report_enum *report_enum = device->report_enum + i;
-
- for (j = 0; j < 256; j++) {
- struct hid_report *report = report_enum->report_id_hash[j];
- if (report)
- hid_free_report(report);
- }
- }
-
- kfree(device->rdesc);
- kfree(device);
-}
-
-/*
- * Fetch a report description item from the data stream. We support long
- * items, though they are not used yet.
- */
-
-static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
-{
- u8 b;
-
- if ((end - start) <= 0)
- return NULL;
-
- b = *start++;
-
- item->type = (b >> 2) & 3;
- item->tag = (b >> 4) & 15;
-
- if (item->tag == HID_ITEM_TAG_LONG) {
-
- item->format = HID_ITEM_FORMAT_LONG;
-
- if ((end - start) < 2)
- return NULL;
-
- item->size = *start++;
- item->tag = *start++;
-
- if ((end - start) < item->size)
- return NULL;
-
- item->data.longdata = start;
- start += item->size;
- return start;
- }
-
- item->format = HID_ITEM_FORMAT_SHORT;
- item->size = b & 3;
-
- switch (item->size) {
-
- case 0:
- return start;
-
- case 1:
- if ((end - start) < 1)
- return NULL;
- item->data.u8 = *start++;
- return start;
-
- case 2:
- if ((end - start) < 2)
- return NULL;
- item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start));
- start = (__u8 *)((__le16 *)start + 1);
- return start;
-
- case 3:
- item->size++;
- if ((end - start) < 4)
- return NULL;
- item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start));
- start = (__u8 *)((__le32 *)start + 1);
- return start;
- }
-
- return NULL;
-}
-
-/*
- * Parse a report description into a hid_device structure. Reports are
- * enumerated, fields are attached to these reports.
- */
-
-static struct hid_device *hid_parse_report(__u8 *start, unsigned size)
-{
- struct hid_device *device;
- struct hid_parser *parser;
- struct hid_item item;
- __u8 *end;
- unsigned i;
- static int (*dispatch_type[])(struct hid_parser *parser,
- struct hid_item *item) = {
- hid_parser_main,
- hid_parser_global,
- hid_parser_local,
- hid_parser_reserved
- };
-
- if (!(device = kmalloc(sizeof(struct hid_device), GFP_KERNEL)))
- return NULL;
- memset(device, 0, sizeof(struct hid_device));
-
- if (!(device->collection = kmalloc(sizeof(struct hid_collection) *
- HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) {
- kfree(device);
- return NULL;
- }
- memset(device->collection, 0, sizeof(struct hid_collection) *
- HID_DEFAULT_NUM_COLLECTIONS);
- device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
-
- for (i = 0; i < HID_REPORT_TYPES; i++)
- INIT_LIST_HEAD(&device->report_enum[i].report_list);
-
- if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) {
- kfree(device->collection);
- kfree(device);
- return NULL;
- }
- memcpy(device->rdesc, start, size);
- device->rsize = size;
-
- if (!(parser = kmalloc(sizeof(struct hid_parser), GFP_KERNEL))) {
- kfree(device->rdesc);
- kfree(device->collection);
- kfree(device);
- return NULL;
- }
- memset(parser, 0, sizeof(struct hid_parser));
- parser->device = device;
-
- end = start + size;
- while ((start = fetch_item(start, end, &item)) != NULL) {
-
- if (item.format != HID_ITEM_FORMAT_SHORT) {
- dbg("unexpected long global item");
- kfree(device->collection);
- hid_free_device(device);
- kfree(parser);
- return NULL;
- }
-
- if (dispatch_type[item.type](parser, &item)) {
- dbg("item %u %u %u %u parsing failed\n",
- item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag);
- kfree(device->collection);
- hid_free_device(device);
- kfree(parser);
- return NULL;
- }
-
- if (start == end) {
- if (parser->collection_stack_ptr) {
- dbg("unbalanced collection at end of report description");
- kfree(device->collection);
- hid_free_device(device);
- kfree(parser);
- return NULL;
- }
- if (parser->local.delimiter_depth) {
- dbg("unbalanced delimiter at end of report description");
- kfree(device->collection);
- hid_free_device(device);
- kfree(parser);
- return NULL;
- }
- kfree(parser);
- return device;
- }
- }
-
- dbg("item fetching failed at offset %d\n", (int)(end - start));
- kfree(device->collection);
- hid_free_device(device);
- kfree(parser);
- return NULL;
-}
-
-/*
- * Convert a signed n-bit integer to signed 32-bit integer. Common
- * cases are done through the compiler, the screwed things has to be
- * done by hand.
- */
-
-static __inline__ __s32 snto32(__u32 value, unsigned n)
-{
- switch (n) {
- case 8: return ((__s8)value);
- case 16: return ((__s16)value);
- case 32: return ((__s32)value);
- }
- return value & (1 << (n - 1)) ? value | (-1 << n) : value;
-}
-
-/*
- * Convert a signed 32-bit integer to a signed n-bit integer.
- */
-
-static __inline__ __u32 s32ton(__s32 value, unsigned n)
-{
- __s32 a = value >> (n - 1);
- if (a && a != -1)
- return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1;
- return value & ((1 << n) - 1);
-}
-
-/*
- * Extract/implement a data field from/to a report.
- */
-
-static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
-{
- report += (offset >> 5) << 2; offset &= 31;
- return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1);
-}
-
-static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
-{
- report += (offset >> 5) << 2; offset &= 31;
- put_unaligned((get_unaligned((__le64*)report)
- & cpu_to_le64(~((((__u64) 1 << n) - 1) << offset)))
- | cpu_to_le64((__u64)value << offset), (__le64*)report);
-}
-
-/*
- * Search an array for a value.
- */
-
-static __inline__ int search(__s32 *array, __s32 value, unsigned n)
-{
- while (n--) {
- if (*array++ == value)
- return 0;
- }
- return -1;
-}
-
-static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs)
-{
- hid_dump_input(usage, value);
- if (hid->claimed & HID_CLAIMED_INPUT)
- hidinput_hid_event(hid, field, usage, value, regs);
- if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt)
- hiddev_hid_event(hid, field, usage, value, regs);
-}
-
-/*
- * Analyse a received field, and fetch the data from it. The field
- * content is stored for next report processing (we do differential
- * reporting to the layer).
- */
-
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs)
-{
- unsigned n;
- unsigned count = field->report_count;
- unsigned offset = field->report_offset;
- unsigned size = field->report_size;
- __s32 min = field->logical_minimum;
- __s32 max = field->logical_maximum;
- __s32 *value;
-
- if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC)))
- return;
-
- for (n = 0; n < count; n++) {
-
- value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) :
- extract(data, offset + n * size, size);
-
- if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */
- && value[n] >= min && value[n] <= max
- && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
- goto exit;
- }
-
- for (n = 0; n < count; n++) {
-
- if (HID_MAIN_ITEM_VARIABLE & field->flags) {
- hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs);
- continue;
- }
-
- if (field->value[n] >= min && field->value[n] <= max
- && field->usage[field->value[n] - min].hid
- && search(value, field->value[n], count))
- hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs);
-
- if (value[n] >= min && value[n] <= max
- && field->usage[value[n] - min].hid
- && search(field->value, value[n], count))
- hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs);
- }
-
- memcpy(field->value, value, count * sizeof(__s32));
-exit:
- kfree(value);
-}
-
-static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs)
-{
- struct hid_device *hid = urb->context;
- struct hid_report_enum *report_enum = hid->report_enum + type;
- u8 *data = urb->transfer_buffer;
- int len = urb->actual_length;
- struct hid_report *report;
- int n, size;
-
- if (!len) {
- dbg("empty report");
- return -1;
- }
-
-#ifdef DEBUG_DATA
- printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un");
-#endif
-
- n = 0; /* Normally report number is 0 */
- if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */
- n = *data++;
- len--;
- }
-
-#ifdef DEBUG_DATA
- {
- int i;
- printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len);
- for (i = 0; i < len; i++)
- printk(" %02x", data[i]);
- printk("\n");
- }
-#endif
-
- if (!(report = report_enum->report_id_hash[n])) {
- dbg("undefined report_id %d received", n);
- return -1;
- }
-
- size = ((report->size - 1) >> 3) + 1;
-
- if (len < size)
- dbg("report %d is too short, (%d < %d)", report->id, len, size);
-
- if (hid->claimed & HID_CLAIMED_HIDDEV)
- hiddev_report_event(hid, report);
-
- for (n = 0; n < report->maxfield; n++)
- hid_input_field(hid, report->field[n], data, interrupt, regs);
-
- if (hid->claimed & HID_CLAIMED_INPUT)
- hidinput_report_event(hid, report);
-
- return 0;
-}
-
-/*
- * Input interrupt completion handler.
- */
-
-static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
-{
- struct hid_device *hid = urb->context;
- int status;
-
- switch (urb->status) {
- case 0: /* success */
- hid_input_report(HID_INPUT_REPORT, urb, 1, regs);
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -EPERM:
- case -ESHUTDOWN: /* unplug */
- case -EILSEQ: /* unplug timeout on uhci */
- return;
- case -ETIMEDOUT: /* NAK */
- break;
- default: /* error */
- warn("input irq status %d received", urb->status);
- }
-
- status = usb_submit_urb(urb, SLAB_ATOMIC);
- if (status)
- err("can't resubmit intr, %s-%s/input%d, status %d",
- hid->dev->bus->bus_name, hid->dev->devpath,
- hid->ifnum, status);
-}
-
-/*
- * Output the field into the report.
- */
-
-static void hid_output_field(struct hid_field *field, __u8 *data)
-{
- unsigned count = field->report_count;
- unsigned offset = field->report_offset;
- unsigned size = field->report_size;
- unsigned n;
-
- for (n = 0; n < count; n++) {
- if (field->logical_minimum < 0) /* signed values */
- implement(data, offset + n * size, size, s32ton(field->value[n], size));
- else /* unsigned values */
- implement(data, offset + n * size, size, field->value[n]);
- }
-}
-
-/*
- * Create a report.
- */
-
-static void hid_output_report(struct hid_report *report, __u8 *data)
-{
- unsigned n;
-
- if (report->id > 0)
- *data++ = report->id;
-
- for (n = 0; n < report->maxfield; n++)
- hid_output_field(report->field[n], data);
-}
-
-/*
- * Set a field value. The report this field belongs to has to be
- * created and transferred to the device, to set this value in the
- * device.
- */
-
-int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
-{
- unsigned size = field->report_size;
-
- hid_dump_input(field->usage + offset, value);
-
- if (offset >= field->report_count) {
- dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count);
- hid_dump_field(field, 8);
- return -1;
- }
- if (field->logical_minimum < 0) {
- if (value != snto32(s32ton(value, size), size)) {
- dbg("value %d is out of range", value);
- return -1;
- }
- }
- field->value[offset] = value;
- return 0;
-}
-
-/*
- * Find a report field with a specified HID usage.
- */
-
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type)
-{
- struct hid_report *report;
- int i;
-
- list_for_each_entry(report, &hid->report_enum[type].report_list, list)
- for (i = 0; i < report->maxfield; i++)
- if (report->field[i]->logical == wanted_usage)
- return report->field[i];
- return NULL;
-}
-
-static int hid_submit_out(struct hid_device *hid)
-{
- struct hid_report *report;
-
- report = hid->out[hid->outtail];
-
- hid_output_report(report, hid->outbuf);
- hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- hid->urbout->dev = hid->dev;
-
- dbg("submitting out urb");
-
- if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) {
- err("usb_submit_urb(out) failed");
- return -1;
- }
-
- return 0;
-}
-
-static int hid_submit_ctrl(struct hid_device *hid)
-{
- struct hid_report *report;
- unsigned char dir;
- int len;
-
- report = hid->ctrl[hid->ctrltail].report;
- dir = hid->ctrl[hid->ctrltail].dir;
-
- len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- if (dir == USB_DIR_OUT) {
- hid_output_report(report, hid->ctrlbuf);
- hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0);
- hid->urbctrl->transfer_buffer_length = len;
- } else {
- int maxpacket, padlen;
-
- hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0);
- maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0);
- if (maxpacket > 0) {
- padlen = (len + maxpacket - 1) / maxpacket;
- padlen *= maxpacket;
- if (padlen > hid->bufsize)
- padlen = hid->bufsize;
- } else
- padlen = 0;
- hid->urbctrl->transfer_buffer_length = padlen;
- }
- hid->urbctrl->dev = hid->dev;
-
- hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
- hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
- hid->cr->wIndex = cpu_to_le16(hid->ifnum);
- hid->cr->wLength = cpu_to_le16(len);
-
- dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u",
- hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
- hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength);
-
- if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) {
- err("usb_submit_urb(ctrl) failed");
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Output interrupt completion handler.
- */
-
-static void hid_irq_out(struct urb *urb, struct pt_regs *regs)
-{
- struct hid_device *hid = urb->context;
- unsigned long flags;
- int unplug = 0;
-
- switch (urb->status) {
- case 0: /* success */
- break;
- case -ESHUTDOWN: /* unplug */
- case -EILSEQ: /* unplug timeout on uhci */
- unplug = 1;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- break;
- default: /* error */
- warn("output irq status %d received", urb->status);
- }
-
- spin_lock_irqsave(&hid->outlock, flags);
-
- if (unplug)
- hid->outtail = hid->outhead;
- else
- hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
-
- if (hid->outhead != hid->outtail) {
- if (hid_submit_out(hid)) {
- clear_bit(HID_OUT_RUNNING, &hid->iofl);;
- wake_up(&hid->wait);
- }
- spin_unlock_irqrestore(&hid->outlock, flags);
- return;
- }
-
- clear_bit(HID_OUT_RUNNING, &hid->iofl);
- spin_unlock_irqrestore(&hid->outlock, flags);
- wake_up(&hid->wait);
-}
-
-/*
- * Control pipe completion handler.
- */
-
-static void hid_ctrl(struct urb *urb, struct pt_regs *regs)
-{
- struct hid_device *hid = urb->context;
- unsigned long flags;
- int unplug = 0;
-
- spin_lock_irqsave(&hid->ctrllock, flags);
-
- switch (urb->status) {
- case 0: /* success */
- if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
- hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
- break;
- case -ESHUTDOWN: /* unplug */
- case -EILSEQ: /* unplug timectrl on uhci */
- unplug = 1;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -EPIPE: /* report not available */
- break;
- default: /* error */
- warn("ctrl urb status %d received", urb->status);
- }
-
- if (unplug)
- hid->ctrltail = hid->ctrlhead;
- else
- hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
-
- if (hid->ctrlhead != hid->ctrltail) {
- if (hid_submit_ctrl(hid)) {
- clear_bit(HID_CTRL_RUNNING, &hid->iofl);
- wake_up(&hid->wait);
- }
- spin_unlock_irqrestore(&hid->ctrllock, flags);
- return;
- }
-
- clear_bit(HID_CTRL_RUNNING, &hid->iofl);
- spin_unlock_irqrestore(&hid->ctrllock, flags);
- wake_up(&hid->wait);
-}
-
-void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
-{
- int head;
- unsigned long flags;
-
- if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
- return;
-
- if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
- spin_lock_irqsave(&hid->outlock, flags);
-
- if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) {
- spin_unlock_irqrestore(&hid->outlock, flags);
- warn("output queue full");
- return;
- }
-
- hid->out[hid->outhead] = report;
- hid->outhead = head;
-
- if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl))
- if (hid_submit_out(hid))
- clear_bit(HID_OUT_RUNNING, &hid->iofl);
-
- spin_unlock_irqrestore(&hid->outlock, flags);
- return;
- }
-
- spin_lock_irqsave(&hid->ctrllock, flags);
-
- if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) {
- spin_unlock_irqrestore(&hid->ctrllock, flags);
- warn("control queue full");
- return;
- }
-
- hid->ctrl[hid->ctrlhead].report = report;
- hid->ctrl[hid->ctrlhead].dir = dir;
- hid->ctrlhead = head;
-
- if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl))
- if (hid_submit_ctrl(hid))
- clear_bit(HID_CTRL_RUNNING, &hid->iofl);
-
- spin_unlock_irqrestore(&hid->ctrllock, flags);
-}
-
-int hid_wait_io(struct hid_device *hid)
-{
- if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) &&
- !test_bit(HID_OUT_RUNNING, &hid->iofl)),
- 10*HZ)) {
- dbg("timeout waiting for ctrl or out queue to clear");
- return -1;
- }
-
- return 0;
-}
-
-static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle)
-{
- return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,
- ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
-}
-
-static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
- unsigned char type, void *buf, int size)
-{
- int result, retries = 4;
-
- memset(buf,0,size); // Make sure we parse really received data
-
- do {
- result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
- (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT);
- retries--;
- } while (result < size && retries);
- return result;
-}
-
-int hid_open(struct hid_device *hid)
-{
- if (hid->open++)
- return 0;
-
- hid->urbin->dev = hid->dev;
-
- if (usb_submit_urb(hid->urbin, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-void hid_close(struct hid_device *hid)
-{
- if (!--hid->open)
- usb_kill_urb(hid->urbin);
-}
-
-/*
- * Initialize all reports
- */
-
-void hid_init_reports(struct hid_device *hid)
-{
- struct hid_report *report;
- int err, ret;
-
- list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
- hid_submit_report(hid, report, USB_DIR_IN);
-
- list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
- hid_submit_report(hid, report, USB_DIR_IN);
-
- err = 0;
- ret = hid_wait_io(hid);
- while (ret) {
- err |= ret;
- if (test_bit(HID_CTRL_RUNNING, &hid->iofl))
- usb_kill_urb(hid->urbctrl);
- if (test_bit(HID_OUT_RUNNING, &hid->iofl))
- usb_kill_urb(hid->urbout);
- ret = hid_wait_io(hid);
- }
-
- if (err)
- warn("timeout initializing reports\n");
-}
-
-#define USB_VENDOR_ID_WACOM 0x056a
-#define USB_DEVICE_ID_WACOM_PENPARTNER 0x0000
-#define USB_DEVICE_ID_WACOM_GRAPHIRE 0x0010
-#define USB_DEVICE_ID_WACOM_INTUOS 0x0020
-#define USB_DEVICE_ID_WACOM_PL 0x0030
-#define USB_DEVICE_ID_WACOM_INTUOS2 0x0040
-#define USB_DEVICE_ID_WACOM_VOLITO 0x0060
-#define USB_DEVICE_ID_WACOM_PTU 0x0003
-#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0
-#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F
-
-#define USB_VENDOR_ID_ACECAD 0x0460
-#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
-#define USB_DEVICE_ID_ACECAD_302 0x0008
-
-#define USB_VENDOR_ID_KBGEAR 0x084e
-#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
-
-#define USB_VENDOR_ID_AIPTEK 0x08ca
-#define USB_DEVICE_ID_AIPTEK_01 0x0001
-#define USB_DEVICE_ID_AIPTEK_10 0x0010
-#define USB_DEVICE_ID_AIPTEK_20 0x0020
-#define USB_DEVICE_ID_AIPTEK_21 0x0021
-#define USB_DEVICE_ID_AIPTEK_22 0x0022
-#define USB_DEVICE_ID_AIPTEK_23 0x0023
-#define USB_DEVICE_ID_AIPTEK_24 0x0024
-
-#define USB_VENDOR_ID_GRIFFIN 0x077d
-#define USB_DEVICE_ID_POWERMATE 0x0410
-#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
-
-#define USB_VENDOR_ID_ATEN 0x0557
-#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
-#define USB_DEVICE_ID_ATEN_CS124U 0x2202
-#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
-#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
-#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208
-
-#define USB_VENDOR_ID_TOPMAX 0x0663
-#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
-
-#define USB_VENDOR_ID_HAPP 0x078b
-#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
-#define USB_DEVICE_ID_UGCI_FLYING 0x0020
-#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
-
-#define USB_VENDOR_ID_MGE 0x0463
-#define USB_DEVICE_ID_MGE_UPS 0xffff
-#define USB_DEVICE_ID_MGE_UPS1 0x0001
-
-#define USB_VENDOR_ID_ONTRAK 0x0a07
-#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
-
-#define USB_VENDOR_ID_TANGTOP 0x0d3d
-#define USB_DEVICE_ID_TANGTOP_USBPS2 0x0001
-
-#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
-#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
-
-#define USB_VENDOR_ID_A4TECH 0x09da
-#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
-
-#define USB_VENDOR_ID_AASHIMA 0x06d6
-#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
-#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026
-
-#define USB_VENDOR_ID_CYPRESS 0x04b4
-#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
-#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
-#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
-
-#define USB_VENDOR_ID_BERKSHIRE 0x0c98
-#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
-
-#define USB_VENDOR_ID_ALPS 0x0433
-#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
-
-#define USB_VENDOR_ID_SAITEK 0x06a3
-#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
-
-#define USB_VENDOR_ID_NEC 0x073e
-#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
-
-#define USB_VENDOR_ID_CHIC 0x05fe
-#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
-
-#define USB_VENDOR_ID_GLAB 0x06c2
-#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
-#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
-#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045
-#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040
-#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053
-
-#define USB_VENDOR_ID_WISEGROUP 0x0925
-#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
-#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
-
-#define USB_VENDOR_ID_CODEMERCS 0x07c0
-#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500
-#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501
-#define USB_DEVICE_ID_CODEMERCS_IOW48 0x1502
-#define USB_DEVICE_ID_CODEMERCS_IOW28 0x1503
-
-#define USB_VENDOR_ID_DELORME 0x1163
-#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
-#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
-
-#define USB_VENDOR_ID_MCC 0x09db
-#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
-#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
-
-#define USB_VENDOR_ID_CHICONY 0x04f2
-#define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100
-
-#define USB_VENDOR_ID_BTC 0x046e
-#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303
-
-#define USB_VENDOR_ID_VERNIER 0x08f7
-#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
-#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
-#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
-#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
-
-#define USB_VENDOR_ID_LD 0x0f11
-#define USB_DEVICE_ID_CASSY 0x1000
-#define USB_DEVICE_ID_POCKETCASSY 0x1010
-#define USB_DEVICE_ID_MOBILECASSY 0x1020
-#define USB_DEVICE_ID_JWM 0x1080
-#define USB_DEVICE_ID_DMMP 0x1081
-#define USB_DEVICE_ID_UMIP 0x1090
-#define USB_DEVICE_ID_VIDEOCOM 0x1200
-#define USB_DEVICE_ID_COM3LAB 0x2000
-#define USB_DEVICE_ID_TELEPORT 0x2010
-#define USB_DEVICE_ID_NETWORKANALYSER 0x2020
-#define USB_DEVICE_ID_POWERCONTROL 0x2030
-
-#define USB_VENDOR_ID_APPLE 0x05ac
-#define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304
-
-/*
- * Alphabetically sorted blacklist by quirk type.
- */
-
-static struct hid_blacklist {
- __u16 idVendor;
- __u16 idProduct;
- unsigned quirks;
-} hid_blacklist[] = {
-
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW48, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PL + 5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
-
- { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
- { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
-
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
- { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET},
- { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET},
- { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
-
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_POWERMOUSE, HID_QUIRK_2WHEEL_POWERMOUSE },
- { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
- { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
-
- { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
- { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
- { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
-
- { 0, 0 }
-};
-
-/*
- * Traverse the supplied list of reports and find the longest
- */
-static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max)
-{
- struct hid_report *report;
- int size;
-
- list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
- size = ((report->size - 1) >> 3) + 1;
- if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered)
- size++;
- if (*max < size)
- *max = size;
- }
-}
-
-static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
-{
- if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
- return -1;
- if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
- return -1;
- if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
- return -1;
- if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
- return -1;
-
- return 0;
-}
-
-static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
-{
- if (hid->inbuf)
- usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma);
- if (hid->outbuf)
- usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma);
- if (hid->cr)
- usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma);
- if (hid->ctrlbuf)
- usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
-}
-
-static struct hid_device *usb_hid_configure(struct usb_interface *intf)
-{
- struct usb_host_interface *interface = intf->cur_altsetting;
- struct usb_device *dev = interface_to_usbdev (intf);
- struct hid_descriptor *hdesc;
- struct hid_device *hid;
- unsigned quirks = 0, rsize = 0;
- char *rdesc;
- int n, len, insize = 0;
-
- for (n = 0; hid_blacklist[n].idVendor; n++)
- if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
- (hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct)))
- quirks = hid_blacklist[n].quirks;
-
- if (quirks & HID_QUIRK_IGNORE)
- return NULL;
-
- if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
- (!interface->desc.bNumEndpoints ||
- usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
- dbg("class descriptor not present\n");
- return NULL;
- }
-
- for (n = 0; n < hdesc->bNumDescriptors; n++)
- if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
- rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
-
- if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
- dbg("weird size of report descriptor (%u)", rsize);
- return NULL;
- }
-
- if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
- dbg("couldn't allocate rdesc memory");
- return NULL;
- }
-
- hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
-
- if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
- dbg("reading report descriptor failed");
- kfree(rdesc);
- return NULL;
- }
-
-#ifdef DEBUG_DATA
- printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);
- for (n = 0; n < rsize; n++)
- printk(" %02x", (unsigned char) rdesc[n]);
- printk("\n");
-#endif
-
- if (!(hid = hid_parse_report(rdesc, n))) {
- dbg("parsing report descriptor failed");
- kfree(rdesc);
- return NULL;
- }
-
- kfree(rdesc);
- hid->quirks = quirks;
-
- hid->bufsize = HID_MIN_BUFFER_SIZE;
- hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize);
- hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize);
- hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize);
-
- if (hid->bufsize > HID_MAX_BUFFER_SIZE)
- hid->bufsize = HID_MAX_BUFFER_SIZE;
-
- hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
-
- if (insize > HID_MAX_BUFFER_SIZE)
- insize = HID_MAX_BUFFER_SIZE;
-
- if (hid_alloc_buffers(dev, hid)) {
- hid_free_buffers(dev, hid);
- goto fail;
- }
-
- for (n = 0; n < interface->desc.bNumEndpoints; n++) {
-
- struct usb_endpoint_descriptor *endpoint;
- int pipe;
- int interval;
-
- endpoint = &interface->endpoint[n].desc;
- if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */
- continue;
-
- interval = endpoint->bInterval;
-
- /* Change the polling interval of mice. */
- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
- interval = hid_mousepoll_interval;
-
- if (endpoint->bEndpointAddress & USB_DIR_IN) {
- if (hid->urbin)
- continue;
- if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
- goto fail;
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize,
- hid_irq_in, hid, interval);
- hid->urbin->transfer_dma = hid->inbuf_dma;
- hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- } else {
- if (hid->urbout)
- continue;
- if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL)))
- goto fail;
- pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress);
- usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
- hid_irq_out, hid, interval);
- hid->urbout->transfer_dma = hid->outbuf_dma;
- hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- }
- }
-
- if (!hid->urbin) {
- err("couldn't find an input interrupt endpoint");
- goto fail;
- }
-
- init_waitqueue_head(&hid->wait);
-
- spin_lock_init(&hid->outlock);
- spin_lock_init(&hid->ctrllock);
-
- hid->version = le16_to_cpu(hdesc->bcdHID);
- hid->country = hdesc->bCountryCode;
- hid->dev = dev;
- hid->intf = intf;
- hid->ifnum = interface->desc.bInterfaceNumber;
-
- hid->name[0] = 0;
-
- if (dev->manufacturer)
- strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(hid->name, " ", sizeof(hid->name));
- strlcat(hid->name, dev->product, sizeof(hid->name));
- }
-
- if (!strlen(hid->name))
- snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, hid->phys, sizeof(hid->phys));
- strlcat(hid->phys, "/input", sizeof(hid->phys));
- len = strlen(hid->phys);
- if (len < sizeof(hid->phys) - 1)
- snprintf(hid->phys + len, sizeof(hid->phys) - len,
- "%d", intf->altsetting[0].desc.bInterfaceNumber);
-
- if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
- hid->uniq[0] = 0;
-
- hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
- if (!hid->urbctrl)
- goto fail;
-
- usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
- hid->ctrlbuf, 1, hid_ctrl, hid);
- hid->urbctrl->setup_dma = hid->cr_dma;
- hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
- hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
-
- /* May be needed for some devices */
- usb_clear_halt(hid->dev, hid->urbin->pipe);
-
- return hid;
-
-fail:
-
- if (hid->urbin)
- usb_free_urb(hid->urbin);
- if (hid->urbout)
- usb_free_urb(hid->urbout);
- if (hid->urbctrl)
- usb_free_urb(hid->urbctrl);
- hid_free_buffers(dev, hid);
- hid_free_device(hid);
-
- return NULL;
-}
-
-static void hid_disconnect(struct usb_interface *intf)
-{
- struct hid_device *hid = usb_get_intfdata (intf);
-
- if (!hid)
- return;
-
- usb_set_intfdata(intf, NULL);
- usb_kill_urb(hid->urbin);
- usb_kill_urb(hid->urbout);
- usb_kill_urb(hid->urbctrl);
-
- if (hid->claimed & HID_CLAIMED_INPUT)
- hidinput_disconnect(hid);
- if (hid->claimed & HID_CLAIMED_HIDDEV)
- hiddev_disconnect(hid);
-
- usb_free_urb(hid->urbin);
- usb_free_urb(hid->urbctrl);
- if (hid->urbout)
- usb_free_urb(hid->urbout);
-
- hid_free_buffers(hid->dev, hid);
- hid_free_device(hid);
-}
-
-static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct hid_device *hid;
- char path[64];
- int i;
- char *c;
-
- dbg("HID probe called for ifnum %d",
- intf->altsetting->desc.bInterfaceNumber);
-
- if (!(hid = usb_hid_configure(intf)))
- return -ENODEV;
-
- hid_init_reports(hid);
- hid_dump_device(hid);
-
- if (!hidinput_connect(hid))
- hid->claimed |= HID_CLAIMED_INPUT;
- if (!hiddev_connect(hid))
- hid->claimed |= HID_CLAIMED_HIDDEV;
-
- usb_set_intfdata(intf, hid);
-
- if (!hid->claimed) {
- printk ("HID device not claimed by input or hiddev\n");
- hid_disconnect(intf);
- return -ENODEV;
- }
-
- printk(KERN_INFO);
-
- if (hid->claimed & HID_CLAIMED_INPUT)
- printk("input");
- if (hid->claimed == (HID_CLAIMED_INPUT | HID_CLAIMED_HIDDEV))
- printk(",");
- if (hid->claimed & HID_CLAIMED_HIDDEV)
- printk("hiddev%d", hid->minor);
-
- c = "Device";
- for (i = 0; i < hid->maxcollection; i++) {
- if (hid->collection[i].type == HID_COLLECTION_APPLICATION &&
- (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK &&
- (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) {
- c = hid_types[hid->collection[i].usage & 0xffff];
- break;
- }
- }
-
- usb_make_path(interface_to_usbdev(intf), path, 63);
-
- printk(": USB HID v%x.%02x %s [%s] on %s\n",
- hid->version >> 8, hid->version & 0xff, c, hid->name, path);
-
- return 0;
-}
-
-static int hid_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct hid_device *hid = usb_get_intfdata (intf);
-
- usb_kill_urb(hid->urbin);
- dev_dbg(&intf->dev, "suspend\n");
- return 0;
-}
-
-static int hid_resume(struct usb_interface *intf)
-{
- struct hid_device *hid = usb_get_intfdata (intf);
- int status;
-
- if (hid->open)
- status = usb_submit_urb(hid->urbin, GFP_NOIO);
- else
- status = 0;
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return status;
-}
-
-static struct usb_device_id hid_usb_ids [] = {
- { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
- .bInterfaceClass = USB_INTERFACE_CLASS_HID },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, hid_usb_ids);
-
-static struct usb_driver hid_driver = {
- .owner = THIS_MODULE,
- .name = "usbhid",
- .probe = hid_probe,
- .disconnect = hid_disconnect,
- .suspend = hid_suspend,
- .resume = hid_resume,
- .id_table = hid_usb_ids,
-};
-
-static int __init hid_init(void)
-{
- int retval;
- retval = hiddev_init();
- if (retval)
- goto hiddev_init_fail;
- retval = usb_register(&hid_driver);
- if (retval)
- goto usb_register_fail;
- info(DRIVER_VERSION ":" DRIVER_DESC);
-
- return 0;
-usb_register_fail:
- hiddev_exit();
-hiddev_init_fail:
- return retval;
-}
-
-static void __exit hid_exit(void)
-{
- usb_deregister(&hid_driver);
- hiddev_exit();
-}
-
-module_init(hid_init);
-module_exit(hid_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h
deleted file mode 100644
index ceebab99eff..00000000000
--- a/drivers/usb/input/hid-debug.h
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * $Id: hid-debug.h,v 1.8 2001/09/25 09:37:57 vojtech Exp $
- *
- * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de>
- * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz>
- *
- * Some debug stuff for the HID parser.
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/input.h>
-
-struct hid_usage_entry {
- unsigned page;
- unsigned usage;
- char *description;
-};
-
-static const struct hid_usage_entry hid_usage_table[] = {
- { 0, 0, "Undefined" },
- { 1, 0, "GenericDesktop" },
- {0, 0x01, "Pointer"},
- {0, 0x02, "Mouse"},
- {0, 0x04, "Joystick"},
- {0, 0x05, "GamePad"},
- {0, 0x06, "Keyboard"},
- {0, 0x07, "Keypad"},
- {0, 0x08, "MultiAxis"},
- {0, 0x30, "X"},
- {0, 0x31, "Y"},
- {0, 0x32, "Z"},
- {0, 0x33, "Rx"},
- {0, 0x34, "Ry"},
- {0, 0x35, "Rz"},
- {0, 0x36, "Slider"},
- {0, 0x37, "Dial"},
- {0, 0x38, "Wheel"},
- {0, 0x39, "HatSwitch"},
- {0, 0x3a, "CountedBuffer"},
- {0, 0x3b, "ByteCount"},
- {0, 0x3c, "MotionWakeup"},
- {0, 0x3d, "Start"},
- {0, 0x3e, "Select"},
- {0, 0x40, "Vx"},
- {0, 0x41, "Vy"},
- {0, 0x42, "Vz"},
- {0, 0x43, "Vbrx"},
- {0, 0x44, "Vbry"},
- {0, 0x45, "Vbrz"},
- {0, 0x46, "Vno"},
- {0, 0x80, "SystemControl"},
- {0, 0x81, "SystemPowerDown"},
- {0, 0x82, "SystemSleep"},
- {0, 0x83, "SystemWakeUp"},
- {0, 0x84, "SystemContextMenu"},
- {0, 0x85, "SystemMainMenu"},
- {0, 0x86, "SystemAppMenu"},
- {0, 0x87, "SystemMenuHelp"},
- {0, 0x88, "SystemMenuExit"},
- {0, 0x89, "SystemMenuSelect"},
- {0, 0x8a, "SystemMenuRight"},
- {0, 0x8b, "SystemMenuLeft"},
- {0, 0x8c, "SystemMenuUp"},
- {0, 0x8d, "SystemMenuDown"},
- {0, 0x90, "D-PadUp"},
- {0, 0x91, "D-PadDown"},
- {0, 0x92, "D-PadRight"},
- {0, 0x93, "D-PadLeft"},
- { 2, 0, "Simulation" },
- {0, 0xb0, "Aileron"},
- {0, 0xb1, "AileronTrim"},
- {0, 0xb2, "Anti-Torque"},
- {0, 0xb3, "Autopilot"},
- {0, 0xb4, "Chaff"},
- {0, 0xb5, "Collective"},
- {0, 0xb6, "DiveBrake"},
- {0, 0xb7, "ElectronicCountermeasures"},
- {0, 0xb8, "Elevator"},
- {0, 0xb9, "ElevatorTrim"},
- {0, 0xba, "Rudder"},
- {0, 0xbb, "Throttle"},
- {0, 0xbc, "FlightCommunications"},
- {0, 0xbd, "FlareRelease"},
- {0, 0xbe, "LandingGear"},
- {0, 0xbf, "ToeBrake"},
- { 7, 0, "Keyboard" },
- { 8, 0, "LED" },
- {0, 0x01, "NumLock"},
- {0, 0x02, "CapsLock"},
- {0, 0x03, "ScrollLock"},
- {0, 0x04, "Compose"},
- {0, 0x05, "Kana"},
- {0, 0x4b, "GenericIndicator"},
- { 9, 0, "Button" },
- { 10, 0, "Ordinal" },
- { 12, 0, "Consumer" },
- {0, 0x238, "HorizontalWheel"},
- { 13, 0, "Digitizers" },
- {0, 0x01, "Digitizer"},
- {0, 0x02, "Pen"},
- {0, 0x03, "LightPen"},
- {0, 0x04, "TouchScreen"},
- {0, 0x05, "TouchPad"},
- {0, 0x20, "Stylus"},
- {0, 0x21, "Puck"},
- {0, 0x22, "Finger"},
- {0, 0x30, "TipPressure"},
- {0, 0x31, "BarrelPressure"},
- {0, 0x32, "InRange"},
- {0, 0x33, "Touch"},
- {0, 0x34, "UnTouch"},
- {0, 0x35, "Tap"},
- {0, 0x39, "TabletFunctionKey"},
- {0, 0x3a, "ProgramChangeKey"},
- {0, 0x3c, "Invert"},
- {0, 0x42, "TipSwitch"},
- {0, 0x43, "SecondaryTipSwitch"},
- {0, 0x44, "BarrelSwitch"},
- {0, 0x45, "Eraser"},
- {0, 0x46, "TabletPick"},
- { 15, 0, "PhysicalInterfaceDevice" },
- {0, 0x00, "Undefined"},
- {0, 0x01, "Physical_Interface_Device"},
- {0, 0x20, "Normal"},
- {0, 0x21, "Set_Effect_Report"},
- {0, 0x22, "Effect_Block_Index"},
- {0, 0x23, "Parameter_Block_Offset"},
- {0, 0x24, "ROM_Flag"},
- {0, 0x25, "Effect_Type"},
- {0, 0x26, "ET_Constant_Force"},
- {0, 0x27, "ET_Ramp"},
- {0, 0x28, "ET_Custom_Force_Data"},
- {0, 0x30, "ET_Square"},
- {0, 0x31, "ET_Sine"},
- {0, 0x32, "ET_Triangle"},
- {0, 0x33, "ET_Sawtooth_Up"},
- {0, 0x34, "ET_Sawtooth_Down"},
- {0, 0x40, "ET_Spring"},
- {0, 0x41, "ET_Damper"},
- {0, 0x42, "ET_Inertia"},
- {0, 0x43, "ET_Friction"},
- {0, 0x50, "Duration"},
- {0, 0x51, "Sample_Period"},
- {0, 0x52, "Gain"},
- {0, 0x53, "Trigger_Button"},
- {0, 0x54, "Trigger_Repeat_Interval"},
- {0, 0x55, "Axes_Enable"},
- {0, 0x56, "Direction_Enable"},
- {0, 0x57, "Direction"},
- {0, 0x58, "Type_Specific_Block_Offset"},
- {0, 0x59, "Block_Type"},
- {0, 0x5A, "Set_Envelope_Report"},
- {0, 0x5B, "Attack_Level"},
- {0, 0x5C, "Attack_Time"},
- {0, 0x5D, "Fade_Level"},
- {0, 0x5E, "Fade_Time"},
- {0, 0x5F, "Set_Condition_Report"},
- {0, 0x60, "CP_Offset"},
- {0, 0x61, "Positive_Coefficient"},
- {0, 0x62, "Negative_Coefficient"},
- {0, 0x63, "Positive_Saturation"},
- {0, 0x64, "Negative_Saturation"},
- {0, 0x65, "Dead_Band"},
- {0, 0x66, "Download_Force_Sample"},
- {0, 0x67, "Isoch_Custom_Force_Enable"},
- {0, 0x68, "Custom_Force_Data_Report"},
- {0, 0x69, "Custom_Force_Data"},
- {0, 0x6A, "Custom_Force_Vendor_Defined_Data"},
- {0, 0x6B, "Set_Custom_Force_Report"},
- {0, 0x6C, "Custom_Force_Data_Offset"},
- {0, 0x6D, "Sample_Count"},
- {0, 0x6E, "Set_Periodic_Report"},
- {0, 0x6F, "Offset"},
- {0, 0x70, "Magnitude"},
- {0, 0x71, "Phase"},
- {0, 0x72, "Period"},
- {0, 0x73, "Set_Constant_Force_Report"},
- {0, 0x74, "Set_Ramp_Force_Report"},
- {0, 0x75, "Ramp_Start"},
- {0, 0x76, "Ramp_End"},
- {0, 0x77, "Effect_Operation_Report"},
- {0, 0x78, "Effect_Operation"},
- {0, 0x79, "Op_Effect_Start"},
- {0, 0x7A, "Op_Effect_Start_Solo"},
- {0, 0x7B, "Op_Effect_Stop"},
- {0, 0x7C, "Loop_Count"},
- {0, 0x7D, "Device_Gain_Report"},
- {0, 0x7E, "Device_Gain"},
- {0, 0x7F, "PID_Pool_Report"},
- {0, 0x80, "RAM_Pool_Size"},
- {0, 0x81, "ROM_Pool_Size"},
- {0, 0x82, "ROM_Effect_Block_Count"},
- {0, 0x83, "Simultaneous_Effects_Max"},
- {0, 0x84, "Pool_Alignment"},
- {0, 0x85, "PID_Pool_Move_Report"},
- {0, 0x86, "Move_Source"},
- {0, 0x87, "Move_Destination"},
- {0, 0x88, "Move_Length"},
- {0, 0x89, "PID_Block_Load_Report"},
- {0, 0x8B, "Block_Load_Status"},
- {0, 0x8C, "Block_Load_Success"},
- {0, 0x8D, "Block_Load_Full"},
- {0, 0x8E, "Block_Load_Error"},
- {0, 0x8F, "Block_Handle"},
- {0, 0x90, "PID_Block_Free_Report"},
- {0, 0x91, "Type_Specific_Block_Handle"},
- {0, 0x92, "PID_State_Report"},
- {0, 0x94, "Effect_Playing"},
- {0, 0x95, "PID_Device_Control_Report"},
- {0, 0x96, "PID_Device_Control"},
- {0, 0x97, "DC_Enable_Actuators"},
- {0, 0x98, "DC_Disable_Actuators"},
- {0, 0x99, "DC_Stop_All_Effects"},
- {0, 0x9A, "DC_Device_Reset"},
- {0, 0x9B, "DC_Device_Pause"},
- {0, 0x9C, "DC_Device_Continue"},
- {0, 0x9F, "Device_Paused"},
- {0, 0xA0, "Actuators_Enabled"},
- {0, 0xA4, "Safety_Switch"},
- {0, 0xA5, "Actuator_Override_Switch"},
- {0, 0xA6, "Actuator_Power"},
- {0, 0xA7, "Start_Delay"},
- {0, 0xA8, "Parameter_Block_Size"},
- {0, 0xA9, "Device_Managed_Pool"},
- {0, 0xAA, "Shared_Parameter_Blocks"},
- {0, 0xAB, "Create_New_Effect_Report"},
- {0, 0xAC, "RAM_Pool_Available"},
- { 0x84, 0, "Power Device" },
- { 0x84, 0x02, "PresentStatus" },
- { 0x84, 0x03, "ChangeStatus" },
- { 0x84, 0x04, "UPS" },
- { 0x84, 0x05, "PowerSupply" },
- { 0x84, 0x10, "BatterySystem" },
- { 0x84, 0x11, "BatterySystemID" },
- { 0x84, 0x12, "Battery" },
- { 0x84, 0x13, "BatteryID" },
- { 0x84, 0x14, "Charger" },
- { 0x84, 0x15, "ChargerID" },
- { 0x84, 0x16, "PowerConverter" },
- { 0x84, 0x17, "PowerConverterID" },
- { 0x84, 0x18, "OutletSystem" },
- { 0x84, 0x19, "OutletSystemID" },
- { 0x84, 0x1a, "Input" },
- { 0x84, 0x1b, "InputID" },
- { 0x84, 0x1c, "Output" },
- { 0x84, 0x1d, "OutputID" },
- { 0x84, 0x1e, "Flow" },
- { 0x84, 0x1f, "FlowID" },
- { 0x84, 0x20, "Outlet" },
- { 0x84, 0x21, "OutletID" },
- { 0x84, 0x22, "Gang" },
- { 0x84, 0x24, "PowerSummary" },
- { 0x84, 0x25, "PowerSummaryID" },
- { 0x84, 0x30, "Voltage" },
- { 0x84, 0x31, "Current" },
- { 0x84, 0x32, "Frequency" },
- { 0x84, 0x33, "ApparentPower" },
- { 0x84, 0x35, "PercentLoad" },
- { 0x84, 0x40, "ConfigVoltage" },
- { 0x84, 0x41, "ConfigCurrent" },
- { 0x84, 0x43, "ConfigApparentPower" },
- { 0x84, 0x53, "LowVoltageTransfer" },
- { 0x84, 0x54, "HighVoltageTransfer" },
- { 0x84, 0x56, "DelayBeforeStartup" },
- { 0x84, 0x57, "DelayBeforeShutdown" },
- { 0x84, 0x58, "Test" },
- { 0x84, 0x5a, "AudibleAlarmControl" },
- { 0x84, 0x60, "Present" },
- { 0x84, 0x61, "Good" },
- { 0x84, 0x62, "InternalFailure" },
- { 0x84, 0x65, "Overload" },
- { 0x84, 0x66, "OverCharged" },
- { 0x84, 0x67, "OverTemperature" },
- { 0x84, 0x68, "ShutdownRequested" },
- { 0x84, 0x69, "ShutdownImminent" },
- { 0x84, 0x6b, "SwitchOn/Off" },
- { 0x84, 0x6c, "Switchable" },
- { 0x84, 0x6d, "Used" },
- { 0x84, 0x6e, "Boost" },
- { 0x84, 0x73, "CommunicationLost" },
- { 0x84, 0xfd, "iManufacturer" },
- { 0x84, 0xfe, "iProduct" },
- { 0x84, 0xff, "iSerialNumber" },
- { 0x85, 0, "Battery System" },
- { 0x85, 0x01, "SMBBatteryMode" },
- { 0x85, 0x02, "SMBBatteryStatus" },
- { 0x85, 0x03, "SMBAlarmWarning" },
- { 0x85, 0x04, "SMBChargerMode" },
- { 0x85, 0x05, "SMBChargerStatus" },
- { 0x85, 0x06, "SMBChargerSpecInfo" },
- { 0x85, 0x07, "SMBSelectorState" },
- { 0x85, 0x08, "SMBSelectorPresets" },
- { 0x85, 0x09, "SMBSelectorInfo" },
- { 0x85, 0x29, "RemainingCapacityLimit" },
- { 0x85, 0x2c, "CapacityMode" },
- { 0x85, 0x42, "BelowRemainingCapacityLimit" },
- { 0x85, 0x44, "Charging" },
- { 0x85, 0x45, "Discharging" },
- { 0x85, 0x4b, "NeedReplacement" },
- { 0x85, 0x66, "RemainingCapacity" },
- { 0x85, 0x68, "RunTimeToEmpty" },
- { 0x85, 0x6a, "AverageTimeToFull" },
- { 0x85, 0x83, "DesignCapacity" },
- { 0x85, 0x85, "ManufacturerDate" },
- { 0x85, 0x89, "iDeviceChemistry" },
- { 0x85, 0x8b, "Rechargable" },
- { 0x85, 0x8f, "iOEMInformation" },
- { 0x85, 0x8d, "CapacityGranularity1" },
- { 0x85, 0xd0, "ACPresent" },
- /* pages 0xff00 to 0xffff are vendor-specific */
- { 0xffff, 0, "Vendor-specific-FF" },
- { 0, 0, NULL }
-};
-
-static void resolv_usage_page(unsigned page) {
- const struct hid_usage_entry *p;
-
- for (p = hid_usage_table; p->description; p++)
- if (p->page == page) {
- printk("%s", p->description);
- return;
- }
- printk("%04x", page);
-}
-
-static void resolv_usage(unsigned usage) {
- const struct hid_usage_entry *p;
-
- resolv_usage_page(usage >> 16);
- printk(".");
- for (p = hid_usage_table; p->description; p++)
- if (p->page == (usage >> 16)) {
- for(++p; p->description && p->usage != 0; p++)
- if (p->usage == (usage & 0xffff)) {
- printk("%s", p->description);
- return;
- }
- break;
- }
- printk("%04x", usage & 0xffff);
-}
-
-__inline__ static void tab(int n) {
- while (n--) printk(" ");
-}
-
-static void hid_dump_field(struct hid_field *field, int n) {
- int j;
-
- if (field->physical) {
- tab(n);
- printk("Physical(");
- resolv_usage(field->physical); printk(")\n");
- }
- if (field->logical) {
- tab(n);
- printk("Logical(");
- resolv_usage(field->logical); printk(")\n");
- }
- tab(n); printk("Usage(%d)\n", field->maxusage);
- for (j = 0; j < field->maxusage; j++) {
- tab(n+2);resolv_usage(field->usage[j].hid); printk("\n");
- }
- if (field->logical_minimum != field->logical_maximum) {
- tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum);
- tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum);
- }
- if (field->physical_minimum != field->physical_maximum) {
- tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum);
- tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum);
- }
- if (field->unit_exponent) {
- tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
- }
- if (field->unit) {
- char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
- char *units[5][8] = {
- { "None", "None", "None", "None", "None", "None", "None", "None" },
- { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
- { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" },
- { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" },
- { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }
- };
-
- int i;
- int sys;
- __u32 data = field->unit;
-
- /* First nibble tells us which system we're in. */
- sys = data & 0xf;
- data >>= 4;
-
- if(sys > 4) {
- tab(n); printk("Unit(Invalid)\n");
- }
- else {
- int earlier_unit = 0;
-
- tab(n); printk("Unit(%s : ", systems[sys]);
-
- for (i=1 ; i<sizeof(__u32)*2 ; i++) {
- char nibble = data & 0xf;
- data >>= 4;
- if (nibble != 0) {
- if(earlier_unit++ > 0)
- printk("*");
- printk("%s", units[sys][i]);
- if(nibble != 1) {
- /* This is a _signed_ nibble(!) */
-
- int val = nibble & 0x7;
- if(nibble & 0x08)
- val = -((0x7 & ~val) +1);
- printk("^%d", val);
- }
- }
- }
- printk(")\n");
- }
- }
- tab(n); printk("Report Size(%u)\n", field->report_size);
- tab(n); printk("Report Count(%u)\n", field->report_count);
- tab(n); printk("Report Offset(%u)\n", field->report_offset);
-
- tab(n); printk("Flags( ");
- j = field->flags;
- printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
- printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
- printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
- printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
- printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
- printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPrefferedState " : "");
- printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
- printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
- printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
- printk(")\n");
-}
-
-static void __attribute__((unused)) hid_dump_device(struct hid_device *device) {
- struct hid_report_enum *report_enum;
- struct hid_report *report;
- struct list_head *list;
- unsigned i,k;
- static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
-
- for (i = 0; i < HID_REPORT_TYPES; i++) {
- report_enum = device->report_enum + i;
- list = report_enum->report_list.next;
- while (list != &report_enum->report_list) {
- report = (struct hid_report *) list;
- tab(2);
- printk("%s", table[i]);
- if (report->id)
- printk("(%d)", report->id);
- printk("[%s]", table[report->type]);
- printk("\n");
- for (k = 0; k < report->maxfield; k++) {
- tab(4);
- printk("Field(%d)\n", k);
- hid_dump_field(report->field[k], 6);
- }
- list = list->next;
- }
- }
-}
-
-static void __attribute__((unused)) hid_dump_input(struct hid_usage *usage, __s32 value) {
- printk("hid-debug: input ");
- resolv_usage(usage->hid);
- printk(" = %d\n", value);
-}
-
-
-static char *events[EV_MAX + 1] = {
- [EV_SYN] = "Sync", [EV_KEY] = "Key",
- [EV_REL] = "Relative", [EV_ABS] = "Absolute",
- [EV_MSC] = "Misc", [EV_LED] = "LED",
- [EV_SND] = "Sound", [EV_REP] = "Repeat",
- [EV_FF] = "ForceFeedback", [EV_PWR] = "Power",
- [EV_FF_STATUS] = "ForceFeedbackStatus",
-};
-
-static char *syncs[2] = {
- [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config",
-};
-static char *keys[KEY_MAX + 1] = {
- [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc",
- [KEY_1] = "1", [KEY_2] = "2",
- [KEY_3] = "3", [KEY_4] = "4",
- [KEY_5] = "5", [KEY_6] = "6",
- [KEY_7] = "7", [KEY_8] = "8",
- [KEY_9] = "9", [KEY_0] = "0",
- [KEY_MINUS] = "Minus", [KEY_EQUAL] = "Equal",
- [KEY_BACKSPACE] = "Backspace", [KEY_TAB] = "Tab",
- [KEY_Q] = "Q", [KEY_W] = "W",
- [KEY_E] = "E", [KEY_R] = "R",
- [KEY_T] = "T", [KEY_Y] = "Y",
- [KEY_U] = "U", [KEY_I] = "I",
- [KEY_O] = "O", [KEY_P] = "P",
- [KEY_LEFTBRACE] = "LeftBrace", [KEY_RIGHTBRACE] = "RightBrace",
- [KEY_ENTER] = "Enter", [KEY_LEFTCTRL] = "LeftControl",
- [KEY_A] = "A", [KEY_S] = "S",
- [KEY_D] = "D", [KEY_F] = "F",
- [KEY_G] = "G", [KEY_H] = "H",
- [KEY_J] = "J", [KEY_K] = "K",
- [KEY_L] = "L", [KEY_SEMICOLON] = "Semicolon",
- [KEY_APOSTROPHE] = "Apostrophe", [KEY_GRAVE] = "Grave",
- [KEY_LEFTSHIFT] = "LeftShift", [KEY_BACKSLASH] = "BackSlash",
- [KEY_Z] = "Z", [KEY_X] = "X",
- [KEY_C] = "C", [KEY_V] = "V",
- [KEY_B] = "B", [KEY_N] = "N",
- [KEY_M] = "M", [KEY_COMMA] = "Comma",
- [KEY_DOT] = "Dot", [KEY_SLASH] = "Slash",
- [KEY_RIGHTSHIFT] = "RightShift", [KEY_KPASTERISK] = "KPAsterisk",
- [KEY_LEFTALT] = "LeftAlt", [KEY_SPACE] = "Space",
- [KEY_CAPSLOCK] = "CapsLock", [KEY_F1] = "F1",
- [KEY_F2] = "F2", [KEY_F3] = "F3",
- [KEY_F4] = "F4", [KEY_F5] = "F5",
- [KEY_F6] = "F6", [KEY_F7] = "F7",
- [KEY_F8] = "F8", [KEY_F9] = "F9",
- [KEY_F10] = "F10", [KEY_NUMLOCK] = "NumLock",
- [KEY_SCROLLLOCK] = "ScrollLock", [KEY_KP7] = "KP7",
- [KEY_KP8] = "KP8", [KEY_KP9] = "KP9",
- [KEY_KPMINUS] = "KPMinus", [KEY_KP4] = "KP4",
- [KEY_KP5] = "KP5", [KEY_KP6] = "KP6",
- [KEY_KPPLUS] = "KPPlus", [KEY_KP1] = "KP1",
- [KEY_KP2] = "KP2", [KEY_KP3] = "KP3",
- [KEY_KP0] = "KP0", [KEY_KPDOT] = "KPDot",
- [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd",
- [KEY_F11] = "F11", [KEY_F12] = "F12",
- [KEY_RO] = "RO", [KEY_KATAKANA] = "Katakana",
- [KEY_HIRAGANA] = "HIRAGANA", [KEY_HENKAN] = "Henkan",
- [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan",
- [KEY_KPJPCOMMA] = "KPJpComma", [KEY_KPENTER] = "KPEnter",
- [KEY_RIGHTCTRL] = "RightCtrl", [KEY_KPSLASH] = "KPSlash",
- [KEY_SYSRQ] = "SysRq", [KEY_RIGHTALT] = "RightAlt",
- [KEY_LINEFEED] = "LineFeed", [KEY_HOME] = "Home",
- [KEY_UP] = "Up", [KEY_PAGEUP] = "PageUp",
- [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right",
- [KEY_END] = "End", [KEY_DOWN] = "Down",
- [KEY_PAGEDOWN] = "PageDown", [KEY_INSERT] = "Insert",
- [KEY_DELETE] = "Delete", [KEY_MACRO] = "Macro",
- [KEY_MUTE] = "Mute", [KEY_VOLUMEDOWN] = "VolumeDown",
- [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power",
- [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus",
- [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma",
- [KEY_HANGUEL] = "Hanguel", [KEY_HANJA] = "Hanja",
- [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta",
- [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose",
- [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again",
- [KEY_PROPS] = "Props", [KEY_UNDO] = "Undo",
- [KEY_FRONT] = "Front", [KEY_COPY] = "Copy",
- [KEY_OPEN] = "Open", [KEY_PASTE] = "Paste",
- [KEY_FIND] = "Find", [KEY_CUT] = "Cut",
- [KEY_HELP] = "Help", [KEY_MENU] = "Menu",
- [KEY_CALC] = "Calc", [KEY_SETUP] = "Setup",
- [KEY_SLEEP] = "Sleep", [KEY_WAKEUP] = "WakeUp",
- [KEY_FILE] = "File", [KEY_SENDFILE] = "SendFile",
- [KEY_DELETEFILE] = "DeleteFile", [KEY_XFER] = "X-fer",
- [KEY_PROG1] = "Prog1", [KEY_PROG2] = "Prog2",
- [KEY_WWW] = "WWW", [KEY_MSDOS] = "MSDOS",
- [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction",
- [KEY_CYCLEWINDOWS] = "CycleWindows", [KEY_MAIL] = "Mail",
- [KEY_BOOKMARKS] = "Bookmarks", [KEY_COMPUTER] = "Computer",
- [KEY_BACK] = "Back", [KEY_FORWARD] = "Forward",
- [KEY_CLOSECD] = "CloseCD", [KEY_EJECTCD] = "EjectCD",
- [KEY_EJECTCLOSECD] = "EjectCloseCD", [KEY_NEXTSONG] = "NextSong",
- [KEY_PLAYPAUSE] = "PlayPause", [KEY_PREVIOUSSONG] = "PreviousSong",
- [KEY_STOPCD] = "StopCD", [KEY_RECORD] = "Record",
- [KEY_REWIND] = "Rewind", [KEY_PHONE] = "Phone",
- [KEY_ISO] = "ISOKey", [KEY_CONFIG] = "Config",
- [KEY_HOMEPAGE] = "HomePage", [KEY_REFRESH] = "Refresh",
- [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move",
- [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp",
- [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis",
- [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New",
- [KEY_REDO] = "Redo", [KEY_F13] = "F13",
- [KEY_F14] = "F14", [KEY_F15] = "F15",
- [KEY_F16] = "F16", [KEY_F17] = "F17",
- [KEY_F18] = "F18", [KEY_F19] = "F19",
- [KEY_F20] = "F20", [KEY_F21] = "F21",
- [KEY_F22] = "F22", [KEY_F23] = "F23",
- [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD",
- [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3",
- [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend",
- [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play",
- [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost",
- [KEY_PRINT] = "Print", [KEY_HP] = "HP",
- [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound",
- [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email",
- [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search",
- [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance",
- [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop",
- [KEY_ALTERASE] = "AlternateErase", [KEY_CANCEL] = "Cancel",
- [KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp",
- [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown",
- [BTN_0] = "Btn0", [BTN_1] = "Btn1",
- [BTN_2] = "Btn2", [BTN_3] = "Btn3",
- [BTN_4] = "Btn4", [BTN_5] = "Btn5",
- [BTN_6] = "Btn6", [BTN_7] = "Btn7",
- [BTN_8] = "Btn8", [BTN_9] = "Btn9",
- [BTN_LEFT] = "LeftBtn", [BTN_RIGHT] = "RightBtn",
- [BTN_MIDDLE] = "MiddleBtn", [BTN_SIDE] = "SideBtn",
- [BTN_EXTRA] = "ExtraBtn", [BTN_FORWARD] = "ForwardBtn",
- [BTN_BACK] = "BackBtn", [BTN_TASK] = "TaskBtn",
- [BTN_TRIGGER] = "Trigger", [BTN_THUMB] = "ThumbBtn",
- [BTN_THUMB2] = "ThumbBtn2", [BTN_TOP] = "TopBtn",
- [BTN_TOP2] = "TopBtn2", [BTN_PINKIE] = "PinkieBtn",
- [BTN_BASE] = "BaseBtn", [BTN_BASE2] = "BaseBtn2",
- [BTN_BASE3] = "BaseBtn3", [BTN_BASE4] = "BaseBtn4",
- [BTN_BASE5] = "BaseBtn5", [BTN_BASE6] = "BaseBtn6",
- [BTN_DEAD] = "BtnDead", [BTN_A] = "BtnA",
- [BTN_B] = "BtnB", [BTN_C] = "BtnC",
- [BTN_X] = "BtnX", [BTN_Y] = "BtnY",
- [BTN_Z] = "BtnZ", [BTN_TL] = "BtnTL",
- [BTN_TR] = "BtnTR", [BTN_TL2] = "BtnTL2",
- [BTN_TR2] = "BtnTR2", [BTN_SELECT] = "BtnSelect",
- [BTN_START] = "BtnStart", [BTN_MODE] = "BtnMode",
- [BTN_THUMBL] = "BtnThumbL", [BTN_THUMBR] = "BtnThumbR",
- [BTN_TOOL_PEN] = "ToolPen", [BTN_TOOL_RUBBER] = "ToolRubber",
- [BTN_TOOL_BRUSH] = "ToolBrush", [BTN_TOOL_PENCIL] = "ToolPencil",
- [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger",
- [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens",
- [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus",
- [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap",
- [BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn",
- [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok",
- [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto",
- [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2",
- [KEY_OPTION] = "Option", [KEY_INFO] = "Info",
- [KEY_TIME] = "Time", [KEY_VENDOR] = "Vendor",
- [KEY_ARCHIVE] = "Archive", [KEY_PROGRAM] = "Program",
- [KEY_CHANNEL] = "Channel", [KEY_FAVORITES] = "Favorites",
- [KEY_EPG] = "EPG", [KEY_PVR] = "PVR",
- [KEY_MHP] = "MHP", [KEY_LANGUAGE] = "Language",
- [KEY_TITLE] = "Title", [KEY_SUBTITLE] = "Subtitle",
- [KEY_ANGLE] = "Angle", [KEY_ZOOM] = "Zoom",
- [KEY_MODE] = "Mode", [KEY_KEYBOARD] = "Keyboard",
- [KEY_SCREEN] = "Screen", [KEY_PC] = "PC",
- [KEY_TV] = "TV", [KEY_TV2] = "TV2",
- [KEY_VCR] = "VCR", [KEY_VCR2] = "VCR2",
- [KEY_SAT] = "Sat", [KEY_SAT2] = "Sat2",
- [KEY_CD] = "CD", [KEY_TAPE] = "Tape",
- [KEY_RADIO] = "Radio", [KEY_TUNER] = "Tuner",
- [KEY_PLAYER] = "Player", [KEY_TEXT] = "Text",
- [KEY_DVD] = "DVD", [KEY_AUX] = "Aux",
- [KEY_MP3] = "MP3", [KEY_AUDIO] = "Audio",
- [KEY_VIDEO] = "Video", [KEY_DIRECTORY] = "Directory",
- [KEY_LIST] = "List", [KEY_MEMO] = "Memo",
- [KEY_CALENDAR] = "Calendar", [KEY_RED] = "Red",
- [KEY_GREEN] = "Green", [KEY_YELLOW] = "Yellow",
- [KEY_BLUE] = "Blue", [KEY_CHANNELUP] = "ChannelUp",
- [KEY_CHANNELDOWN] = "ChannelDown", [KEY_FIRST] = "First",
- [KEY_LAST] = "Last", [KEY_AB] = "AB",
- [KEY_NEXT] = "Next", [KEY_RESTART] = "Restart",
- [KEY_SLOW] = "Slow", [KEY_SHUFFLE] = "Shuffle",
- [KEY_BREAK] = "Break", [KEY_PREVIOUS] = "Previous",
- [KEY_DIGITS] = "Digits", [KEY_TEEN] = "TEEN",
- [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL",
- [KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine",
- [KEY_DEL_LINE] = "DeleteLine",
- [KEY_SEND] = "Send", [KEY_REPLY] = "Reply",
- [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save",
- [KEY_DOCUMENTS] = "Documents",
-};
-
-static char *relatives[REL_MAX + 1] = {
- [REL_X] = "X", [REL_Y] = "Y",
- [REL_Z] = "Z", [REL_HWHEEL] = "HWheel",
- [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel",
- [REL_MISC] = "Misc",
-};
-
-static char *absolutes[ABS_MAX + 1] = {
- [ABS_X] = "X", [ABS_Y] = "Y",
- [ABS_Z] = "Z", [ABS_RX] = "Rx",
- [ABS_RY] = "Ry", [ABS_RZ] = "Rz",
- [ABS_THROTTLE] = "Throttle", [ABS_RUDDER] = "Rudder",
- [ABS_WHEEL] = "Wheel", [ABS_GAS] = "Gas",
- [ABS_BRAKE] = "Brake", [ABS_HAT0X] = "Hat0X",
- [ABS_HAT0Y] = "Hat0Y", [ABS_HAT1X] = "Hat1X",
- [ABS_HAT1Y] = "Hat1Y", [ABS_HAT2X] = "Hat2X",
- [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X",
- [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure",
- [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt",
- [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "Tool Width",
- [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc",
-};
-
-static char *misc[MSC_MAX + 1] = {
- [MSC_SERIAL] = "Serial", [MSC_PULSELED] = "Pulseled",
- [MSC_GESTURE] = "Gesture", [MSC_RAW] = "RawData"
-};
-
-static char *leds[LED_MAX + 1] = {
- [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock",
- [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose",
- [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep",
- [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute",
- [LED_MISC] = "Misc",
-};
-
-static char *repeats[REP_MAX + 1] = {
- [REP_DELAY] = "Delay", [REP_PERIOD] = "Period"
-};
-
-static char *sounds[SND_MAX + 1] = {
- [SND_CLICK] = "Click", [SND_BELL] = "Bell",
- [SND_TONE] = "Tone"
-};
-
-static char **names[EV_MAX + 1] = {
- [EV_SYN] = syncs, [EV_KEY] = keys,
- [EV_REL] = relatives, [EV_ABS] = absolutes,
- [EV_MSC] = misc, [EV_LED] = leds,
- [EV_SND] = sounds, [EV_REP] = repeats,
-};
-
-static void __attribute__((unused)) resolv_event(__u8 type, __u16 code) {
-
- printk("%s.%s", events[type] ? events[type] : "?",
- names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
-}
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
deleted file mode 100644
index 72e698658b5..00000000000
--- a/drivers/usb/input/hid-ff.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * $Id: hid-ff.c,v 1.2 2002/04/18 22:02:47 jdeneux Exp $
- *
- * Force feedback support for hid devices.
- * Not all hid devices use the same protocol. For example, some use PID,
- * other use their own proprietary procotol.
- *
- * Copyright (c) 2002-2004 Johann Deneux
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <johann.deneux@it.uu.se>
- */
-
-#include <linux/input.h>
-
-#undef DEBUG
-#include <linux/usb.h>
-
-#include "hid.h"
-
-/* Drivers' initializing functions */
-extern int hid_lgff_init(struct hid_device* hid);
-extern int hid_lg3d_init(struct hid_device* hid);
-extern int hid_pid_init(struct hid_device* hid);
-extern int hid_tmff_init(struct hid_device* hid);
-
-/*
- * This table contains pointers to initializers. To add support for new
- * devices, you need to add the USB vendor and product ids here.
- */
-struct hid_ff_initializer {
- u16 idVendor;
- u16 idProduct;
- int (*init)(struct hid_device*);
-};
-
-static struct hid_ff_initializer inits[] = {
-#ifdef CONFIG_LOGITECH_FF
- {0x46d, 0xc211, hid_lgff_init}, // Logitech Cordless rumble pad
- {0x46d, 0xc283, hid_lgff_init}, // Logitech Wingman Force 3d
- {0x46d, 0xc295, hid_lgff_init}, // Logitech MOMO force wheel
- {0x46d, 0xc219, hid_lgff_init}, // Logitech Cordless rumble pad 2
-#endif
-#ifdef CONFIG_HID_PID
- {0x45e, 0x001b, hid_pid_init},
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF
- {0x44f, 0xb304, hid_tmff_init},
-#endif
- {0, 0, NULL} /* Terminating entry */
-};
-
-static struct hid_ff_initializer *hid_get_ff_init(__u16 idVendor,
- __u16 idProduct)
-{
- struct hid_ff_initializer *init;
- for (init = inits;
- init->idVendor
- && !(init->idVendor == idVendor
- && init->idProduct == idProduct);
- init++);
-
- return init->idVendor? init : NULL;
-}
-
-int hid_ff_init(struct hid_device* hid)
-{
- struct hid_ff_initializer *init;
-
- init = hid_get_ff_init(le16_to_cpu(hid->dev->descriptor.idVendor),
- le16_to_cpu(hid->dev->descriptor.idProduct));
-
- if (!init) {
- dbg("hid_ff_init could not find initializer");
- return -ENOSYS;
- }
- return init->init(hid);
-}
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
deleted file mode 100644
index 9ff25eb520a..00000000000
--- a/drivers/usb/input/hid-input.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * $Id: hid-input.c,v 1.2 2002/04/23 00:59:25 rdamazio Exp $
- *
- * Copyright (c) 2000-2001 Vojtech Pavlik
- *
- * USB HID to Linux Input mapping
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-#undef DEBUG
-
-#include "hid.h"
-
-#define unk KEY_UNKNOWN
-
-static unsigned char hid_keyboard[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
- 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
- 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
- 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
-};
-
-static struct {
- __s32 x;
- __s32 y;
-} hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
-
-#define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0)
-#define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0)
-#define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0)
-#define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0)
-#define map_ff(c) do { usage->code = c; usage->type = EV_FF; bit = input->ffbit; max = FF_MAX; } while (0)
-
-#define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0)
-#define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0)
-#define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0)
-
-static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
- struct hid_usage *usage)
-{
- struct input_dev *input = hidinput->input;
- struct hid_device *device = input->private;
- int max = 0, code;
- unsigned long *bit = NULL;
-
- field->hidinput = hidinput;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "Mapping: ");
- resolv_usage(usage->hid);
- printk(" ---> ");
-#endif
-
- if (field->flags & HID_MAIN_ITEM_CONSTANT)
- goto ignore;
-
- switch (usage->hid & HID_USAGE_PAGE) {
-
- case HID_UP_UNDEFINED:
- goto ignore;
-
- case HID_UP_KEYBOARD:
-
- set_bit(EV_REP, input->evbit);
-
- if ((usage->hid & HID_USAGE) < 256) {
- if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
- map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
- } else
- map_key(KEY_UNKNOWN);
-
- break;
-
- case HID_UP_BUTTON:
-
- code = ((usage->hid - 1) & 0xf);
-
- switch (field->application) {
- case HID_GD_MOUSE:
- case HID_GD_POINTER: code += 0x110; break;
- case HID_GD_JOYSTICK: code += 0x120; break;
- case HID_GD_GAMEPAD: code += 0x130; break;
- default:
- switch (field->physical) {
- case HID_GD_MOUSE:
- case HID_GD_POINTER: code += 0x110; break;
- case HID_GD_JOYSTICK: code += 0x120; break;
- case HID_GD_GAMEPAD: code += 0x130; break;
- default: code += 0x100;
- }
- }
-
- map_key(code);
- break;
-
-
- case HID_UP_SIMULATION:
-
- switch (usage->hid & 0xffff) {
- case 0xba: map_abs(ABS_RUDDER); break;
- case 0xbb: map_abs(ABS_THROTTLE); break;
- }
- break;
-
- case HID_UP_GENDESK:
-
- if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */
- switch (usage->hid & 0xf) {
- case 0x1: map_key_clear(KEY_POWER); break;
- case 0x2: map_key_clear(KEY_SLEEP); break;
- case 0x3: map_key_clear(KEY_WAKEUP); break;
- default: goto unknown;
- }
- break;
- }
-
- if ((usage->hid & 0xf0) == 0x90) { /* D-pad */
- switch (usage->hid) {
- case HID_GD_UP: usage->hat_dir = 1; break;
- case HID_GD_DOWN: usage->hat_dir = 5; break;
- case HID_GD_RIGHT: usage->hat_dir = 3; break;
- case HID_GD_LEFT: usage->hat_dir = 7; break;
- default: goto unknown;
- }
- if (field->dpad) {
- map_abs(field->dpad);
- goto ignore;
- }
- map_abs(ABS_HAT0X);
- break;
- }
-
- switch (usage->hid) {
-
- /* These usage IDs map directly to the usage codes. */
- case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
- case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
- case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
- if (field->flags & HID_MAIN_ITEM_RELATIVE)
- map_rel(usage->hid & 0xf);
- else
- map_abs(usage->hid & 0xf);
- break;
-
- case HID_GD_HATSWITCH:
- usage->hat_min = field->logical_minimum;
- usage->hat_max = field->logical_maximum;
- map_abs(ABS_HAT0X);
- break;
-
- case HID_GD_START: map_key_clear(BTN_START); break;
- case HID_GD_SELECT: map_key_clear(BTN_SELECT); break;
-
- default: goto unknown;
- }
-
- break;
-
- case HID_UP_LED:
- if (((usage->hid - 1) & 0xffff) >= LED_MAX)
- goto ignore;
- map_led((usage->hid - 1) & 0xffff);
- break;
-
- case HID_UP_DIGITIZER:
-
- switch (usage->hid & 0xff) {
-
- case 0x30: /* TipPressure */
- if (!test_bit(BTN_TOUCH, input->keybit)) {
- device->quirks |= HID_QUIRK_NOTOUCH;
- set_bit(EV_KEY, input->evbit);
- set_bit(BTN_TOUCH, input->keybit);
- }
-
- map_abs_clear(ABS_PRESSURE);
- break;
-
- case 0x32: /* InRange */
- switch (field->physical & 0xff) {
- case 0x21: map_key(BTN_TOOL_MOUSE); break;
- case 0x22: map_key(BTN_TOOL_FINGER); break;
- default: map_key(BTN_TOOL_PEN); break;
- }
- break;
-
- case 0x3c: /* Invert */
- map_key_clear(BTN_TOOL_RUBBER);
- break;
-
- case 0x33: /* Touch */
- case 0x42: /* TipSwitch */
- case 0x43: /* TipSwitch2 */
- device->quirks &= ~HID_QUIRK_NOTOUCH;
- map_key_clear(BTN_TOUCH);
- break;
-
- case 0x44: /* BarrelSwitch */
- map_key_clear(BTN_STYLUS);
- break;
-
- default: goto unknown;
- }
- break;
-
- case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */
-
- switch (usage->hid & HID_USAGE) {
- case 0x000: goto ignore;
- case 0x034: map_key_clear(KEY_SLEEP); break;
- case 0x036: map_key_clear(BTN_MISC); break;
- case 0x045: map_key_clear(KEY_RADIO); break;
- case 0x08a: map_key_clear(KEY_WWW); break;
- case 0x08d: map_key_clear(KEY_PROGRAM); break;
- case 0x095: map_key_clear(KEY_HELP); break;
- case 0x09c: map_key_clear(KEY_CHANNELUP); break;
- case 0x09d: map_key_clear(KEY_CHANNELDOWN); break;
- case 0x0b0: map_key_clear(KEY_PLAY); break;
- case 0x0b1: map_key_clear(KEY_PAUSE); break;
- case 0x0b2: map_key_clear(KEY_RECORD); break;
- case 0x0b3: map_key_clear(KEY_FASTFORWARD); break;
- case 0x0b4: map_key_clear(KEY_REWIND); break;
- case 0x0b5: map_key_clear(KEY_NEXTSONG); break;
- case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break;
- case 0x0b7: map_key_clear(KEY_STOPCD); break;
- case 0x0b8: map_key_clear(KEY_EJECTCD); break;
- case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
- case 0x0e0: map_abs_clear(ABS_VOLUME); break;
- case 0x0e2: map_key_clear(KEY_MUTE); break;
- case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
- case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
- case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
- case 0x183: map_key_clear(KEY_CONFIG); break;
- case 0x18a: map_key_clear(KEY_MAIL); break;
- case 0x192: map_key_clear(KEY_CALC); break;
- case 0x194: map_key_clear(KEY_FILE); break;
- case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
- case 0x201: map_key_clear(KEY_NEW); break;
- case 0x207: map_key_clear(KEY_SAVE); break;
- case 0x208: map_key_clear(KEY_PRINT); break;
- case 0x209: map_key_clear(KEY_PROPS); break;
- case 0x21a: map_key_clear(KEY_UNDO); break;
- case 0x21b: map_key_clear(KEY_COPY); break;
- case 0x21c: map_key_clear(KEY_CUT); break;
- case 0x21d: map_key_clear(KEY_PASTE); break;
- case 0x221: map_key_clear(KEY_FIND); break;
- case 0x223: map_key_clear(KEY_HOMEPAGE); break;
- case 0x224: map_key_clear(KEY_BACK); break;
- case 0x225: map_key_clear(KEY_FORWARD); break;
- case 0x226: map_key_clear(KEY_STOP); break;
- case 0x227: map_key_clear(KEY_REFRESH); break;
- case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
- case 0x238: map_rel(REL_HWHEEL); break;
- case 0x279: map_key_clear(KEY_REDO); break;
- case 0x289: map_key_clear(KEY_REPLY); break;
- case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
- case 0x28c: map_key_clear(KEY_SEND); break;
- default: goto ignore;
- }
- break;
-
- case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
-
- set_bit(EV_REP, input->evbit);
- switch (usage->hid & HID_USAGE) {
- case 0x021: map_key_clear(KEY_PRINT); break;
- case 0x070: map_key_clear(KEY_HP); break;
- case 0x071: map_key_clear(KEY_CAMERA); break;
- case 0x072: map_key_clear(KEY_SOUND); break;
- case 0x073: map_key_clear(KEY_QUESTION); break;
- case 0x080: map_key_clear(KEY_EMAIL); break;
- case 0x081: map_key_clear(KEY_CHAT); break;
- case 0x082: map_key_clear(KEY_SEARCH); break;
- case 0x083: map_key_clear(KEY_CONNECT); break;
- case 0x084: map_key_clear(KEY_FINANCE); break;
- case 0x085: map_key_clear(KEY_SPORT); break;
- case 0x086: map_key_clear(KEY_SHOP); break;
- default: goto ignore;
- }
- break;
-
- case HID_UP_MSVENDOR:
- goto ignore;
-
- case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */
-
- set_bit(EV_REP, input->evbit);
- switch(usage->hid & HID_USAGE) {
- case 0x003: map_key_clear(KEY_FN); break;
- default: goto ignore;
- }
- break;
-
- case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */
-
- set_bit(EV_REP, input->evbit);
- switch(usage->hid & HID_USAGE) {
- case 0x004: map_key_clear(KEY_AGAIN); break;
- case 0x00d: map_key_clear(KEY_HOME); break;
- case 0x024: map_key_clear(KEY_SHUFFLE); break;
- case 0x025: map_key_clear(KEY_TV); break;
- case 0x026: map_key_clear(KEY_MENU); break;
- case 0x031: map_key_clear(KEY_AUDIO); break;
- case 0x032: map_key_clear(KEY_SUBTITLE); break;
- case 0x033: map_key_clear(KEY_LAST); break;
- case 0x047: map_key_clear(KEY_MP3); break;
- case 0x048: map_key_clear(KEY_DVD); break;
- case 0x049: map_key_clear(KEY_MEDIA); break;
- case 0x04a: map_key_clear(KEY_VIDEO); break;
- case 0x04b: map_key_clear(KEY_ANGLE); break;
- case 0x04c: map_key_clear(KEY_LANGUAGE); break;
- case 0x04d: map_key_clear(KEY_SUBTITLE); break;
- case 0x051: map_key_clear(KEY_RED); break;
- case 0x052: map_key_clear(KEY_CLOSE); break;
- default: goto ignore;
- }
- break;
-
- case HID_UP_PID:
-
- set_bit(EV_FF, input->evbit);
- switch(usage->hid & HID_USAGE) {
- case 0x26: map_ff_effect(FF_CONSTANT); goto ignore;
- case 0x27: map_ff_effect(FF_RAMP); goto ignore;
- case 0x28: map_ff_effect(FF_CUSTOM); goto ignore;
- case 0x30: map_ff_effect(FF_SQUARE); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x31: map_ff_effect(FF_SINE); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x32: map_ff_effect(FF_TRIANGLE); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x33: map_ff_effect(FF_SAW_UP); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x34: map_ff_effect(FF_SAW_DOWN); map_ff_effect(FF_PERIODIC); goto ignore;
- case 0x40: map_ff_effect(FF_SPRING); goto ignore;
- case 0x41: map_ff_effect(FF_DAMPER); goto ignore;
- case 0x42: map_ff_effect(FF_INERTIA); goto ignore;
- case 0x43: map_ff_effect(FF_FRICTION); goto ignore;
- case 0x7e: map_ff(FF_GAIN); break;
- case 0x83: input->ff_effects_max = field->value[0]; goto ignore;
- case 0x98: map_ff(FF_AUTOCENTER); break;
- case 0xa4: map_key_clear(BTN_DEAD); break;
- default: goto ignore;
- }
- break;
-
- default:
- unknown:
- if (field->report_size == 1) {
- if (field->report->type == HID_OUTPUT_REPORT) {
- map_led(LED_MISC);
- break;
- }
- map_key(BTN_MISC);
- break;
- }
- if (field->flags & HID_MAIN_ITEM_RELATIVE) {
- map_rel(REL_MISC);
- break;
- }
- map_abs(ABS_MISC);
- break;
- }
-
- set_bit(usage->type, input->evbit);
-
- while (usage->code <= max && test_and_set_bit(usage->code, bit))
- usage->code = find_next_zero_bit(bit, max + 1, usage->code);
-
- if (usage->code > max)
- goto ignore;
-
- if (((device->quirks & (HID_QUIRK_2WHEEL_POWERMOUSE)) && (usage->hid == 0x00010032)))
- map_rel(REL_HWHEEL);
-
- if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
- (usage->type == EV_REL) && (usage->code == REL_WHEEL))
- set_bit(REL_HWHEEL, bit);
-
- if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
- || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
- goto ignore;
-
- if (usage->type == EV_ABS) {
-
- int a = field->logical_minimum;
- int b = field->logical_maximum;
-
- if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) {
- a = field->logical_minimum = 0;
- b = field->logical_maximum = 255;
- }
-
- if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
- input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
- else input_set_abs_params(input, usage->code, a, b, 0, 0);
-
- }
-
- if (usage->hat_min < usage->hat_max || usage->hat_dir) {
- int i;
- for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
- input_set_abs_params(input, i, -1, 1, 0, 0);
- set_bit(i, input->absbit);
- }
- if (usage->hat_dir && !field->dpad)
- field->dpad = usage->code;
- }
-
-#ifdef DEBUG
- resolv_event(usage->type, usage->code);
- printk("\n");
-#endif
- return;
-
-ignore:
-#ifdef DEBUG
- printk("IGNORED\n");
-#endif
- return;
-}
-
-void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
-{
- struct input_dev *input;
- int *quirks = &hid->quirks;
-
- if (!field->hidinput)
- return;
-
- input = field->hidinput->input;
-
- input_regs(input, regs);
-
- if (!usage->type)
- return;
-
- if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
- || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) {
- if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
- else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
- return;
- }
-
- if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
- input_event(input, usage->type, REL_HWHEEL, value);
- return;
- }
-
- if (usage->hat_min < usage->hat_max || usage->hat_dir) {
- int hat_dir = usage->hat_dir;
- if (!hat_dir)
- hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
- if (hat_dir < 0 || hat_dir > 8) hat_dir = 0;
- input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x);
- input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y);
- return;
- }
-
- if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
- *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
- return;
- }
-
- if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
- if (value) {
- input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
- return;
- }
- input_event(input, usage->type, usage->code, 0);
- input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
- return;
- }
-
- if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */
- int a = field->logical_minimum;
- int b = field->logical_maximum;
- input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
- }
-
- if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
- input->ff_effects_max = value;
- dbg("Maximum Effects - %d",input->ff_effects_max);
- return;
- }
-
- if (usage->hid == (HID_UP_PID | 0x7fUL)) {
- dbg("PID Pool Report\n");
- return;
- }
-
- if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
- return;
-
- input_event(input, usage->type, usage->code, value);
-
- if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY))
- input_event(input, usage->type, usage->code, 0);
-}
-
-void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
-{
- struct hid_input *hidinput;
-
- list_for_each_entry(hidinput, &hid->inputs, list)
- input_sync(hidinput->input);
-}
-
-static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
-{
- struct hid_report *report;
- int i, j;
-
- list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
- for (i = 0; i < report->maxfield; i++) {
- *field = report->field[i];
- for (j = 0; j < (*field)->maxusage; j++)
- if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
- return j;
- }
- }
- return -1;
-}
-
-static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-{
- struct hid_device *hid = dev->private;
- struct hid_field *field;
- int offset;
-
- if (type == EV_FF)
- return hid_ff_event(hid, dev, type, code, value);
-
- if (type != EV_LED)
- return -1;
-
- if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
- warn("event field not found");
- return -1;
- }
-
- hid_set_field(field, offset, value);
- hid_submit_report(hid, field->report, USB_DIR_OUT);
-
- return 0;
-}
-
-static int hidinput_open(struct input_dev *dev)
-{
- struct hid_device *hid = dev->private;
- return hid_open(hid);
-}
-
-static void hidinput_close(struct input_dev *dev)
-{
- struct hid_device *hid = dev->private;
- hid_close(hid);
-}
-
-/*
- * Register the input device; print a message.
- * Configure the input layer interface
- * Read all reports and initialize the absolute field values.
- */
-
-int hidinput_connect(struct hid_device *hid)
-{
- struct usb_device *dev = hid->dev;
- struct hid_report *report;
- struct hid_input *hidinput = NULL;
- struct input_dev *input_dev;
- int i, j, k;
-
- INIT_LIST_HEAD(&hid->inputs);
-
- for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
- hid->collection[i].type == HID_COLLECTION_PHYSICAL)
- if (IS_INPUT_APPLICATION(hid->collection[i].usage))
- break;
-
- if (i == hid->maxcollection)
- return -1;
-
- for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++)
- list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
-
- if (!report->maxfield)
- continue;
-
- if (!hidinput) {
- hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!hidinput || !input_dev) {
- kfree(hidinput);
- input_free_device(input_dev);
- err("Out of memory during hid input probe");
- return -1;
- }
-
- input_dev->private = hid;
- input_dev->event = hidinput_input_event;
- input_dev->open = hidinput_open;
- input_dev->close = hidinput_close;
-
- input_dev->name = hid->name;
- input_dev->phys = hid->phys;
- input_dev->uniq = hid->uniq;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->cdev.dev = &hid->intf->dev;
-
- hidinput->input = input_dev;
- list_add_tail(&hidinput->list, &hid->inputs);
- }
-
- for (i = 0; i < report->maxfield; i++)
- for (j = 0; j < report->field[i]->maxusage; j++)
- hidinput_configure_usage(hidinput, report->field[i],
- report->field[i]->usage + j);
-
- if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
- /* This will leave hidinput NULL, so that it
- * allocates another one if we have more inputs on
- * the same interface. Some devices (e.g. Happ's
- * UGCI) cram a lot of unrelated inputs into the
- * same interface. */
- hidinput->report = report;
- input_register_device(hidinput->input);
- hidinput = NULL;
- }
- }
-
- /* This only gets called when we are a single-input (most of the
- * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is
- * only useful in this case, and not for multi-input quirks. */
- if (hidinput) {
- hid_ff_init(hid);
- input_register_device(hidinput->input);
- }
-
- return 0;
-}
-
-void hidinput_disconnect(struct hid_device *hid)
-{
- struct hid_input *hidinput, *next;
-
- list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
- list_del(&hidinput->list);
- input_unregister_device(hidinput->input);
- kfree(hidinput);
- }
-}
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
deleted file mode 100644
index f82c9c9e5d5..00000000000
--- a/drivers/usb/input/hid-lgff.c
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * $$
- *
- * Force feedback support for hid-compliant for some of the devices from
- * Logitech, namely:
- * - WingMan Cordless RumblePad
- * - WingMan Force 3D
- *
- * Copyright (c) 2002-2004 Johann Deneux
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <johann.deneux@it.uu.se>
- */
-
-#include <linux/input.h>
-#include <linux/sched.h>
-
-//#define DEBUG
-#include <linux/usb.h>
-
-#include <linux/circ_buf.h>
-
-#include "hid.h"
-#include "fixp-arith.h"
-
-
-/* Periodicity of the update */
-#define PERIOD (HZ/10)
-
-#define RUN_AT(t) (jiffies + (t))
-
-/* Effect status */
-#define EFFECT_STARTED 0 /* Effect is going to play after some time
- (ff_replay.delay) */
-#define EFFECT_PLAYING 1 /* Effect is being played */
-#define EFFECT_USED 2
-
-// For lgff_device::flags
-#define DEVICE_CLOSING 0 /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
- || effect.owner == current->pid)
-
-#define LGFF_CHECK_OWNERSHIP(i, l) \
- (i>=0 && i<LGFF_EFFECTS \
- && test_bit(EFFECT_USED, l->effects[i].flags) \
- && CHECK_OWNERSHIP(l->effects[i]))
-
-#define LGFF_EFFECTS 8
-
-struct device_type {
- u16 idVendor;
- u16 idProduct;
- signed short *ff;
-};
-
-struct lgff_effect {
- pid_t owner;
-
- struct ff_effect effect;
-
- unsigned long flags[1];
- unsigned int count; /* Number of times left to play */
- unsigned long started_at; /* When the effect started to play */
-};
-
-struct lgff_device {
- struct hid_device* hid;
-
- struct hid_report* constant;
- struct hid_report* rumble;
- struct hid_report* condition;
-
- struct lgff_effect effects[LGFF_EFFECTS];
- spinlock_t lock; /* device-level lock. Having locks on
- a per-effect basis could be nice, but
- isn't really necessary */
-
- unsigned long flags[1]; /* Contains various information about the
- state of the driver for this device */
-
- struct timer_list timer;
-};
-
-/* Callbacks */
-static void hid_lgff_exit(struct hid_device* hid);
-static int hid_lgff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value);
-static int hid_lgff_flush(struct input_dev *input, struct file *file);
-static int hid_lgff_upload_effect(struct input_dev *input,
- struct ff_effect *effect);
-static int hid_lgff_erase(struct input_dev *input, int id);
-
-/* Local functions */
-static void hid_lgff_input_init(struct hid_device* hid);
-static void hid_lgff_timer(unsigned long timer_data);
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report*);
-static void hid_lgff_delete_report(struct hid_report*);
-
-static signed short ff_rumble[] = {
- FF_RUMBLE,
- -1
-};
-
-static signed short ff_joystick[] = {
- FF_CONSTANT,
- -1
-};
-
-static struct device_type devices[] = {
- {0x046d, 0xc211, ff_rumble},
- {0x046d, 0xc219, ff_rumble},
- {0x046d, 0xc283, ff_joystick},
- {0x0000, 0x0000, ff_joystick}
-};
-
-int hid_lgff_init(struct hid_device* hid)
-{
- struct lgff_device *private;
- struct hid_report* report;
- struct hid_field* field;
-
- /* Find the report to use */
- if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
- err("No output report found");
- return -1;
- }
- /* Check that the report looks ok */
- report = (struct hid_report*)hid->report_enum[HID_OUTPUT_REPORT].report_list.next;
- if (!report) {
- err("NULL output report");
- return -1;
- }
- field = report->field[0];
- if (!field) {
- err("NULL field");
- return -1;
- }
-
- private = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
- if (!private)
- return -1;
- memset(private, 0, sizeof(struct lgff_device));
- hid->ff_private = private;
-
- /* Input init */
- hid_lgff_input_init(hid);
-
-
- private->constant = hid_lgff_duplicate_report(report);
- if (!private->constant) {
- kfree(private);
- return -1;
- }
- private->constant->field[0]->value[0] = 0x51;
- private->constant->field[0]->value[1] = 0x08;
- private->constant->field[0]->value[2] = 0x7f;
- private->constant->field[0]->value[3] = 0x7f;
-
- private->rumble = hid_lgff_duplicate_report(report);
- if (!private->rumble) {
- hid_lgff_delete_report(private->constant);
- kfree(private);
- return -1;
- }
- private->rumble->field[0]->value[0] = 0x42;
-
-
- private->condition = hid_lgff_duplicate_report(report);
- if (!private->condition) {
- hid_lgff_delete_report(private->rumble);
- hid_lgff_delete_report(private->constant);
- kfree(private);
- return -1;
- }
-
- private->hid = hid;
-
- spin_lock_init(&private->lock);
- init_timer(&private->timer);
- private->timer.data = (unsigned long)private;
- private->timer.function = hid_lgff_timer;
-
- /* Event and exit callbacks */
- hid->ff_exit = hid_lgff_exit;
- hid->ff_event = hid_lgff_event;
-
- /* Start the update task */
- private->timer.expires = RUN_AT(PERIOD);
- add_timer(&private->timer); /*TODO: only run the timer when at least
- one effect is playing */
-
- printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
-
- return 0;
-}
-
-static struct hid_report* hid_lgff_duplicate_report(struct hid_report* report)
-{
- struct hid_report* ret;
-
- ret = kmalloc(sizeof(struct lgff_device), GFP_KERNEL);
- if (!ret)
- return NULL;
- *ret = *report;
-
- ret->field[0] = kmalloc(sizeof(struct hid_field), GFP_KERNEL);
- if (!ret->field[0]) {
- kfree(ret);
- return NULL;
- }
- *ret->field[0] = *report->field[0];
-
- ret->field[0]->value = kmalloc(sizeof(s32[8]), GFP_KERNEL);
- if (!ret->field[0]->value) {
- kfree(ret->field[0]);
- kfree(ret);
- return NULL;
- }
- memset(ret->field[0]->value, 0, sizeof(s32[8]));
-
- return ret;
-}
-
-static void hid_lgff_delete_report(struct hid_report* report)
-{
- if (report) {
- kfree(report->field[0]->value);
- kfree(report->field[0]);
- kfree(report);
- }
-}
-
-static void hid_lgff_input_init(struct hid_device* hid)
-{
- struct device_type* dev = devices;
- signed short* ff;
- u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
- u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
-
- while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
- dev++;
-
- for (ff = dev->ff; *ff >= 0; ff++)
- set_bit(*ff, input_dev->ffbit);
-
- input_dev->upload_effect = hid_lgff_upload_effect;
- input_dev->flush = hid_lgff_flush;
-
- set_bit(EV_FF, input_dev->evbit);
- input_dev->ff_effects_max = LGFF_EFFECTS;
-}
-
-static void hid_lgff_exit(struct hid_device* hid)
-{
- struct lgff_device *lgff = hid->ff_private;
-
- set_bit(DEVICE_CLOSING, lgff->flags);
- del_timer_sync(&lgff->timer);
-
- hid_lgff_delete_report(lgff->condition);
- hid_lgff_delete_report(lgff->rumble);
- hid_lgff_delete_report(lgff->constant);
-
- kfree(lgff);
-}
-
-static int hid_lgff_event(struct hid_device *hid, struct input_dev* input,
- unsigned int type, unsigned int code, int value)
-{
- struct lgff_device *lgff = hid->ff_private;
- struct lgff_effect *effect = lgff->effects + code;
- unsigned long flags;
-
- if (type != EV_FF) return -EINVAL;
- if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
- if (value < 0) return -EINVAL;
-
- spin_lock_irqsave(&lgff->lock, flags);
-
- if (value > 0) {
- if (test_bit(EFFECT_STARTED, effect->flags)) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -EBUSY;
- }
- if (test_bit(EFFECT_PLAYING, effect->flags)) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -EBUSY;
- }
-
- effect->count = value;
-
- if (effect->effect.replay.delay) {
- set_bit(EFFECT_STARTED, effect->flags);
- } else {
- set_bit(EFFECT_PLAYING, effect->flags);
- }
- effect->started_at = jiffies;
- }
- else { /* value == 0 */
- clear_bit(EFFECT_STARTED, effect->flags);
- clear_bit(EFFECT_PLAYING, effect->flags);
- }
-
- spin_unlock_irqrestore(&lgff->lock, flags);
-
- return 0;
-
-}
-
-/* Erase all effects this process owns */
-static int hid_lgff_flush(struct input_dev *dev, struct file *file)
-{
- struct hid_device *hid = dev->private;
- struct lgff_device *lgff = hid->ff_private;
- int i;
-
- for (i=0; i<dev->ff_effects_max; ++i) {
-
- /*NOTE: no need to lock here. The only times EFFECT_USED is
- modified is when effects are uploaded or when an effect is
- erased. But a process cannot close its dev/input/eventX fd
- and perform ioctls on the same fd all at the same time */
- if ( current->pid == lgff->effects[i].owner
- && test_bit(EFFECT_USED, lgff->effects[i].flags)) {
-
- if (hid_lgff_erase(dev, i))
- warn("erase effect %d failed", i);
- }
-
- }
-
- return 0;
-}
-
-static int hid_lgff_erase(struct input_dev *dev, int id)
-{
- struct hid_device *hid = dev->private;
- struct lgff_device *lgff = hid->ff_private;
- unsigned long flags;
-
- if (!LGFF_CHECK_OWNERSHIP(id, lgff)) return -EACCES;
-
- spin_lock_irqsave(&lgff->lock, flags);
- lgff->effects[id].flags[0] = 0;
- spin_unlock_irqrestore(&lgff->lock, flags);
-
- return 0;
-}
-
-static int hid_lgff_upload_effect(struct input_dev* input,
- struct ff_effect* effect)
-{
- struct hid_device *hid = input->private;
- struct lgff_device *lgff = hid->ff_private;
- struct lgff_effect new;
- int id;
- unsigned long flags;
-
- dbg("ioctl rumble");
-
- if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
-
- spin_lock_irqsave(&lgff->lock, flags);
-
- if (effect->id == -1) {
- int i;
-
- for (i=0; i<LGFF_EFFECTS && test_bit(EFFECT_USED, lgff->effects[i].flags); ++i);
- if (i >= LGFF_EFFECTS) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -ENOSPC;
- }
-
- effect->id = i;
- lgff->effects[i].owner = current->pid;
- lgff->effects[i].flags[0] = 0;
- set_bit(EFFECT_USED, lgff->effects[i].flags);
- }
- else if (!LGFF_CHECK_OWNERSHIP(effect->id, lgff)) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -EACCES;
- }
-
- id = effect->id;
- new = lgff->effects[id];
-
- new.effect = *effect;
-
- if (test_bit(EFFECT_STARTED, lgff->effects[id].flags)
- || test_bit(EFFECT_STARTED, lgff->effects[id].flags)) {
-
- /* Changing replay parameters is not allowed (for the time
- being) */
- if (new.effect.replay.delay != lgff->effects[id].effect.replay.delay
- || new.effect.replay.length != lgff->effects[id].effect.replay.length) {
- spin_unlock_irqrestore(&lgff->lock, flags);
- return -ENOSYS;
- }
-
- lgff->effects[id] = new;
-
- } else {
- lgff->effects[id] = new;
- }
-
- spin_unlock_irqrestore(&lgff->lock, flags);
- return 0;
-}
-
-static void hid_lgff_timer(unsigned long timer_data)
-{
- struct lgff_device *lgff = (struct lgff_device*)timer_data;
- struct hid_device *hid = lgff->hid;
- unsigned long flags;
- int x = 0x7f, y = 0x7f; // Coordinates of constant effects
- unsigned int left = 0, right = 0; // Rumbling
- int i;
-
- spin_lock_irqsave(&lgff->lock, flags);
-
- for (i=0; i<LGFF_EFFECTS; ++i) {
- struct lgff_effect* effect = lgff->effects +i;
-
- if (test_bit(EFFECT_PLAYING, effect->flags)) {
-
- switch (effect->effect.type) {
- case FF_CONSTANT: {
- //TODO: handle envelopes
- int degrees = effect->effect.direction * 360 >> 16;
- x += fixp_mult(fixp_sin(degrees),
- fixp_new16(effect->effect.u.constant.level));
- y += fixp_mult(-fixp_cos(degrees),
- fixp_new16(effect->effect.u.constant.level));
- } break;
- case FF_RUMBLE:
- right += effect->effect.u.rumble.strong_magnitude;
- left += effect->effect.u.rumble.weak_magnitude;
- break;
- };
-
- /* One run of the effect is finished playing */
- if (time_after(jiffies,
- effect->started_at
- + effect->effect.replay.delay*HZ/1000
- + effect->effect.replay.length*HZ/1000)) {
- dbg("Finished playing once %d", i);
- if (--effect->count <= 0) {
- dbg("Stopped %d", i);
- clear_bit(EFFECT_PLAYING, effect->flags);
- }
- else {
- dbg("Start again %d", i);
- if (effect->effect.replay.length != 0) {
- clear_bit(EFFECT_PLAYING, effect->flags);
- set_bit(EFFECT_STARTED, effect->flags);
- }
- effect->started_at = jiffies;
- }
- }
-
- } else if (test_bit(EFFECT_STARTED, lgff->effects[i].flags)) {
- /* Check if we should start playing the effect */
- if (time_after(jiffies,
- lgff->effects[i].started_at
- + lgff->effects[i].effect.replay.delay*HZ/1000)) {
- dbg("Now playing %d", i);
- clear_bit(EFFECT_STARTED, lgff->effects[i].flags);
- set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
- }
- }
- }
-
-#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
-
- // Clamp values
- CLAMP(x);
- CLAMP(y);
- CLAMP(left);
- CLAMP(right);
-
-#undef CLAMP
-
- if (x != lgff->constant->field[0]->value[2]
- || y != lgff->constant->field[0]->value[3]) {
- lgff->constant->field[0]->value[2] = x;
- lgff->constant->field[0]->value[3] = y;
- dbg("(x,y)=(%04x, %04x)", x, y);
- hid_submit_report(hid, lgff->constant, USB_DIR_OUT);
- }
-
- if (left != lgff->rumble->field[0]->value[2]
- || right != lgff->rumble->field[0]->value[3]) {
- lgff->rumble->field[0]->value[2] = left;
- lgff->rumble->field[0]->value[3] = right;
- dbg("(left,right)=(%04x, %04x)", left, right);
- hid_submit_report(hid, lgff->rumble, USB_DIR_OUT);
- }
-
- if (!test_bit(DEVICE_CLOSING, lgff->flags)) {
- lgff->timer.expires = RUN_AT(PERIOD);
- add_timer(&lgff->timer);
- }
-
- spin_unlock_irqrestore(&lgff->lock, flags);
-}
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
deleted file mode 100644
index 023fd5ac31c..00000000000
--- a/drivers/usb/input/hid-tmff.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Force feedback support for various HID compliant devices by ThrustMaster:
- * ThrustMaster FireStorm Dual Power 2
- * and possibly others whose device ids haven't been added.
- *
- * Modified to support ThrustMaster devices by Zinx Verituse
- * on 2003-01-25 from the Logitech force feedback driver,
- * which is by Johann Deneux.
- *
- * Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
- * Copyright (c) 2002 Johann Deneux
- */
-
-/*
- * 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/input.h>
-#include <linux/sched.h>
-
-#undef DEBUG
-#include <linux/usb.h>
-
-#include <linux/circ_buf.h>
-
-#include "hid.h"
-#include "fixp-arith.h"
-
-/* Usages for thrustmaster devices I know about */
-#define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb)
-#define DELAY_CALC(t,delay) ((t) + (delay)*HZ/1000)
-
-/* Effect status */
-#define EFFECT_STARTED 0 /* Effect is going to play after some time */
-#define EFFECT_PLAYING 1 /* Effect is playing */
-#define EFFECT_USED 2
-
-/* For tmff_device::flags */
-#define DEVICE_CLOSING 0 /* The driver is being unitialised */
-
-/* Check that the current process can access an effect */
-#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
- || effect.owner == current->pid)
-
-#define TMFF_CHECK_ID(id) ((id) >= 0 && (id) < TMFF_EFFECTS)
-
-#define TMFF_CHECK_OWNERSHIP(i, l) \
- (test_bit(EFFECT_USED, l->effects[i].flags) \
- && CHECK_OWNERSHIP(l->effects[i]))
-
-#define TMFF_EFFECTS 8
-
-struct tmff_effect {
- pid_t owner;
-
- struct ff_effect effect;
-
- unsigned long flags[1];
- unsigned int count; /* Number of times left to play */
-
- unsigned long play_at; /* When the effect starts to play */
- unsigned long stop_at; /* When the effect ends */
-};
-
-struct tmff_device {
- struct hid_device *hid;
-
- struct hid_report *report;
-
- struct hid_field *rumble;
-
- unsigned int effects_playing;
- struct tmff_effect effects[TMFF_EFFECTS];
- spinlock_t lock; /* device-level lock. Having locks on
- a per-effect basis could be nice, but
- isn't really necessary */
-
- unsigned long flags[1]; /* Contains various information about the
- state of the driver for this device */
-
- struct timer_list timer;
-};
-
-/* Callbacks */
-static void hid_tmff_exit(struct hid_device *hid);
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value);
-static int hid_tmff_flush(struct input_dev *input, struct file *file);
-static int hid_tmff_upload_effect(struct input_dev *input,
- struct ff_effect *effect);
-static int hid_tmff_erase(struct input_dev *input, int id);
-
-/* Local functions */
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff);
-static void hid_tmff_timer(unsigned long timer_data);
-
-int hid_tmff_init(struct hid_device *hid)
-{
- struct tmff_device *private;
- struct list_head *pos;
- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
-
- private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
- if (!private)
- return -ENOMEM;
-
- memset(private, 0, sizeof(struct tmff_device));
- hid->ff_private = private;
-
- /* Find the report to use */
- __list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
- struct hid_report *report = (struct hid_report *)pos;
- int fieldnum;
-
- for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
- struct hid_field *field = report->field[fieldnum];
-
- if (field->maxusage <= 0)
- continue;
-
- switch (field->usage[0].hid) {
- case THRUSTMASTER_USAGE_RUMBLE_LR:
- if (field->report_count < 2) {
- warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with report_count < 2");
- continue;
- }
-
- if (field->logical_maximum == field->logical_minimum) {
- warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with logical_maximum == logical_minimum");
- continue;
- }
-
- if (private->report && private->report != report) {
- warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report");
- continue;
- }
-
- if (private->rumble && private->rumble != field) {
- warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR");
- continue;
- }
-
- private->report = report;
- private->rumble = field;
-
- set_bit(FF_RUMBLE, input_dev->ffbit);
- break;
-
- default:
- warn("ignoring unknown output usage %08x", field->usage[0].hid);
- continue;
- }
-
- /* Fallthrough to here only when a valid usage is found */
- input_dev->upload_effect = hid_tmff_upload_effect;
- input_dev->flush = hid_tmff_flush;
-
- set_bit(EV_FF, input_dev->evbit);
- input_dev->ff_effects_max = TMFF_EFFECTS;
- }
- }
-
- private->hid = hid;
-
- spin_lock_init(&private->lock);
- init_timer(&private->timer);
- private->timer.data = (unsigned long)private;
- private->timer.function = hid_tmff_timer;
-
- /* Event and exit callbacks */
- hid->ff_exit = hid_tmff_exit;
- hid->ff_event = hid_tmff_event;
-
- info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
-
- return 0;
-}
-
-static void hid_tmff_exit(struct hid_device *hid)
-{
- struct tmff_device *tmff = hid->ff_private;
- unsigned long flags;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- set_bit(DEVICE_CLOSING, tmff->flags);
- del_timer_sync(&tmff->timer);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-
- kfree(tmff);
-}
-
-static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value)
-{
- struct tmff_device *tmff = hid->ff_private;
- struct tmff_effect *effect = &tmff->effects[code];
- unsigned long flags;
-
- if (type != EV_FF)
- return -EINVAL;
- if (!TMFF_CHECK_ID(code))
- return -EINVAL;
- if (!TMFF_CHECK_OWNERSHIP(code, tmff))
- return -EACCES;
- if (value < 0)
- return -EINVAL;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- if (value > 0) {
- set_bit(EFFECT_STARTED, effect->flags);
- clear_bit(EFFECT_PLAYING, effect->flags);
- effect->count = value;
- effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
- } else {
- clear_bit(EFFECT_STARTED, effect->flags);
- clear_bit(EFFECT_PLAYING, effect->flags);
- }
-
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-
- return 0;
-
-}
-
-/* Erase all effects this process owns */
-
-static int hid_tmff_flush(struct input_dev *dev, struct file *file)
-{
- struct hid_device *hid = dev->private;
- struct tmff_device *tmff = hid->ff_private;
- int i;
-
- for (i=0; i<dev->ff_effects_max; ++i)
-
- /* NOTE: no need to lock here. The only times EFFECT_USED is
- modified is when effects are uploaded or when an effect is
- erased. But a process cannot close its dev/input/eventX fd
- and perform ioctls on the same fd all at the same time */
-
- if (current->pid == tmff->effects[i].owner
- && test_bit(EFFECT_USED, tmff->effects[i].flags))
- if (hid_tmff_erase(dev, i))
- warn("erase effect %d failed", i);
-
-
- return 0;
-}
-
-static int hid_tmff_erase(struct input_dev *dev, int id)
-{
- struct hid_device *hid = dev->private;
- struct tmff_device *tmff = hid->ff_private;
- unsigned long flags;
-
- if (!TMFF_CHECK_ID(id))
- return -EINVAL;
- if (!TMFF_CHECK_OWNERSHIP(id, tmff))
- return -EACCES;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- tmff->effects[id].flags[0] = 0;
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-
- return 0;
-}
-
-static int hid_tmff_upload_effect(struct input_dev *input,
- struct ff_effect *effect)
-{
- struct hid_device *hid = input->private;
- struct tmff_device *tmff = hid->ff_private;
- int id;
- unsigned long flags;
-
- if (!test_bit(effect->type, input->ffbit))
- return -EINVAL;
- if (effect->id != -1 && !TMFF_CHECK_ID(effect->id))
- return -EINVAL;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- if (effect->id == -1) {
- /* Find a free effect */
- for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id);
-
- if (id >= TMFF_EFFECTS) {
- spin_unlock_irqrestore(&tmff->lock, flags);
- return -ENOSPC;
- }
-
- effect->id = id;
- tmff->effects[id].owner = current->pid;
- tmff->effects[id].flags[0] = 0;
- set_bit(EFFECT_USED, tmff->effects[id].flags);
-
- } else {
- /* Re-uploading an owned effect, to change parameters */
- id = effect->id;
- clear_bit(EFFECT_PLAYING, tmff->effects[id].flags);
- }
-
- tmff->effects[id].effect = *effect;
-
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
- return 0;
-}
-
-/* Start the timer for the next start/stop/delay */
-/* Always call this while tmff->lock is locked */
-
-static void hid_tmff_recalculate_timer(struct tmff_device *tmff)
-{
- int i;
- int events = 0;
- unsigned long next_time;
-
- next_time = 0; /* Shut up compiler's incorrect warning */
-
- /* Find the next change in an effect's status */
- for (i = 0; i < TMFF_EFFECTS; ++i) {
- struct tmff_effect *effect = &tmff->effects[i];
- unsigned long play_time;
-
- if (!test_bit(EFFECT_STARTED, effect->flags))
- continue;
-
- effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length);
-
- if (!test_bit(EFFECT_PLAYING, effect->flags))
- play_time = effect->play_at;
- else
- play_time = effect->stop_at;
-
- events++;
-
- if (time_after(jiffies, play_time))
- play_time = jiffies;
-
- if (events == 1)
- next_time = play_time;
- else {
- if (time_after(next_time, play_time))
- next_time = play_time;
- }
- }
-
- if (!events && tmff->effects_playing) {
- /* Treat all effects turning off as an event */
- events = 1;
- next_time = jiffies;
- }
-
- if (!events) {
- /* No events, no time, no need for a timer. */
- del_timer_sync(&tmff->timer);
- return;
- }
-
- mod_timer(&tmff->timer, next_time);
-}
-
-/* Changes values from 0 to 0xffff into values from minimum to maximum */
-static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
-{
- int ret;
-
- ret = (in * (maximum - minimum) / 0xffff) + minimum;
- if (ret < minimum)
- return minimum;
- if (ret > maximum)
- return maximum;
- return ret;
-}
-
-static void hid_tmff_timer(unsigned long timer_data)
-{
- struct tmff_device *tmff = (struct tmff_device *) timer_data;
- struct hid_device *hid = tmff->hid;
- unsigned long flags;
- int left = 0, right = 0; /* Rumbling */
- int i;
-
- spin_lock_irqsave(&tmff->lock, flags);
-
- tmff->effects_playing = 0;
-
- for (i = 0; i < TMFF_EFFECTS; ++i) {
- struct tmff_effect *effect = &tmff->effects[i];
-
- if (!test_bit(EFFECT_STARTED, effect->flags))
- continue;
-
- if (!time_after(jiffies, effect->play_at))
- continue;
-
- if (time_after(jiffies, effect->stop_at)) {
-
- dbg("Finished playing once %d", i);
- clear_bit(EFFECT_PLAYING, effect->flags);
-
- if (--effect->count <= 0) {
- dbg("Stopped %d", i);
- clear_bit(EFFECT_STARTED, effect->flags);
- continue;
- } else {
- dbg("Start again %d", i);
- effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
- continue;
- }
- }
-
- ++tmff->effects_playing;
-
- set_bit(EFFECT_PLAYING, effect->flags);
-
- switch (effect->effect.type) {
- case FF_RUMBLE:
- right += effect->effect.u.rumble.strong_magnitude;
- left += effect->effect.u.rumble.weak_magnitude;
- break;
- default:
- BUG();
- break;
- }
- }
-
- left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
- right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
-
- if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) {
- tmff->rumble->value[0] = left;
- tmff->rumble->value[1] = right;
- dbg("(left,right)=(%08x, %08x)", left, right);
- hid_submit_report(hid, tmff->report, USB_DIR_OUT);
- }
-
- if (!test_bit(DEVICE_CLOSING, tmff->flags))
- hid_tmff_recalculate_timer(tmff);
-
- spin_unlock_irqrestore(&tmff->lock, flags);
-}
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
deleted file mode 100644
index ee48a227610..00000000000
--- a/drivers/usb/input/hid.h
+++ /dev/null
@@ -1,517 +0,0 @@
-#ifndef __HID_H
-#define __HID_H
-
-/*
- * $Id: hid.h,v 1.24 2001/12/27 10:37:41 vojtech Exp $
- *
- * Copyright (c) 1999 Andreas Gal
- * Copyright (c) 2000-2001 Vojtech Pavlik
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/list.h>
-
-/*
- * USB HID (Human Interface Device) interface class code
- */
-
-#define USB_INTERFACE_CLASS_HID 3
-
-/*
- * HID class requests
- */
-
-#define HID_REQ_GET_REPORT 0x01
-#define HID_REQ_GET_IDLE 0x02
-#define HID_REQ_GET_PROTOCOL 0x03
-#define HID_REQ_SET_REPORT 0x09
-#define HID_REQ_SET_IDLE 0x0A
-#define HID_REQ_SET_PROTOCOL 0x0B
-
-/*
- * HID class descriptor types
- */
-
-#define HID_DT_HID (USB_TYPE_CLASS | 0x01)
-#define HID_DT_REPORT (USB_TYPE_CLASS | 0x02)
-#define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
-
-/*
- * We parse each description item into this structure. Short items data
- * values are expanded to 32-bit signed int, long items contain a pointer
- * into the data area.
- */
-
-struct hid_item {
- unsigned format;
- __u8 size;
- __u8 type;
- __u8 tag;
- union {
- __u8 u8;
- __s8 s8;
- __u16 u16;
- __s16 s16;
- __u32 u32;
- __s32 s32;
- __u8 *longdata;
- } data;
-};
-
-/*
- * HID report item format
- */
-
-#define HID_ITEM_FORMAT_SHORT 0
-#define HID_ITEM_FORMAT_LONG 1
-
-/*
- * Special tag indicating long items
- */
-
-#define HID_ITEM_TAG_LONG 15
-
-/*
- * HID report descriptor item type (prefix bit 2,3)
- */
-
-#define HID_ITEM_TYPE_MAIN 0
-#define HID_ITEM_TYPE_GLOBAL 1
-#define HID_ITEM_TYPE_LOCAL 2
-#define HID_ITEM_TYPE_RESERVED 3
-
-/*
- * HID report descriptor main item tags
- */
-
-#define HID_MAIN_ITEM_TAG_INPUT 8
-#define HID_MAIN_ITEM_TAG_OUTPUT 9
-#define HID_MAIN_ITEM_TAG_FEATURE 11
-#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
-#define HID_MAIN_ITEM_TAG_END_COLLECTION 12
-
-/*
- * HID report descriptor main item contents
- */
-
-#define HID_MAIN_ITEM_CONSTANT 0x001
-#define HID_MAIN_ITEM_VARIABLE 0x002
-#define HID_MAIN_ITEM_RELATIVE 0x004
-#define HID_MAIN_ITEM_WRAP 0x008
-#define HID_MAIN_ITEM_NONLINEAR 0x010
-#define HID_MAIN_ITEM_NO_PREFERRED 0x020
-#define HID_MAIN_ITEM_NULL_STATE 0x040
-#define HID_MAIN_ITEM_VOLATILE 0x080
-#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
-
-/*
- * HID report descriptor collection item types
- */
-
-#define HID_COLLECTION_PHYSICAL 0
-#define HID_COLLECTION_APPLICATION 1
-#define HID_COLLECTION_LOGICAL 2
-
-/*
- * HID report descriptor global item tags
- */
-
-#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
-#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
-#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
-#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
-#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
-#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
-#define HID_GLOBAL_ITEM_TAG_UNIT 6
-#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
-#define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
-#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
-#define HID_GLOBAL_ITEM_TAG_PUSH 10
-#define HID_GLOBAL_ITEM_TAG_POP 11
-
-/*
- * HID report descriptor local item tags
- */
-
-#define HID_LOCAL_ITEM_TAG_USAGE 0
-#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
-#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
-#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
-#define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
-#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
-#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
-#define HID_LOCAL_ITEM_TAG_DELIMITER 10
-
-/*
- * HID usage tables
- */
-
-#define HID_USAGE_PAGE 0xffff0000
-
-#define HID_UP_UNDEFINED 0x00000000
-#define HID_UP_GENDESK 0x00010000
-#define HID_UP_SIMULATION 0x00020000
-#define HID_UP_KEYBOARD 0x00070000
-#define HID_UP_LED 0x00080000
-#define HID_UP_BUTTON 0x00090000
-#define HID_UP_ORDINAL 0x000a0000
-#define HID_UP_CONSUMER 0x000c0000
-#define HID_UP_DIGITIZER 0x000d0000
-#define HID_UP_PID 0x000f0000
-#define HID_UP_HPVENDOR 0xff7f0000
-#define HID_UP_MSVENDOR 0xff000000
-#define HID_UP_CUSTOM 0x00ff0000
-#define HID_UP_LOGIVENDOR 0xffbc0000
-
-#define HID_USAGE 0x0000ffff
-
-#define HID_GD_POINTER 0x00010001
-#define HID_GD_MOUSE 0x00010002
-#define HID_GD_JOYSTICK 0x00010004
-#define HID_GD_GAMEPAD 0x00010005
-#define HID_GD_KEYBOARD 0x00010006
-#define HID_GD_KEYPAD 0x00010007
-#define HID_GD_MULTIAXIS 0x00010008
-#define HID_GD_X 0x00010030
-#define HID_GD_Y 0x00010031
-#define HID_GD_Z 0x00010032
-#define HID_GD_RX 0x00010033
-#define HID_GD_RY 0x00010034
-#define HID_GD_RZ 0x00010035
-#define HID_GD_SLIDER 0x00010036
-#define HID_GD_DIAL 0x00010037
-#define HID_GD_WHEEL 0x00010038
-#define HID_GD_HATSWITCH 0x00010039
-#define HID_GD_BUFFER 0x0001003a
-#define HID_GD_BYTECOUNT 0x0001003b
-#define HID_GD_MOTION 0x0001003c
-#define HID_GD_START 0x0001003d
-#define HID_GD_SELECT 0x0001003e
-#define HID_GD_VX 0x00010040
-#define HID_GD_VY 0x00010041
-#define HID_GD_VZ 0x00010042
-#define HID_GD_VBRX 0x00010043
-#define HID_GD_VBRY 0x00010044
-#define HID_GD_VBRZ 0x00010045
-#define HID_GD_VNO 0x00010046
-#define HID_GD_FEATURE 0x00010047
-#define HID_GD_UP 0x00010090
-#define HID_GD_DOWN 0x00010091
-#define HID_GD_RIGHT 0x00010092
-#define HID_GD_LEFT 0x00010093
-
-/*
- * HID report types --- Ouch! HID spec says 1 2 3!
- */
-
-#define HID_INPUT_REPORT 0
-#define HID_OUTPUT_REPORT 1
-#define HID_FEATURE_REPORT 2
-
-/*
- * HID device quirks.
- */
-
-#define HID_QUIRK_INVERT 0x001
-#define HID_QUIRK_NOTOUCH 0x002
-#define HID_QUIRK_IGNORE 0x004
-#define HID_QUIRK_NOGET 0x008
-#define HID_QUIRK_HIDDEV 0x010
-#define HID_QUIRK_BADPAD 0x020
-#define HID_QUIRK_MULTI_INPUT 0x040
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100
-#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200
-#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400
-
-/*
- * This is the global environment of the parser. This information is
- * persistent for main-items. The global environment can be saved and
- * restored with PUSH/POP statements.
- */
-
-struct hid_global {
- unsigned usage_page;
- __s32 logical_minimum;
- __s32 logical_maximum;
- __s32 physical_minimum;
- __s32 physical_maximum;
- __s32 unit_exponent;
- unsigned unit;
- unsigned report_id;
- unsigned report_size;
- unsigned report_count;
-};
-
-/*
- * This is the local environment. It is persistent up the next main-item.
- */
-
-#define HID_MAX_DESCRIPTOR_SIZE 4096
-#define HID_MAX_USAGES 1024
-#define HID_DEFAULT_NUM_COLLECTIONS 16
-
-struct hid_local {
- unsigned usage[HID_MAX_USAGES]; /* usage array */
- unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
- unsigned usage_index;
- unsigned usage_minimum;
- unsigned delimiter_depth;
- unsigned delimiter_branch;
-};
-
-/*
- * This is the collection stack. We climb up the stack to determine
- * application and function of each field.
- */
-
-struct hid_collection {
- unsigned type;
- unsigned usage;
- unsigned level;
-};
-
-struct hid_usage {
- unsigned hid; /* hid usage code */
- unsigned collection_index; /* index into collection array */
- /* hidinput data */
- __u16 code; /* input driver code */
- __u8 type; /* input driver type */
- __s8 hat_min; /* hat switch fun */
- __s8 hat_max; /* ditto */
- __s8 hat_dir; /* ditto */
-};
-
-struct hid_input;
-
-struct hid_field {
- unsigned physical; /* physical usage for this field */
- unsigned logical; /* logical usage for this field */
- unsigned application; /* application usage for this field */
- struct hid_usage *usage; /* usage table for this function */
- unsigned maxusage; /* maximum usage index */
- unsigned flags; /* main-item flags (i.e. volatile,array,constant) */
- unsigned report_offset; /* bit offset in the report */
- unsigned report_size; /* size of this field in the report */
- unsigned report_count; /* number of this field in the report */
- unsigned report_type; /* (input,output,feature) */
- __s32 *value; /* last known value(s) */
- __s32 logical_minimum;
- __s32 logical_maximum;
- __s32 physical_minimum;
- __s32 physical_maximum;
- __s32 unit_exponent;
- unsigned unit;
- struct hid_report *report; /* associated report */
- unsigned index; /* index into report->field[] */
- /* hidinput data */
- struct hid_input *hidinput; /* associated input structure */
- __u16 dpad; /* dpad input code */
-};
-
-#define HID_MAX_FIELDS 64
-
-struct hid_report {
- struct list_head list;
- unsigned id; /* id of this report */
- unsigned type; /* report type */
- struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
- unsigned maxfield; /* maximum valid field index */
- unsigned size; /* size of the report (bits) */
- struct hid_device *device; /* associated device */
-};
-
-struct hid_report_enum {
- unsigned numbered;
- struct list_head report_list;
- struct hid_report *report_id_hash[256];
-};
-
-#define HID_REPORT_TYPES 3
-
-#define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
-#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
-#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
-#define HID_OUTPUT_FIFO_SIZE 64
-
-struct hid_control_fifo {
- unsigned char dir;
- struct hid_report *report;
-};
-
-#define HID_CLAIMED_INPUT 1
-#define HID_CLAIMED_HIDDEV 2
-
-#define HID_CTRL_RUNNING 1
-#define HID_OUT_RUNNING 2
-
-struct hid_input {
- struct list_head list;
- struct hid_report *report;
- struct input_dev *input;
-};
-
-struct hid_device { /* device report descriptor */
- __u8 *rdesc;
- unsigned rsize;
- struct hid_collection *collection; /* List of HID collections */
- unsigned collection_size; /* Number of allocated hid_collections */
- unsigned maxcollection; /* Number of parsed collections */
- unsigned maxapplication; /* Number of applications */
- unsigned version; /* HID version */
- unsigned country; /* HID country */
- struct hid_report_enum report_enum[HID_REPORT_TYPES];
-
- struct usb_device *dev; /* USB device */
- struct usb_interface *intf; /* USB interface */
- int ifnum; /* USB interface number */
-
- unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
-
- unsigned int bufsize; /* URB buffer size */
-
- struct urb *urbin; /* Input URB */
- char *inbuf; /* Input buffer */
- dma_addr_t inbuf_dma; /* Input buffer dma */
-
- struct urb *urbctrl; /* Control URB */
- struct usb_ctrlrequest *cr; /* Control request struct */
- dma_addr_t cr_dma; /* Control request struct dma */
- struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
- unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
- char *ctrlbuf; /* Control buffer */
- dma_addr_t ctrlbuf_dma; /* Control buffer dma */
- spinlock_t ctrllock; /* Control fifo spinlock */
-
- struct urb *urbout; /* Output URB */
- struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
- unsigned char outhead, outtail; /* Output pipe fifo head & tail */
- char *outbuf; /* Output buffer */
- dma_addr_t outbuf_dma; /* Output buffer dma */
- spinlock_t outlock; /* Output fifo spinlock */
-
- unsigned claimed; /* Claimed by hidinput, hiddev? */
- unsigned quirks; /* Various quirks the device can pull on us */
-
- struct list_head inputs; /* The list of inputs */
- void *hiddev; /* The hiddev structure */
- int minor; /* Hiddev minor number */
-
- wait_queue_head_t wait; /* For sleeping */
-
- int open; /* is the device open by anyone? */
- char name[128]; /* Device name */
- char phys[64]; /* Device physical location */
- char uniq[64]; /* Device unique identifier (serial #) */
-
- void *ff_private; /* Private data for the force-feedback driver */
- void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */
- int (*ff_event)(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value);
-};
-
-#define HID_GLOBAL_STACK_SIZE 4
-#define HID_COLLECTION_STACK_SIZE 4
-
-struct hid_parser {
- struct hid_global global;
- struct hid_global global_stack[HID_GLOBAL_STACK_SIZE];
- unsigned global_stack_ptr;
- struct hid_local local;
- unsigned collection_stack[HID_COLLECTION_STACK_SIZE];
- unsigned collection_stack_ptr;
- struct hid_device *device;
-};
-
-struct hid_class_descriptor {
- __u8 bDescriptorType;
- __u16 wDescriptorLength;
-} __attribute__ ((packed));
-
-struct hid_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u16 bcdHID;
- __u8 bCountryCode;
- __u8 bNumDescriptors;
-
- struct hid_class_descriptor desc[1];
-} __attribute__ ((packed));
-
-#ifdef DEBUG
-#include "hid-debug.h"
-#else
-#define hid_dump_input(a,b) do { } while (0)
-#define hid_dump_device(c) do { } while (0)
-#define hid_dump_field(a,b) do { } while (0)
-#define resolv_usage(a) do { } while (0)
-#define resolv_event(a,b) do { } while (0)
-#endif
-
-#endif
-
-#ifdef CONFIG_USB_HIDINPUT
-/* Applications from HID Usage Tables 4/8/99 Version 1.1 */
-/* We ignore a few input applications that are not widely used */
-#define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001))
-extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs);
-extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
-extern int hidinput_connect(struct hid_device *);
-extern void hidinput_disconnect(struct hid_device *);
-#else
-#define IS_INPUT_APPLICATION(a) (0)
-static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
-static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { }
-static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
-static inline void hidinput_disconnect(struct hid_device *hid) { }
-#endif
-
-int hid_open(struct hid_device *);
-void hid_close(struct hid_device *);
-int hid_set_field(struct hid_field *, unsigned, __s32);
-void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir);
-void hid_init_reports(struct hid_device *hid);
-struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type);
-int hid_wait_io(struct hid_device* hid);
-
-
-#ifdef CONFIG_HID_FF
-int hid_ff_init(struct hid_device *hid);
-#else
-static inline int hid_ff_init(struct hid_device *hid) { return -1; }
-#endif
-static inline void hid_ff_exit(struct hid_device *hid)
-{
- if (hid->ff_exit)
- hid->ff_exit(hid);
-}
-static inline int hid_ff_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value)
-{
- if (hid->ff_event)
- return hid->ff_event(hid, input, type, code, value);
- return -ENOSYS;
-}
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
deleted file mode 100644
index 440377c7a0d..00000000000
--- a/drivers/usb/input/hiddev.c
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- * Copyright (c) 2001 Paul Stewart
- * Copyright (c) 2001 Vojtech Pavlik
- *
- * HID char devices, giving access to raw HID device events.
- *
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
- */
-
-#include <linux/config.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include "hid.h"
-#include <linux/hiddev.h>
-#include <linux/devfs_fs_kernel.h>
-
-#ifdef CONFIG_USB_DYNAMIC_MINORS
-#define HIDDEV_MINOR_BASE 0
-#define HIDDEV_MINORS 256
-#else
-#define HIDDEV_MINOR_BASE 96
-#define HIDDEV_MINORS 16
-#endif
-#define HIDDEV_BUFFER_SIZE 64
-
-struct hiddev {
- int exist;
- int open;
- wait_queue_head_t wait;
- struct hid_device *hid;
- struct hiddev_list *list;
-};
-
-struct hiddev_list {
- struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
- int head;
- int tail;
- unsigned flags;
- struct fasync_struct *fasync;
- struct hiddev *hiddev;
- struct hiddev_list *next;
-};
-
-static struct hiddev *hiddev_table[HIDDEV_MINORS];
-
-/*
- * Find a report, given the report's type and ID. The ID can be specified
- * indirectly by REPORT_ID_FIRST (which returns the first report of the given
- * type) or by (REPORT_ID_NEXT | old_id), which returns the next report of the
- * given type which follows old_id.
- */
-static struct hid_report *
-hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
-{
- unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
- struct hid_report_enum *report_enum;
- struct list_head *list;
-
- if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
- rinfo->report_type > HID_REPORT_TYPE_MAX) return NULL;
-
- report_enum = hid->report_enum +
- (rinfo->report_type - HID_REPORT_TYPE_MIN);
-
- switch (flags) {
- case 0: /* Nothing to do -- report_id is already set correctly */
- break;
-
- case HID_REPORT_ID_FIRST:
- list = report_enum->report_list.next;
- if (list == &report_enum->report_list)
- return NULL;
- rinfo->report_id = ((struct hid_report *) list)->id;
- break;
-
- case HID_REPORT_ID_NEXT:
- list = (struct list_head *)
- report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK];
- if (list == NULL)
- return NULL;
- list = list->next;
- if (list == &report_enum->report_list)
- return NULL;
- rinfo->report_id = ((struct hid_report *) list)->id;
- break;
-
- default:
- return NULL;
- }
-
- return report_enum->report_id_hash[rinfo->report_id];
-}
-
-/*
- * Perform an exhaustive search of the report table for a usage, given its
- * type and usage id.
- */
-static struct hid_field *
-hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
-{
- int i, j;
- struct hid_report *report;
- struct hid_report_enum *report_enum;
- struct hid_field *field;
-
- if (uref->report_type < HID_REPORT_TYPE_MIN ||
- uref->report_type > HID_REPORT_TYPE_MAX) return NULL;
-
- report_enum = hid->report_enum +
- (uref->report_type - HID_REPORT_TYPE_MIN);
-
- list_for_each_entry(report, &report_enum->report_list, list)
- for (i = 0; i < report->maxfield; i++) {
- field = report->field[i];
- for (j = 0; j < field->maxusage; j++) {
- if (field->usage[j].hid == uref->usage_code) {
- uref->report_id = report->id;
- uref->field_index = i;
- uref->usage_index = j;
- return field;
- }
- }
- }
-
- return NULL;
-}
-
-static void hiddev_send_event(struct hid_device *hid,
- struct hiddev_usage_ref *uref)
-{
- struct hiddev *hiddev = hid->hiddev;
- struct hiddev_list *list = hiddev->list;
-
- while (list) {
- if (uref->field_index != HID_FIELD_INDEX_NONE ||
- (list->flags & HIDDEV_FLAG_REPORT) != 0) {
- list->buffer[list->head] = *uref;
- list->head = (list->head + 1) &
- (HIDDEV_BUFFER_SIZE - 1);
- kill_fasync(&list->fasync, SIGIO, POLL_IN);
- }
-
- list = list->next;
- }
-
- wake_up_interruptible(&hiddev->wait);
-}
-
-/*
- * This is where hid.c calls into hiddev to pass an event that occurred over
- * the interrupt pipe
- */
-void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
- struct hid_usage *usage, __s32 value, struct pt_regs *regs)
-{
- unsigned type = field->report_type;
- struct hiddev_usage_ref uref;
-
- uref.report_type =
- (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
- ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
- ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
- uref.report_id = field->report->id;
- uref.field_index = field->index;
- uref.usage_index = (usage - field->usage);
- uref.usage_code = usage->hid;
- uref.value = value;
-
- hiddev_send_event(hid, &uref);
-}
-
-
-void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
-{
- unsigned type = report->type;
- struct hiddev_usage_ref uref;
-
- memset(&uref, 0, sizeof(uref));
- uref.report_type =
- (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
- ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
- ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
- uref.report_id = report->id;
- uref.field_index = HID_FIELD_INDEX_NONE;
-
- hiddev_send_event(hid, &uref);
-}
-/*
- * fasync file op
- */
-static int hiddev_fasync(int fd, struct file *file, int on)
-{
- int retval;
- struct hiddev_list *list = file->private_data;
- retval = fasync_helper(fd, file, on, &list->fasync);
- return retval < 0 ? retval : 0;
-}
-
-
-/*
- * release file op
- */
-static int hiddev_release(struct inode * inode, struct file * file)
-{
- struct hiddev_list *list = file->private_data;
- struct hiddev_list **listptr;
-
- listptr = &list->hiddev->list;
- hiddev_fasync(-1, file, 0);
-
- while (*listptr && (*listptr != list))
- listptr = &((*listptr)->next);
- *listptr = (*listptr)->next;
-
- if (!--list->hiddev->open) {
- if (list->hiddev->exist)
- hid_close(list->hiddev->hid);
- else
- kfree(list->hiddev);
- }
-
- kfree(list);
-
- return 0;
-}
-
-/*
- * open file op
- */
-static int hiddev_open(struct inode * inode, struct file * file) {
- struct hiddev_list *list;
-
- int i = iminor(inode) - HIDDEV_MINOR_BASE;
-
- if (i >= HIDDEV_MINORS || !hiddev_table[i])
- return -ENODEV;
-
- if (!(list = kmalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
- return -ENOMEM;
- memset(list, 0, sizeof(struct hiddev_list));
-
- list->hiddev = hiddev_table[i];
- list->next = hiddev_table[i]->list;
- hiddev_table[i]->list = list;
-
- file->private_data = list;
-
- if (!list->hiddev->open++)
- if (list->hiddev->exist)
- hid_open(hiddev_table[i]->hid);
-
- return 0;
-}
-
-/*
- * "write" file op
- */
-static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
-{
- return -EINVAL;
-}
-
-/*
- * "read" file op
- */
-static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
-{
- DECLARE_WAITQUEUE(wait, current);
- struct hiddev_list *list = file->private_data;
- int event_size;
- int retval = 0;
-
- event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
- sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
-
- if (count < event_size)
- return 0;
-
- while (retval == 0) {
- if (list->head == list->tail) {
- add_wait_queue(&list->hiddev->wait, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- while (list->head == list->tail) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
- if (!list->hiddev->exist) {
- retval = -EIO;
- break;
- }
-
- schedule();
- }
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&list->hiddev->wait, &wait);
- }
-
- if (retval)
- return retval;
-
-
- while (list->head != list->tail &&
- retval + event_size <= count) {
- if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
- if (list->buffer[list->tail].field_index !=
- HID_FIELD_INDEX_NONE) {
- struct hiddev_event event;
- event.hid = list->buffer[list->tail].usage_code;
- event.value = list->buffer[list->tail].value;
- if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event)))
- return -EFAULT;
- retval += sizeof(struct hiddev_event);
- }
- } else {
- if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
- (list->flags & HIDDEV_FLAG_REPORT) != 0) {
- if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref)))
- return -EFAULT;
- retval += sizeof(struct hiddev_usage_ref);
- }
- }
- list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
- }
-
- }
-
- return retval;
-}
-
-/*
- * "poll" file op
- * No kernel lock - fine
- */
-static unsigned int hiddev_poll(struct file *file, poll_table *wait)
-{
- struct hiddev_list *list = file->private_data;
- poll_wait(file, &list->hiddev->wait, wait);
- if (list->head != list->tail)
- return POLLIN | POLLRDNORM;
- if (!list->hiddev->exist)
- return POLLERR | POLLHUP;
- return 0;
-}
-
-/*
- * "ioctl" file op
- */
-static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct hiddev_list *list = file->private_data;
- struct hiddev *hiddev = list->hiddev;
- struct hid_device *hid = hiddev->hid;
- struct usb_device *dev = hid->dev;
- struct hiddev_collection_info cinfo;
- struct hiddev_report_info rinfo;
- struct hiddev_field_info finfo;
- struct hiddev_usage_ref_multi *uref_multi=NULL;
- struct hiddev_usage_ref *uref;
- struct hiddev_devinfo dinfo;
- struct hid_report *report;
- struct hid_field *field;
- void __user *user_arg = (void __user *)arg;
- int i;
-
- if (!hiddev->exist)
- return -EIO;
-
- switch (cmd) {
-
- case HIDIOCGVERSION:
- return put_user(HID_VERSION, (int __user *)arg);
-
- case HIDIOCAPPLICATION:
- if (arg < 0 || arg >= hid->maxapplication)
- return -EINVAL;
-
- for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type ==
- HID_COLLECTION_APPLICATION && arg-- == 0)
- break;
-
- if (i == hid->maxcollection)
- return -EINVAL;
-
- return hid->collection[i].usage;
-
- case HIDIOCGDEVINFO:
- dinfo.bustype = BUS_USB;
- dinfo.busnum = dev->bus->busnum;
- dinfo.devnum = dev->devnum;
- dinfo.ifnum = hid->ifnum;
- dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
- dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
- dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
- dinfo.num_applications = hid->maxapplication;
- if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
- return -EFAULT;
-
- return 0;
-
- case HIDIOCGFLAG:
- if (put_user(list->flags, (int __user *)arg))
- return -EFAULT;
-
- return 0;
-
- case HIDIOCSFLAG:
- {
- int newflags;
- if (get_user(newflags, (int __user *)arg))
- return -EFAULT;
-
- if ((newflags & ~HIDDEV_FLAGS) != 0 ||
- ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
- (newflags & HIDDEV_FLAG_UREF) == 0))
- return -EINVAL;
-
- list->flags = newflags;
-
- return 0;
- }
-
- case HIDIOCGSTRING:
- {
- int idx, len;
- char *buf;
-
- if (get_user(idx, (int __user *)arg))
- return -EFAULT;
-
- if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
- return -ENOMEM;
-
- if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
- kfree(buf);
- return -EINVAL;
- }
-
- if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
- kfree(buf);
- return -EFAULT;
- }
-
- kfree(buf);
-
- return len;
- }
-
- case HIDIOCINITREPORT:
- hid_init_reports(hid);
-
- return 0;
-
- case HIDIOCGREPORT:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
- return -EFAULT;
-
- if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
- return -EINVAL;
-
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
-
- hid_submit_report(hid, report, USB_DIR_IN);
- hid_wait_io(hid);
-
- return 0;
-
- case HIDIOCSREPORT:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
- return -EFAULT;
-
- if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
- return -EINVAL;
-
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
-
- hid_submit_report(hid, report, USB_DIR_OUT);
- hid_wait_io(hid);
-
- return 0;
-
- case HIDIOCGREPORTINFO:
- if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
- return -EFAULT;
-
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
-
- rinfo.num_fields = report->maxfield;
-
- if (copy_to_user(user_arg, &rinfo, sizeof(rinfo)))
- return -EFAULT;
-
- return 0;
-
- case HIDIOCGFIELDINFO:
- if (copy_from_user(&finfo, user_arg, sizeof(finfo)))
- return -EFAULT;
- rinfo.report_type = finfo.report_type;
- rinfo.report_id = finfo.report_id;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- return -EINVAL;
-
- if (finfo.field_index >= report->maxfield)
- return -EINVAL;
-
- field = report->field[finfo.field_index];
- memset(&finfo, 0, sizeof(finfo));
- finfo.report_type = rinfo.report_type;
- finfo.report_id = rinfo.report_id;
- finfo.field_index = field->report_count - 1;
- finfo.maxusage = field->maxusage;
- finfo.flags = field->flags;
- finfo.physical = field->physical;
- finfo.logical = field->logical;
- finfo.application = field->application;
- finfo.logical_minimum = field->logical_minimum;
- finfo.logical_maximum = field->logical_maximum;
- finfo.physical_minimum = field->physical_minimum;
- finfo.physical_maximum = field->physical_maximum;
- finfo.unit_exponent = field->unit_exponent;
- finfo.unit = field->unit;
-
- if (copy_to_user(user_arg, &finfo, sizeof(finfo)))
- return -EFAULT;
-
- return 0;
-
- case HIDIOCGUCODE:
- uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
- if (!uref_multi)
- return -ENOMEM;
- uref = &uref_multi->uref;
- if (copy_from_user(uref, user_arg, sizeof(*uref)))
- goto fault;
-
- rinfo.report_type = uref->report_type;
- rinfo.report_id = uref->report_id;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- goto inval;
-
- if (uref->field_index >= report->maxfield)
- goto inval;
-
- field = report->field[uref->field_index];
- if (uref->usage_index >= field->maxusage)
- goto inval;
-
- uref->usage_code = field->usage[uref->usage_index].hid;
-
- if (copy_to_user(user_arg, uref, sizeof(*uref)))
- goto fault;
-
- kfree(uref_multi);
- return 0;
-
- case HIDIOCGUSAGE:
- case HIDIOCSUSAGE:
- case HIDIOCGUSAGES:
- case HIDIOCSUSAGES:
- case HIDIOCGCOLLECTIONINDEX:
- uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
- if (!uref_multi)
- return -ENOMEM;
- uref = &uref_multi->uref;
- if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
- if (copy_from_user(uref_multi, user_arg,
- sizeof(*uref_multi)))
- goto fault;
- } else {
- if (copy_from_user(uref, user_arg, sizeof(*uref)))
- goto fault;
- }
-
- if (cmd != HIDIOCGUSAGE &&
- cmd != HIDIOCGUSAGES &&
- uref->report_type == HID_REPORT_TYPE_INPUT)
- goto inval;
-
- if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
- field = hiddev_lookup_usage(hid, uref);
- if (field == NULL)
- goto inval;
- } else {
- rinfo.report_type = uref->report_type;
- rinfo.report_id = uref->report_id;
- if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
- goto inval;
-
- if (uref->field_index >= report->maxfield)
- goto inval;
-
- field = report->field[uref->field_index];
-
- if (cmd == HIDIOCGCOLLECTIONINDEX) {
- if (uref->usage_index >= field->maxusage)
- goto inval;
- } else if (uref->usage_index >= field->report_count)
- goto inval;
-
- else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
- (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
- uref->usage_index + uref_multi->num_values >= field->report_count))
- goto inval;
- }
-
- switch (cmd) {
- case HIDIOCGUSAGE:
- uref->value = field->value[uref->usage_index];
- if (copy_to_user(user_arg, uref, sizeof(*uref)))
- goto fault;
- goto goodreturn;
-
- case HIDIOCSUSAGE:
- field->value[uref->usage_index] = uref->value;
- goto goodreturn;
-
- case HIDIOCGCOLLECTIONINDEX:
- kfree(uref_multi);
- return field->usage[uref->usage_index].collection_index;
- case HIDIOCGUSAGES:
- for (i = 0; i < uref_multi->num_values; i++)
- uref_multi->values[i] =
- field->value[uref->usage_index + i];
- if (copy_to_user(user_arg, uref_multi,
- sizeof(*uref_multi)))
- goto fault;
- goto goodreturn;
- case HIDIOCSUSAGES:
- for (i = 0; i < uref_multi->num_values; i++)
- field->value[uref->usage_index + i] =
- uref_multi->values[i];
- goto goodreturn;
- }
-
-goodreturn:
- kfree(uref_multi);
- return 0;
-fault:
- kfree(uref_multi);
- return -EFAULT;
-inval:
- kfree(uref_multi);
- return -EINVAL;
-
- case HIDIOCGCOLLECTIONINFO:
- if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
- return -EFAULT;
-
- if (cinfo.index >= hid->maxcollection)
- return -EINVAL;
-
- cinfo.type = hid->collection[cinfo.index].type;
- cinfo.usage = hid->collection[cinfo.index].usage;
- cinfo.level = hid->collection[cinfo.index].level;
-
- if (copy_to_user(user_arg, &cinfo, sizeof(cinfo)))
- return -EFAULT;
- return 0;
-
- default:
-
- if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
- return -EINVAL;
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
- int len;
- if (!hid->name)
- return 0;
- len = strlen(hid->name) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->name, len) ?
- -EFAULT : len;
- }
-
- if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
- int len;
- if (!hid->phys)
- return 0;
- len = strlen(hid->phys) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- return copy_to_user(user_arg, hid->phys, len) ?
- -EFAULT : len;
- }
- }
- return -EINVAL;
-}
-
-static struct file_operations hiddev_fops = {
- .owner = THIS_MODULE,
- .read = hiddev_read,
- .write = hiddev_write,
- .poll = hiddev_poll,
- .open = hiddev_open,
- .release = hiddev_release,
- .ioctl = hiddev_ioctl,
- .fasync = hiddev_fasync,
-};
-
-static struct usb_class_driver hiddev_class = {
- .name = "hiddev%d",
- .fops = &hiddev_fops,
- .minor_base = HIDDEV_MINOR_BASE,
-};
-
-/*
- * This is where hid.c calls us to connect a hid device to the hiddev driver
- */
-int hiddev_connect(struct hid_device *hid)
-{
- struct hiddev *hiddev;
- int i;
- int retval;
-
- for (i = 0; i < hid->maxcollection; i++)
- if (hid->collection[i].type ==
- HID_COLLECTION_APPLICATION &&
- !IS_INPUT_APPLICATION(hid->collection[i].usage))
- break;
-
- if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
- return -1;
-
- if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
- return -1;
- memset(hiddev, 0, sizeof(struct hiddev));
-
- retval = usb_register_dev(hid->intf, &hiddev_class);
- if (retval) {
- err("Not able to get a minor for this device.");
- kfree(hiddev);
- return -1;
- }
-
- init_waitqueue_head(&hiddev->wait);
-
- hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
-
- hiddev->hid = hid;
- hiddev->exist = 1;
-
- hid->minor = hid->intf->minor;
- hid->hiddev = hiddev;
-
- return 0;
-}
-
-/*
- * This is where hid.c calls us to disconnect a hiddev device from the
- * corresponding hid device (usually because the usb device has disconnected)
- */
-static struct usb_class_driver hiddev_class;
-void hiddev_disconnect(struct hid_device *hid)
-{
- struct hiddev *hiddev = hid->hiddev;
-
- hiddev->exist = 0;
-
- hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
- usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
-
- if (hiddev->open) {
- hid_close(hiddev->hid);
- wake_up_interruptible(&hiddev->wait);
- } else {
- kfree(hiddev);
- }
-}
-
-/* Currently this driver is a USB driver. It's not a conventional one in
- * the sense that it doesn't probe at the USB level. Instead it waits to
- * be connected by HID through the hiddev_connect / hiddev_disconnect
- * routines. The reason to register as a USB device is to gain part of the
- * minor number space from the USB major.
- *
- * In theory, should the HID code be generalized to more than one physical
- * medium (say, IEEE 1384), this driver will probably need to register its
- * own major number, and in doing so, no longer need to register with USB.
- * At that point the probe routine and hiddev_driver struct below will no
- * longer be useful.
- */
-
-
-/* We never attach in this manner, and rely on HID to connect us. This
- * is why there is no disconnect routine defined in the usb_driver either.
- */
-static int hiddev_usbd_probe(struct usb_interface *intf,
- const struct usb_device_id *hiddev_info)
-{
- return -ENODEV;
-}
-
-
-static /* const */ struct usb_driver hiddev_driver = {
- .owner = THIS_MODULE,
- .name = "hiddev",
- .probe = hiddev_usbd_probe,
-};
-
-int __init hiddev_init(void)
-{
- devfs_mk_dir("usb/hid");
- return usb_register(&hiddev_driver);
-}
-
-void hiddev_exit(void)
-{
- usb_deregister(&hiddev_driver);
- devfs_remove("usb/hid");
-}
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
deleted file mode 100644
index 3b581853cf1..00000000000
--- a/drivers/usb/input/itmtouch.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/******************************************************************************
- * itmtouch.c -- Driver for ITM touchscreen panel
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Based upon original work by Chris Collins <xfire-itmtouch@xware.cx>.
- *
- * Kudos to ITM for providing me with the datasheet for the panel,
- * even though it was a day later than I had finished writing this
- * driver.
- *
- * It has meant that I've been able to correct my interpretation of the
- * protocol packets however.
- *
- * CC -- 2003/9/29
- *
- * History
- * 1.0 & 1.1 2003 (CC) vojtech@suse.cz
- * Original version for 2.4.x kernels
- *
- * 1.2 02/03/2005 (HCE) hc@mivu.no
- * Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints.
- * Unfortunately no calibration support at this time.
- *
- * 1.2.1 09/03/2005 (HCE) hc@mivu.no
- * Code cleanup and adjusting syntax to start matching kernel standards
- *
- *****************************************************************************/
-
-#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-/* only an 8 byte buffer necessary for a single packet */
-#define ITM_BUFSIZE 8
-#define PATH_SIZE 64
-
-#define USB_VENDOR_ID_ITMINC 0x0403
-#define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9
-
-#define DRIVER_AUTHOR "Hans-Christian Egtvedt <hc@mivu.no>"
-#define DRIVER_VERSION "v1.2.1"
-#define DRIVER_DESC "USB ITM Inc Touch Panel Driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
-MODULE_LICENSE( DRIVER_LICENSE );
-
-struct itmtouch_dev {
- struct usb_device *usbdev; /* usb device */
- struct input_dev *inputdev; /* input device */
- struct urb *readurb; /* urb */
- char rbuf[ITM_BUFSIZE]; /* data */
- int users;
- char name[128];
- char phys[64];
-};
-
-static struct usb_device_id itmtouch_ids [] = {
- { USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) },
- { }
-};
-
-static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct itmtouch_dev *itmtouch = urb->context;
- unsigned char *data = urb->transfer_buffer;
- struct input_dev *dev = itmtouch->inputdev;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ETIMEDOUT:
- /* this urb is timing out */
- dbg("%s - urb timed out - was the device unplugged?",
- __FUNCTION__);
- return;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- input_regs(dev, regs);
-
- /* if pressure has been released, then don't report X/Y */
- if (data[7] & 0x20) {
- input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F));
- input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F));
- }
-
- input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F));
- input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20);
- input_sync(dev);
-
-exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- printk(KERN_ERR "%s - usb_submit_urb failed with result: %d",
- __FUNCTION__, retval);
-}
-
-static int itmtouch_open(struct input_dev *input)
-{
- struct itmtouch_dev *itmtouch = input->private;
-
- itmtouch->readurb->dev = itmtouch->usbdev;
-
- if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void itmtouch_close(struct input_dev *input)
-{
- struct itmtouch_dev *itmtouch = input->private;
-
- usb_kill_urb(itmtouch->readurb);
-}
-
-static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct itmtouch_dev *itmtouch;
- struct input_dev *input_dev;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_device *udev = interface_to_usbdev(intf);
- unsigned int pipe;
- unsigned int maxp;
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
-
- itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!itmtouch || !input_dev) {
- err("%s - Out of memory.", __FUNCTION__);
- goto fail;
- }
-
- itmtouch->usbdev = udev;
- itmtouch->inputdev = input_dev;
-
- if (udev->manufacturer)
- strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name));
-
- if (udev->product) {
- if (udev->manufacturer)
- strlcat(itmtouch->name, " ", sizeof(itmtouch->name));
- strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name));
- }
-
- if (!strlen(itmtouch->name))
- sprintf(itmtouch->name, "USB ITM touchscreen");
-
- usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys));
- strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys));
-
- input_dev->name = itmtouch->name;
- input_dev->phys = itmtouch->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->cdev.dev = &intf->dev;
- input_dev->private = itmtouch;
-
- input_dev->open = itmtouch_open;
- input_dev->close = itmtouch_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_TOUCH)] = BIT(BTN_TOUCH);
-
- /* device limits */
- /* as specified by the ITM datasheet, X and Y are 12bit,
- * Z (pressure) is 8 bit. However, the fields are defined up
- * to 14 bits for future possible expansion.
- */
- input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0);
-
- /* initialise the URB so we can read from the transport stream */
- pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-
- if (maxp > ITM_BUFSIZE)
- maxp = ITM_BUFSIZE;
-
- itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
- if (!itmtouch->readurb) {
- dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
- goto fail;
- }
-
- usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
- maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
-
- input_register_device(itmtouch->inputdev);
-
- usb_set_intfdata(intf, itmtouch);
-
- return 0;
-
- fail: input_free_device(input_dev);
- kfree(itmtouch);
- return -ENOMEM;
-}
-
-static void itmtouch_disconnect(struct usb_interface *intf)
-{
- struct itmtouch_dev *itmtouch = usb_get_intfdata(intf);
-
- usb_set_intfdata(intf, NULL);
-
- if (itmtouch) {
- input_unregister_device(itmtouch->inputdev);
- usb_kill_urb(itmtouch->readurb);
- usb_free_urb(itmtouch->readurb);
- kfree(itmtouch);
- }
-}
-
-MODULE_DEVICE_TABLE(usb, itmtouch_ids);
-
-static struct usb_driver itmtouch_driver = {
- .owner = THIS_MODULE,
- .name = "itmtouch",
- .probe = itmtouch_probe,
- .disconnect = itmtouch_disconnect,
- .id_table = itmtouch_ids,
-};
-
-static int __init itmtouch_init(void)
-{
- info(DRIVER_DESC " " DRIVER_VERSION);
- info(DRIVER_AUTHOR);
- return usb_register(&itmtouch_driver);
-}
-
-static void __exit itmtouch_exit(void)
-{
- usb_deregister(&itmtouch_driver);
-}
-
-module_init(itmtouch_init);
-module_exit(itmtouch_exit);
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
deleted file mode 100644
index a248664b5d1..00000000000
--- a/drivers/usb/input/kbtab.c
+++ /dev/null
@@ -1,224 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.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 pt_regs *regs)
-{
- 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 = dev->private;
-
- 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 = dev->private;
-
- 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;
-
- 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->cdev.dev = &intf->dev;
- input_dev->private = 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_X, 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;
-
- input_register_device(kbtab->dev);
-
- usb_set_intfdata(intf, kbtab);
- return 0;
-
-fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
-fail1: input_free_device(input_dev);
- kfree(kbtab);
- return -ENOMEM;
-}
-
-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 = {
- .owner = THIS_MODULE,
- .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 5b8d65f62ab..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/config.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#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 int keyspan_key_table[] = {
- KEY_RESERVED, /* 0 is just a place holder. */
- KEY_RESERVED,
- KEY_STOP,
- KEY_PLAYCD,
- KEY_RESERVED,
- KEY_PREVIOUSSONG,
- KEY_REWIND,
- KEY_FORWARD,
- KEY_NEXTSONG,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_PAUSE,
- KEY_VOLUMEUP,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_VOLUMEDOWN,
- KEY_RESERVED,
- KEY_UP,
- KEY_RESERVED,
- KEY_MUTE,
- KEY_LEFT,
- KEY_ENTER,
- KEY_RIGHT,
- KEY_RESERVED,
- KEY_RESERVED,
- KEY_DOWN,
- KEY_RESERVED,
- KEY_KPASTERISK,
- KEY_RESERVED,
- KEY_MENU
-};
-
-static struct usb_driver keyspan_driver;
-
-/*
- * Debug routine that prints out what we've received from the remote.
- */
-static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
-{
- char codes[4 * RECV_SIZE];
- int i;
-
- for (i = 0; i < RECV_SIZE; i++)
- snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]);
-
- dev_info(&dev->udev->dev, "%s\n", codes);
-}
-
-/*
- * Routine that manages the bit_tester structure. It makes sure that there are
- * at least bits_needed bits loaded into the tester.
- */
-static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
-{
- if (dev->data.bits_left >= bits_needed)
- return 0;
-
- /*
- * Somehow we've missed the last message. The message will be repeated
- * though so it's not too big a deal
- */
- if (dev->data.pos >= dev->data.len) {
- dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
- __FUNCTION__, dev->data.pos, dev->data.len);
- return -1;
- }
-
- /* Load as much as we can into the tester. */
- while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) &&
- (dev->data.pos < dev->data.len)) {
- dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left);
- dev->data.bits_left += 8;
- }
-
- return 0;
-}
-
-/*
- * Routine that handles all the logic needed to parse out the message from the remote.
- */
-static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
-{
- int i;
- int found = 0;
- struct keyspan_message message;
-
- switch(remote->stage) {
- case 0:
- /*
- * In stage 0 we want to find the start of a message. The remote sends a 0xFF as filler.
- * So the first byte that isn't a FF should be the start of a new message.
- */
- for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i);
-
- if (i < RECV_SIZE) {
- memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE);
- remote->data.len = RECV_SIZE;
- remote->data.pos = 0;
- remote->data.tester = 0;
- remote->data.bits_left = 0;
- remote->stage = 1;
- }
- break;
-
- case 1:
- /*
- * Stage 1 we should have 16 bytes and should be able to detect a
- * SYNC. The SYNC is 14 bits, 7 0's and then 7 1's.
- */
- memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
- remote->data.len += RECV_SIZE;
-
- found = 0;
- while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) {
- for (i = 0; i < 8; ++i) {
- if (keyspan_load_tester(remote, 14) != 0) {
- remote->stage = 0;
- return;
- }
-
- if ((remote->data.tester & SYNC_MASK) == SYNC) {
- remote->data.tester = remote->data.tester >> 14;
- remote->data.bits_left -= 14;
- found = 1;
- break;
- } else {
- remote->data.tester = remote->data.tester >> 1;
- --remote->data.bits_left;
- }
- }
- }
-
- if (!found) {
- remote->stage = 0;
- remote->data.len = 0;
- } else {
- remote->stage = 2;
- }
- break;
-
- case 2:
- /*
- * Stage 2 we should have 24 bytes which will be enough for a full
- * message. We need to parse out the system code, button code,
- * toggle code, and stop.
- */
- memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
- remote->data.len += RECV_SIZE;
-
- message.system = 0;
- for (i = 0; i < 9; i++) {
- keyspan_load_tester(remote, 6);
-
- if ((remote->data.tester & ZERO_MASK) == ZERO) {
- message.system = message.system << 1;
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else if ((remote->data.tester & ONE_MASK) == ONE) {
- message.system = (message.system << 1) + 1;
- remote->data.tester = remote->data.tester >> 6;
- remote->data.bits_left -= 6;
- } else {
- err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
- remote->stage = 0;
- return;
- }
- }
-
- message.button = 0;
- for (i = 0; i < 5; i++) {
- keyspan_load_tester(remote, 6);
-
- if ((remote->data.tester & ZERO_MASK) == ZERO) {
- message.button = message.button << 1;
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else if ((remote->data.tester & ONE_MASK) == ONE) {
- message.button = (message.button << 1) + 1;
- remote->data.tester = remote->data.tester >> 6;
- remote->data.bits_left -= 6;
- } else {
- err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
- remote->stage = 0;
- return;
- }
- }
-
- keyspan_load_tester(remote, 6);
- if ((remote->data.tester & ZERO_MASK) == ZERO) {
- message.toggle = 0;
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else if ((remote->data.tester & ONE_MASK) == ONE) {
- message.toggle = 1;
- remote->data.tester = remote->data.tester >> 6;
- remote->data.bits_left -= 6;
- } else {
- err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
- }
-
- keyspan_load_tester(remote, 5);
- if ((remote->data.tester & STOP_MASK) == STOP) {
- remote->data.tester = remote->data.tester >> 5;
- remote->data.bits_left -= 5;
- } else {
- err("Bad message recieved, no stop bit found.\n");
- }
-
- dev_dbg(&remote->udev,
- "%s found valid message: system: %d, button: %d, toggle: %d\n",
- __FUNCTION__, message.system, message.button, message.toggle);
-
- if (message.toggle != remote->toggle) {
- input_regs(remote->input, regs);
- input_report_key(remote->input, keyspan_key_table[message.button], 1);
- input_report_key(remote->input, keyspan_key_table[message.button], 0);
- input_sync(remote->input);
- remote->toggle = message.toggle;
- }
-
- remote->stage = 0;
- break;
- }
-}
-
-/*
- * Routine for sending all the initialization messages to the remote.
- */
-static int keyspan_setup(struct usb_device* dev)
-{
- int retval = 0;
-
- retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
- if (retval) {
- dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
- __FUNCTION__, retval);
- return(retval);
- }
-
- retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
- if (retval) {
- dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
- __FUNCTION__, retval);
- return(retval);
- }
-
- retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
- if (retval) {
- dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
- __FUNCTION__, retval);
- return(retval);
- }
-
- dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
- return(retval);
-}
-
-/*
- * Routine used to handle a new message that has come in.
- */
-static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs)
-{
- struct usb_keyspan *dev = urb->context;
- int retval;
-
- /* Check our status in case we need to bail out early. */
- switch (urb->status) {
- case 0:
- break;
-
- /* Device went away so don't keep trying to read from it. */
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- return;
-
- default:
- goto resubmit;
- break;
- }
-
- if (debug)
- keyspan_print(dev);
-
- keyspan_check_data(dev, regs);
-
-resubmit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
-}
-
-static int keyspan_open(struct input_dev *dev)
-{
- struct usb_keyspan *remote = dev->private;
-
- 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 = dev->private;
-
- 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 ((endpoint->bEndpointAddress & USB_DIR_IN) &&
- ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
- /* 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, retval;
-
- 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) {
- retval = -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, SLAB_ATOMIC, &remote->in_dma);
- if (!remote->in_buffer) {
- retval = -ENOMEM;
- goto fail1;
- }
-
- remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!remote->irq_urb) {
- retval = -ENOMEM;
- goto fail2;
- }
-
- retval = keyspan_setup(udev);
- if (retval) {
- retval = -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->cdev.dev = &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_dev->private = 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 */
- input_register_device(remote->input);
-
- /* 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 retval;
-}
-
-/*
- * 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 =
-{
- .owner = THIS_MODULE,
- .name = "keyspan_remote",
- .probe = keyspan_probe,
- .disconnect = keyspan_disconnect,
- .id_table = keyspan_table
-};
-
-static int __init usb_keyspan_init(void)
-{
- int result;
-
- /* register this driver with the USB subsystem */
- result = usb_register(&keyspan_driver);
- if (result)
- err("usb_register failed. Error number %d\n", result);
-
- return result;
-}
-
-static void __exit usb_keyspan_exit(void)
-{
- /* deregister this driver with the USB subsystem */
- usb_deregister(&keyspan_driver);
-}
-
-module_init(usb_keyspan_init);
-module_exit(usb_keyspan_exit);
-
-MODULE_DEVICE_TABLE(usb, keyspan_table);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/usb/input/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/mtouchusb.c b/drivers/usb/input/mtouchusb.c
deleted file mode 100644
index 7fce526560c..00000000000
--- a/drivers/usb/input/mtouchusb.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/******************************************************************************
- * mtouchusb.c -- Driver for Microtouch (Now 3M) USB Touchscreens
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Based upon original work by Radoslaw Garbacz (usb-support@ite.pl)
- * (http://freshmeat.net/projects/3mtouchscreendriver)
- *
- * History
- *
- * 0.3 & 0.4 2002 (TEJ) tejohnson@yahoo.com
- * Updated to 2.4.18, then 2.4.19
- * Old version still relied on stealing a minor
- *
- * 0.5 02/26/2004 (TEJ) tejohnson@yahoo.com
- * Complete rewrite using Linux Input in 2.6.3
- * Unfortunately no calibration support at this time
- *
- * 1.4 04/25/2004 (TEJ) tejohnson@yahoo.com
- * Changed reset from standard USB dev reset to vendor reset
- * Changed data sent to host from compensated to raw coordinates
- * Eliminated vendor/product module params
- * Performed multiple successful tests with an EXII-5010UC
- *
- * 1.5 02/27/2005 ddstreet@ieee.org
- * Added module parameter to select raw or hw-calibrated coordinate reporting
- *
- *****************************************************************************/
-
-#include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
- #define DEBUG
-#else
- #undef DEBUG
-#endif
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-#define MTOUCHUSB_MIN_XC 0x0
-#define MTOUCHUSB_MAX_RAW_XC 0x4000
-#define MTOUCHUSB_MAX_CALIB_XC 0xffff
-#define MTOUCHUSB_XC_FUZZ 0x0
-#define MTOUCHUSB_XC_FLAT 0x0
-#define MTOUCHUSB_MIN_YC 0x0
-#define MTOUCHUSB_MAX_RAW_YC 0x4000
-#define MTOUCHUSB_MAX_CALIB_YC 0xffff
-#define MTOUCHUSB_YC_FUZZ 0x0
-#define MTOUCHUSB_YC_FLAT 0x0
-
-#define MTOUCHUSB_ASYNC_REPORT 1
-#define MTOUCHUSB_RESET 7
-#define MTOUCHUSB_REPORT_DATA_SIZE 11
-#define MTOUCHUSB_REQ_CTRLLR_ID 10
-
-#define MTOUCHUSB_GET_RAW_XC(data) (data[8]<<8 | data[7])
-#define MTOUCHUSB_GET_CALIB_XC(data) (data[4]<<8 | data[3])
-#define MTOUCHUSB_GET_RAW_YC(data) (data[10]<<8 | data[9])
-#define MTOUCHUSB_GET_CALIB_YC(data) (data[6]<<8 | data[5])
-#define MTOUCHUSB_GET_XC(data) (raw_coordinates ? \
- MTOUCHUSB_GET_RAW_XC(data) : \
- MTOUCHUSB_GET_CALIB_XC(data))
-#define MTOUCHUSB_GET_YC(data) (raw_coordinates ? \
- MTOUCHUSB_GET_RAW_YC(data) : \
- MTOUCHUSB_GET_CALIB_YC(data))
-#define MTOUCHUSB_GET_TOUCHED(data) ((data[2] & 0x40) ? 1:0)
-
-#define DRIVER_VERSION "v1.5"
-#define DRIVER_AUTHOR "Todd E. Johnson, tejohnson@yahoo.com"
-#define DRIVER_DESC "3M USB Touchscreen Driver"
-#define DRIVER_LICENSE "GPL"
-
-static int raw_coordinates = 1;
-
-module_param(raw_coordinates, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)");
-
-struct mtouch_usb {
- unsigned char *data;
- dma_addr_t data_dma;
- struct urb *irq;
- struct usb_device *udev;
- struct input_dev *input;
- char name[128];
- char phys[64];
-};
-
-static struct usb_device_id mtouchusb_devices[] = {
- { USB_DEVICE(0x0596, 0x0001) },
- { }
-};
-
-static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct mtouch_usb *mtouch = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ETIMEDOUT:
- /* this urb is timing out */
- dbg("%s - urb timed out - was the device unplugged?",
- __FUNCTION__);
- return;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- input_regs(mtouch->input, regs);
- input_report_key(mtouch->input, BTN_TOUCH,
- MTOUCHUSB_GET_TOUCHED(mtouch->data));
- input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
- input_report_abs(mtouch->input, ABS_Y,
- (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
- - MTOUCHUSB_GET_YC(mtouch->data));
- input_sync(mtouch->input);
-
-exit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- err("%s - usb_submit_urb failed with result: %d",
- __FUNCTION__, retval);
-}
-
-static int mtouchusb_open(struct input_dev *input)
-{
- struct mtouch_usb *mtouch = input->private;
-
- mtouch->irq->dev = mtouch->udev;
-
- if (usb_submit_urb(mtouch->irq, GFP_ATOMIC))
- return -EIO;
-
- return 0;
-}
-
-static void mtouchusb_close(struct input_dev *input)
-{
- struct mtouch_usb *mtouch = input->private;
-
- usb_kill_urb(mtouch->irq);
-}
-
-static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch)
-{
- dbg("%s - called", __FUNCTION__);
-
- mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
- SLAB_ATOMIC, &mtouch->data_dma);
-
- if (!mtouch->data)
- return -1;
-
- return 0;
-}
-
-static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch)
-{
- dbg("%s - called", __FUNCTION__);
-
- if (mtouch->data)
- usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE,
- mtouch->data, mtouch->data_dma);
-}
-
-static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct mtouch_usb *mtouch;
- struct input_dev *input_dev;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_device *udev = interface_to_usbdev(intf);
- int nRet;
-
- dbg("%s - called", __FUNCTION__);
-
- dbg("%s - setting interface", __FUNCTION__);
- interface = intf->cur_altsetting;
-
- dbg("%s - setting endpoint", __FUNCTION__);
- endpoint = &interface->endpoint[0].desc;
-
- mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!mtouch || !input_dev) {
- err("%s - Out of memory.", __FUNCTION__);
- goto fail1;
- }
-
- dbg("%s - allocating buffers", __FUNCTION__);
- if (mtouchusb_alloc_buffers(udev, mtouch))
- goto fail2;
-
- mtouch->udev = udev;
- mtouch->input = input_dev;
-
- if (udev->manufacturer)
- strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name));
-
- if (udev->product) {
- if (udev->manufacturer)
- strlcat(mtouch->name, " ", sizeof(mtouch->name));
- strlcat(mtouch->name, udev->product, sizeof(mtouch->name));
- }
-
- if (!strlen(mtouch->name))
- snprintf(mtouch->name, sizeof(mtouch->name),
- "USB Touchscreen %04x:%04x",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys));
- strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys));
-
- input_dev->name = mtouch->name;
- input_dev->phys = mtouch->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->cdev.dev = &intf->dev;
- input_dev->private = mtouch;
-
- input_dev->open = mtouchusb_open;
- input_dev->close = mtouchusb_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, MTOUCHUSB_MIN_XC,
- raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC,
- MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT);
- input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC,
- raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC,
- MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT);
-
- nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
- MTOUCHUSB_RESET,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
- dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
- __FUNCTION__, nRet);
-
- dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__);
- mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!mtouch->irq) {
- dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
- goto fail2;
- }
-
- dbg("%s - usb_fill_int_urb", __FUNCTION__);
- usb_fill_int_urb(mtouch->irq, mtouch->udev,
- usb_rcvintpipe(mtouch->udev, 0x81),
- mtouch->data, MTOUCHUSB_REPORT_DATA_SIZE,
- mtouchusb_irq, mtouch, endpoint->bInterval);
-
- dbg("%s - input_register_device", __FUNCTION__);
- input_register_device(mtouch->input);
-
- nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
- MTOUCHUSB_ASYNC_REPORT,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
- dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
- __FUNCTION__, nRet);
-
- usb_set_intfdata(intf, mtouch);
- return 0;
-
-fail2: mtouchusb_free_buffers(udev, mtouch);
-fail1: input_free_device(input_dev);
- kfree(mtouch);
- return -ENOMEM;
-}
-
-static void mtouchusb_disconnect(struct usb_interface *intf)
-{
- struct mtouch_usb *mtouch = usb_get_intfdata(intf);
-
- dbg("%s - called", __FUNCTION__);
- usb_set_intfdata(intf, NULL);
- if (mtouch) {
- dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
- usb_kill_urb(mtouch->irq);
- input_unregister_device(mtouch->input);
- usb_free_urb(mtouch->irq);
- mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
- kfree(mtouch);
- }
-}
-
-MODULE_DEVICE_TABLE(usb, mtouchusb_devices);
-
-static struct usb_driver mtouchusb_driver = {
- .owner = THIS_MODULE,
- .name = "mtouchusb",
- .probe = mtouchusb_probe,
- .disconnect = mtouchusb_disconnect,
- .id_table = mtouchusb_devices,
-};
-
-static int __init mtouchusb_init(void)
-{
- dbg("%s - called", __FUNCTION__);
- return usb_register(&mtouchusb_driver);
-}
-
-static void __exit mtouchusb_cleanup(void)
-{
- dbg("%s - called", __FUNCTION__);
- usb_deregister(&mtouchusb_driver);
-}
-
-module_init(mtouchusb_init);
-module_exit(mtouchusb_cleanup);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
deleted file mode 100644
index dca5ee93a4e..00000000000
--- a/drivers/usb/input/pid.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * PID Force feedback support for hid devices.
- *
- * Copyright (c) 2002 Rodrigo Damazio.
- * Portions by Johann Deneux and Bjorn Augustson
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/smp_lock.h>
-#include <linux/spinlock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include "hid.h"
-#include "pid.h"
-
-#define DEBUG
-
-#define CHECK_OWNERSHIP(i, hid_pid) \
- ((i) < FF_EFFECTS_MAX && i >= 0 && \
- test_bit(FF_PID_FLAGS_USED, &hid_pid->effects[(i)].flags) && \
- (current->pid == 0 || \
- (hid_pid)->effects[(i)].owner == current->pid))
-
-/* Called when a transfer is completed */
-static void hid_pid_ctrl_out(struct urb *u, struct pt_regs *regs)
-{
- dev_dbg(&u->dev->dev, "hid_pid_ctrl_out - Transfer Completed\n");
-}
-
-static void hid_pid_exit(struct hid_device *hid)
-{
- struct hid_ff_pid *private = hid->ff_private;
-
- if (private->urbffout) {
- usb_kill_urb(private->urbffout);
- usb_free_urb(private->urbffout);
- }
-}
-
-static int pid_upload_periodic(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "requested periodic force upload\n");
- return 0;
-}
-
-static int pid_upload_constant(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "requested constant force upload\n");
- return 0;
-}
-
-static int pid_upload_condition(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "requested Condition force upload\n");
- return 0;
-}
-
-static int pid_upload_ramp(struct hid_ff_pid *pid, struct ff_effect *effect, int is_update)
-{
- dev_info(&pid->hid->dev->dev, "request ramp force upload\n");
- return 0;
-}
-
-static int hid_pid_event(struct hid_device *hid, struct input_dev *input,
- unsigned int type, unsigned int code, int value)
-{
- dev_dbg(&hid->dev->dev, "PID event received: type=%d,code=%d,value=%d.\n", type, code, value);
-
- if (type != EV_FF)
- return -1;
-
- return 0;
-}
-
-/* Lock must be held by caller */
-static void hid_pid_ctrl_playback(struct hid_device *hid, struct hid_pid_effect *effect, int play)
-{
- if (play)
- set_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
- else
- clear_bit(FF_PID_FLAGS_PLAYING, &effect->flags);
-}
-
-static int hid_pid_erase(struct input_dev *dev, int id)
-{
- struct hid_device *hid = dev->private;
- struct hid_ff_pid *pid = hid->ff_private;
- struct hid_field *field;
- unsigned long flags;
- int ret;
-
- if (!CHECK_OWNERSHIP(id, pid))
- return -EACCES;
-
- /* Find report */
- field = hid_find_field_by_usage(hid, HID_UP_PID | FF_PID_USAGE_BLOCK_FREE,
- HID_OUTPUT_REPORT);
- if (!field) {
- dev_err(&hid->dev->dev, "couldn't find report\n");
- return -EIO;
- }
-
- ret = hid_set_field(field, 0, pid->effects[id].device_id);
- if (ret) {
- dev_err(&hid->dev->dev, "couldn't set field\n");
- return ret;
- }
-
- hid_submit_report(hid, field->report, USB_DIR_OUT);
-
- spin_lock_irqsave(&pid->lock, flags);
- hid_pid_ctrl_playback(hid, pid->effects + id, 0);
- pid->effects[id].flags = 0;
- spin_unlock_irqrestore(&pid->lock, flags);
-
- return 0;
-}
-
-/* Erase all effects this process owns */
-static int hid_pid_flush(struct input_dev *dev, struct file *file)
-{
- struct hid_device *hid = dev->private;
- struct hid_ff_pid *pid = hid->ff_private;
- int i;
-
- /*NOTE: no need to lock here. The only times EFFECT_USED is
- modified is when effects are uploaded or when an effect is
- erased. But a process cannot close its dev/input/eventX fd
- and perform ioctls on the same fd all at the same time */
- /*FIXME: multiple threads, anyone? */
- for (i = 0; i < dev->ff_effects_max; ++i)
- if (current->pid == pid->effects[i].owner
- && test_bit(FF_PID_FLAGS_USED, &pid->effects[i].flags))
- if (hid_pid_erase(dev, i))
- dev_warn(&hid->dev->dev, "erase effect %d failed", i);
-
- return 0;
-}
-
-static int hid_pid_upload_effect(struct input_dev *dev,
- struct ff_effect *effect)
-{
- struct hid_ff_pid *pid_private = (struct hid_ff_pid *)(dev->private);
- int ret;
- int is_update;
- unsigned long flags;
-
- dev_dbg(&pid_private->hid->dev->dev, "upload effect called: effect_type=%x\n", effect->type);
- /* Check this effect type is supported by this device */
- if (!test_bit(effect->type, dev->ffbit)) {
- dev_dbg(&pid_private->hid->dev->dev,
- "invalid kind of effect requested.\n");
- return -EINVAL;
- }
-
- /*
- * If we want to create a new effect, get a free id
- */
- if (effect->id == -1) {
- int id = 0;
-
- // Spinlock so we don`t get a race condition when choosing IDs
- spin_lock_irqsave(&pid_private->lock, flags);
-
- while (id < FF_EFFECTS_MAX)
- if (!test_and_set_bit(FF_PID_FLAGS_USED, &pid_private->effects[id++].flags))
- break;
-
- if (id == FF_EFFECTS_MAX) {
- spin_unlock_irqrestore(&pid_private->lock, flags);
-// TEMP - We need to get ff_effects_max correctly first: || id >= dev->ff_effects_max) {
- dev_dbg(&pid_private->hid->dev->dev, "Not enough device memory\n");
- return -ENOMEM;
- }
-
- effect->id = id;
- dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
- pid_private->effects[id].owner = current->pid;
- pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
- spin_unlock_irqrestore(&pid_private->lock, flags);
-
- is_update = FF_PID_FALSE;
- } else {
- /* We want to update an effect */
- if (!CHECK_OWNERSHIP(effect->id, pid_private))
- return -EACCES;
-
- /* Parameter type cannot be updated */
- if (effect->type != pid_private->effects[effect->id].effect.type)
- return -EINVAL;
-
- /* Check the effect is not already being updated */
- if (test_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags))
- return -EAGAIN;
-
- is_update = FF_PID_TRUE;
- }
-
- /*
- * Upload the effect
- */
- switch (effect->type) {
- case FF_PERIODIC:
- ret = pid_upload_periodic(pid_private, effect, is_update);
- break;
-
- case FF_CONSTANT:
- ret = pid_upload_constant(pid_private, effect, is_update);
- break;
-
- case FF_SPRING:
- case FF_FRICTION:
- case FF_DAMPER:
- case FF_INERTIA:
- ret = pid_upload_condition(pid_private, effect, is_update);
- break;
-
- case FF_RAMP:
- ret = pid_upload_ramp(pid_private, effect, is_update);
- break;
-
- default:
- dev_dbg(&pid_private->hid->dev->dev,
- "invalid type of effect requested - %x.\n",
- effect->type);
- return -EINVAL;
- }
- /* If a packet was sent, forbid new updates until we are notified
- * that the packet was updated
- */
- if (ret == 0)
- set_bit(FF_PID_FLAGS_UPDATING, &pid_private->effects[effect->id].flags);
- pid_private->effects[effect->id].effect = *effect;
- return ret;
-}
-
-int hid_pid_init(struct hid_device *hid)
-{
- struct hid_ff_pid *private;
- struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
- struct input_dev *input_dev = hidinput->input;
-
- private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
- if (!private)
- return -ENOMEM;
-
- private->hid = hid;
-
- hid->ff_exit = hid_pid_exit;
- hid->ff_event = hid_pid_event;
-
- /* Open output URB */
- if (!(private->urbffout = usb_alloc_urb(0, GFP_KERNEL))) {
- kfree(private);
- return -1;
- }
-
- usb_fill_control_urb(private->urbffout, hid->dev, 0,
- (void *)&private->ffcr, private->ctrl_buffer, 8,
- hid_pid_ctrl_out, hid);
-
- input_dev->upload_effect = hid_pid_upload_effect;
- input_dev->flush = hid_pid_flush;
- input_dev->ff_effects_max = 8; // A random default
- set_bit(EV_FF, input_dev->evbit);
- set_bit(EV_FF_STATUS, input_dev->evbit);
-
- spin_lock_init(&private->lock);
-
- printk(KERN_INFO "Force feedback driver for PID devices by Rodrigo Damazio <rdamazio@lsi.usp.br>.\n");
-
- return 0;
-}
diff --git a/drivers/usb/input/pid.h b/drivers/usb/input/pid.h
deleted file mode 100644
index a2cb9627ed0..00000000000
--- a/drivers/usb/input/pid.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * PID Force feedback support for hid devices.
- *
- * Copyright (c) 2002 Rodrigo Damazio.
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <rdamazio@lsi.usp.br>
- */
-
-#define FF_EFFECTS_MAX 64
-
-#define FF_PID_FLAGS_USED 1 /* If the effect exists */
-#define FF_PID_FLAGS_UPDATING 2 /* If the effect is being updated */
-#define FF_PID_FLAGS_PLAYING 3 /* If the effect is currently being played */
-
-#define FF_PID_FALSE 0
-#define FF_PID_TRUE 1
-
-struct hid_pid_effect {
- unsigned long flags;
- pid_t owner;
- unsigned int device_id; /* The device-assigned ID */
- struct ff_effect effect;
-};
-
-struct hid_ff_pid {
- struct hid_device *hid;
- unsigned long gain;
-
- struct urb *urbffout;
- struct usb_ctrlrequest ffcr;
- spinlock_t lock;
-
- unsigned char ctrl_buffer[8];
-
- struct hid_pid_effect effects[FF_EFFECTS_MAX];
-};
-
-/*
- * Constants from the PID usage table (still far from complete)
- */
-
-#define FF_PID_USAGE_BLOCK_LOAD 0x89UL
-#define FF_PID_USAGE_BLOCK_FREE 0x90UL
-#define FF_PID_USAGE_NEW_EFFECT 0xABUL
-#define FF_PID_USAGE_POOL_REPORT 0x7FUL
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
deleted file mode 100644
index b7476233ef5..00000000000
--- a/drivers/usb/input/powermate.c
+++ /dev/null
@@ -1,466 +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/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/usb.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, struct pt_regs *regs);
-
-/* Callback for data arriving from the PowerMate over the USB interrupt pipe */
-static void powermate_irq(struct urb *urb, struct pt_regs *regs)
-{
- 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_regs(pm->input, regs);
- 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 pt_regs *regs)
-{
- 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 = dev->private;
-
- if (type == EV_MSC && code == MSC_PULSELED){
- /*
- bits 0- 7: 8 bits: LED brightness
- bits 8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster.
- bits 17-18: 2 bits: pulse table (0, 1, 2 valid)
- bit 19: 1 bit : pulse whilst asleep?
- bit 20: 1 bit : pulse constantly?
- */
- int static_brightness = command & 0xFF; // bits 0-7
- int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16
- int pulse_table = (command >> 17) & 0x3; // bits 17-18
- int pulse_asleep = (command >> 19) & 0x1; // bit 19
- int pulse_awake = (command >> 20) & 0x1; // bit 20
-
- powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake);
- }
-
- 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,
- SLAB_ATOMIC, &pm->data_dma);
- if (!pm->data)
- return -1;
-
- pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
- SLAB_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 err = -ENOMEM;
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & 0x80))
- return -EIO;
- if ((endpoint->bmAttributes & 3) != 3)
- 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->cdev.dev = &intf->dev;
- input_dev->private = 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)) {
- err = -EIO;
- goto fail4;
- }
-
- input_register_device(pm->input);
-
- /* 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;
-
-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 err;
-}
-
-/* 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 = {
- .owner = THIS_MODULE,
- .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/touchkitusb.c b/drivers/usb/input/touchkitusb.c
deleted file mode 100644
index 0043e6ebcd1..00000000000
--- a/drivers/usb/input/touchkitusb.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/******************************************************************************
- * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens
- *
- * Copyright (C) 2004 by Daniel Ritz
- * 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.
- *
- * Based upon mtouchusb.c
- *
- *****************************************************************************/
-
-//#define DEBUG
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#if !defined(DEBUG) && defined(CONFIG_USB_DEBUG)
-#define DEBUG
-#endif
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-#define TOUCHKIT_MIN_XC 0x0
-#define TOUCHKIT_MAX_XC 0x07ff
-#define TOUCHKIT_XC_FUZZ 0x0
-#define TOUCHKIT_XC_FLAT 0x0
-#define TOUCHKIT_MIN_YC 0x0
-#define TOUCHKIT_MAX_YC 0x07ff
-#define TOUCHKIT_YC_FUZZ 0x0
-#define TOUCHKIT_YC_FLAT 0x0
-#define TOUCHKIT_REPORT_DATA_SIZE 8
-
-#define TOUCHKIT_DOWN 0x01
-#define TOUCHKIT_POINT_TOUCH 0x81
-#define TOUCHKIT_POINT_NOTOUCH 0x80
-
-#define TOUCHKIT_GET_TOUCHED(dat) ((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0)
-#define TOUCHKIT_GET_X(dat) (((dat)[3] << 7) | (dat)[4])
-#define TOUCHKIT_GET_Y(dat) (((dat)[1] << 7) | (dat)[2])
-
-#define DRIVER_VERSION "v0.1"
-#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
-#define DRIVER_DESC "eGalax TouchKit USB HID 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.");
-
-struct touchkit_usb {
- unsigned char *data;
- dma_addr_t data_dma;
- struct urb *irq;
- struct usb_device *udev;
- struct input_dev *input;
- char name[128];
- char phys[64];
-};
-
-static struct usb_device_id touchkit_devices[] = {
- {USB_DEVICE(0x3823, 0x0001)},
- {USB_DEVICE(0x0123, 0x0001)},
- {USB_DEVICE(0x0eef, 0x0001)},
- {USB_DEVICE(0x0eef, 0x0002)},
- {}
-};
-
-static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct touchkit_usb *touchkit = urb->context;
- int retval;
- int x, y;
-
- switch (urb->status) {
- case 0:
- /* success */
- break;
- case -ETIMEDOUT:
- /* this urb is timing out */
- dbg("%s - urb timed out - was the device unplugged?",
- __FUNCTION__);
- return;
- case -ECONNRESET:
- case -ENOENT:
- case -ESHUTDOWN:
- /* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d",
- __FUNCTION__, urb->status);
- return;
- default:
- dbg("%s - nonzero urb status received: %d",
- __FUNCTION__, urb->status);
- goto exit;
- }
-
- if (swap_xy) {
- y = TOUCHKIT_GET_X(touchkit->data);
- x = TOUCHKIT_GET_Y(touchkit->data);
- } else {
- x = TOUCHKIT_GET_X(touchkit->data);
- y = TOUCHKIT_GET_Y(touchkit->data);
- }
-
- input_regs(touchkit->input, regs);
- input_report_key(touchkit->input, BTN_TOUCH,
- TOUCHKIT_GET_TOUCHED(touchkit->data));
- input_report_abs(touchkit->input, ABS_X, x);
- input_report_abs(touchkit->input, ABS_Y, y);
- input_sync(touchkit->input);
-
-exit:
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (retval)
- err("%s - usb_submit_urb failed with result: %d",
- __FUNCTION__, retval);
-}
-
-static int touchkit_open(struct input_dev *input)
-{
- struct touchkit_usb *touchkit = input->private;
-
- touchkit->irq->dev = touchkit->udev;
-
- if (usb_submit_urb(touchkit->irq, GFP_ATOMIC))
- return -EIO;
-
- return 0;
-}
-
-static void touchkit_close(struct input_dev *input)
-{
- struct touchkit_usb *touchkit = input->private;
-
- usb_kill_urb(touchkit->irq);
-}
-
-static int touchkit_alloc_buffers(struct usb_device *udev,
- struct touchkit_usb *touchkit)
-{
- touchkit->data = usb_buffer_alloc(udev, TOUCHKIT_REPORT_DATA_SIZE,
- SLAB_ATOMIC, &touchkit->data_dma);
-
- if (!touchkit->data)
- return -1;
-
- return 0;
-}
-
-static void touchkit_free_buffers(struct usb_device *udev,
- struct touchkit_usb *touchkit)
-{
- if (touchkit->data)
- usb_buffer_free(udev, TOUCHKIT_REPORT_DATA_SIZE,
- touchkit->data, touchkit->data_dma);
-}
-
-static int touchkit_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct touchkit_usb *touchkit;
- struct input_dev *input_dev;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_device *udev = interface_to_usbdev(intf);
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
-
- touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!touchkit || !input_dev)
- goto out_free;
-
- if (touchkit_alloc_buffers(udev, touchkit))
- goto out_free;
-
- touchkit->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!touchkit->irq) {
- dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__);
- goto out_free_buffers;
- }
-
- touchkit->udev = udev;
- touchkit->input = input_dev;
-
- if (udev->manufacturer)
- strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name));
-
- if (udev->product) {
- if (udev->manufacturer)
- strlcat(touchkit->name, " ", sizeof(touchkit->name));
- strlcat(touchkit->name, udev->product, sizeof(touchkit->name));
- }
-
- if (!strlen(touchkit->name))
- snprintf(touchkit->name, sizeof(touchkit->name),
- "USB Touchscreen %04x:%04x",
- le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct));
-
- usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys));
- strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys));
-
- input_dev->name = touchkit->name;
- input_dev->phys = touchkit->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->cdev.dev = &intf->dev;
- input_dev->private = touchkit;
- input_dev->open = touchkit_open;
- input_dev->close = touchkit_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, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC,
- TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT);
- input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC,
- TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT);
-
- usb_fill_int_urb(touchkit->irq, touchkit->udev,
- usb_rcvintpipe(touchkit->udev, 0x81),
- touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
- touchkit_irq, touchkit, endpoint->bInterval);
-
- input_register_device(touchkit->input);
-
- usb_set_intfdata(intf, touchkit);
- return 0;
-
-out_free_buffers:
- touchkit_free_buffers(udev, touchkit);
-out_free:
- input_free_device(input_dev);
- kfree(touchkit);
- return -ENOMEM;
-}
-
-static void touchkit_disconnect(struct usb_interface *intf)
-{
- struct touchkit_usb *touchkit = usb_get_intfdata(intf);
-
- dbg("%s - called", __FUNCTION__);
-
- if (!touchkit)
- return;
-
- dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__);
- usb_set_intfdata(intf, NULL);
- usb_kill_urb(touchkit->irq);
- input_unregister_device(touchkit->input);
- usb_free_urb(touchkit->irq);
- touchkit_free_buffers(interface_to_usbdev(intf), touchkit);
- kfree(touchkit);
-}
-
-MODULE_DEVICE_TABLE(usb, touchkit_devices);
-
-static struct usb_driver touchkit_driver = {
- .owner = THIS_MODULE,
- .name = "touchkitusb",
- .probe = touchkit_probe,
- .disconnect = touchkit_disconnect,
- .id_table = touchkit_devices,
-};
-
-static int __init touchkit_init(void)
-{
- return usb_register(&touchkit_driver);
-}
-
-static void __exit touchkit_cleanup(void)
-{
- usb_deregister(&touchkit_driver);
-}
-
-module_init(touchkit_init);
-module_exit(touchkit_cleanup);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
deleted file mode 100644
index 226b6f90a90..00000000000
--- a/drivers/usb/input/usbkbd.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * $Id: usbkbd.c,v 1.27 2001/12/27 10:37:41 vojtech Exp $
- *
- * Copyright (c) 1999-2001 Vojtech Pavlik
- *
- * USB HIDBP Keyboard 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/input.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION ""
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-static unsigned char usb_kbd_keycode[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
- 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
- 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
- 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
- 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
- 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
- 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
- 122,123, 90, 91, 85, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140
-};
-
-struct usb_kbd {
- struct input_dev *dev;
- struct usb_device *usbdev;
- unsigned char old[8];
- struct urb *irq, *led;
- unsigned char newleds;
- char name[128];
- char phys[64];
-
- unsigned char *new;
- struct usb_ctrlrequest *cr;
- unsigned char *leds;
- dma_addr_t cr_dma;
- dma_addr_t new_dma;
- dma_addr_t leds_dma;
-};
-
-static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct usb_kbd *kbd = urb->context;
- int i;
-
- switch (urb->status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- input_regs(kbd->dev, regs);
-
- for (i = 0; i < 8; i++)
- input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
-
- for (i = 2; i < 8; i++) {
-
- if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
- if (usb_kbd_keycode[kbd->old[i]])
- input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
- else
- info("Unknown key (scancode %#x) released.", kbd->old[i]);
- }
-
- if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
- if (usb_kbd_keycode[kbd->new[i]])
- input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
- else
- info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
- }
- }
-
- input_sync(kbd->dev);
-
- memcpy(kbd->old, kbd->new, 8);
-
-resubmit:
- i = usb_submit_urb (urb, SLAB_ATOMIC);
- if (i)
- err ("can't resubmit intr, %s-%s/input0, status %d",
- kbd->usbdev->bus->bus_name,
- kbd->usbdev->devpath, i);
-}
-
-static int usb_kbd_event(struct input_dev *dev, unsigned int type,
- unsigned int code, int value)
-{
- struct usb_kbd *kbd = dev->private;
-
- if (type != EV_LED)
- return -1;
-
-
- kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
- (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
- (!!test_bit(LED_NUML, dev->led));
-
- if (kbd->led->status == -EINPROGRESS)
- return 0;
-
- if (*(kbd->leds) == kbd->newleds)
- return 0;
-
- *(kbd->leds) = kbd->newleds;
- kbd->led->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- err("usb_submit_urb(leds) failed");
-
- return 0;
-}
-
-static void usb_kbd_led(struct urb *urb, struct pt_regs *regs)
-{
- struct usb_kbd *kbd = urb->context;
-
- if (urb->status)
- warn("led urb status %d received", urb->status);
-
- if (*(kbd->leds) == kbd->newleds)
- return;
-
- *(kbd->leds) = kbd->newleds;
- kbd->led->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->led, GFP_ATOMIC))
- err("usb_submit_urb(leds) failed");
-}
-
-static int usb_kbd_open(struct input_dev *dev)
-{
- struct usb_kbd *kbd = dev->private;
-
- kbd->irq->dev = kbd->usbdev;
- if (usb_submit_urb(kbd->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usb_kbd_close(struct input_dev *dev)
-{
- struct usb_kbd *kbd = dev->private;
-
- usb_kill_urb(kbd->irq);
-}
-
-static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
-{
- if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL)))
- return -1;
- if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
- return -1;
- if (!(kbd->new = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbd->new_dma)))
- return -1;
- if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), SLAB_ATOMIC, &kbd->cr_dma)))
- return -1;
- if (!(kbd->leds = usb_buffer_alloc(dev, 1, SLAB_ATOMIC, &kbd->leds_dma)))
- return -1;
-
- return 0;
-}
-
-static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
-{
- if (kbd->irq)
- usb_free_urb(kbd->irq);
- if (kbd->led)
- usb_free_urb(kbd->led);
- if (kbd->new)
- usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
- if (kbd->cr)
- usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
- if (kbd->leds)
- usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
-}
-
-static int usb_kbd_probe(struct usb_interface *iface,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(iface);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_kbd *kbd;
- struct input_dev *input_dev;
- int i, pipe, maxp;
-
- interface = iface->cur_altsetting;
-
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & USB_DIR_IN))
- return -ENODEV;
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
- return -ENODEV;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!kbd || !input_dev)
- goto fail1;
-
- if (usb_kbd_alloc_mem(dev, kbd))
- goto fail2;
-
- kbd->usbdev = dev;
- kbd->dev = input_dev;
-
- if (dev->manufacturer)
- strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(kbd->name, " ", sizeof(kbd->name));
- strlcat(kbd->name, dev->product, sizeof(kbd->name));
- }
-
- if (!strlen(kbd->name))
- snprintf(kbd->name, sizeof(kbd->name),
- "USB HIDBP Keyboard %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
- strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
-
- input_dev->name = kbd->name;
- input_dev->phys = kbd->phys;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->cdev.dev = &iface->dev;
- input_dev->private = kbd;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
- input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
-
- for (i = 0; i < 255; i++)
- set_bit(usb_kbd_keycode[i], input_dev->keybit);
- clear_bit(0, input_dev->keybit);
-
- input_dev->event = usb_kbd_event;
- input_dev->open = usb_kbd_open;
- input_dev->close = usb_kbd_close;
-
- usb_fill_int_urb(kbd->irq, dev, pipe,
- kbd->new, (maxp > 8 ? 8 : maxp),
- usb_kbd_irq, kbd, endpoint->bInterval);
- kbd->irq->transfer_dma = kbd->new_dma;
- kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- kbd->cr->bRequest = 0x09;
- kbd->cr->wValue = cpu_to_le16(0x200);
- kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
- kbd->cr->wLength = cpu_to_le16(1);
-
- usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
- (void *) kbd->cr, kbd->leds, 1,
- usb_kbd_led, kbd);
- kbd->led->setup_dma = kbd->cr_dma;
- kbd->led->transfer_dma = kbd->leds_dma;
- kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
-
- input_register_device(kbd->dev);
-
- usb_set_intfdata(iface, kbd);
- return 0;
-
-fail2: usb_kbd_free_mem(dev, kbd);
-fail1: input_free_device(input_dev);
- kfree(kbd);
- return -ENOMEM;
-}
-
-static void usb_kbd_disconnect(struct usb_interface *intf)
-{
- struct usb_kbd *kbd = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (kbd) {
- usb_kill_urb(kbd->irq);
- input_unregister_device(kbd->dev);
- usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
- kfree(kbd);
- }
-}
-
-static struct usb_device_id usb_kbd_id_table [] = {
- { USB_INTERFACE_INFO(3, 1, 1) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
-
-static struct usb_driver usb_kbd_driver = {
- .owner = THIS_MODULE,
- .name = "usbkbd",
- .probe = usb_kbd_probe,
- .disconnect = usb_kbd_disconnect,
- .id_table = usb_kbd_id_table,
-};
-
-static int __init usb_kbd_init(void)
-{
- int result = usb_register(&usb_kbd_driver);
- if (result == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
- return result;
-}
-
-static void __exit usb_kbd_exit(void)
-{
- usb_deregister(&usb_kbd_driver);
-}
-
-module_init(usb_kbd_init);
-module_exit(usb_kbd_exit);
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
deleted file mode 100644
index 230f6b1b314..00000000000
--- a/drivers/usb/input/usbmouse.c
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * $Id: usbmouse.c,v 1.15 2001/12/27 10:37:41 vojtech Exp $
- *
- * Copyright (c) 1999-2001 Vojtech Pavlik
- *
- * USB HIDBP Mouse 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#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>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.6"
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB HID Boot Protocol mouse driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-struct usb_mouse {
- char name[128];
- char phys[64];
- struct usb_device *usbdev;
- struct input_dev *dev;
- struct urb *irq;
-
- signed char *data;
- dma_addr_t data_dma;
-};
-
-static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct usb_mouse *mouse = urb->context;
- signed char *data = mouse->data;
- struct input_dev *dev = mouse->dev;
- int status;
-
- switch (urb->status) {
- case 0: /* success */
- break;
- case -ECONNRESET: /* unlink */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- /* -EPIPE: should clear the halt */
- default: /* error */
- goto resubmit;
- }
-
- input_regs(dev, regs);
-
- input_report_key(dev, BTN_LEFT, data[0] & 0x01);
- input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
- input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
- input_report_key(dev, BTN_SIDE, data[0] & 0x08);
- input_report_key(dev, BTN_EXTRA, data[0] & 0x10);
-
- input_report_rel(dev, REL_X, data[1]);
- input_report_rel(dev, REL_Y, data[2]);
- input_report_rel(dev, REL_WHEEL, data[3]);
-
- input_sync(dev);
-resubmit:
- status = usb_submit_urb (urb, SLAB_ATOMIC);
- if (status)
- err ("can't resubmit intr, %s-%s/input0, status %d",
- mouse->usbdev->bus->bus_name,
- mouse->usbdev->devpath, status);
-}
-
-static int usb_mouse_open(struct input_dev *dev)
-{
- struct usb_mouse *mouse = dev->private;
-
- mouse->irq->dev = mouse->usbdev;
- if (usb_submit_urb(mouse->irq, GFP_KERNEL))
- return -EIO;
-
- return 0;
-}
-
-static void usb_mouse_close(struct input_dev *dev)
-{
- struct usb_mouse *mouse = dev->private;
-
- usb_kill_urb(mouse->irq);
-}
-
-static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- struct usb_mouse *mouse;
- struct input_dev *input_dev;
- int pipe, maxp;
-
- interface = intf->cur_altsetting;
-
- if (interface->desc.bNumEndpoints != 1)
- return -ENODEV;
-
- endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & USB_DIR_IN))
- return -ENODEV;
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
- return -ENODEV;
-
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!mouse || !input_dev)
- goto fail1;
-
- mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
- if (!mouse->data)
- goto fail1;
-
- mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
- if (!mouse->irq)
- goto fail2;
-
- mouse->usbdev = dev;
- mouse->dev = input_dev;
-
- if (dev->manufacturer)
- strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
-
- if (dev->product) {
- if (dev->manufacturer)
- strlcat(mouse->name, " ", sizeof(mouse->name));
- strlcat(mouse->name, dev->product, sizeof(mouse->name));
- }
-
- if (!strlen(mouse->name))
- snprintf(mouse->name, sizeof(mouse->name),
- "USB HIDBP Mouse %04x:%04x",
- le16_to_cpu(dev->descriptor.idVendor),
- le16_to_cpu(dev->descriptor.idProduct));
-
- usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
- strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
-
- input_dev->name = mouse->name;
- input_dev->phys = mouse->phys;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->cdev.dev = &intf->dev;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- input_dev->relbit[0] |= BIT(REL_WHEEL);
-
- input_dev->private = mouse;
- input_dev->open = usb_mouse_open;
- input_dev->close = usb_mouse_close;
-
- usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
- (maxp > 8 ? 8 : maxp),
- usb_mouse_irq, mouse, endpoint->bInterval);
- mouse->irq->transfer_dma = mouse->data_dma;
- mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- input_register_device(mouse->dev);
-
- usb_set_intfdata(intf, mouse);
- return 0;
-
-fail2: usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
-fail1: input_free_device(input_dev);
- kfree(mouse);
- return -ENOMEM;
-}
-
-static void usb_mouse_disconnect(struct usb_interface *intf)
-{
- struct usb_mouse *mouse = usb_get_intfdata (intf);
-
- usb_set_intfdata(intf, NULL);
- if (mouse) {
- usb_kill_urb(mouse->irq);
- input_unregister_device(mouse->dev);
- usb_free_urb(mouse->irq);
- usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
- kfree(mouse);
- }
-}
-
-static struct usb_device_id usb_mouse_id_table [] = {
- { USB_INTERFACE_INFO(3, 1, 2) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
-
-static struct usb_driver usb_mouse_driver = {
- .owner = THIS_MODULE,
- .name = "usbmouse",
- .probe = usb_mouse_probe,
- .disconnect = usb_mouse_disconnect,
- .id_table = usb_mouse_id_table,
-};
-
-static int __init usb_mouse_init(void)
-{
- int retval = usb_register(&usb_mouse_driver);
- if (retval == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
- return retval;
-}
-
-static void __exit usb_mouse_exit(void)
-{
- usb_deregister(&usb_mouse_driver);
-}
-
-module_init(usb_mouse_init);
-module_exit(usb_mouse_exit);
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
deleted file mode 100644
index ea0f75773ae..00000000000
--- a/drivers/usb/input/wacom.c
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
- * 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-2005 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
- */
-
-/*
- * 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 <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/input.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-#include <asm/unaligned.h>
-#include <asm/byteorder.h>
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.43"
-#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
-#define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
-#define DRIVER_LICENSE "GPL"
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-#define USB_VENDOR_ID_WACOM 0x056a
-
-enum {
- PENPARTNER = 0,
- GRAPHIRE,
- PL,
- INTUOS,
- INTUOS3,
- CINTIQ,
- MAX_TYPE
-};
-
-struct wacom_features {
- char *name;
- int pktlen;
- int x_max;
- int y_max;
- int pressure_max;
- int distance_max;
- int type;
- usb_complete_t irq;
-};
-
-struct wacom {
- signed char *data;
- dma_addr_t data_dma;
- struct input_dev *dev;
- struct usb_device *usbdev;
- struct urb *irq;
- struct wacom_features *features;
- int tool[2];
- __u32 serial[2];
- char phys[32];
-};
-
-#define USB_REQ_SET_REPORT 0x09
-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 void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->dev;
- int prox, pressure;
- 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;
- }
-
- if (data[0] != 2) {
- dbg("wacom_pl_irq: received unknown report #%d", data[0]);
- goto exit;
- }
-
- prox = data[1] & 0x40;
-
- input_regs(dev, regs);
-
- 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]) {
- /* 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 */
- input_report_key(dev, wacom->tool[1], 0);
- input_sync(dev);
- wacom->tool[1] = BTN_TOOL_PEN;
- goto exit;
- }
- }
- if (wacom->tool[1] != BTN_TOOL_RUBBER) {
- /* Unknown tool selected default to pen tool */
- wacom->tool[1] = BTN_TOOL_PEN;
- }
- input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
- input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
- input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
- input_report_abs(dev, ABS_PRESSURE, pressure);
-
- input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
- input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
- /* Only allow the stylus2 button to be reported for the pen tool. */
- input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
- } else {
- /* 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;
- }
- input_report_key(dev, wacom->tool[1], prox);
- }
-
- wacom->tool[0] = prox; /* Save proximity state */
- input_sync(dev);
-
- exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->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;
- }
-
- if (data[0] != 2) {
- printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
- goto exit;
- }
-
- input_regs(dev, regs);
- if (data[1] & 0x04) {
- input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
- input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
- } else {
- input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
- input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
- }
- input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[2]));
- input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[4]));
- input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
- input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
- input_report_key(dev, BTN_STYLUS2, data[1] & 0x10);
-
- input_sync(dev);
-
- exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->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;
- }
-
- if (data[0] != 2) {
- printk(KERN_INFO "wacom_penpartner_irq: received unknown report #%d\n", data[0]);
- goto exit;
- }
-
- input_regs(dev, regs);
- input_report_key(dev, BTN_TOOL_PEN, 1);
- input_report_abs(dev, ABS_X, le16_to_cpu(*(__le16 *) &data[1]));
- input_report_abs(dev, ABS_Y, le16_to_cpu(*(__le16 *) &data[3]));
- input_report_abs(dev, ABS_PRESSURE, (signed char)data[6] + 127);
- input_report_key(dev, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
- input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
- input_sync(dev);
-
- exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->dev;
- int x, y;
- 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;
- }
-
- if (data[0] != 2) {
- dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
- goto exit;
- }
-
- input_regs(dev, regs);
-
- if (data[1] & 0x10) { /* 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;
- break;
-
- case 2: /* Mouse with wheel */
- input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
- input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
- /* fall through */
-
- case 3: /* Mouse without wheel */
- wacom->tool[0] = BTN_TOOL_MOUSE;
- input_report_key(dev, BTN_LEFT, data[1] & 0x01);
- input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
- input_report_abs(dev, ABS_DISTANCE, data[7]);
- break;
- }
- }
-
- if (data[1] & 0x90) {
- x = le16_to_cpu(*(__le16 *) &data[2]);
- y = le16_to_cpu(*(__le16 *) &data[4]);
- input_report_abs(dev, ABS_X, x);
- input_report_abs(dev, ABS_Y, y);
- if (wacom->tool[0] != BTN_TOOL_MOUSE) {
- input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
- input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
- input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
- input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
- }
- }
-
- input_report_key(dev, wacom->tool[0], data[1] & 0x10);
- 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 int wacom_intuos_inout(struct urb *urb)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->dev;
- 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);
-
- switch ((data[2] << 4) | (data[3] >> 4)) {
- 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;
- }
- input_report_key(dev, wacom->tool[idx], 1);
- input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- input_sync(dev);
- return 1;
- }
-
- /* Exit report */
- if ((data[1] & 0xfe) == 0x80) {
- input_report_key(dev, wacom->tool[idx], 0);
- input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- input_sync(dev);
- return 1;
- }
-
- return 0;
-}
-
-static void wacom_intuos_general(struct urb *urb)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->dev;
- unsigned int t;
-
- /* general pen packet */
- if ((data[1] & 0xb8) == 0xa0) {
- t = (data[6] << 2) | ((data[7] >> 6) & 3);
- input_report_abs(dev, ABS_PRESSURE, t);
- input_report_abs(dev, ABS_TILT_X,
- ((data[7] << 1) & 0x7e) | (data[8] >> 7));
- input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
- input_report_key(dev, BTN_STYLUS, data[1] & 2);
- input_report_key(dev, BTN_STYLUS2, data[1] & 4);
- input_report_key(dev, BTN_TOUCH, t > 10);
- }
-
- /* airbrush second packet */
- if ((data[1] & 0xbc) == 0xb4) {
- input_report_abs(dev, ABS_WHEEL,
- (data[6] << 2) | ((data[7] >> 6) & 3));
- input_report_abs(dev, ABS_TILT_X,
- ((data[7] << 1) & 0x7e) | (data[8] >> 7));
- input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
- }
- return;
-}
-
-static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
-{
- struct wacom *wacom = urb->context;
- unsigned char *data = wacom->data;
- struct input_dev *dev = wacom->dev;
- unsigned int t;
- int idx;
- 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;
- }
-
- if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
- dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
- goto exit;
- }
-
- input_regs(dev, regs);
-
- /* 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;
- input_report_key(dev, wacom->tool[1], 1);
- }
- input_report_key(dev, BTN_0, (data[5] & 0x01));
- input_report_key(dev, BTN_1, (data[5] & 0x02));
- input_report_key(dev, BTN_2, (data[5] & 0x04));
- input_report_key(dev, BTN_3, (data[5] & 0x08));
- input_report_key(dev, BTN_4, (data[6] & 0x01));
- input_report_key(dev, BTN_5, (data[6] & 0x02));
- input_report_key(dev, BTN_6, (data[6] & 0x04));
- input_report_key(dev, BTN_7, (data[6] & 0x08));
- input_report_abs(dev, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
- input_report_abs(dev, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
- input_event(dev, EV_MSC, MSC_SERIAL, 0xffffffff);
- input_sync(dev);
- goto exit;
- }
-
- /* process in/out prox events */
- if (wacom_intuos_inout(urb))
- goto exit;
-
- /* Cintiq doesn't send data when RDY bit isn't set */
- if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
- goto exit;
-
- if (wacom->features->type >= INTUOS3) {
- input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
- input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
- input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
- } else {
- input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
- input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
- input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
- }
-
- /* process general packets */
- wacom_intuos_general(urb);
-
- /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
- if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
-
- if (data[1] & 0x02) {
- /* Rotation packet */
- if (wacom->features->type >= INTUOS3) {
- /* I3 marker pen rotation reported as wheel
- * due to valuator limitation
- */
- t = (data[6] << 3) | ((data[7] >> 5) & 7);
- t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
- ((t-1) / 2 + 450)) : (450 - t / 2) ;
- input_report_abs(dev, ABS_WHEEL, t);
- } else {
- /* 4D mouse rotation packet */
- t = (data[6] << 3) | ((data[7] >> 5) & 7);
- input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
- ((t - 1) / 2) : -t / 2);
- }
-
- } else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
- /* 4D mouse packet */
- input_report_key(dev, BTN_LEFT, data[8] & 0x01);
- input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
- input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
-
- input_report_key(dev, BTN_SIDE, data[8] & 0x20);
- input_report_key(dev, BTN_EXTRA, data[8] & 0x10);
- t = (data[6] << 2) | ((data[7] >> 6) & 3);
- input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
-
- } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
- /* 2D mouse packet */
- input_report_key(dev, BTN_LEFT, data[8] & 0x04);
- input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
- input_report_key(dev, BTN_RIGHT, data[8] & 0x10);
- input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1)
- - (data[8] & 0x01));
-
- /* I3 2D mouse side buttons */
- if (wacom->features->type == INTUOS3) {
- input_report_key(dev, BTN_SIDE, data[8] & 0x40);
- input_report_key(dev, BTN_EXTRA, data[8] & 0x20);
- }
-
- } else if (wacom->features->type < INTUOS3) {
- /* Lens cursor packets */
- input_report_key(dev, BTN_LEFT, data[8] & 0x01);
- input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
- input_report_key(dev, BTN_RIGHT, data[8] & 0x04);
- input_report_key(dev, BTN_SIDE, data[8] & 0x10);
- input_report_key(dev, BTN_EXTRA, data[8] & 0x08);
- }
- }
-
- input_report_key(dev, wacom->tool[idx], 1);
- input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
- input_sync(dev);
-
-exit:
- retval = usb_submit_urb (urb, GFP_ATOMIC);
- if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __FUNCTION__, retval);
-}
-
-static struct wacom_features wacom_features[] = {
- { "Wacom Penpartner", 7, 5040, 3780, 255, 32, PENPARTNER, wacom_penpartner_irq },
- { "Wacom Graphire", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom PL400", 8, 5408, 4056, 255, 32, PL, wacom_pl_irq },
- { "Wacom PL500", 8, 6144, 4608, 255, 32, PL, wacom_pl_irq },
- { "Wacom PL600", 8, 6126, 4604, 255, 32, PL, wacom_pl_irq },
- { "Wacom PL600SX", 8, 6260, 5016, 255, 32, PL, wacom_pl_irq },
- { "Wacom PL550", 8, 6144, 4608, 511, 32, PL, wacom_pl_irq },
- { "Wacom PL800", 8, 7220, 5780, 511, 32, PL, wacom_pl_irq },
- { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS, wacom_intuos_irq },
- { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq },
- { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, PL, wacom_ptu_irq },
- { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 15, INTUOS3, wacom_intuos_irq },
- { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 15, INTUOS3, wacom_intuos_irq },
- { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 15, INTUOS3, wacom_intuos_irq },
- { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 15, CINTIQ, wacom_intuos_irq },
- { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, INTUOS, wacom_intuos_irq },
- { }
-};
-
-static struct usb_device_id wacom_ids[] = {
- { 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, 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, 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, 0x60) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
- { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
- { }
-};
-
-MODULE_DEVICE_TABLE(usb, wacom_ids);
-
-static int wacom_open(struct input_dev *dev)
-{
- struct wacom *wacom = dev->private;
-
- 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 = dev->private;
-
- usb_kill_urb(wacom->irq);
-}
-
-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 input_dev *input_dev;
- char rep_data[2] = {0x02, 0x02};
-
- wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!wacom || !input_dev)
- goto fail1;
-
- wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
- if (!wacom->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->features = wacom_features + (id - wacom_ids);
- if (wacom->features->pktlen > 10)
- BUG();
-
- input_dev->name = wacom->features->name;
- usb_to_input_id(dev, &input_dev->id);
-
- input_dev->cdev.dev = &intf->dev;
- input_dev->private = 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->features->y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
-
- switch (wacom->features->type) {
- case GRAPHIRE:
- 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->features->distance_max, 0, 0);
- break;
-
- case INTUOS3:
- case CINTIQ:
- 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) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
- input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
- input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
- /* fall through */
-
- case INTUOS:
- 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->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);
- break;
-
- case PL:
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
- break;
- }
-
- endpoint = &intf->cur_altsetting->endpoint[0].desc;
-
- if (wacom->features->pktlen > 10)
- BUG();
-
- usb_fill_int_urb(wacom->irq, dev,
- usb_rcvintpipe(dev, endpoint->bEndpointAddress),
- wacom->data, wacom->features->pktlen,
- wacom->features->irq, wacom, endpoint->bInterval);
- wacom->irq->transfer_dma = wacom->data_dma;
- wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- input_register_device(wacom->dev);
-
- /* ask the tablet to report tablet data */
- usb_set_report(intf, 3, 2, rep_data, 2);
- /* repeat once (not sure why the first call often fails) */
- usb_set_report(intf, 3, 2, rep_data, 2);
-
- usb_set_intfdata(intf, wacom);
- return 0;
-
-fail2: usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
-fail1: input_free_device(input_dev);
- kfree(wacom);
- return -ENOMEM;
-}
-
-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->data, wacom->data_dma);
- kfree(wacom);
- }
-}
-
-static struct usb_driver wacom_driver = {
- .owner = THIS_MODULE,
- .name = "wacom",
- .probe = wacom_probe,
- .disconnect = wacom_disconnect,
- .id_table = wacom_ids,
-};
-
-static int __init wacom_init(void)
-{
- int 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/xpad.c b/drivers/usb/input/xpad.c
deleted file mode 100644
index 43112f040b6..00000000000
--- a/drivers/usb/input/xpad.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * X-Box gamepad - v0.0.5
- *
- * Copyright (c) 2002 Marko Friedemann <mfr@bmx-chemnitz.de>
- *
- *
- * 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
- *
- * TODO:
- * - fine tune axes
- * - fix "analog" buttons (reported as digital now)
- * - get rumble working
- *
- * 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
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/smp_lock.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-#define DRIVER_VERSION "v0.0.5"
-#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
-#define DRIVER_DESC "X-Box pad driver"
-
-#define XPAD_PKT_LEN 32
-
-static struct xpad_device {
- u16 idVendor;
- u16 idProduct;
- char *name;
-} xpad_device[] = {
- { 0x045e, 0x0202, "Microsoft X-Box pad (US)" },
- { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)" },
- { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)" },
- { 0x0000, 0x0000, "X-Box pad" }
-};
-
-static 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 */
-};
-
-static signed short xpad_abs[] = {
- ABS_X, ABS_Y, /* left stick */
- ABS_RX, ABS_RY, /* right stick */
- ABS_Z, ABS_RZ, /* triggers left/right */
- ABS_HAT0X, ABS_HAT0Y, /* digital pad */
- -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 */
-};
-
-/*
- * 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 pt_regs *regs)
-{
- struct input_dev *dev = xpad->dev;
-
- input_regs(dev, regs);
-
- /* left stick */
- input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
- input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14]));
-
- /* right stick */
- input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16]));
- input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18]));
-
- /* triggers left/right */
- input_report_abs(dev, ABS_Z, data[10]);
- input_report_abs(dev, ABS_RZ, data[11]);
-
- /* digital pad */
- input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
- input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
-
- /* start/back buttons and stick press left/right */
- input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
- input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
- input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
- input_report_key(dev, BTN_THUMBR, data[2] >> 7);
-
- /* "analog" buttons A, B, X, Y */
- input_report_key(dev, BTN_A, data[4]);
- input_report_key(dev, BTN_B, data[5]);
- input_report_key(dev, BTN_X, data[6]);
- input_report_key(dev, BTN_Y, data[7]);
-
- /* "analog" buttons black, white */
- input_report_key(dev, BTN_C, data[8]);
- input_report_key(dev, BTN_Z, data[9]);
-
- input_sync(dev);
-}
-
-static void xpad_irq_in(struct urb *urb, struct pt_regs *regs)
-{
- struct usb_xpad *xpad = urb->context;
- int retval;
-
- switch (urb->status) {
- case 0:
- /* success */
- 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, regs);
-
-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 = dev->private;
-
- 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 = dev->private;
-
- usb_kill_urb(xpad->irq_in);
-}
-
-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;
-
- 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,
- SLAB_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->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->cdev.dev = &intf->dev;
- input_dev->private = xpad;
- input_dev->open = xpad_open;
- input_dev->close = xpad_close;
-
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
- for (i = 0; xpad_btn[i] >= 0; i++)
- set_bit(xpad_btn[i], input_dev->keybit);
-
- for (i = 0; xpad_abs[i] >= 0; i++) {
-
- signed short t = xpad_abs[i];
-
- set_bit(t, input_dev->absbit);
-
- switch (t) {
- case ABS_X:
- case ABS_Y:
- case ABS_RX:
- case ABS_RY: /* the two sticks */
- input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
- break;
- case ABS_Z:
- case ABS_RZ: /* the triggers */
- input_set_abs_params(input_dev, t, 0, 255, 0, 0);
- break;
- case ABS_HAT0X:
- case ABS_HAT0Y: /* the d-pad */
- input_set_abs_params(input_dev, t, -1, 1, 0, 0);
- break;
- }
- }
-
- 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;
-
- input_register_device(xpad->dev);
-
- usb_set_intfdata(intf, xpad);
- return 0;
-
-fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
-fail1: input_free_device(input_dev);
- kfree(xpad);
- return -ENOMEM;
-
-}
-
-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 = {
- .owner = THIS_MODULE,
- .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 f526aebea50..00000000000
--- a/drivers/usb/input/yealink.c
+++ /dev/null
@@ -1,1017 +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/config.h>
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/rwsem.h>
-#include <linux/usb.h>
-#include <linux/usb_input.h>
-
-#include "map_to_7segment.h"
-#include "yealink.h"
-
-#define DRIVER_VERSION "yld-20050816"
-#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 pt_regs *regs)
-{
- struct input_dev *idev = yld->idev;
-
- input_regs(idev, regs);
- 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 pt_regs *regs)
-{
- 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]), regs);
- 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 pt_regs *regs)
-{
- 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 = dev->private;
- 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 = dev->private;
-
- 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
- ******************************************************************************/
-
-static const struct yld_device {
- u16 idVendor;
- u16 idProduct;
- char *name;
-} yld_device[] = {
- { 0x6993, 0xb001, "Yealink usb-p1k" },
-};
-
-static struct usb_device_id usb_table [] = {
- { USB_INTERFACE_INFO(USB_CLASS_HID, 0, 0) },
- { }
-};
-
-static int usb_cleanup(struct yealink_dev *yld, int err)
-{
- if (yld == NULL)
- return err;
-
- if (yld->urb_irq) {
- usb_kill_urb(yld->urb_irq);
- usb_free_urb(yld->urb_irq);
- }
- if (yld->urb_ctl)
- usb_free_urb(yld->urb_ctl);
- 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);
- 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_match(struct usb_device *udev)
-{
- int i;
- u16 idVendor = le16_to_cpu(udev->descriptor.idVendor);
- u16 idProduct = le16_to_cpu(udev->descriptor.idProduct);
-
- for (i = 0; i < ARRAY_SIZE(yld_device); i++) {
- if ((idVendor == yld_device[i].idVendor) &&
- (idProduct == yld_device[i].idProduct))
- return i;
- }
- return -ENODEV;
-}
-
-static int usb_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 yealink_dev *yld;
- struct input_dev *input_dev;
- int ret, pipe, i;
-
- i = usb_match(udev);
- if (i < 0)
- return -ENODEV;
-
- interface = intf->cur_altsetting;
- endpoint = &interface->endpoint[0].desc;
- if (!(endpoint->bEndpointAddress & USB_DIR_IN))
- return -EIO;
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
- return -EIO;
-
- 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,
- SLAB_ATOMIC, &yld->irq_dma);
- if (yld->irq_data == NULL)
- return usb_cleanup(yld, -ENOMEM);
-
- yld->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
- SLAB_ATOMIC, &yld->ctl_dma);
- if (!yld->ctl_data)
- return usb_cleanup(yld, -ENOMEM);
-
- yld->ctl_req = usb_buffer_alloc(udev, sizeof(*(yld->ctl_req)),
- SLAB_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 %d", 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 = yld_device[i].name;
- input_dev->phys = yld->phys;
- usb_to_input_id(udev, &input_dev->id);
- input_dev->cdev.dev = &intf->dev;
-
- input_dev->private = 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);
- }
- }
-
- input_register_device(yld->idev);
-
- 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) */
- sysfs_create_group(&intf->dev.kobj, &yld_attr_group);
- return 0;
-}
-
-static struct usb_driver yealink_driver = {
- .owner = THIS_MODULE,
- .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 */