]> git.sur5r.net Git - u-boot/blobdiff - drivers/usb/host/dwc2.c
usb: dwc2: implement interrupt transfers
[u-boot] / drivers / usb / host / dwc2.c
index 5f4ca7abf7bf76f282b992639f09779eb629c924..f3fbe76acf9b094604585aeda52dbec22d8a608b 100644 (file)
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <usb.h>
 #include <malloc.h>
+#include <phys2bus.h>
 #include <usbroothubdes.h>
 #include <asm/io.h>
 
@@ -397,15 +398,18 @@ static void dwc_otg_core_init(struct dwc2_core_regs *regs)
  * @param hc Information needed to initialize the host channel
  */
 static void dwc_otg_hc_init(struct dwc2_core_regs *regs, uint8_t hc_num,
-               uint8_t dev_addr, uint8_t ep_num, uint8_t ep_is_in,
-               uint8_t ep_type, uint16_t max_packet)
+               struct usb_device *dev, uint8_t dev_addr, uint8_t ep_num,
+               uint8_t ep_is_in, uint8_t ep_type, uint16_t max_packet)
 {
        struct dwc2_hc_regs *hc_regs = &regs->hc_regs[hc_num];
-       const uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) |
-                               (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) |
-                               (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) |
-                               (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) |
-                               (max_packet << DWC2_HCCHAR_MPS_OFFSET);
+       uint32_t hcchar = (dev_addr << DWC2_HCCHAR_DEVADDR_OFFSET) |
+                         (ep_num << DWC2_HCCHAR_EPNUM_OFFSET) |
+                         (ep_is_in << DWC2_HCCHAR_EPDIR_OFFSET) |
+                         (ep_type << DWC2_HCCHAR_EPTYPE_OFFSET) |
+                         (max_packet << DWC2_HCCHAR_MPS_OFFSET);
+
+       if (dev->speed == USB_SPEED_LOW)
+               hcchar |= DWC2_HCCHAR_LSPDDEV;
 
        /* Clear old interrupt conditions for this host channel. */
        writel(0x3fff, &hc_regs->hcint);
@@ -462,7 +466,11 @@ static int dwc_otg_submit_rh_msg_in_status(struct usb_device *dev, void *buffer,
                if (hprt0 & DWC2_HPRT0_PRTPWR)
                        port_status |= USB_PORT_STAT_POWER;
 
-               port_status |= USB_PORT_STAT_HIGH_SPEED;
+               if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) == DWC2_HPRT0_PRTSPD_LOW)
+                       port_status |= USB_PORT_STAT_LOW_SPEED;
+               else if ((hprt0 & DWC2_HPRT0_PRTSPD_MASK) ==
+                        DWC2_HPRT0_PRTSPD_HIGH)
+                       port_status |= USB_PORT_STAT_HIGH_SPEED;
 
                if (hprt0 & DWC2_HPRT0_PRTENCHNG)
                        port_change |= USB_PORT_STAT_C_ENABLE;
@@ -761,8 +769,8 @@ int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in,
 
        do {
                /* Initialize channel */
-               dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, devnum, ep, in, eptype,
-                               max);
+               dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, dev, devnum, ep, in,
+                               eptype, max);
 
                xfer_len = len - done;
                if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
@@ -795,7 +803,8 @@ int chunk_msg(struct usb_device *dev, unsigned long pipe, int *pid, int in,
                if (!in)
                        memcpy(aligned_buffer, (char *)buffer + done, len);
 
-               writel((uint32_t)aligned_buffer, &hc_regs->hcdma);
+               writel(phys_to_bus((unsigned long)aligned_buffer),
+                      &hc_regs->hcdma);
 
                /* Set host channel enable after all other setup is complete. */
                clrsetbits_le32(&hc_regs->hcchar, DWC2_HCCHAR_MULTICNT_MASK |
@@ -895,9 +904,8 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
                   int len, int interval)
 {
-       printf("dev = %p pipe = %#lx buf = %p size = %d int = %d\n",
-              dev, pipe, buffer, len, interval);
-       return -ENOSYS;
+       /* FIXME: what is interval? */
+       return submit_bulk_msg(dev, pipe, buffer, len);
 }
 
 /* U-Boot USB control interface */