This allows the keyboard to avoid requests via Interrupt Endpoint altogether and run all requests via Control Endpoint. This uses the Get_Report request.
Signed-off-by: Marek Vasut <marek.va...@gmail.com> Cc: Remy Bohmer <li...@bohmer.net> --- common/usb_kbd.c | 64 ++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 50 insertions(+), 14 deletions(-) V2: Add missing condition to ignore repetitive events when polling via EP0 diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 9957dcc..503d175 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -96,6 +96,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 ******************************************************************/ @@ -120,9 +140,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 @@ -132,11 +157,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 @@ -308,15 +338,10 @@ static int usb_kbd_translate(unsigned char scancode,unsigned char modifier,int p } /* 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]) { @@ -345,6 +370,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) { -- 1.7.5.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot