Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
846 giacomo 1
/*
2
 * $Id: usbmouse.c,v 1.1 2004-09-13 15:04:47 giacomo Exp $
3
 *
4
 *  Copyright (c) 1999-2001 Vojtech Pavlik
5
 *
6
 *  USB HIDBP Mouse support
7
 */
8
 
9
/*
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
 *
24
 * Should you need to contact me, the author, you can do so either by
25
 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
26
 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
27
 */
28
 
29
#include <linux/kernel.h>
30
#include <linux/slab.h>
31
#include <linux/input.h>
32
#include <linux/module.h>
33
#include <linux/init.h>
34
#include <linux/usb.h>
35
 
36
/*
37
 * Version Information
38
 */
39
#define DRIVER_VERSION "v1.6"
40
#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
41
#define DRIVER_DESC "USB HID Boot Protocol mouse driver"
42
#define DRIVER_LICENSE "GPL"
43
 
44
MODULE_AUTHOR(DRIVER_AUTHOR);
45
MODULE_DESCRIPTION(DRIVER_DESC);
46
MODULE_LICENSE(DRIVER_LICENSE);
47
 
48
struct usb_mouse {
49
        char name[128];
50
        char phys[64];
51
        struct usb_device *usbdev;
52
        struct input_dev dev;
53
        struct urb *irq;
54
        int open;
55
 
56
        signed char *data;
57
        dma_addr_t data_dma;
58
};
59
 
60
static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
61
{
62
        struct usb_mouse *mouse = urb->context;
63
        signed char *data = mouse->data;
64
        struct input_dev *dev = &mouse->dev;
65
        int status;
66
 
67
        switch (urb->status) {
68
        case 0:                 /* success */
69
                break;
70
        case -ECONNRESET:       /* unlink */
71
        case -ENOENT:
72
        case -ESHUTDOWN:
73
                return;
74
        /* -EPIPE:  should clear the halt */
75
        default:                /* error */
76
                goto resubmit;
77
        }
78
 
79
        input_regs(dev, regs);
80
 
81
        input_report_key(dev, BTN_LEFT,   data[0] & 0x01);
82
        input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);
83
        input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
84
        input_report_key(dev, BTN_SIDE,   data[0] & 0x08);
85
        input_report_key(dev, BTN_EXTRA,  data[0] & 0x10);
86
 
87
        input_report_rel(dev, REL_X,     data[1]);
88
        input_report_rel(dev, REL_Y,     data[2]);
89
        input_report_rel(dev, REL_WHEEL, data[3]);
90
 
91
        input_sync(dev);
92
resubmit:
93
        status = usb_submit_urb (urb, SLAB_ATOMIC);
94
        if (status)
95
                err ("can't resubmit intr, %s-%s/input0, status %d",
96
                                mouse->usbdev->bus->bus_name,
97
                                mouse->usbdev->devpath, status);
98
}
99
 
100
static int usb_mouse_open(struct input_dev *dev)
101
{
102
        struct usb_mouse *mouse = dev->private;
103
 
104
        if (mouse->open++)
105
                return 0;
106
 
107
        mouse->irq->dev = mouse->usbdev;
108
        if (usb_submit_urb(mouse->irq, GFP_KERNEL)) {
109
                mouse->open--;
110
                return -EIO;
111
        }
112
 
113
        return 0;
114
}
115
 
116
static void usb_mouse_close(struct input_dev *dev)
117
{
118
        struct usb_mouse *mouse = dev->private;
119
 
120
        if (!--mouse->open)
121
                usb_unlink_urb(mouse->irq);
122
}
123
 
124
static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
125
{
126
        struct usb_device * dev = interface_to_usbdev(intf);
127
        struct usb_host_interface *interface;
128
        struct usb_endpoint_descriptor *endpoint;
129
        struct usb_mouse *mouse;
130
        int pipe, maxp;
131
        char path[64];
132
        char *buf;
133
 
134
        interface = &intf->altsetting[intf->act_altsetting];
135
 
136
        if (interface->desc.bNumEndpoints != 1)
137
                return -ENODEV;
138
 
139
        endpoint = &interface->endpoint[0].desc;
140
        if (!(endpoint->bEndpointAddress & 0x80))
141
                return -ENODEV;
142
        if ((endpoint->bmAttributes & 3) != 3)
143
                return -ENODEV;
144
 
145
        pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
146
        maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
147
 
148
        if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
149
                return -ENOMEM;
150
        memset(mouse, 0, sizeof(struct usb_mouse));
151
 
152
        mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
153
        if (!mouse->data) {
154
                kfree(mouse);
155
                return -ENOMEM;
156
        }
157
 
158
        mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
159
        if (!mouse->irq) {
160
                usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
161
                kfree(mouse);
162
                return -ENODEV;
163
        }
164
 
165
        mouse->usbdev = dev;
166
 
167
        mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
168
        mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
169
        mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
170
        mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
171
        mouse->dev.relbit[0] |= BIT(REL_WHEEL);
172
 
173
        mouse->dev.private = mouse;
174
        mouse->dev.open = usb_mouse_open;
175
        mouse->dev.close = usb_mouse_close;
176
 
177
        usb_make_path(dev, path, 64);
178
        sprintf26(mouse->phys, "%s/input0", path);
179
 
180
        mouse->dev.name = mouse->name;
181
        mouse->dev.phys = mouse->phys;
182
        mouse->dev.id.bustype = BUS_USB;
183
        mouse->dev.id.vendor = dev->descriptor.idVendor;
184
        mouse->dev.id.product = dev->descriptor.idProduct;
185
        mouse->dev.id.version = dev->descriptor.bcdDevice;
186
 
187
        if (!(buf = kmalloc(63, GFP_KERNEL))) {
188
                usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
189
                kfree(mouse);
190
                return -ENOMEM;
191
        }
192
 
193
        if (dev->descriptor.iManufacturer &&
194
                usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
195
                        strcat(mouse->name, buf);
196
        if (dev->descriptor.iProduct &&
197
                usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
198
                        sprintf26(mouse->name, "%s %s", mouse->name, buf);
199
 
200
        if (!strlen(mouse->name))
201
                sprintf26(mouse->name, "USB HIDBP Mouse %04x:%04x",
202
                        mouse->dev.id.vendor, mouse->dev.id.product);
203
 
204
        kfree(buf);
205
 
206
        usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
207
                         (maxp > 8 ? 8 : maxp),
208
                         usb_mouse_irq, mouse, endpoint->bInterval);
209
        mouse->irq->transfer_dma = mouse->data_dma;
210
        mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
211
 
212
        input_register_device(&mouse->dev);
213
        printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
214
 
215
        usb_set_intfdata(intf, mouse);
216
        return 0;
217
}
218
 
219
static void usb_mouse_disconnect(struct usb_interface *intf)
220
{
221
        struct usb_mouse *mouse = usb_get_intfdata (intf);
222
 
223
        usb_set_intfdata(intf, NULL);
224
        if (mouse) {
225
                usb_unlink_urb(mouse->irq);
226
                input_unregister_device(&mouse->dev);
227
                usb_free_urb(mouse->irq);
228
                usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
229
                kfree(mouse);
230
        }
231
}
232
 
233
static struct usb_device_id usb_mouse_id_table [] = {
234
        { USB_INTERFACE_INFO(3, 1, 2) },
235
    { }                                         /* Terminating entry */
236
};
237
 
238
MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
239
 
240
static struct usb_driver usb_mouse_driver = {
241
        .owner          = THIS_MODULE,
242
        .name           = "usbmouse",
243
        .probe          = usb_mouse_probe,
244
        .disconnect     = usb_mouse_disconnect,
245
        .id_table       = usb_mouse_id_table,
246
};
247
 
248
/*static*/ int __init usb_mouse_init(void)
249
{
250
        int retval = usb_register(&usb_mouse_driver);
251
        if (retval == 0)
252
                info(DRIVER_VERSION ":" DRIVER_DESC);
253
        return retval;
254
}
255
 
256
/*static*/ void __exit usb_mouse_exit(void)
257
{
258
        usb_deregister(&usb_mouse_driver);
259
}
260
 
261
module_init(usb_mouse_init);
262
module_exit(usb_mouse_exit);