Merge tag 'edac_for_4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
[deliverable/linux.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
4291ee30
JP
27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
1da177e4
LT
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/module.h>
1da177e4 32#include <linux/init.h>
ae0dadcf 33#include <linux/usb/input.h>
4ef2e23f 34#include <linux/hid.h>
1da177e4
LT
35
36/*
37 * Version Information
38 */
39#define DRIVER_VERSION ""
40#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
41#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
42#define DRIVER_LICENSE "GPL"
43
44MODULE_AUTHOR(DRIVER_AUTHOR);
45MODULE_DESCRIPTION(DRIVER_DESC);
46MODULE_LICENSE(DRIVER_LICENSE);
47
a44ebcce 48static const unsigned char usb_kbd_keycode[256] = {
1da177e4
LT
49 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
51 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
52 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
53 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
54 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
55 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
56 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
57 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
58 122,123, 90, 91, 85, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
64 150,158,159,128,136,177,178,176,142,152,173,140
65};
66
c196adf8
WP
67
68/**
69 * struct usb_kbd - state of each attached keyboard
70 * @dev: input device associated with this keyboard
71 * @usbdev: usb device associated with this keyboard
72 * @old: data received in the past from the @irq URB representing which
73 * keys were pressed. By comparing with the current list of keys
74 * that are pressed, we are able to see key releases.
75 * @irq: URB for receiving a list of keys that are pressed when a
76 * new key is pressed or a key that was pressed is released.
77 * @led: URB for sending LEDs (e.g. numlock, ...)
78 * @newleds: data that will be sent with the @led URB representing which LEDs
79 should be on
80 * @name: Name of the keyboard. @dev's name field points to this buffer
81 * @phys: Physical path of the keyboard. @dev's phys field points to this
82 * buffer
83 * @new: Buffer for the @irq URB
84 * @cr: Control request for @led URB
85 * @leds: Buffer for the @led URB
86 * @new_dma: DMA address for @irq URB
87 * @leds_dma: DMA address for @led URB
88 * @leds_lock: spinlock that protects @leds, @newleds, and @led_urb_submitted
89 * @led_urb_submitted: indicates whether @led is in progress, i.e. it has been
90 * submitted and its completion handler has not returned yet
91 * without resubmitting @led
92 */
1da177e4 93struct usb_kbd {
c5b7c7c3 94 struct input_dev *dev;
1da177e4
LT
95 struct usb_device *usbdev;
96 unsigned char old[8];
97 struct urb *irq, *led;
98 unsigned char newleds;
99 char name[128];
100 char phys[64];
1da177e4
LT
101
102 unsigned char *new;
103 struct usb_ctrlrequest *cr;
104 unsigned char *leds;
1da177e4
LT
105 dma_addr_t new_dma;
106 dma_addr_t leds_dma;
c196adf8
WP
107
108 spinlock_t leds_lock;
109 bool led_urb_submitted;
110
1da177e4
LT
111};
112
7d12e780 113static void usb_kbd_irq(struct urb *urb)
1da177e4
LT
114{
115 struct usb_kbd *kbd = urb->context;
116 int i;
117
118 switch (urb->status) {
119 case 0: /* success */
120 break;
121 case -ECONNRESET: /* unlink */
122 case -ENOENT:
123 case -ESHUTDOWN:
124 return;
125 /* -EPIPE: should clear the halt */
126 default: /* error */
127 goto resubmit;
128 }
129
1da177e4 130 for (i = 0; i < 8; i++)
c5b7c7c3 131 input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
1da177e4
LT
132
133 for (i = 2; i < 8; i++) {
134
135 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
136 if (usb_kbd_keycode[kbd->old[i]])
c5b7c7c3 137 input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
1da177e4 138 else
4291ee30
JP
139 hid_info(urb->dev,
140 "Unknown key (scancode %#x) released.\n",
141 kbd->old[i]);
1da177e4
LT
142 }
143
144 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
145 if (usb_kbd_keycode[kbd->new[i]])
c5b7c7c3 146 input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
1da177e4 147 else
4291ee30 148 hid_info(urb->dev,
9fee8240 149 "Unknown key (scancode %#x) pressed.\n",
4291ee30 150 kbd->new[i]);
1da177e4
LT
151 }
152 }
153
c5b7c7c3 154 input_sync(kbd->dev);
1da177e4
LT
155
156 memcpy(kbd->old, kbd->new, 8);
157
158resubmit:
54e6ecb2 159 i = usb_submit_urb (urb, GFP_ATOMIC);
1da177e4 160 if (i)
4291ee30
JP
161 hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d",
162 kbd->usbdev->bus->bus_name,
163 kbd->usbdev->devpath, i);
1da177e4
LT
164}
165
be5e3383
AB
166static int usb_kbd_event(struct input_dev *dev, unsigned int type,
167 unsigned int code, int value)
1da177e4 168{
c196adf8 169 unsigned long flags;
e0712985 170 struct usb_kbd *kbd = input_get_drvdata(dev);
1da177e4
LT
171
172 if (type != EV_LED)
173 return -1;
174
c196adf8 175 spin_lock_irqsave(&kbd->leds_lock, flags);
1da177e4
LT
176 kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
177 (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
178 (!!test_bit(LED_NUML, dev->led));
179
c196adf8
WP
180 if (kbd->led_urb_submitted){
181 spin_unlock_irqrestore(&kbd->leds_lock, flags);
1da177e4 182 return 0;
c196adf8 183 }
1da177e4 184
c196adf8
WP
185 if (*(kbd->leds) == kbd->newleds){
186 spin_unlock_irqrestore(&kbd->leds_lock, flags);
1da177e4 187 return 0;
c196adf8 188 }
1da177e4
LT
189
190 *(kbd->leds) = kbd->newleds;
c196adf8 191
1da177e4
LT
192 kbd->led->dev = kbd->usbdev;
193 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
4291ee30 194 pr_err("usb_submit_urb(leds) failed\n");
c196adf8
WP
195 else
196 kbd->led_urb_submitted = true;
197
198 spin_unlock_irqrestore(&kbd->leds_lock, flags);
199
1da177e4
LT
200 return 0;
201}
202
7d12e780 203static void usb_kbd_led(struct urb *urb)
1da177e4 204{
c196adf8 205 unsigned long flags;
1da177e4
LT
206 struct usb_kbd *kbd = urb->context;
207
208 if (urb->status)
4291ee30 209 hid_warn(urb->dev, "led urb status %d received\n",
7d89fe12 210 urb->status);
05f091ab 211
c196adf8
WP
212 spin_lock_irqsave(&kbd->leds_lock, flags);
213
214 if (*(kbd->leds) == kbd->newleds){
215 kbd->led_urb_submitted = false;
216 spin_unlock_irqrestore(&kbd->leds_lock, flags);
1da177e4 217 return;
c196adf8 218 }
1da177e4
LT
219
220 *(kbd->leds) = kbd->newleds;
c196adf8 221
1da177e4 222 kbd->led->dev = kbd->usbdev;
c196adf8 223 if (usb_submit_urb(kbd->led, GFP_ATOMIC)){
4291ee30 224 hid_err(urb->dev, "usb_submit_urb(leds) failed\n");
c196adf8
WP
225 kbd->led_urb_submitted = false;
226 }
227 spin_unlock_irqrestore(&kbd->leds_lock, flags);
228
1da177e4
LT
229}
230
231static int usb_kbd_open(struct input_dev *dev)
232{
e0712985 233 struct usb_kbd *kbd = input_get_drvdata(dev);
1da177e4 234
1da177e4 235 kbd->irq->dev = kbd->usbdev;
65cde54b 236 if (usb_submit_urb(kbd->irq, GFP_KERNEL))
1da177e4 237 return -EIO;
1da177e4
LT
238
239 return 0;
240}
241
242static void usb_kbd_close(struct input_dev *dev)
243{
e0712985 244 struct usb_kbd *kbd = input_get_drvdata(dev);
1da177e4 245
65cde54b 246 usb_kill_urb(kbd->irq);
1da177e4
LT
247}
248
249static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
250{
251 if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL)))
252 return -1;
253 if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
254 return -1;
997ea58e 255 if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
1da177e4 256 return -1;
0ede76fc 257 if (!(kbd->cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL)))
1da177e4 258 return -1;
997ea58e 259 if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
1da177e4
LT
260 return -1;
261
262 return 0;
263}
264
265static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
266{
4ba0b2ed
MK
267 usb_free_urb(kbd->irq);
268 usb_free_urb(kbd->led);
997ea58e 269 usb_free_coherent(dev, 8, kbd->new, kbd->new_dma);
0ede76fc 270 kfree(kbd->cr);
997ea58e 271 usb_free_coherent(dev, 1, kbd->leds, kbd->leds_dma);
1da177e4
LT
272}
273
05f091ab 274static int usb_kbd_probe(struct usb_interface *iface,
1da177e4
LT
275 const struct usb_device_id *id)
276{
c5b7c7c3 277 struct usb_device *dev = interface_to_usbdev(iface);
1da177e4
LT
278 struct usb_host_interface *interface;
279 struct usb_endpoint_descriptor *endpoint;
280 struct usb_kbd *kbd;
c5b7c7c3 281 struct input_dev *input_dev;
1da177e4 282 int i, pipe, maxp;
5d6341c6 283 int error = -ENOMEM;
1da177e4
LT
284
285 interface = iface->cur_altsetting;
286
287 if (interface->desc.bNumEndpoints != 1)
288 return -ENODEV;
289
290 endpoint = &interface->endpoint[0].desc;
a20c3144 291 if (!usb_endpoint_is_int_in(endpoint))
1da177e4
LT
292 return -ENODEV;
293
294 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
295 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
296
c5b7c7c3
DT
297 kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
298 input_dev = input_allocate_device();
299 if (!kbd || !input_dev)
300 goto fail1;
1da177e4 301
c5b7c7c3
DT
302 if (usb_kbd_alloc_mem(dev, kbd))
303 goto fail2;
1da177e4
LT
304
305 kbd->usbdev = dev;
c5b7c7c3 306 kbd->dev = input_dev;
c196adf8 307 spin_lock_init(&kbd->leds_lock);
c5b7c7c3
DT
308
309 if (dev->manufacturer)
310 strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
311
312 if (dev->product) {
313 if (dev->manufacturer)
314 strlcat(kbd->name, " ", sizeof(kbd->name));
315 strlcat(kbd->name, dev->product, sizeof(kbd->name));
316 }
317
318 if (!strlen(kbd->name))
319 snprintf(kbd->name, sizeof(kbd->name),
320 "USB HIDBP Keyboard %04x:%04x",
321 le16_to_cpu(dev->descriptor.idVendor),
322 le16_to_cpu(dev->descriptor.idProduct));
323
324 usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
6236dfaa 325 strlcat(kbd->phys, "/input0", sizeof(kbd->phys));
1da177e4 326
c5b7c7c3
DT
327 input_dev->name = kbd->name;
328 input_dev->phys = kbd->phys;
329 usb_to_input_id(dev, &input_dev->id);
e0712985
DT
330 input_dev->dev.parent = &iface->dev;
331
332 input_set_drvdata(input_dev, kbd);
c5b7c7c3 333
7b19ada2
JS
334 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
335 BIT_MASK(EV_REP);
336 input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
337 BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
338 BIT_MASK(LED_KANA);
1da177e4
LT
339
340 for (i = 0; i < 255; i++)
c5b7c7c3
DT
341 set_bit(usb_kbd_keycode[i], input_dev->keybit);
342 clear_bit(0, input_dev->keybit);
05f091ab 343
c5b7c7c3
DT
344 input_dev->event = usb_kbd_event;
345 input_dev->open = usb_kbd_open;
346 input_dev->close = usb_kbd_close;
1da177e4
LT
347
348 usb_fill_int_urb(kbd->irq, dev, pipe,
349 kbd->new, (maxp > 8 ? 8 : maxp),
350 usb_kbd_irq, kbd, endpoint->bInterval);
351 kbd->irq->transfer_dma = kbd->new_dma;
352 kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
353
354 kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
355 kbd->cr->bRequest = 0x09;
356 kbd->cr->wValue = cpu_to_le16(0x200);
357 kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
358 kbd->cr->wLength = cpu_to_le16(1);
359
1da177e4
LT
360 usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
361 (void *) kbd->cr, kbd->leds, 1,
362 usb_kbd_led, kbd);
1da177e4 363 kbd->led->transfer_dma = kbd->leds_dma;
0ede76fc 364 kbd->led->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1da177e4 365
5d6341c6
DT
366 error = input_register_device(kbd->dev);
367 if (error)
368 goto fail2;
1da177e4
LT
369
370 usb_set_intfdata(iface, kbd);
3d61510f 371 device_set_wakeup_enable(&dev->dev, 1);
1da177e4 372 return 0;
c5b7c7c3 373
5d6341c6
DT
374fail2:
375 usb_kbd_free_mem(dev, kbd);
376fail1:
377 input_free_device(input_dev);
c5b7c7c3 378 kfree(kbd);
5d6341c6 379 return error;
1da177e4
LT
380}
381
382static void usb_kbd_disconnect(struct usb_interface *intf)
383{
384 struct usb_kbd *kbd = usb_get_intfdata (intf);
05f091ab 385
1da177e4
LT
386 usb_set_intfdata(intf, NULL);
387 if (kbd) {
388 usb_kill_urb(kbd->irq);
c5b7c7c3 389 input_unregister_device(kbd->dev);
a2b2c20b 390 usb_kill_urb(kbd->led);
1da177e4
LT
391 usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
392 kfree(kbd);
393 }
394}
395
396static struct usb_device_id usb_kbd_id_table [] = {
4ef2e23f
MO
397 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
398 USB_INTERFACE_PROTOCOL_KEYBOARD) },
1da177e4
LT
399 { } /* Terminating entry */
400};
401
402MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
403
404static struct usb_driver usb_kbd_driver = {
1da177e4
LT
405 .name = "usbkbd",
406 .probe = usb_kbd_probe,
407 .disconnect = usb_kbd_disconnect,
408 .id_table = usb_kbd_id_table,
409};
410
42f06a13 411module_usb_driver(usb_kbd_driver);
This page took 0.857939 seconds and 5 git commands to generate.