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