U-boot does not like my USB keyboards

I prefer mechanical keyboards, in particular, the tenkeyless (TKL) variety.

I have attempted to use three different keyboards, none of which u-boot seems to like. The only keyboard that I own that u-boot does like, is a logitech keyboard (104 keys). But this keyboard is old and ready to be discarded.

I have searched and can not find much concerning such an issue. Anyone else have issue with u-boot not recognizing their keyboard? I am not sure if this is an issue with noname brand keyboards or an issue with the keyboards being tenkeykess.

Sounds like your mechanical keyboards use a different driver than the one that works. That driver would need to be ported/enabled in uboot.

1 Like

common/usb_kbd.c

/* probes the USB device dev for keyboard type. */
static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
{
        struct usb_interface *iface;
        struct usb_endpoint_descriptor *ep;
        struct usb_kbd_pdata *data;
        int epNum;

        if (dev->descriptor.bNumConfigurations != 1)
                return 0;

        iface = &dev->config.if_desc[ifnum];

        if (iface->desc.bInterfaceClass != USB_CLASS_HID)
                return 0;

        if (iface->desc.bInterfaceSubClass != USB_SUB_HID_BOOT)
                return 0;

        if (iface->desc.bInterfaceProtocol != USB_PROT_HID_KEYBOARD)
                return 0;

        for (epNum = 0; epNum < iface->desc.bNumEndpoints; epNum++) {
                ep = &iface->ep_desc[epNum];

                /* Check if endpoint is interrupt IN endpoint */
                if ((ep->bmAttributes & 3) != 3)
                        continue;

                if (ep->bEndpointAddress & 0x80)
                        break;
        }

        if (epNum == iface->desc.bNumEndpoints)
                return 0;

        debug("USB KBD: found interrupt EP: 0x%x\n", ep->bEndpointAddress);

        data = malloc(sizeof(struct usb_kbd_pdata));
        if (!data) {
                printf("USB KBD: Error allocating private data\n");
                return 0;
        }

        /* Clear private data */
        memset(data, 0, sizeof(struct usb_kbd_pdata));

        /* allocate input buffer aligned and sized to USB DMA alignment */
        data->new = memalign(USB_DMA_MINALIGN,
                roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN));

        /* Insert private data into USB device structure */
        dev->privptr = data;

        /* Set IRQ handler */
        dev->irq_handle = usb_kbd_irq;

        data->intpipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
        data->intpktsize = min(usb_maxpacket(dev, data->intpipe),
                               USB_KBD_BOOT_REPORT_SIZE);
        data->intinterval = ep->bInterval;
        data->last_report = -1;

        /* We found a USB Keyboard, install it. */
        debug("USB KBD: set boot protocol\n");
        usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);

#if !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) && \
    !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
        debug("USB KBD: set idle interval...\n");
        usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE / 4, 0);
#else
        debug("USB KBD: set idle interval=0...\n");
        usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
#endif

        debug("USB KBD: enable interrupt pipe...\n");
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
        data->intq = create_int_queue(dev, data->intpipe, 1,
                                      USB_KBD_BOOT_REPORT_SIZE, data->new,
                                      data->intinterval);
        if (!data->intq) {
#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
        if (usb_get_report(dev, iface->desc.bInterfaceNumber,
                           1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE) < 0) {
#else
        if (usb_int_msg(dev, data->intpipe, data->new, data->intpktsize,
                        data->intinterval, false) < 0) {
#endif
                printf("Failed to get keyboard state from device %04x:%04x\n",
                       dev->descriptor.idVendor, dev->descriptor.idProduct);
                /* Abort, we don't want to use that non-functional keyboard. */
                return 0;
        }

        /* Success. */
        return 1;
}

It seems to fall through to this point, without discovering the keyboard.

                 printf("Failed to get keyboard state from device %04x:%04x\n",
                       dev->descriptor.idVendor, dev->descriptor.idProduct);
                /* Abort, we don't want to use that non-functional keyboard. */
                return 0;

I think maybe I need to try and add the idVendor and idProduct codes for my “noname” keyboards. But it does not appear to test based on them, but rather more direct query of the device.

Edit: The Drop ENTR is the latest keyboard to fail to be recognized. This is surprising to me.
A Leopold is correctly identified, but it too is 104 keys.