]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/hid/usbhid/usbkbd.c
HID:usbkbd:mark usb_kbd_keycode array as const
[net-next-2.6.git] / drivers / hid / usbhid / usbkbd.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 * Copyright (c) 1999-2001 Vojtech Pavlik
3 *
4 * USB HIDBP Keyboard support
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
05f091ab 10 * the Free Software Foundation; either version 2 of the License, or
1da177e4 11 * (at your option) any later version.
05f091ab 12 *
1da177e4
LT
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
05f091ab 17 *
1da177e4
LT
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
05f091ab 21 *
1da177e4
LT
22 * Should you need to contact me, the author, you can do so either by
23 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
24 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
25 */
26
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/module.h>
1da177e4 30#include <linux/init.h>
ae0dadcf 31#include <linux/usb/input.h>
4ef2e23f 32#include <linux/hid.h>
1da177e4
LT
33
34/*
35 * Version Information
36 */
37#define DRIVER_VERSION ""
38#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
39#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
40#define DRIVER_LICENSE "GPL"
41
42MODULE_AUTHOR(DRIVER_AUTHOR);
43MODULE_DESCRIPTION(DRIVER_DESC);
44MODULE_LICENSE(DRIVER_LICENSE);
45
a44ebcce 46static const unsigned char usb_kbd_keycode[256] = {
1da177e4
LT
47 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
48 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
49 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
50 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
51 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
52 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
53 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
54 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
55 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
56 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
62 150,158,159,128,136,177,178,176,142,152,173,140
63};
64
65struct usb_kbd {
c5b7c7c3 66 struct input_dev *dev;
1da177e4
LT
67 struct usb_device *usbdev;
68 unsigned char old[8];
69 struct urb *irq, *led;
70 unsigned char newleds;
71 char name[128];
72 char phys[64];
1da177e4
LT
73
74 unsigned char *new;
75 struct usb_ctrlrequest *cr;
76 unsigned char *leds;
77 dma_addr_t cr_dma;
78 dma_addr_t new_dma;
79 dma_addr_t leds_dma;
80};
81
7d12e780 82static void usb_kbd_irq(struct urb *urb)
1da177e4
LT
83{
84 struct usb_kbd *kbd = urb->context;
85 int i;
86
87 switch (urb->status) {
88 case 0: /* success */
89 break;
90 case -ECONNRESET: /* unlink */
91 case -ENOENT:
92 case -ESHUTDOWN:
93 return;
94 /* -EPIPE: should clear the halt */
95 default: /* error */
96 goto resubmit;
97 }
98
1da177e4 99 for (i = 0; i < 8; i++)
c5b7c7c3 100 input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
1da177e4
LT
101
102 for (i = 2; i < 8; i++) {
103
104 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
105 if (usb_kbd_keycode[kbd->old[i]])
c5b7c7c3 106 input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
1da177e4
LT
107 else
108 info("Unknown key (scancode %#x) released.", kbd->old[i]);
109 }
110
111 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
112 if (usb_kbd_keycode[kbd->new[i]])
c5b7c7c3 113 input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
1da177e4
LT
114 else
115 info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
116 }
117 }
118
c5b7c7c3 119 input_sync(kbd->dev);
1da177e4
LT
120
121 memcpy(kbd->old, kbd->new, 8);
122
123resubmit:
54e6ecb2 124 i = usb_submit_urb (urb, GFP_ATOMIC);
1da177e4 125 if (i)
58037eb9 126 err_hid ("can't resubmit intr, %s-%s/input0, status %d",
1da177e4
LT
127 kbd->usbdev->bus->bus_name,
128 kbd->usbdev->devpath, i);
129}
130
be5e3383
AB
131static int usb_kbd_event(struct input_dev *dev, unsigned int type,
132 unsigned int code, int value)
1da177e4 133{
e0712985 134 struct usb_kbd *kbd = input_get_drvdata(dev);
1da177e4
LT
135
136 if (type != EV_LED)
137 return -1;
138
1da177e4
LT
139 kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
140 (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
141 (!!test_bit(LED_NUML, dev->led));
142
143 if (kbd->led->status == -EINPROGRESS)
144 return 0;
145
146 if (*(kbd->leds) == kbd->newleds)
147 return 0;
148
149 *(kbd->leds) = kbd->newleds;
150 kbd->led->dev = kbd->usbdev;
151 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
58037eb9 152 err_hid("usb_submit_urb(leds) failed");
1da177e4
LT
153
154 return 0;
155}
156
7d12e780 157static void usb_kbd_led(struct urb *urb)
1da177e4
LT
158{
159 struct usb_kbd *kbd = urb->context;
160
161 if (urb->status)
162 warn("led urb status %d received", urb->status);
05f091ab 163
1da177e4
LT
164 if (*(kbd->leds) == kbd->newleds)
165 return;
166
167 *(kbd->leds) = kbd->newleds;
168 kbd->led->dev = kbd->usbdev;
169 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
58037eb9 170 err_hid("usb_submit_urb(leds) failed");
1da177e4
LT
171}
172
173static int usb_kbd_open(struct input_dev *dev)
174{
e0712985 175 struct usb_kbd *kbd = input_get_drvdata(dev);
1da177e4 176
1da177e4 177 kbd->irq->dev = kbd->usbdev;
65cde54b 178 if (usb_submit_urb(kbd->irq, GFP_KERNEL))
1da177e4 179 return -EIO;
1da177e4
LT
180
181 return 0;
182}
183
184static void usb_kbd_close(struct input_dev *dev)
185{
e0712985 186 struct usb_kbd *kbd = input_get_drvdata(dev);
1da177e4 187
65cde54b 188 usb_kill_urb(kbd->irq);
1da177e4
LT
189}
190
191static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
192{
193 if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL)))
194 return -1;
195 if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
196 return -1;
54e6ecb2 197 if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
1da177e4 198 return -1;
54e6ecb2 199 if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
1da177e4 200 return -1;
54e6ecb2 201 if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
1da177e4
LT
202 return -1;
203
204 return 0;
205}
206
207static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
208{
4ba0b2ed
MK
209 usb_free_urb(kbd->irq);
210 usb_free_urb(kbd->led);
6675c5bd
DT
211 usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
212 usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
213 usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
1da177e4
LT
214}
215
05f091ab 216static int usb_kbd_probe(struct usb_interface *iface,
1da177e4
LT
217 const struct usb_device_id *id)
218{
c5b7c7c3 219 struct usb_device *dev = interface_to_usbdev(iface);
1da177e4
LT
220 struct usb_host_interface *interface;
221 struct usb_endpoint_descriptor *endpoint;
222 struct usb_kbd *kbd;
c5b7c7c3 223 struct input_dev *input_dev;
1da177e4 224 int i, pipe, maxp;
5d6341c6 225 int error = -ENOMEM;
1da177e4
LT
226
227 interface = iface->cur_altsetting;
228
229 if (interface->desc.bNumEndpoints != 1)
230 return -ENODEV;
231
232 endpoint = &interface->endpoint[0].desc;
a20c3144 233 if (!usb_endpoint_is_int_in(endpoint))
1da177e4
LT
234 return -ENODEV;
235
b0e66824 236#ifdef CONFIG_USB_HID
9f6b3727
PT
237 if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
238 le16_to_cpu(dev->descriptor.idProduct))
239 & HID_QUIRK_IGNORE) {
240 return -ENODEV;
241 }
b0e66824 242#endif
9f6b3727 243
1da177e4
LT
244 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
245 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
246
c5b7c7c3
DT
247 kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
248 input_dev = input_allocate_device();
249 if (!kbd || !input_dev)
250 goto fail1;
1da177e4 251
c5b7c7c3
DT
252 if (usb_kbd_alloc_mem(dev, kbd))
253 goto fail2;
1da177e4
LT
254
255 kbd->usbdev = dev;
c5b7c7c3
DT
256 kbd->dev = input_dev;
257
258 if (dev->manufacturer)
259 strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
260
261 if (dev->product) {
262 if (dev->manufacturer)
263 strlcat(kbd->name, " ", sizeof(kbd->name));
264 strlcat(kbd->name, dev->product, sizeof(kbd->name));
265 }
266
267 if (!strlen(kbd->name))
268 snprintf(kbd->name, sizeof(kbd->name),
269 "USB HIDBP Keyboard %04x:%04x",
270 le16_to_cpu(dev->descriptor.idVendor),
271 le16_to_cpu(dev->descriptor.idProduct));
272
273 usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
274 strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
1da177e4 275
c5b7c7c3
DT
276 input_dev->name = kbd->name;
277 input_dev->phys = kbd->phys;
278 usb_to_input_id(dev, &input_dev->id);
e0712985
DT
279 input_dev->dev.parent = &iface->dev;
280
281 input_set_drvdata(input_dev, kbd);
c5b7c7c3 282
7b19ada2
JS
283 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
284 BIT_MASK(EV_REP);
285 input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
286 BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
287 BIT_MASK(LED_KANA);
1da177e4
LT
288
289 for (i = 0; i < 255; i++)
c5b7c7c3
DT
290 set_bit(usb_kbd_keycode[i], input_dev->keybit);
291 clear_bit(0, input_dev->keybit);
05f091ab 292
c5b7c7c3
DT
293 input_dev->event = usb_kbd_event;
294 input_dev->open = usb_kbd_open;
295 input_dev->close = usb_kbd_close;
1da177e4
LT
296
297 usb_fill_int_urb(kbd->irq, dev, pipe,
298 kbd->new, (maxp > 8 ? 8 : maxp),
299 usb_kbd_irq, kbd, endpoint->bInterval);
300 kbd->irq->transfer_dma = kbd->new_dma;
301 kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
302
303 kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
304 kbd->cr->bRequest = 0x09;
305 kbd->cr->wValue = cpu_to_le16(0x200);
306 kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
307 kbd->cr->wLength = cpu_to_le16(1);
308
1da177e4
LT
309 usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
310 (void *) kbd->cr, kbd->leds, 1,
311 usb_kbd_led, kbd);
312 kbd->led->setup_dma = kbd->cr_dma;
313 kbd->led->transfer_dma = kbd->leds_dma;
c5b7c7c3 314 kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
1da177e4 315
5d6341c6
DT
316 error = input_register_device(kbd->dev);
317 if (error)
318 goto fail2;
1da177e4
LT
319
320 usb_set_intfdata(iface, kbd);
321 return 0;
c5b7c7c3 322
5d6341c6
DT
323fail2:
324 usb_kbd_free_mem(dev, kbd);
325fail1:
326 input_free_device(input_dev);
c5b7c7c3 327 kfree(kbd);
5d6341c6 328 return error;
1da177e4
LT
329}
330
331static void usb_kbd_disconnect(struct usb_interface *intf)
332{
333 struct usb_kbd *kbd = usb_get_intfdata (intf);
05f091ab 334
1da177e4
LT
335 usb_set_intfdata(intf, NULL);
336 if (kbd) {
337 usb_kill_urb(kbd->irq);
c5b7c7c3 338 input_unregister_device(kbd->dev);
1da177e4
LT
339 usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
340 kfree(kbd);
341 }
342}
343
344static struct usb_device_id usb_kbd_id_table [] = {
4ef2e23f
MO
345 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
346 USB_INTERFACE_PROTOCOL_KEYBOARD) },
1da177e4
LT
347 { } /* Terminating entry */
348};
349
350MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
351
352static struct usb_driver usb_kbd_driver = {
1da177e4
LT
353 .name = "usbkbd",
354 .probe = usb_kbd_probe,
355 .disconnect = usb_kbd_disconnect,
356 .id_table = usb_kbd_id_table,
357};
358
359static int __init usb_kbd_init(void)
360{
361 int result = usb_register(&usb_kbd_driver);
362 if (result == 0)
363 info(DRIVER_VERSION ":" DRIVER_DESC);
364 return result;
365}
366
367static void __exit usb_kbd_exit(void)
368{
369 usb_deregister(&usb_kbd_driver);
370}
371
372module_init(usb_kbd_init);
373module_exit(usb_kbd_exit);