1 /*
2  * Copyright (c) 2022-2025 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #include "usbh_core.h"
8 #include "hpm_common.h"
9 #include "hpm_soc.h"
10 #include "hpm_usb_drv.h"
11 #include "usb_glue_hpm.h"
12 
13 #if !defined(CONFIG_USB_EHCI_HPMICRO) || !CONFIG_USB_EHCI_HPMICRO
14 #error "hpm ehci must set CONFIG_USB_EHCI_HPMICRO=1"
15 #endif
16 
17 #if !defined(CONFIG_USB_EHCI_HCCR_OFFSET) || CONFIG_USB_EHCI_HCCR_OFFSET != 0x100
18 #error "hpm ehci must config CONFIG_USB_EHCI_HCCR_OFFSET to 0x100"
19 #endif
20 
21 extern void (*g_usb_hpm_irq[2])(uint8_t busid);
22 extern uint8_t g_usb_hpm_busid[2];
23 
usb_host_mode_init(USB_Type * ptr)24 static void usb_host_mode_init(USB_Type *ptr)
25 {
26     /* Set mode to host, must be set immediately after reset */
27     ptr->USBMODE &= ~USB_USBMODE_CM_MASK;
28     ptr->USBMODE |= USB_USBMODE_CM_SET(3);
29 
30     /* Set the endian */
31     ptr->USBMODE &= ~USB_USBMODE_ES_MASK;
32 
33     /* Set parallel interface signal */
34     ptr->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
35 
36     /* Set parallel transceiver width */
37     ptr->PORTSC1 &= ~USB_PORTSC1_PTW_MASK;
38 
39 #ifdef CONFIG_USB_HOST_FORCE_FULL_SPEED
40     /* Set usb forced to full speed mode */
41     ptr->PORTSC1 |= USB_PORTSC1_PFSC_MASK;
42 #endif
43 
44     /* Not use interrupt threshold. */
45     ptr->USBCMD &= ~USB_USBCMD_ITC_MASK;
46 }
47 
usb_hc_low_level_init(struct usbh_bus * bus)48 void usb_hc_low_level_init(struct usbh_bus *bus)
49 {
50     usb_phy_init((USB_Type *)(bus->hcd.reg_base), true);
51 }
52 
usb_hc_low_level2_init(struct usbh_bus * bus)53 void usb_hc_low_level2_init(struct usbh_bus *bus)
54 {
55     usb_host_mode_init((USB_Type *)(bus->hcd.reg_base));
56 
57     if (bus->hcd.reg_base == HPM_USB0_BASE) {
58         g_usb_hpm_busid[0] = bus->hcd.hcd_id;
59         g_usb_hpm_irq[0] = USBH_IRQHandler;
60 
61         hpm_usb_isr_enable(HPM_USB0_BASE);
62     } else {
63 #ifdef HPM_USB1_BASE
64         g_usb_hpm_busid[1] = bus->hcd.hcd_id;
65         g_usb_hpm_irq[1] = USBH_IRQHandler;
66 
67         hpm_usb_isr_enable(HPM_USB1_BASE);
68 #endif
69     }
70 }
71 
usb_hc_low_level_deinit(struct usbh_bus * bus)72 void usb_hc_low_level_deinit(struct usbh_bus *bus)
73 {
74     usb_phy_deinit((USB_Type *)(bus->hcd.reg_base));
75 
76     if (bus->hcd.reg_base == HPM_USB0_BASE) {
77         hpm_usb_isr_disable(HPM_USB0_BASE);
78 
79         g_usb_hpm_busid[0] = 0;
80         g_usb_hpm_irq[0] = NULL;
81     } else {
82 #ifdef HPM_USB1_BASE
83         hpm_usb_isr_disable(HPM_USB1_BASE);
84 
85         g_usb_hpm_busid[1] = 0;
86         g_usb_hpm_irq[1] = NULL;
87 #endif
88     }
89 }
90 
usbh_get_port_speed(struct usbh_bus * bus,const uint8_t port)91 uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
92 {
93     (void)port;
94     uint8_t speed;
95 
96     speed = usb_get_port_speed((USB_Type *)(bus->hcd.reg_base));
97 
98     if (speed == 0x00) {
99         return USB_SPEED_FULL;
100     }
101     if (speed == 0x01) {
102         return USB_SPEED_LOW;
103     }
104     if (speed == 0x02) {
105         return USB_SPEED_HIGH;
106     }
107 
108     return 0;
109 }