diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/input/mouse/synaptics_usb.c')
-rw-r--r-- | ANDROID_3.4.5/drivers/input/mouse/synaptics_usb.c | 557 |
1 files changed, 0 insertions, 557 deletions
diff --git a/ANDROID_3.4.5/drivers/input/mouse/synaptics_usb.c b/ANDROID_3.4.5/drivers/input/mouse/synaptics_usb.c deleted file mode 100644 index 3c5eaaa5..00000000 --- a/ANDROID_3.4.5/drivers/input/mouse/synaptics_usb.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * USB Synaptics device driver - * - * Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk) - * Copyright (c) 2003 Ron Lee (ron@debian.org) - * cPad driver for kernel 2.4 - * - * Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de) - * Copyright (c) 2004 Ron Lee (ron@debian.org) - * rewritten for kernel 2.6 - * - * cPad display character device part is not included. It can be found at - * http://jan-steinhoff.de/linux/synaptics-usb.html - * - * Bases on: usb_skeleton.c v2.2 by Greg Kroah-Hartman - * drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik - * drivers/input/mouse/synaptics.c by Peter Osterlund - * - * 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. - * - * Trademarks are the property of their respective owners. - */ - -/* - * There are three different types of Synaptics USB devices: Touchpads, - * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported - * by this driver, touchstick support has not been tested much yet, and - * touchscreens have not been tested at all. - * - * Up to three alternate settings are possible: - * setting 0: one int endpoint for relative movement (used by usbhid.ko) - * setting 1: one int endpoint for absolute finger position - * setting 2 (cPad only): one int endpoint for absolute finger position and - * two bulk endpoints for the display (in/out) - * This driver uses setting 1. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/usb.h> -#include <linux/input.h> -#include <linux/usb/input.h> - -#define USB_VENDOR_ID_SYNAPTICS 0x06cb -#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 /* Synaptics USB TouchPad */ -#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 /* Integrated USB TouchPad */ -#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 /* Synaptics cPad */ -#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 /* Synaptics TouchScreen */ -#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 /* Synaptics USB Styk */ -#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 /* Synaptics USB WheelPad */ -#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 /* Composite USB TouchPad */ -#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 /* Wireless TouchPad */ -#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 /* DisplayPad */ - -#define SYNUSB_TOUCHPAD (1 << 0) -#define SYNUSB_STICK (1 << 1) -#define SYNUSB_TOUCHSCREEN (1 << 2) -#define SYNUSB_AUXDISPLAY (1 << 3) /* For cPad */ -#define SYNUSB_COMBO (1 << 4) /* Composite device (TP + stick) */ -#define SYNUSB_IO_ALWAYS (1 << 5) - -#define USB_DEVICE_SYNAPTICS(prod, kind) \ - USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, \ - USB_DEVICE_ID_SYNAPTICS_##prod), \ - .driver_info = (kind), - -#define SYNUSB_RECV_SIZE 8 - -#define XMIN_NOMINAL 1472 -#define XMAX_NOMINAL 5472 -#define YMIN_NOMINAL 1408 -#define YMAX_NOMINAL 4448 - -struct synusb { - struct usb_device *udev; - struct usb_interface *intf; - struct urb *urb; - unsigned char *data; - - /* input device related data structures */ - struct input_dev *input; - char name[128]; - char phys[64]; - - /* characteristics of the device */ - unsigned long flags; -}; - -static void synusb_report_buttons(struct synusb *synusb) -{ - struct input_dev *input_dev = synusb->input; - - input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04); - input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01); - input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02); -} - -static void synusb_report_stick(struct synusb *synusb) -{ - struct input_dev *input_dev = synusb->input; - int x, y; - unsigned int pressure; - - pressure = synusb->data[6]; - x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7; - y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7; - - if (pressure > 0) { - input_report_rel(input_dev, REL_X, x); - input_report_rel(input_dev, REL_Y, -y); - } - - input_report_abs(input_dev, ABS_PRESSURE, pressure); - - synusb_report_buttons(synusb); - - input_sync(input_dev); -} - -static void synusb_report_touchpad(struct synusb *synusb) -{ - struct input_dev *input_dev = synusb->input; - unsigned int num_fingers, tool_width; - unsigned int x, y; - unsigned int pressure, w; - - pressure = synusb->data[6]; - x = be16_to_cpup((__be16 *)&synusb->data[2]); - y = be16_to_cpup((__be16 *)&synusb->data[4]); - w = synusb->data[0] & 0x0f; - - if (pressure > 0) { - num_fingers = 1; - tool_width = 5; - switch (w) { - case 0 ... 1: - num_fingers = 2 + w; - break; - - case 2: /* pen, pretend its a finger */ - break; - - case 4 ... 15: - tool_width = w; - break; - } - } else { - num_fingers = 0; - tool_width = 0; - } - - /* - * Post events - * BTN_TOUCH has to be first as mousedev relies on it when doing - * absolute -> relative conversion - */ - - if (pressure > 30) - input_report_key(input_dev, BTN_TOUCH, 1); - if (pressure < 25) - input_report_key(input_dev, BTN_TOUCH, 0); - - if (num_fingers > 0) { - input_report_abs(input_dev, ABS_X, x); - input_report_abs(input_dev, ABS_Y, - YMAX_NOMINAL + YMIN_NOMINAL - y); - } - - input_report_abs(input_dev, ABS_PRESSURE, pressure); - input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width); - - input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1); - input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); - input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); - - synusb_report_buttons(synusb); - if (synusb->flags & SYNUSB_AUXDISPLAY) - input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08); - - input_sync(input_dev); -} - -static void synusb_irq(struct urb *urb) -{ - struct synusb *synusb = urb->context; - int error; - - /* Check our status in case we need to bail out early. */ - switch (urb->status) { - case 0: - usb_mark_last_busy(synusb->udev); - 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 (synusb->flags & SYNUSB_STICK) - synusb_report_stick(synusb); - else - synusb_report_touchpad(synusb); - -resubmit: - error = usb_submit_urb(urb, GFP_ATOMIC); - if (error && error != -EPERM) - dev_err(&synusb->intf->dev, - "%s - usb_submit_urb failed with result: %d", - __func__, error); -} - -static struct usb_endpoint_descriptor * -synusb_get_in_endpoint(struct usb_host_interface *iface) -{ - - struct usb_endpoint_descriptor *endpoint; - int i; - - for (i = 0; i < iface->desc.bNumEndpoints; ++i) { - endpoint = &iface->endpoint[i].desc; - - if (usb_endpoint_is_int_in(endpoint)) { - /* we found our interrupt in endpoint */ - return endpoint; - } - } - - return NULL; -} - -static int synusb_open(struct input_dev *dev) -{ - struct synusb *synusb = input_get_drvdata(dev); - int retval; - - retval = usb_autopm_get_interface(synusb->intf); - if (retval) { - dev_err(&synusb->intf->dev, - "%s - usb_autopm_get_interface failed, error: %d\n", - __func__, retval); - return retval; - } - - retval = usb_submit_urb(synusb->urb, GFP_KERNEL); - if (retval) { - dev_err(&synusb->intf->dev, - "%s - usb_submit_urb failed, error: %d\n", - __func__, retval); - retval = -EIO; - goto out; - } - - synusb->intf->needs_remote_wakeup = 1; - -out: - usb_autopm_put_interface(synusb->intf); - return retval; -} - -static void synusb_close(struct input_dev *dev) -{ - struct synusb *synusb = input_get_drvdata(dev); - int autopm_error; - - autopm_error = usb_autopm_get_interface(synusb->intf); - - usb_kill_urb(synusb->urb); - synusb->intf->needs_remote_wakeup = 0; - - if (!autopm_error) - usb_autopm_put_interface(synusb->intf); -} - -static int synusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_endpoint_descriptor *ep; - struct synusb *synusb; - struct input_dev *input_dev; - unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber; - unsigned int altsetting = min(intf->num_altsetting, 1U); - int error; - - error = usb_set_interface(udev, intf_num, altsetting); - if (error) { - dev_err(&udev->dev, - "Can not set alternate setting to %i, error: %i", - altsetting, error); - return error; - } - - ep = synusb_get_in_endpoint(intf->cur_altsetting); - if (!ep) - return -ENODEV; - - synusb = kzalloc(sizeof(*synusb), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!synusb || !input_dev) { - error = -ENOMEM; - goto err_free_mem; - } - - synusb->udev = udev; - synusb->intf = intf; - synusb->input = input_dev; - - synusb->flags = id->driver_info; - if (synusb->flags & SYNUSB_COMBO) { - /* - * This is a combo device, we need to set proper - * capability, depending on the interface. - */ - synusb->flags |= intf_num == 1 ? - SYNUSB_STICK : SYNUSB_TOUCHPAD; - } - - synusb->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!synusb->urb) { - error = -ENOMEM; - goto err_free_mem; - } - - synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL, - &synusb->urb->transfer_dma); - if (!synusb->data) { - error = -ENOMEM; - goto err_free_urb; - } - - usb_fill_int_urb(synusb->urb, udev, - usb_rcvintpipe(udev, ep->bEndpointAddress), - synusb->data, SYNUSB_RECV_SIZE, - synusb_irq, synusb, - ep->bInterval); - synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - if (udev->manufacturer) - strlcpy(synusb->name, udev->manufacturer, - sizeof(synusb->name)); - - if (udev->product) { - if (udev->manufacturer) - strlcat(synusb->name, " ", sizeof(synusb->name)); - strlcat(synusb->name, udev->product, sizeof(synusb->name)); - } - - if (!strlen(synusb->name)) - snprintf(synusb->name, sizeof(synusb->name), - "USB Synaptics Device %04x:%04x", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - if (synusb->flags & SYNUSB_STICK) - strlcat(synusb->name, " (Stick) ", sizeof(synusb->name)); - - usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); - strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); - - input_dev->name = synusb->name; - input_dev->phys = synusb->phys; - usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &synusb->intf->dev; - - if (!(synusb->flags & SYNUSB_IO_ALWAYS)) { - input_dev->open = synusb_open; - input_dev->close = synusb_close; - } - - input_set_drvdata(input_dev, synusb); - - __set_bit(EV_ABS, input_dev->evbit); - __set_bit(EV_KEY, input_dev->evbit); - - if (synusb->flags & SYNUSB_STICK) { - __set_bit(EV_REL, input_dev->evbit); - __set_bit(REL_X, input_dev->relbit); - __set_bit(REL_Y, input_dev->relbit); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); - } else { - input_set_abs_params(input_dev, ABS_X, - XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); - input_set_abs_params(input_dev, ABS_Y, - YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); - input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); - __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); - __set_bit(BTN_RIGHT, input_dev->keybit); - __set_bit(BTN_MIDDLE, input_dev->keybit); - - usb_set_intfdata(intf, synusb); - - if (synusb->flags & SYNUSB_IO_ALWAYS) { - error = synusb_open(input_dev); - if (error) - goto err_free_dma; - } - - error = input_register_device(input_dev); - if (error) { - dev_err(&udev->dev, - "Failed to register input device, error %d\n", - error); - goto err_stop_io; - } - - return 0; - -err_stop_io: - if (synusb->flags & SYNUSB_IO_ALWAYS) - synusb_close(synusb->input); -err_free_dma: - usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, - synusb->urb->transfer_dma); -err_free_urb: - usb_free_urb(synusb->urb); -err_free_mem: - input_free_device(input_dev); - kfree(synusb); - usb_set_intfdata(intf, NULL); - - return error; -} - -static void synusb_disconnect(struct usb_interface *intf) -{ - struct synusb *synusb = usb_get_intfdata(intf); - struct usb_device *udev = interface_to_usbdev(intf); - - if (synusb->flags & SYNUSB_IO_ALWAYS) - synusb_close(synusb->input); - - input_unregister_device(synusb->input); - - usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, - synusb->urb->transfer_dma); - usb_free_urb(synusb->urb); - kfree(synusb); - - usb_set_intfdata(intf, NULL); -} - -static int synusb_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct synusb *synusb = usb_get_intfdata(intf); - struct input_dev *input_dev = synusb->input; - - mutex_lock(&input_dev->mutex); - usb_kill_urb(synusb->urb); - mutex_unlock(&input_dev->mutex); - - return 0; -} - -static int synusb_resume(struct usb_interface *intf) -{ - struct synusb *synusb = usb_get_intfdata(intf); - struct input_dev *input_dev = synusb->input; - int retval = 0; - - mutex_lock(&input_dev->mutex); - - if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && - usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { - retval = -EIO; - } - - mutex_unlock(&input_dev->mutex); - - return retval; -} - -static int synusb_pre_reset(struct usb_interface *intf) -{ - struct synusb *synusb = usb_get_intfdata(intf); - struct input_dev *input_dev = synusb->input; - - mutex_lock(&input_dev->mutex); - usb_kill_urb(synusb->urb); - - return 0; -} - -static int synusb_post_reset(struct usb_interface *intf) -{ - struct synusb *synusb = usb_get_intfdata(intf); - struct input_dev *input_dev = synusb->input; - int retval = 0; - - if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && - usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { - retval = -EIO; - } - - mutex_unlock(&input_dev->mutex); - - return retval; -} - -static int synusb_reset_resume(struct usb_interface *intf) -{ - return synusb_resume(intf); -} - -static struct usb_device_id synusb_idtable[] = { - { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) }, - { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) }, - { USB_DEVICE_SYNAPTICS(CPAD, - SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) }, - { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) }, - { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) }, - { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) }, - { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) }, - { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) }, - { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) }, - { } -}; -MODULE_DEVICE_TABLE(usb, synusb_idtable); - -static struct usb_driver synusb_driver = { - .name = "synaptics_usb", - .probe = synusb_probe, - .disconnect = synusb_disconnect, - .id_table = synusb_idtable, - .suspend = synusb_suspend, - .resume = synusb_resume, - .pre_reset = synusb_pre_reset, - .post_reset = synusb_post_reset, - .reset_resume = synusb_reset_resume, - .supports_autosuspend = 1, -}; - -module_usb_driver(synusb_driver); - -MODULE_AUTHOR("Rob Miller <rob@inpharmatica.co.uk>, " - "Ron Lee <ron@debian.org>, " - "Jan Steinhoff <cpad@jan-steinhoff.de>"); -MODULE_DESCRIPTION("Synaptics USB device driver"); -MODULE_LICENSE("GPL"); |