]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/usb_kbd.c
karo: tx48: fix build error "undefined reference to `mmc_legacy_init'"
[karo-tx-uboot.git] / common / usb_kbd.c
index e02529fca4b1657ff109bf984d358d7cd085562a..0227024441710041a4cbcb2fd5c30920ad9078a6 100644 (file)
@@ -8,6 +8,7 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <stdio_dev.h>
@@ -30,7 +31,7 @@ int overwrite_console(void)
 #endif
 
 /* Keyboard sampling rate */
-#define REPEAT_RATE    (40 / 4)        /* 40msec -> 25cps */
+#define REPEAT_RATE    40              /* 40msec -> 25cps */
 #define REPEAT_DELAY   10              /* 10 x REPEAT_RATE = 400msec */
 
 #define NUM_LOCK       0x53
@@ -102,6 +103,7 @@ struct usb_kbd_pdata {
        unsigned long   intpipe;
        int             intpktsize;
        int             intinterval;
+       unsigned long   last_report;
        struct int_queue *intq;
 
        uint32_t        repeat_delay;
@@ -309,7 +311,7 @@ static int usb_kbd_irq(struct usb_device *dev)
 /* Interrupt polling */
 static inline void usb_kbd_poll_for_event(struct usb_device *dev)
 {
-#if    defined(CONFIG_SYS_USB_EVENT_POLL)
+#if defined(CONFIG_SYS_USB_EVENT_POLL)
        struct usb_kbd_pdata *data = dev->privptr;
 
        /* Submit a interrupt transfer request */
@@ -317,15 +319,17 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
                           data->intinterval);
 
        usb_kbd_irq_worker(dev);
-#elif  defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
+#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) || \
+      defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
+#if defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
        struct usb_interface *iface;
        struct usb_kbd_pdata *data = dev->privptr;
        iface = &dev->config.if_desc[0];
        usb_get_report(dev, iface->desc.bInterfaceNumber,
                       1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE);
-       if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE))
+       if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) {
                usb_kbd_irq_worker(dev);
-#elif  defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
+#else
        struct usb_kbd_pdata *data = dev->privptr;
        if (poll_int_queue(dev, data->intq)) {
                usb_kbd_irq_worker(dev);
@@ -334,6 +338,13 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
                data->intq = create_int_queue(dev, data->intpipe, 1,
                                      USB_KBD_BOOT_REPORT_SIZE, data->new,
                                      data->intinterval);
+#endif
+               data->last_report = get_timer(0);
+       /* Repeat last usb hid report every REPEAT_RATE ms for keyrepeat */
+       } else if (data->last_report != -1 &&
+                  get_timer(data->last_report) > REPEAT_RATE) {
+               usb_kbd_irq_worker(dev);
+               data->last_report = get_timer(0);
        }
 #endif
 }
@@ -444,12 +455,18 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
        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. */
        usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0);
 
        debug("USB KBD: found set idle...\n");
-       usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);
+#if !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) && \
+    !defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
+       usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE / 4, 0);
+#else
+       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
@@ -520,7 +537,37 @@ int drv_usb_kbd_init(void)
 {
        int error, i;
 
-       debug("%s: Probing for keyboard\n", __func__);/* Scan all USB Devices */
+       debug("%s: Probing for keyboard\n", __func__);
+#ifdef CONFIG_DM_USB
+       /*
+        * TODO: We should add U_BOOT_USB_DEVICE() declarations to each USB
+        * keyboard driver and then most of this file can be removed.
+        */
+       struct udevice *bus;
+       struct uclass *uc;
+       int ret;
+
+       ret = uclass_get(UCLASS_USB, &uc);
+       if (ret)
+               return ret;
+       uclass_foreach_dev(bus, uc) {
+               for (i = 0; i < USB_MAX_DEVICE; i++) {
+                       struct usb_device *dev;
+
+                       dev = usb_get_dev_index(bus, i); /* get device */
+                       debug("i=%d, %p\n", i, dev);
+                       if (!dev)
+                               break; /* no more devices available */
+
+                       error = probe_usb_keyboard(dev);
+                       if (!error)
+                               return 1;
+                       if (error && error != -ENOENT)
+                               return error;
+               } /* for */
+       }
+#else
+       /* Scan all USB Devices */
        for (i = 0; i < USB_MAX_DEVICE; i++) {
                struct usb_device *dev;
 
@@ -538,6 +585,7 @@ int drv_usb_kbd_init(void)
                if (error && error != -ENOENT)
                        return error;
        }
+#endif
 
        /* No USB Keyboard found */
        return -1;