xref: /OK3568_Linux_fs/u-boot/common/usb_kbd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland
4  *
5  * Part of this source has been derived from the Linux USB
6  * project.
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 #include <common.h>
11 #include <console.h>
12 #include <dm.h>
13 #include <errno.h>
14 #include <malloc.h>
15 #include <memalign.h>
16 #include <stdio_dev.h>
17 #include <asm/byteorder.h>
18 #include <linux/input.h>
19 
20 #include <usb.h>
21 
22 /*
23  * If overwrite_console returns 1, the stdin, stderr and stdout
24  * are switched to the serial port, else the settings in the
25  * environment are used
26  */
27 #ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
28 extern int overwrite_console(void);
29 #else
overwrite_console(void)30 int overwrite_console(void)
31 {
32 	return 0;
33 }
34 #endif
35 
36 /* Keyboard sampling rate */
37 #define REPEAT_RATE	40		/* 40msec -> 25cps */
38 #define REPEAT_DELAY	10		/* 10 x REPEAT_RATE = 400msec */
39 
40 #define NUM_LOCK	0x53
41 #define CAPS_LOCK	0x39
42 #define SCROLL_LOCK	0x47
43 
44 /* Modifier bits */
45 #define LEFT_CNTR	(1 << 0)
46 #define LEFT_SHIFT	(1 << 1)
47 #define LEFT_ALT	(1 << 2)
48 #define LEFT_GUI	(1 << 3)
49 #define RIGHT_CNTR	(1 << 4)
50 #define RIGHT_SHIFT	(1 << 5)
51 #define RIGHT_ALT	(1 << 6)
52 #define RIGHT_GUI	(1 << 7)
53 
54 /* Size of the keyboard buffer */
55 #define USB_KBD_BUFFER_LEN	0x20
56 
57 /* Device name */
58 #define DEVNAME			"usbkbd"
59 
60 /* Keyboard maps */
61 static const unsigned char usb_kbd_numkey[] = {
62 	'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
63 	'\r', 0x1b, '\b', '\t', ' ', '-', '=', '[', ']',
64 	'\\', '#', ';', '\'', '`', ',', '.', '/'
65 };
66 static const unsigned char usb_kbd_numkey_shifted[] = {
67 	'!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
68 	'\r', 0x1b, '\b', '\t', ' ', '_', '+', '{', '}',
69 	'|', '~', ':', '"', '~', '<', '>', '?'
70 };
71 
72 static const unsigned char usb_kbd_num_keypad[] = {
73 	'/', '*', '-', '+', '\r',
74 	'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
75 	'.', 0, 0, 0, '='
76 };
77 
78 static const u8 usb_special_keys[] = {
79 #ifdef CONFIG_USB_KEYBOARD_FN_KEYS
80 	'2', 'H', '5', '3', 'F', '6', 'C', 'D', 'B', 'A'
81 #else
82 	'C', 'D', 'B', 'A'
83 #endif
84 };
85 
86 /*
87  * NOTE: It's important for the NUM, CAPS, SCROLL-lock bits to be in this
88  *       order. See usb_kbd_setled() function!
89  */
90 #define USB_KBD_NUMLOCK		(1 << 0)
91 #define USB_KBD_CAPSLOCK	(1 << 1)
92 #define USB_KBD_SCROLLLOCK	(1 << 2)
93 #define USB_KBD_CTRL		(1 << 3)
94 
95 #define USB_KBD_LEDMASK		\
96 	(USB_KBD_NUMLOCK | USB_KBD_CAPSLOCK | USB_KBD_SCROLLLOCK)
97 
98 /*
99  * USB Keyboard reports are 8 bytes in boot protocol.
100  * Appendix B of HID Device Class Definition 1.11
101  */
102 #define USB_KBD_BOOT_REPORT_SIZE 8
103 
104 struct usb_kbd_pdata {
105 	unsigned long	intpipe;
106 	int		intpktsize;
107 	int		intinterval;
108 	unsigned long	last_report;
109 	struct int_queue *intq;
110 
111 	uint32_t	repeat_delay;
112 
113 	uint32_t	usb_in_pointer;
114 	uint32_t	usb_out_pointer;
115 	uint8_t		usb_kbd_buffer[USB_KBD_BUFFER_LEN];
116 
117 	uint8_t		*new;
118 	uint8_t		old[USB_KBD_BOOT_REPORT_SIZE];
119 
120 	uint8_t		flags;
121 };
122 
123 extern int __maybe_unused net_busy_flag;
124 
125 /* The period of time between two calls of usb_kbd_testc(). */
126 static unsigned long __maybe_unused kbd_testc_tms;
127 
128 /* Puts character in the queue and sets up the in and out pointer. */
usb_kbd_put_queue(struct usb_kbd_pdata * data,u8 c)129 static void usb_kbd_put_queue(struct usb_kbd_pdata *data, u8 c)
130 {
131 	if (data->usb_in_pointer == USB_KBD_BUFFER_LEN - 1) {
132 		/* Check for buffer full. */
133 		if (data->usb_out_pointer == 0)
134 			return;
135 
136 		data->usb_in_pointer = 0;
137 	} else {
138 		/* Check for buffer full. */
139 		if (data->usb_in_pointer == data->usb_out_pointer - 1)
140 			return;
141 
142 		data->usb_in_pointer++;
143 	}
144 
145 	data->usb_kbd_buffer[data->usb_in_pointer] = c;
146 }
147 
148 /*
149  * Set the LEDs. Since this is used in the irq routine, the control job is
150  * issued with a timeout of 0. This means, that the job is queued without
151  * waiting for job completion.
152  */
usb_kbd_setled(struct usb_device * dev)153 static void usb_kbd_setled(struct usb_device *dev)
154 {
155 	struct usb_interface *iface = &dev->config.if_desc[0];
156 	struct usb_kbd_pdata *data = dev->privptr;
157 	ALLOC_ALIGN_BUFFER(uint32_t, leds, 1, USB_DMA_MINALIGN);
158 
159 	*leds = data->flags & USB_KBD_LEDMASK;
160 	usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
161 		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
162 		0x200, iface->desc.bInterfaceNumber, leds, 1, 0);
163 }
164 
165 #define CAPITAL_MASK	0x20
166 /* Translate the scancode in ASCII */
usb_kbd_translate(struct usb_kbd_pdata * data,unsigned char scancode,unsigned char modifier,int pressed)167 static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,
168 				unsigned char modifier, int pressed)
169 {
170 	uint8_t keycode = 0;
171 
172 	/* Key released */
173 	if (pressed == 0) {
174 		data->repeat_delay = 0;
175 		return 0;
176 	}
177 
178 	if (pressed == 2) {
179 		data->repeat_delay++;
180 		if (data->repeat_delay < REPEAT_DELAY)
181 			return 0;
182 
183 		data->repeat_delay = REPEAT_DELAY;
184 	}
185 
186 	/* Alphanumeric values */
187 	if ((scancode > 3) && (scancode <= 0x1d)) {
188 		keycode = scancode - 4 + 'a';
189 
190 		if (data->flags & USB_KBD_CAPSLOCK)
191 			keycode &= ~CAPITAL_MASK;
192 
193 		if (modifier & (LEFT_SHIFT | RIGHT_SHIFT)) {
194 			/* Handle CAPSLock + Shift pressed simultaneously */
195 			if (keycode & CAPITAL_MASK)
196 				keycode &= ~CAPITAL_MASK;
197 			else
198 				keycode |= CAPITAL_MASK;
199 		}
200 	}
201 
202 	if ((scancode > 0x1d) && (scancode < 0x39)) {
203 		/* Shift pressed */
204 		if (modifier & (LEFT_SHIFT | RIGHT_SHIFT))
205 			keycode = usb_kbd_numkey_shifted[scancode - 0x1e];
206 		else
207 			keycode = usb_kbd_numkey[scancode - 0x1e];
208 	}
209 
210 	/* Numeric keypad */
211 	if ((scancode >= 0x54) && (scancode <= 0x67))
212 		keycode = usb_kbd_num_keypad[scancode - 0x54];
213 
214 	if (data->flags & USB_KBD_CTRL)
215 		keycode = scancode - 0x3;
216 
217 	if (pressed == 1) {
218 		if (scancode == NUM_LOCK) {
219 			data->flags ^= USB_KBD_NUMLOCK;
220 			return 1;
221 		}
222 
223 		if (scancode == CAPS_LOCK) {
224 			data->flags ^= USB_KBD_CAPSLOCK;
225 			return 1;
226 		}
227 		if (scancode == SCROLL_LOCK) {
228 			data->flags ^= USB_KBD_SCROLLLOCK;
229 			return 1;
230 		}
231 	}
232 
233 	/* Report keycode if any */
234 	if (keycode) {
235 		debug("%c", keycode);
236 		usb_kbd_put_queue(data, keycode);
237 		return 0;
238 	}
239 
240 #ifdef CONFIG_USB_KEYBOARD_FN_KEYS
241 	if (scancode < 0x3a || scancode > 0x52 ||
242 	    scancode == 0x46 || scancode == 0x47)
243 		return 1;
244 
245 	usb_kbd_put_queue(data, 0x1b);
246 	if (scancode < 0x3e) {
247 		/* F1 - F4 */
248 		usb_kbd_put_queue(data, 0x4f);
249 		usb_kbd_put_queue(data, scancode - 0x3a + 'P');
250 		return 0;
251 	}
252 	usb_kbd_put_queue(data, '[');
253 	if (scancode < 0x42) {
254 		/* F5 - F8 */
255 		usb_kbd_put_queue(data, '1');
256 		if (scancode == 0x3e)
257 			--scancode;
258 		keycode = scancode - 0x3f + '7';
259 	} else if (scancode < 0x49) {
260 		/* F9 - F12 */
261 		usb_kbd_put_queue(data, '2');
262 		if (scancode > 0x43)
263 			++scancode;
264 		keycode = scancode - 0x42 + '0';
265 	} else {
266 		/*
267 		 * INSERT, HOME, PAGE UP, DELETE, END, PAGE DOWN,
268 		 * RIGHT, LEFT, DOWN, UP
269 		 */
270 		keycode = usb_special_keys[scancode - 0x49];
271 	}
272 	usb_kbd_put_queue(data, keycode);
273 	if (scancode < 0x4f && scancode != 0x4a && scancode != 0x4d)
274 		usb_kbd_put_queue(data, '~');
275 	return 0;
276 #else
277 	/* Left, Right, Up, Down */
278 	if (scancode > 0x4e && scancode < 0x53) {
279 		usb_kbd_put_queue(data, 0x1b);
280 		usb_kbd_put_queue(data, '[');
281 		usb_kbd_put_queue(data, usb_special_keys[scancode - 0x4f]);
282 		return 0;
283 	}
284 	return 1;
285 #endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
286 }
287 
usb_kbd_service_key(struct usb_device * dev,int i,int up)288 static uint32_t usb_kbd_service_key(struct usb_device *dev, int i, int up)
289 {
290 	uint32_t res = 0;
291 	struct usb_kbd_pdata *data = dev->privptr;
292 	uint8_t *new;
293 	uint8_t *old;
294 
295 	if (up) {
296 		new = data->old;
297 		old = data->new;
298 	} else {
299 		new = data->new;
300 		old = data->old;
301 	}
302 
303 	if ((old[i] > 3) &&
304 	    (memscan(new + 2, old[i], USB_KBD_BOOT_REPORT_SIZE - 2) ==
305 			new + USB_KBD_BOOT_REPORT_SIZE)) {
306 		res |= usb_kbd_translate(data, old[i], data->new[0], up);
307 	}
308 
309 	return res;
310 }
311 
312 /* Interrupt service routine */
usb_kbd_irq_worker(struct usb_device * dev)313 static int usb_kbd_irq_worker(struct usb_device *dev)
314 {
315 	struct usb_kbd_pdata *data = dev->privptr;
316 	int i, res = 0;
317 
318 	/* No combo key pressed */
319 	if (data->new[0] == 0x00)
320 		data->flags &= ~USB_KBD_CTRL;
321 	/* Left or Right Ctrl pressed */
322 	else if ((data->new[0] == LEFT_CNTR) || (data->new[0] == RIGHT_CNTR))
323 		data->flags |= USB_KBD_CTRL;
324 
325 	for (i = 2; i < USB_KBD_BOOT_REPORT_SIZE; i++) {
326 		res |= usb_kbd_service_key(dev, i, 0);
327 		res |= usb_kbd_service_key(dev, i, 1);
328 	}
329 
330 	/* Key is still pressed */
331 	if ((data->new[2] > 3) && (data->old[2] == data->new[2]))
332 		res |= usb_kbd_translate(data, data->new[2], data->new[0], 2);
333 
334 	if (res == 1)
335 		usb_kbd_setled(dev);
336 
337 	memcpy(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE);
338 
339 	return 1;
340 }
341 
342 /* Keyboard interrupt handler */
usb_kbd_irq(struct usb_device * dev)343 static int usb_kbd_irq(struct usb_device *dev)
344 {
345 	if ((dev->irq_status != 0) ||
346 	    (dev->irq_act_len != USB_KBD_BOOT_REPORT_SIZE)) {
347 		debug("USB KBD: Error %lX, len %d\n",
348 		      dev->irq_status, dev->irq_act_len);
349 		return 1;
350 	}
351 
352 	return usb_kbd_irq_worker(dev);
353 }
354 
355 /* Interrupt polling */
usb_kbd_poll_for_event(struct usb_device * dev)356 static inline void usb_kbd_poll_for_event(struct usb_device *dev)
357 {
358 #if defined(CONFIG_SYS_USB_EVENT_POLL)
359 	struct usb_kbd_pdata *data = dev->privptr;
360 
361 	/* Submit an interrupt transfer request */
362 	if (usb_int_msg(dev, data->intpipe, &data->new[0],
363 			data->intpktsize, data->intinterval, true) >= 0)
364 		usb_kbd_irq_worker(dev);
365 #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) || \
366       defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
367 #if defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
368 	struct usb_interface *iface;
369 	struct usb_kbd_pdata *data = dev->privptr;
370 	iface = &dev->config.if_desc[0];
371 	usb_get_report(dev, iface->desc.bInterfaceNumber,
372 		       1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE);
373 	if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) {
374 		usb_kbd_irq_worker(dev);
375 #else
376 	struct usb_kbd_pdata *data = dev->privptr;
377 	if (poll_int_queue(dev, data->intq)) {
378 		usb_kbd_irq_worker(dev);
379 		/* We've consumed all queued int packets, create new */
380 		destroy_int_queue(dev, data->intq);
381 		data->intq = create_int_queue(dev, data->intpipe, 1,
382 				      USB_KBD_BOOT_REPORT_SIZE, data->new,
383 				      data->intinterval);
384 #endif
385 		data->last_report = get_timer(0);
386 	/* Repeat last usb hid report every REPEAT_RATE ms for keyrepeat */
387 	} else if (data->last_report != -1 &&
388 		   get_timer(data->last_report) > REPEAT_RATE) {
389 		usb_kbd_irq_worker(dev);
390 		data->last_report = get_timer(0);
391 	}
392 #endif
393 }
394 
395 /* test if a character is in the queue */
396 static int usb_kbd_testc(struct stdio_dev *sdev)
397 {
398 	struct stdio_dev *dev;
399 	struct usb_device *usb_kbd_dev;
400 	struct usb_kbd_pdata *data;
401 
402 #ifdef CONFIG_CMD_NET
403 	/*
404 	 * If net_busy_flag is 1, NET transfer is running,
405 	 * then we check key-pressed every second (first check may be
406 	 * less than 1 second) to improve TFTP booting performance.
407 	 */
408 	if (net_busy_flag && (get_timer(kbd_testc_tms) < CONFIG_SYS_HZ))
409 		return 0;
410 	kbd_testc_tms = get_timer(0);
411 #endif
412 	dev = stdio_get_by_name(DEVNAME);
413 	usb_kbd_dev = (struct usb_device *)dev->priv;
414 	data = usb_kbd_dev->privptr;
415 
416 	usb_kbd_poll_for_event(usb_kbd_dev);
417 
418 	return !(data->usb_in_pointer == data->usb_out_pointer);
419 }
420 
421 /* gets the character from the queue */
422 static int usb_kbd_getc(struct stdio_dev *sdev)
423 {
424 	struct stdio_dev *dev;
425 	struct usb_device *usb_kbd_dev;
426 	struct usb_kbd_pdata *data;
427 
428 	dev = stdio_get_by_name(DEVNAME);
429 	usb_kbd_dev = (struct usb_device *)dev->priv;
430 	data = usb_kbd_dev->privptr;
431 
432 	while (data->usb_in_pointer == data->usb_out_pointer)
433 		usb_kbd_poll_for_event(usb_kbd_dev);
434 
435 	if (data->usb_out_pointer == USB_KBD_BUFFER_LEN - 1)
436 		data->usb_out_pointer = 0;
437 	else
438 		data->usb_out_pointer++;
439 
440 	return data->usb_kbd_buffer[data->usb_out_pointer];
441 }
442 
443 /* probes the USB device dev for keyboard type. */
444 static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
445 {
446 	struct usb_interface *iface;
447 	struct usb_endpoint_descriptor *ep;
448 	struct usb_kbd_pdata *data;
449 
450 	if (dev->descriptor.bNumConfigurations != 1)
451 		return 0;
452 
453 	iface = &dev->config.if_desc[ifnum];
454 
455 	if (iface->desc.bInterfaceClass != USB_CLASS_HID)
456 		return 0;
457 
458 	if (iface->desc.bInterfaceSubClass != USB_SUB_HID_BOOT)
459 		return 0;
460 
461 	if (iface->desc.bInterfaceProtocol != USB_PROT_HID_KEYBOARD)
462 		return 0;
463 
464 	if (iface->desc.bNumEndpoints != 1)
465 		return 0;
466 
467 	ep = &iface->ep_desc[0];
468 
469 	/* Check if endpoint 1 is interrupt endpoint */
470 	if (!(ep->bEndpointAddress & 0x80))
471 		return 0;
472 
473 	if ((ep->bmAttributes & 3) != 3)
474 		return 0;
475 
476 	debug("USB KBD: found set protocol...\n");
477 
478 	data = malloc(sizeof(struct usb_kbd_pdata));
479 	if (!data) {
480 		printf("USB KBD: Error allocating private data\n");
481 		return 0;
482 	}
483 
484 	/* Clear private data */
485 	memset(data, 0, sizeof(struct usb_kbd_pdata));
486 
487 	/* allocate input buffer aligned and sized to USB DMA alignment */
488 	data->new = memalign(USB_DMA_MINALIGN,
489 		roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN));
490 
491 	/* Insert private data into USB device structure */
492 	dev->privptr = data;
493 
494 	/* Set IRQ handler */
495 	dev->irq_handle = usb_kbd_irq;
496 
497 	data->intpipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
498 	data->intpktsize = min(usb_maxpacket(dev, data->intpipe),
499 			       USB_KBD_BOOT_REPORT_SIZE);
500 	data->intinterval = ep->bInterval;
501 	data->last_report = -1;
502 
503 	/* We found a USB Keyboard, install it. */
504 	usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);
505 
506 	debug("USB KBD: found set idle...\n");
507 #if !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) && \
508     !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
509 	usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE / 4, 0);
510 #else
511 	usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
512 #endif
513 
514 	debug("USB KBD: enable interrupt pipe...\n");
515 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
516 	data->intq = create_int_queue(dev, data->intpipe, 1,
517 				      USB_KBD_BOOT_REPORT_SIZE, data->new,
518 				      data->intinterval);
519 	if (!data->intq) {
520 #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
521 	if (usb_get_report(dev, iface->desc.bInterfaceNumber,
522 			   1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE) < 0) {
523 #else
524 	if (usb_int_msg(dev, data->intpipe, data->new, data->intpktsize,
525 			data->intinterval, false) < 0) {
526 #endif
527 		printf("Failed to get keyboard state from device %04x:%04x\n",
528 		       dev->descriptor.idVendor, dev->descriptor.idProduct);
529 		/* Abort, we don't want to use that non-functional keyboard. */
530 		return 0;
531 	}
532 
533 	/* Success. */
534 	return 1;
535 }
536 
537 static int probe_usb_keyboard(struct usb_device *dev)
538 {
539 	char *stdinname;
540 	struct stdio_dev usb_kbd_dev;
541 	int error;
542 
543 	/* Try probing the keyboard */
544 	if (usb_kbd_probe_dev(dev, 0) != 1)
545 		return -ENOENT;
546 
547 	/* Register the keyboard */
548 	debug("USB KBD: register.\n");
549 	memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
550 	strcpy(usb_kbd_dev.name, DEVNAME);
551 	usb_kbd_dev.flags =  DEV_FLAGS_INPUT;
552 	usb_kbd_dev.getc = usb_kbd_getc;
553 	usb_kbd_dev.tstc = usb_kbd_testc;
554 	usb_kbd_dev.priv = (void *)dev;
555 	error = stdio_register(&usb_kbd_dev);
556 	if (error)
557 		return error;
558 
559 	stdinname = env_get("stdin");
560 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
561 	error = iomux_doenv(stdin, stdinname);
562 	if (error)
563 		return error;
564 #else
565 	/* Check if this is the standard input device. */
566 	if (strcmp(stdinname, DEVNAME))
567 		return 1;
568 
569 	/* Reassign the console */
570 	if (overwrite_console())
571 		return 1;
572 
573 	error = console_assign(stdin, DEVNAME);
574 	if (error)
575 		return error;
576 #endif
577 
578 	return 0;
579 }
580 
581 #if !CONFIG_IS_ENABLED(DM_USB)
582 /* Search for keyboard and register it if found. */
583 int drv_usb_kbd_init(void)
584 {
585 	int error, i;
586 
587 	debug("%s: Probing for keyboard\n", __func__);
588 	/* Scan all USB Devices */
589 	for (i = 0; i < USB_MAX_DEVICE; i++) {
590 		struct usb_device *dev;
591 
592 		/* Get USB device. */
593 		dev = usb_get_dev_index(i);
594 		if (!dev)
595 			break;
596 
597 		if (dev->devnum == -1)
598 			continue;
599 
600 		error = probe_usb_keyboard(dev);
601 		if (!error)
602 			return 1;
603 		if (error && error != -ENOENT)
604 			return error;
605 	}
606 
607 	/* No USB Keyboard found */
608 	return -1;
609 }
610 
611 /* Deregister the keyboard. */
612 int usb_kbd_deregister(int force)
613 {
614 #if CONFIG_IS_ENABLED(SYS_STDIO_DEREGISTER)
615 	struct stdio_dev *dev;
616 	struct usb_device *usb_kbd_dev;
617 	struct usb_kbd_pdata *data;
618 
619 	dev = stdio_get_by_name(DEVNAME);
620 	if (dev) {
621 		usb_kbd_dev = (struct usb_device *)dev->priv;
622 		data = usb_kbd_dev->privptr;
623 		if (stdio_deregister_dev(dev, force) != 0)
624 			return 1;
625 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
626 		if (iomux_doenv(stdin, env_get("stdin")) != 0)
627 			return 1;
628 #endif
629 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
630 		destroy_int_queue(usb_kbd_dev, data->intq);
631 #endif
632 		free(data->new);
633 		free(data);
634 	}
635 
636 	return 0;
637 #else
638 	return 1;
639 #endif
640 }
641 
642 #endif
643 
644 #if CONFIG_IS_ENABLED(DM_USB)
645 
646 int usb_kbd_recv_fn(int key_fn)
647 {
648 	char ch[5];
649 	int i;
650 
651 	if (!ftstc(stdin)) {
652 		debug("No char\n");
653 		return 0;
654 	}
655 
656 	memset(ch, 0, 5);
657 	for (i = 0; i < 5; i++) {
658 		if (!ftstc(stdin))
659 			break;
660 		ch[i] = fgetc(stdin);
661 		debug("char[%d]: 0x%x, %d\n", i, ch[i], ch[i]);
662 	}
663 
664 	if (ch[0] != 0x1b) {
665 		debug("Invalid 0x1b\n");
666 		return 0;
667 	}
668 
669 	switch (key_fn) {
670 	case KEY_F1:
671 	case KEY_F2:
672 	case KEY_F3:
673 	case KEY_F4:
674 		if (ch[1] != 0x4f)
675 			return 0;
676 		return (ch[2] - 21 == key_fn);
677 	case KEY_F5:
678 	case KEY_F6:
679 	case KEY_F7:
680 	case KEY_F8:
681 		if (ch[1] != '[' || ch[2] != '1' || ch[4] != '~')
682 			return 0;
683 		return (ch[3] + 9 == key_fn);
684 	case KEY_F9:
685 	case KEY_F10:
686 		if (ch[1] != '[' || ch[2] != '2' || ch[4] != '~')
687 			return 0;
688 		return (ch[3] + 19 == key_fn);
689 	case KEY_F11:
690 	case KEY_F12:
691 		if (ch[1] != '[' || ch[2] != '2' || ch[4] != '~')
692 			return 0;
693 		return (ch[3] + 36 == key_fn);
694 	default:
695 		return 0;
696 	}
697 
698 	return 0;
699 }
700 
701 static int usb_kbd_probe(struct udevice *dev)
702 {
703 	struct usb_device *udev = dev_get_parent_priv(dev);
704 
705 	return probe_usb_keyboard(udev);
706 }
707 
708 static int usb_kbd_remove(struct udevice *dev)
709 {
710 	struct usb_device *udev = dev_get_parent_priv(dev);
711 	struct usb_kbd_pdata *data;
712 	struct stdio_dev *sdev;
713 	int ret;
714 
715 	sdev = stdio_get_by_name(DEVNAME);
716 	if (!sdev) {
717 		ret = -ENXIO;
718 		goto err;
719 	}
720 	data = udev->privptr;
721 	if (stdio_deregister_dev(sdev, true)) {
722 		ret = -EPERM;
723 		goto err;
724 	}
725 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
726 	if (iomux_doenv(stdin, env_get("stdin"))) {
727 		ret = -ENOLINK;
728 		goto err;
729 	}
730 #endif
731 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
732 	destroy_int_queue(udev, data->intq);
733 #endif
734 	free(data->new);
735 	free(data);
736 
737 	return 0;
738 err:
739 	printf("%s: warning, ret=%d", __func__, ret);
740 	return ret;
741 }
742 
743 static const struct udevice_id usb_kbd_ids[] = {
744 	{ .compatible = "usb-keyboard" },
745 	{ }
746 };
747 
748 U_BOOT_DRIVER(usb_kbd) = {
749 	.name	= "usb_kbd",
750 	.id	= UCLASS_KEYBOARD,
751 	.of_match = usb_kbd_ids,
752 	.probe = usb_kbd_probe,
753 	.remove = usb_kbd_remove,
754 };
755 
756 static const struct usb_device_id kbd_id_table[] = {
757 	{
758 		.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
759 			USB_DEVICE_ID_MATCH_INT_SUBCLASS |
760 			USB_DEVICE_ID_MATCH_INT_PROTOCOL,
761 		.bInterfaceClass = USB_CLASS_HID,
762 		.bInterfaceSubClass = USB_SUB_HID_BOOT,
763 		.bInterfaceProtocol = USB_PROT_HID_KEYBOARD,
764 	},
765 	{ }		/* Terminating entry */
766 };
767 
768 U_BOOT_USB_DEVICE(usb_kbd, kbd_id_table);
769 
770 #endif
771