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