0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/kernel.h>
0016 #include <linux/slab.h>
0017 #include <linux/module.h>
0018 #include <linux/init.h>
0019 #include <linux/usb/input.h>
0020 #include <linux/hid.h>
0021
0022
0023 #ifdef CONFIG_USB_HID_MODULE
0024 #include "../hid-ids.h"
0025 #endif
0026
0027
0028
0029
0030 #define DRIVER_VERSION "v1.6"
0031 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
0032 #define DRIVER_DESC "USB HID Boot Protocol mouse driver"
0033
0034 MODULE_AUTHOR(DRIVER_AUTHOR);
0035 MODULE_DESCRIPTION(DRIVER_DESC);
0036 MODULE_LICENSE("GPL");
0037
0038 struct usb_mouse {
0039 char name[128];
0040 char phys[64];
0041 struct usb_device *usbdev;
0042 struct input_dev *dev;
0043 struct urb *irq;
0044
0045 signed char *data;
0046 dma_addr_t data_dma;
0047 };
0048
0049 static void usb_mouse_irq(struct urb *urb)
0050 {
0051 struct usb_mouse *mouse = urb->context;
0052 signed char *data = mouse->data;
0053 struct input_dev *dev = mouse->dev;
0054 int status;
0055
0056 switch (urb->status) {
0057 case 0:
0058 break;
0059 case -ECONNRESET:
0060 case -ENOENT:
0061 case -ESHUTDOWN:
0062 return;
0063
0064 default:
0065 goto resubmit;
0066 }
0067
0068 input_report_key(dev, BTN_LEFT, data[0] & 0x01);
0069 input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
0070 input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
0071 input_report_key(dev, BTN_SIDE, data[0] & 0x08);
0072 input_report_key(dev, BTN_EXTRA, data[0] & 0x10);
0073
0074 input_report_rel(dev, REL_X, data[1]);
0075 input_report_rel(dev, REL_Y, data[2]);
0076 input_report_rel(dev, REL_WHEEL, data[3]);
0077
0078 input_sync(dev);
0079 resubmit:
0080 status = usb_submit_urb (urb, GFP_ATOMIC);
0081 if (status)
0082 dev_err(&mouse->usbdev->dev,
0083 "can't resubmit intr, %s-%s/input0, status %d\n",
0084 mouse->usbdev->bus->bus_name,
0085 mouse->usbdev->devpath, status);
0086 }
0087
0088 static int usb_mouse_open(struct input_dev *dev)
0089 {
0090 struct usb_mouse *mouse = input_get_drvdata(dev);
0091
0092 mouse->irq->dev = mouse->usbdev;
0093 if (usb_submit_urb(mouse->irq, GFP_KERNEL))
0094 return -EIO;
0095
0096 return 0;
0097 }
0098
0099 static void usb_mouse_close(struct input_dev *dev)
0100 {
0101 struct usb_mouse *mouse = input_get_drvdata(dev);
0102
0103 usb_kill_urb(mouse->irq);
0104 }
0105
0106 static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
0107 {
0108 struct usb_device *dev = interface_to_usbdev(intf);
0109 struct usb_host_interface *interface;
0110 struct usb_endpoint_descriptor *endpoint;
0111 struct usb_mouse *mouse;
0112 struct input_dev *input_dev;
0113 int pipe, maxp;
0114 int error = -ENOMEM;
0115
0116 interface = intf->cur_altsetting;
0117
0118 if (interface->desc.bNumEndpoints != 1)
0119 return -ENODEV;
0120
0121 endpoint = &interface->endpoint[0].desc;
0122 if (!usb_endpoint_is_int_in(endpoint))
0123 return -ENODEV;
0124
0125 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
0126 maxp = usb_maxpacket(dev, pipe);
0127
0128 mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
0129 input_dev = input_allocate_device();
0130 if (!mouse || !input_dev)
0131 goto fail1;
0132
0133 mouse->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &mouse->data_dma);
0134 if (!mouse->data)
0135 goto fail1;
0136
0137 mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
0138 if (!mouse->irq)
0139 goto fail2;
0140
0141 mouse->usbdev = dev;
0142 mouse->dev = input_dev;
0143
0144 if (dev->manufacturer)
0145 strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
0146
0147 if (dev->product) {
0148 if (dev->manufacturer)
0149 strlcat(mouse->name, " ", sizeof(mouse->name));
0150 strlcat(mouse->name, dev->product, sizeof(mouse->name));
0151 }
0152
0153 if (!strlen(mouse->name))
0154 snprintf(mouse->name, sizeof(mouse->name),
0155 "USB HIDBP Mouse %04x:%04x",
0156 le16_to_cpu(dev->descriptor.idVendor),
0157 le16_to_cpu(dev->descriptor.idProduct));
0158
0159 usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
0160 strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
0161
0162 input_dev->name = mouse->name;
0163 input_dev->phys = mouse->phys;
0164 usb_to_input_id(dev, &input_dev->id);
0165 input_dev->dev.parent = &intf->dev;
0166
0167 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
0168 input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
0169 BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
0170 input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
0171 input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
0172 BIT_MASK(BTN_EXTRA);
0173 input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
0174
0175 input_set_drvdata(input_dev, mouse);
0176
0177 input_dev->open = usb_mouse_open;
0178 input_dev->close = usb_mouse_close;
0179
0180 usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
0181 (maxp > 8 ? 8 : maxp),
0182 usb_mouse_irq, mouse, endpoint->bInterval);
0183 mouse->irq->transfer_dma = mouse->data_dma;
0184 mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0185
0186 error = input_register_device(mouse->dev);
0187 if (error)
0188 goto fail3;
0189
0190 usb_set_intfdata(intf, mouse);
0191 return 0;
0192
0193 fail3:
0194 usb_free_urb(mouse->irq);
0195 fail2:
0196 usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
0197 fail1:
0198 input_free_device(input_dev);
0199 kfree(mouse);
0200 return error;
0201 }
0202
0203 static void usb_mouse_disconnect(struct usb_interface *intf)
0204 {
0205 struct usb_mouse *mouse = usb_get_intfdata (intf);
0206
0207 usb_set_intfdata(intf, NULL);
0208 if (mouse) {
0209 usb_kill_urb(mouse->irq);
0210 input_unregister_device(mouse->dev);
0211 usb_free_urb(mouse->irq);
0212 usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
0213 kfree(mouse);
0214 }
0215 }
0216
0217 static const struct usb_device_id usb_mouse_id_table[] = {
0218 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
0219 USB_INTERFACE_PROTOCOL_MOUSE) },
0220 { }
0221 };
0222
0223 MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
0224
0225 static struct usb_driver usb_mouse_driver = {
0226 .name = "usbmouse",
0227 .probe = usb_mouse_probe,
0228 .disconnect = usb_mouse_disconnect,
0229 .id_table = usb_mouse_id_table,
0230 };
0231
0232 module_usb_driver(usb_mouse_driver);