dm: usb: Add support for USB keyboards with driver model
authorSimon Glass <sjg@chromium.org>
Tue, 8 Sep 2015 17:15:11 +0000 (11:15 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 20 Nov 2015 03:13:39 +0000 (20:13 -0700)
Switch USB keyboards over to use driver model instead of scanning with the
horrible usb_get_dev_index() function. This involves creating a new uclass
for keyboards, although so far there is no API.

Signed-off-by: Simon Glass <sjg@chromium.org>
common/cmd_usb.c
common/usb_kbd.c
include/dm/uclass-id.h

index 1ef55dc..4679134 100644 (file)
@@ -527,11 +527,14 @@ static void do_usb_start(void)
 
        /* Driver model will probe the devices as they are found */
 #ifndef CONFIG_DM_USB
-#ifdef CONFIG_USB_STORAGE
+# ifdef CONFIG_USB_STORAGE
        /* try to recognize storage devices immediately */
        usb_stor_curr_dev = usb_stor_scan(1);
-#endif
-#endif
+# endif
+# ifdef CONFIG_USB_KEYBOARD
+       drv_usb_kbd_init();
+# endif
+#endif /* !CONFIG_DM_USB */
 #ifdef CONFIG_USB_HOST_ETHER
 # ifdef CONFIG_DM_ETH
 #  ifndef CONFIG_DM_USB
@@ -542,9 +545,6 @@ static void do_usb_start(void)
        usb_ether_curr_dev = usb_host_eth_scan(1);
 # endif
 #endif
-#ifdef CONFIG_USB_KEYBOARD
-       drv_usb_kbd_init();
-#endif
 }
 
 #ifdef CONFIG_DM_USB
index 0302e5b..137ec65 100644 (file)
@@ -399,7 +399,7 @@ static int usb_kbd_getc(struct stdio_dev *sdev)
 }
 
 /* probes the USB device dev for keyboard type. */
-static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
+static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
 {
        struct usb_interface *iface;
        struct usb_endpoint_descriptor *ep;
@@ -496,7 +496,7 @@ static int probe_usb_keyboard(struct usb_device *dev)
        int error;
 
        /* Try probing the keyboard */
-       if (usb_kbd_probe(dev, 0) != 1)
+       if (usb_kbd_probe_dev(dev, 0) != 1)
                return -ENOENT;
 
        /* Register the keyboard */
@@ -533,6 +533,7 @@ static int probe_usb_keyboard(struct usb_device *dev)
        return 0;
 }
 
+#ifndef CONFIG_DM_USB
 /* Search for keyboard and register it if found. */
 int drv_usb_kbd_init(void)
 {
@@ -591,6 +592,7 @@ int drv_usb_kbd_init(void)
        /* No USB Keyboard found */
        return -1;
 }
+#endif
 
 /* Deregister the keyboard. */
 int usb_kbd_deregister(int force)
@@ -622,3 +624,49 @@ int usb_kbd_deregister(int force)
        return 1;
 #endif
 }
+
+#ifdef CONFIG_DM_USB
+
+static int usb_kbd_probe(struct udevice *dev)
+{
+       struct usb_device *udev = dev_get_parent_priv(dev);
+       int ret;
+
+       ret = probe_usb_keyboard(udev);
+
+       return ret;
+}
+
+static const struct udevice_id usb_kbd_ids[] = {
+       { .compatible = "usb-keyboard" },
+       { }
+};
+
+U_BOOT_DRIVER(usb_kbd) = {
+       .name   = "usb_kbd",
+       .id     = UCLASS_KEYBOARD,
+       .of_match = usb_kbd_ids,
+       .probe = usb_kbd_probe,
+};
+
+/* TODO(sjg@chromium.org): Move this into a common location */
+UCLASS_DRIVER(keyboard) = {
+       .id             = UCLASS_KEYBOARD,
+       .name           = "keyboard",
+};
+
+static const struct usb_device_id kbd_id_table[] = {
+       {
+               .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
+                       USB_DEVICE_ID_MATCH_INT_SUBCLASS |
+                       USB_DEVICE_ID_MATCH_INT_PROTOCOL,
+               .bInterfaceClass = USB_CLASS_HID,
+               .bInterfaceSubClass = 1,
+               .bInterfaceProtocol = 1,
+       },
+       { }             /* Terminating entry */
+};
+
+U_BOOT_USB_DEVICE(usb_kbd, kbd_id_table);
+
+#endif
index 327de34..27fa0b6 100644 (file)
@@ -37,6 +37,7 @@ enum uclass_id {
        UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
        UCLASS_I2C_GENERIC,     /* Generic I2C device */
        UCLASS_I2C_MUX,         /* I2C multiplexer */
+       UCLASS_KEYBOARD,        /* Keyboard input device */
        UCLASS_LED,             /* Light-emitting diode (LED) */
        UCLASS_LPC,             /* x86 'low pin count' interface */
        UCLASS_MASS_STORAGE,    /* Mass storage device */