Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (c) 1999-2001 Vojtech Pavlik
0004  *
0005  *  USB HIDBP Mouse support
0006  */
0007 
0008 /*
0009  *
0010  * Should you need to contact me, the author, you can do so either by
0011  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
0012  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
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 /* for apple IDs */
0023 #ifdef CONFIG_USB_HID_MODULE
0024 #include "../hid-ids.h"
0025 #endif
0026 
0027 /*
0028  * Version Information
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:         /* success */
0058         break;
0059     case -ECONNRESET:   /* unlink */
0060     case -ENOENT:
0061     case -ESHUTDOWN:
0062         return;
0063     /* -EPIPE:  should clear the halt */
0064     default:        /* error */
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     { } /* Terminating entry */
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);