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