summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-11-28 15:37:57 +0100
committerHiFiPhile <[email protected]>2026-01-06 19:49:28 +0100
commit3302c07d129e8a6c2631a9b15d5a3549b455a3ea (patch)
treebda9c0d2d26c6abecb8e4fff14e25788951fc198
parent593dce28349cf5b1299c2cf1193312cb783574f3 (diff)
dwc2: implement deinit
Signed-off-by: HiFiPhile <[email protected]>
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c12
-rw-r--r--src/portable/synopsys/dwc2/dwc2_common.c13
-rw-r--r--src/portable/synopsys/dwc2/dwc2_common.h1
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c10
4 files changed, 36 insertions, 0 deletions
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 44f7137f9..57dcb6fba 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -491,6 +491,18 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
return true;
}
+bool dcd_deinit(uint8_t rhport) {
+ dwc2_regs_t* dwc2 = DWC2_REG(rhport);
+
+ // Disable global interrupt
+ dwc2->gahbcfg &= ~GAHBCFG_GINT;
+
+ dcd_disconnect(rhport);
+
+ dwc2_core_deinit(rhport);
+ return true;
+}
+
void dcd_int_enable(uint8_t rhport) {
dwc2_dcd_int_enable(rhport);
}
diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c
index a7e6188df..ce38ed6ec 100644
--- a/src/portable/synopsys/dwc2/dwc2_common.c
+++ b/src/portable/synopsys/dwc2/dwc2_common.c
@@ -251,6 +251,19 @@ bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) {
return true;
}
+void dwc2_core_deinit(uint8_t rhport) {
+ dwc2_regs_t* dwc2 = DWC2_REG(rhport);
+
+ // Soft disconnect
+ dwc2->dctl |= DCTL_SDIS;
+
+ // Reset global registers
+ dwc2->gotgctl = 0;
+
+ // Reset core
+ reset_core(dwc2);
+}
+
// void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr) {
// (void) in_isr;
// dwc2_regs_t * const dwc2 = DWC2_REG(rhport);
diff --git a/src/portable/synopsys/dwc2/dwc2_common.h b/src/portable/synopsys/dwc2/dwc2_common.h
index 428304ba9..af532dc5e 100644
--- a/src/portable/synopsys/dwc2/dwc2_common.h
+++ b/src/portable/synopsys/dwc2/dwc2_common.h
@@ -86,6 +86,7 @@ TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) {
bool dwc2_core_is_highspeed(dwc2_regs_t* dwc2, tusb_role_t role);
bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma);
+void dwc2_core_deinit(uint8_t rhport);
void dwc2_core_handle_common_irq(uint8_t rhport, bool in_isr);
//--------------------------------------------------------------------+
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index c40703b09..fc27b3f55 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -445,6 +445,16 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
return true;
}
+bool hcd_deinit(uint8_t rhport) {
+ dwc2_regs_t* dwc2 = DWC2_REG(rhport);
+
+ // Disable global interrupt
+ dwc2->gahbcfg &= ~GAHBCFG_GINT;
+
+ dwc2_core_deinit(rhport);
+ return true;
+}
+
// Enable USB interrupt
void hcd_int_enable (uint8_t rhport) {
dwc2_int_set(rhport, TUSB_ROLE_HOST, true);