1 /*
2  * Copyright (c) 2025, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbd_core.h"
7 #include "usbh_core.h"
8 #include "usb_musb_reg.h"
9 
10 #undef USB_POWER_SOFTCONN
11 #undef USB_DEVCTL_FSDEV
12 #undef USB_DEVCTL_LSDEV
13 #undef USB_DEVCTL_SESSION
14 #undef USB_POWER_HSENAB
15 #undef USB_POWER_HSMODE
16 #undef USB_POWER_RESET
17 #undef USB_POWER_RESUME
18 
19 #ifndef CONFIG_USB_MUSB_SIFLI
20 #error must define CONFIG_USB_MUSB_SIFLI when use sunxi chips
21 #endif
22 
23 #include "bf0_hal.h"
24 
usbd_get_musb_fifo_cfg(struct musb_fifo_cfg ** cfg)25 uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg)
26 {
27     *cfg = NULL; // No FIFO configuration for this implementation, readonly
28     return 0;
29 }
30 
usbh_get_musb_fifo_cfg(struct musb_fifo_cfg ** cfg)31 uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg)
32 {
33     *cfg = NULL; // No FIFO configuration for this implementation, readonly
34     return 0;
35 }
36 
usb_get_musb_ram_size(void)37 uint32_t usb_get_musb_ram_size(void)
38 {
39     return 0xFFFF; // No specific RAM size for this implementation
40 }
41 
usbd_musb_delay_ms(uint8_t ms)42 void usbd_musb_delay_ms(uint8_t ms)
43 {
44     /* implement later */
45 }
46 
47 #ifdef PKG_CHERRYUSB_DEVICE
usb_dc_low_level_init(uint8_t busid)48 void usb_dc_low_level_init(uint8_t busid)
49 {
50     HAL_RCC_EnableModule(RCC_MOD_USBC);
51 
52 #ifdef SOC_SF32LB58X
53     //hwp_usbc->utmicfg12 = hwp_usbc->utmicfg12 | 0x3; //set xo_clk_sel
54     hwp_usbc->ldo25 = hwp_usbc->ldo25 | 0xa; //set psw_en and ldo25_en
55     HAL_Delay(1);
56     hwp_usbc->swcntl3 = 0x1;                    //set utmi_en for USB2.0
57     hwp_usbc->usbcfg = hwp_usbc->usbcfg | 0x40; //enable usb PLL.
58 #elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
59     hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN;
60 #elif defined(SOC_SF32LB55X)
61     hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN;
62 #endif
63 #ifndef SOC_SF32LB55X
64     hwp_usbc->usbcfg |= (USB_USBCFG_AVALID | USB_USBCFG_AVALID_DR);
65     hwp_usbc->dpbrxdisl = 0xFE;
66     hwp_usbc->dpbtxdisl = 0xFE;
67 #endif
68     NVIC_EnableIRQ(USBC_IRQn);
69     __HAL_SYSCFG_Enable_USB();
70 }
71 
usb_dc_low_level_deinit(uint8_t busid)72 void usb_dc_low_level_deinit(uint8_t busid)
73 {
74     NVIC_DisableIRQ(USBC_IRQn);
75 #ifdef SOC_SF32LB58X
76     hwp_usbc->usbcfg &= ~0x40; // Disable usb PLL.
77     hwp_usbc->swcntl3 = 0x0;
78     hwp_usbc->ldo25 &= ~0xa; // Disable psw_en and ldo25_en
79 #elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
80     hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN);
81 #elif defined(SOC_SF32LB55X)
82     hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN);
83 #endif
84     /* reset USB to make DP change to PULLDOWN state */
85     hwp_hpsys_rcc->RSTR2 |= HPSYS_RCC_RSTR2_USBC;
86     HAL_Delay_us(100);
87     hwp_hpsys_rcc->RSTR2 &= ~HPSYS_RCC_RSTR2_USBC;
88     HAL_RCC_DisableModule(RCC_MOD_USBC);
89 }
90 #endif
91 
92 #ifdef PKG_CHERRYUSB_HOST
usb_hc_low_level_init(struct usbh_bus * bus)93 void usb_hc_low_level_init(struct usbh_bus *bus)
94 {
95     HAL_RCC_EnableModule(RCC_MOD_USBC);
96 
97 #ifdef SOC_SF32LB58X
98     //hwp_usbc->utmicfg12 = hwp_usbc->utmicfg12 | 0x3; //set xo_clk_sel
99     hwp_usbc->ldo25 = hwp_usbc->ldo25 | 0xa; //set psw_en and ldo25_en
100     HAL_Delay(1);
101     hwp_usbc->swcntl3 = 0x1;                    //set utmi_en for USB2.0
102     hwp_usbc->usbcfg = hwp_usbc->usbcfg | 0x40; //enable usb PLL.
103 #elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
104     hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN;
105 #elif defined(SOC_SF32LB55X)
106     hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN;
107 #endif
108 #ifndef SOC_SF32LB55X
109     hwp_usbc->usbcfg |= (USB_USBCFG_AVALID | USB_USBCFG_AVALID_DR);
110     hwp_usbc->dpbrxdisl = 0xFE;
111     hwp_usbc->dpbtxdisl = 0xFE;
112 #endif
113     __HAL_SYSCFG_Enable_USB();
114     hwp_usbc->usbcfg &= 0xEF;
115     hwp_usbc->dbgl = 0x80;
116 
117     NVIC_EnableIRQ(USBC_IRQn);
118 }
119 
usb_hc_low_level_deinit(struct usbh_bus * bus)120 void usb_hc_low_level_deinit(struct usbh_bus *bus)
121 {
122     NVIC_DisableIRQ(USBC_IRQn);
123 #ifdef SOC_SF32LB58X
124     hwp_usbc->usbcfg &= ~0x40; // Disable usb PLL.
125     hwp_usbc->swcntl3 = 0x0;
126     hwp_usbc->ldo25 &= ~0xa; // Disable psw_en and ldo25_en
127 #elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
128     hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN);
129 #elif defined(SOC_SF32LB55X)
130     hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN);
131 #endif
132     /* reset USB to make DP change to PULLDOWN state */
133     hwp_hpsys_rcc->RSTR2 |= HPSYS_RCC_RSTR2_USBC;
134     HAL_Delay_us(100);
135     hwp_hpsys_rcc->RSTR2 &= ~HPSYS_RCC_RSTR2_USBC;
136     HAL_RCC_DisableModule(RCC_MOD_USBC);
137 }
138 
musb_reset_prev(void)139 void musb_reset_prev(void)
140 {
141 #if defined(SF32LB58X)
142     hwp_usbc->rsvd0 = 0xc; //58
143 #endif
144 }
145 
musb_reset_post(void)146 void musb_reset_post(void)
147 {
148 #if defined(SF32LB58X)
149     hwp_usbc->rsvd0 = 0x0; //58
150 #endif
151 }
152 #endif
153 
USBC_IRQHandler(void)154 void USBC_IRQHandler(void)
155 {
156 #ifdef PKG_CHERRYUSB_DEVICE
157     USBD_IRQHandler(0);
158 #endif
159 #ifdef PKG_CHERRYUSB_HOST
160     USBH_IRQHandler(0);
161 #endif
162 }