summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjzlv <[email protected]>2022-02-09 15:18:08 +0800
committerjzlv <[email protected]>2022-02-09 15:18:14 +0800
commit1f4eb91259629db8266b83b7444a054072475f61 (patch)
tree976175546d8940fffd83e6f90df7e81e01998498
parent1ca9783de56c25bf68a2feb736054cbd025f6506 (diff)
update ehci driver
-rw-r--r--common/usb_hc.h2
-rw-r--r--port/ehci/usb_ehci.c55
-rw-r--r--port/ehci/usb_ehci.h4
3 files changed, 55 insertions, 6 deletions
diff --git a/common/usb_hc.h b/common/usb_hc.h
index 78ad77f0..7a12a98b 100644
--- a/common/usb_hc.h
+++ b/common/usb_hc.h
@@ -78,7 +78,7 @@ int usbh_reset_port(const uint8_t port);
* @brief get roothub port speed
*
* @param port port index
- * @return return 0 means USB_SPEED_LOW, 1 means USB_SPEED_FULL and 2 means USB_SPEED_HIGH.
+ * @return return 1 means USB_SPEED_LOW, 2 means USB_SPEED_FULL and 3 means USB_SPEED_HIGH.
*/
uint8_t usbh_get_port_speed(const uint8_t port);
diff --git a/port/ehci/usb_ehci.c b/port/ehci/usb_ehci.c
index c015311c..96d78833 100644
--- a/port/ehci/usb_ehci.c
+++ b/port/ehci/usb_ehci.c
@@ -2192,10 +2192,11 @@ int usb_hc_init(void)
usb_ehci_putreg(regval, &HCOR->usbcmd);
/* Route all ports to this host controller by setting the CONFIG flag. */
- // regval = usb_ehci_getreg(&HCOR->configflag);
- // regval |= EHCI_CONFIGFLAG;
- // usb_ehci_putreg(regval, &HCOR->configflag);
-
+#ifdef CONFIG_USB_EHCI_CONFIGFLAG
+ regval = usb_ehci_getreg(&HCOR->configflag);
+ regval |= EHCI_CONFIGFLAG;
+ usb_ehci_putreg(regval, &HCOR->configflag);
+#endif
/* Wait for the EHCI to run (i.e., no longer report halted) */
ret = usb_ehci_wait_usbsts(EHCI_USBSTS_HALTED, 0, 100 * 1000);
if (ret < 0) {
@@ -2212,6 +2213,52 @@ int usb_hc_init(void)
return ret;
}
+int usbh_reset_port(const uint8_t port)
+{
+ uint32_t timeout = 0;
+ uint32_t regval;
+ regval = usb_ehci_getreg(&HCOR->portsc[port - 1]);
+ regval &= ~EHCI_PORTSC_PE;
+ regval |= EHCI_PORTSC_RESET;
+ usb_ehci_putreg(regval, &HCOR->portsc[port - 1]);
+
+ usb_osal_msleep(55);
+
+ regval = usb_ehci_getreg(&HCOR->portsc[port - 1]);
+ regval &= ~EHCI_PORTSC_RESET;
+ usb_ehci_putreg(regval, &HCOR->portsc[port - 1]);
+
+ /* Wait for the port reset to complete
+ *
+ * Paragraph 2.3.9:
+ *
+ * "Note that when software writes a zero to this bit there may be a
+ * delay before the bit status changes to a zero. The bit status will
+ * not read as a zero until after the reset has completed. If the port
+ * is in high-speed mode after reset is complete, the host controller
+ * will automatically enable this port (e.g. set the Port Enable bit
+ * to a one). A host controller must terminate the reset and stabilize
+ * the state of the port within 2 milliseconds of software transitioning
+ * this bit from a one to a zero ..."
+ */
+
+ while ((usb_ehci_getreg(&HCOR->portsc[port - 1]) & EHCI_PORTSC_RESET) != 0) {
+ usb_osal_msleep(1);
+ timeout++;
+ if (timeout > 100) {
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+__WEAK uint8_t usbh_get_port_speed(const uint8_t port)
+{
+ /* Defined by individual manufacturers */
+ return 0;
+}
+
int usbh_ep0_reconfigure(usbh_epinfo_t ep, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed)
{
struct usb_ehci_epinfo_s *epinfo;
diff --git a/port/ehci/usb_ehci.h b/port/ehci/usb_ehci.h
index 1393a3b8..cf25ce30 100644
--- a/port/ehci/usb_ehci.h
+++ b/port/ehci/usb_ehci.h
@@ -872,7 +872,9 @@ struct ehci_hcor_s
uint32_t ctrldssegment; /* 0x10: 4G Segment Selector */
uint32_t periodiclistbase; /* 0x14: Frame List Base Address */
uint32_t asynclistaddr; /* 0x18: Next Asynchronous List Address */
- // uint32_t reserved[9];
+#ifdef CONFIG_USB_ECHI_HCOR_RESERVED
+ uint32_t reserved[9];
+#endif
uint32_t configflag; /* 0x40: Configured Flag Register */
uint32_t portsc[15]; /* 0x44: Port Status/Control */
};