diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 69939f06ac..ef440e4723 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -98,6 +98,26 @@ static unsigned char usb_kbd_numkey_shifted[] = { '|', '~', ':', '"', '~', '<', '>', '?' }; +static int usb_kbd_irq_worker(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) + usb_event_poll(); + usb_kbd_irq_worker(dev); +#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) + struct usb_interface *iface; + iface = &dev->config.if_desc[0]; + usb_get_report(dev, iface->desc.bInterfaceNumber, + 1, 1, new, sizeof(new)); + if (memcmp(old, new, sizeof(new))) + usb_kbd_irq_worker(dev); +#endif +} + /****************************************************************** * Queue handling ******************************************************************/ @@ -121,9 +141,14 @@ static void usb_kbd_put_queue(char data) /* test if a character is in the queue */ static int usb_kbd_testc(void) { -#ifdef CONFIG_SYS_USB_EVENT_POLL - usb_event_poll(); -#endif + struct stdio_dev *dev; + struct usb_device *usb_kbd_dev; + + dev = stdio_get_by_name("usbkbd"); + usb_kbd_dev = (struct usb_device *)dev->priv; + + usb_kbd_poll_for_event(usb_kbd_dev); + if (usb_in_pointer == usb_out_pointer) return 0; /* no data */ else @@ -133,11 +158,16 @@ static int usb_kbd_testc(void) static int usb_kbd_getc(void) { char c; - while (usb_in_pointer == usb_out_pointer) { -#ifdef CONFIG_SYS_USB_EVENT_POLL - usb_event_poll(); -#endif - } + + struct stdio_dev *dev; + struct usb_device *usb_kbd_dev; + + dev = stdio_get_by_name("usbkbd"); + usb_kbd_dev = (struct usb_device *)dev->priv; + + while (usb_in_pointer == usb_out_pointer) + usb_kbd_poll_for_event(usb_kbd_dev); + if ((usb_out_pointer+1) == USB_KBD_BUFFER_LEN) usb_out_pointer = 0; else @@ -323,15 +353,10 @@ static int usb_kbd_translate(unsigned char scancode, unsigned char modifier, } /* Interrupt service routine */ -static int usb_kbd_irq(struct usb_device *dev) +static int usb_kbd_irq_worker(struct usb_device *dev) { int i, res; - if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) { - USB_KBD_PRINTF("usb_keyboard Error %lX, len %d\n", - dev->irq_status, dev->irq_act_len); - return 1; - } res = 0; switch (new[0]) { @@ -362,6 +387,17 @@ static int usb_kbd_irq(struct usb_device *dev) return 1; /* install IRQ Handler again */ } +static int usb_kbd_irq(struct usb_device *dev) +{ + if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) { + USB_KBD_PRINTF("usb_keyboard Error %lX, len %d\n", + dev->irq_status, dev->irq_act_len); + return 1; + } + + return usb_kbd_irq_worker(dev); +} + /* probes the USB device dev for keyboard type */ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum) {