cy7c67200_300_hcd.c
来自「linux嵌入式课程实践中的一个关于声卡驱动程序 。」· C语言 代码 · 共 2,356 行 · 第 1/4 页
C
2,356 行
if( hci == 0 ) { return; } sh_schedule_trans (cy_priv, SIE1);}/******************************************************************/void hcd_irq_mb_in(cy_priv_t *cy_priv){ // currently not used}/******************************************************************/void hcd_irq_mb_out(unsigned int message, int sie, cy_priv_t *cy_priv){ hci_t *hci = cy_priv->hci; sie_t * sie_struct = &hci->sie[sie]; if( hci == NULL ) { return; } if (message & HUSB_TDListDone) { // cy_dbg(": TD_LIST_DONE_MSG_ID RECEIVED."); /* HOST: Lyberty has finished transfer of the TD */ /* Check the status of the TDs */ sh_td_list_check_stat (cy_priv, sie); sie_struct->td_active = FALSE; /* shedule the next set of TDs */ sh_schedule_trans (cy_priv, sie); }}/******************************************************************/void hcd_irq_resume1(cy_priv_t *cy_priv){ unsigned short usb_stats; hci_t *hci = cy_priv->hci; unsigned short usb_stat_sie = 0; otg_t *otg = cy_priv->otg; if( hci == 0 ) { return; } HWTrace (0x2090); /* Read the USB Interrupt Status Register for SIE 1*/ lcd_read_reg(SIE1_INT_STATUS_REG, &usb_stats, cy_priv); cy_dbg("SIE1_INT_STATUS_REG = 0x%X", usb_stats); if (otg != NULL) { /* Are we in the USB OTG States to detect HNP Accept? */ if (usb_stats & A_CHG_IRQ_FLG) { HWTrace (0x2091); if( reset_in_progress[PORT0] != 0 ) { usb_stat_sie = A_CHG_IRQ_FLG | A_SE0_STAT | A_WAKE_IRQ_FLG | B_CHG_IRQ_FLG | B_SE0_STAT | B_WAKE_IRQ_FLG; lcd_write_reg(HOST1_STAT_REG, usb_stat_sie, cy_priv); return; } /* determine if the HNP has been accepted by the device */ if (usb_stats & A_SE0_STAT) { HWTrace (0x209A); otg->b_conn = FALSE; otg->a_conn = FALSE; //cy_err("ACON4:0"); usb_stat_sie |= A_SE0_STAT; } else { if(otg->id == A_DEV) { otg->b_conn = TRUE; } else { otg->a_conn = TRUE; //cy_err("ACON5:1"); } } if (!otg->a_vbus_vld && otg->state == a_idle) { HWTrace (0x2092); /* OTG SRP Functionality: * SRP request has been detected. */ otg->b_conn = FALSE; otg->a_srp_det = TRUE; otg->a_bus_req = TRUE; } else { otg->a_srp_det = FALSE; } usb_stat_sie |= A_CHG_IRQ_FLG; } /* Detect Remote Wakeup */ if (usb_stats & A_WAKE_IRQ_FLG) { HWTrace (0x2096); /* Detected Remote Wakeup on port A */ /* Set the HCD to be active and start SOF */ otg->b_bus_resume = TRUE; usb_stat_sie |= A_WAKE_IRQ_FLG; } update_otg_state(otg); /* Clear the B port interrupts just in case */ usb_stat_sie |= B_SE0_STAT | B_CHG_IRQ_FLG | B_WAKE_IRQ_FLG; } else { if (usb_stats & A_CHG_IRQ_FLG) { if (reset_in_progress[PORT0] == 0) { HWTrace (0x20C0); /* USB Insert/Remove Interrupt on port B*/ /* qualify with the USB Reset */ /* Determine if a device has connected or disconnected by * reading the USB Reset bit of the USB status register */ if (hci->valid_host_port[PORT0] != 1) { cy_err("invalid host port 0"); } else { if (usb_stats & A_SE0_STAT) { cy_err("Device removed on PORT0"); HWTrace (0x20C1); /* Device has been disconnected */ handle_device_removal(cy_priv, PORT0); } else { cy_err("Device inserted on PORT0"); HWTrace (0x20C2); /* Device has been connected */ handle_device_insertion(cy_priv, PORT0); } } } usb_stat_sie |= A_CHG_IRQ_FLG; } if (usb_stats & B_CHG_IRQ_FLG) { if (reset_in_progress[PORT1] == 0) { HWTrace (0x2093); /* USB Insert/Remove Interrupt on port B*/ /* qualify with the USB Reset */ /* Determine if a device has connected or disconnected by * reading the USB Reset bit of the USB status register */ if (hci->valid_host_port[PORT1] != 1) { cy_err("invalid host port 1"); } else { if (usb_stats & B_SE0_STAT) { cy_err("Device removed on PORT1"); HWTrace (0x2094); /* Device has been disconnected */ handle_device_removal(cy_priv, PORT1); } else { cy_err("Device inserted on PORT1"); HWTrace (0x2095); /* Device has been connected */ handle_device_insertion(cy_priv, PORT1); } } } usb_stat_sie |= B_CHG_IRQ_FLG; } if (usb_stats & A_WAKE_IRQ_FLG) { HWTrace (0x2010); /* Detected Remote Wakeup on port A */ handle_remote_wakeup(cy_priv, PORT0); usb_stat_sie |= A_WAKE_IRQ_FLG; } if (usb_stats & B_WAKE_IRQ_FLG) { HWTrace (0x2011); /* Detected Remote Wakeup on port B */ handle_remote_wakeup(cy_priv, PORT1); usb_stat_sie |= B_WAKE_IRQ_FLG; } } /* Detect Remote Wakeup */ HWTrace (0x2099); /* clear the associated interrupt(s) */ lcd_write_reg(HOST1_STAT_REG, usb_stat_sie, cy_priv); }/******************************************************************/void hcd_irq_resume2(cy_priv_t *cy_priv){ unsigned short usb_stats; hci_t *hci = cy_priv->hci; unsigned short usb_stat_sie = 0; otg_t *otg = cy_priv->otg; if( hci == 0 ) { return; } HWTrace (0x2080); /* Read the USB Interrupt Status Register for SIE 1*/ lcd_read_reg(HOST2_STAT_REG, &usb_stats, cy_priv); cy_dbg("HOST2_STAT_REG = 0x%X", usb_stats); if (usb_stats & A_CHG_IRQ_FLG) { if (reset_in_progress[PORT2] == 0) { HWTrace (0x2081); /* USB Insert/Remove Interrupt on port A*/ /* Determine if a device has connected or disconnected by * reading the USB Reset bit of the USB status register */ if (hci->valid_host_port[PORT2] != 1) { cy_err("invalid host port 2"); } else { if (usb_stats & A_SE0_STAT) { cy_err("Device removed on PORT2"); HWTrace (0x2082); /* device has been removed */ handle_device_removal(cy_priv, PORT2); } else { cy_err("Device inserted on PORT2"); HWTrace (0x2083); /* device has been inserted */ handle_device_insertion(cy_priv, PORT2); } } } usb_stat_sie |= A_CHG_IRQ_FLG; } if (usb_stats & B_CHG_IRQ_FLG) { if (reset_in_progress[PORT3] == 0) { /* USB Insert/Remove Interrupt on port B*/ /* qualify with the USB Reset */ /* Determine if a device has connected or disconnected by * reading the USB Reset bit of the USB status register */ HWTrace (0x2084); if (hci->valid_host_port[PORT3] != 1) { cy_err("invalid host port 3"); } else { if (usb_stats & B_SE0_STAT) { cy_err("Device removed on PORT3"); HWTrace (0x2085); /* device has been removed */ handle_device_removal(cy_priv, PORT3); } else { cy_err("Device inserted on PORT3"); HWTrace (0x2086); /* Device has been connected */ handle_device_insertion(cy_priv, PORT3); } } } usb_stat_sie |= B_CHG_IRQ_FLG; } /* Detect Remote Wakeup */ if (usb_stats & A_WAKE_IRQ_FLG) { HWTrace (0x2087); /* Detected Remote Wakeup on port A */ handle_remote_wakeup(cy_priv, PORT2); usb_stat_sie |= A_WAKE_IRQ_FLG; } if (usb_stats & B_WAKE_IRQ_FLG) { HWTrace (0x2088); /* Detected Remote Wakeup on port B */ handle_remote_wakeup(cy_priv, PORT3); usb_stat_sie |= B_WAKE_IRQ_FLG; } /* clear the associated interrupt */ lcd_write_reg(HOST2_STAT_REG, usb_stat_sie, cy_priv); } /*****************************************************************/void hcd_irq_enable_host_periph_ints(cy_priv_t *cy_priv){ hci_t *hci = cy_priv->hci; if( hci == 0 ) { return; } /* enable the interrupt: * At this point, the host may become a peripheral or vise versa * It is necessary to setup Interrupt Enable based on the "hostship" * of the current SIE. */ cy_dbg("hcd_irq_enable_host_periph_ints enter: cy_priv = %p", cy_priv); if (is_host_enable(hci, PORT0)) { HWTrace (0x20A0); lcd_write_reg(SIE1_INT_EN_REG, DFLT_HOST1_IRQ_ENBL, cy_priv); } else { lcd_write_reg(SIE1_INT_EN_REG, DFLT_PERIPHERAL1_IRQ_ENBL, cy_priv); } if (is_host_enable(hci, PORT2)) { HWTrace (0x20B0); lcd_write_reg(SIE2_INT_EN_REG, DFLT_HOST2_IRQ_ENBL, cy_priv); } else { lcd_write_reg(SIE2_INT_EN_REG, DFLT_PERIPHERAL2_IRQ_ENBL, cy_priv); }}/****************************************************************** * THE FOLLOWING FUNCTIONS ARE BOARD SPECIFIC * * MODIFIED FOR YOUR OWN BOARD!! * *******************************************************************/ /***************************************************************** * * Function Name: cy67x00_get_hw_config * * This function is board specific. It reads the DIP switch from * Lyberty to determine the HW operating mode * * Input: n/a * * Return: * DIP switch value * *****************************************************************/static int cy67x00_get_hw_config (){ unsigned short val;// val = inw(SBC_DIP_REG); return val;}/***************************************************************** * * Function Name: cy67x00_get_current_frame_number * * This function is board specific. It reads the frame number * from Lyberty for the specified sie. * * Input: * cy_priv cy67x00 private data * sie sie number * * Return: * Current Frame Number * *****************************************************************/int cy67x00_get_current_frame_number (cy_priv_t * cy_priv, int port_num){ unsigned short temp_val = 0; if ((port_num == PORT0) || (port_num == PORT1)) { lcd_read_reg(SIE1_USB_FRAME_NO, &temp_val, cy_priv); } else { lcd_read_reg(SIE2_USB_FRAME_NO, &temp_val, cy_priv); } temp_val &= HOST_FRAME_NUM; if (temp_val == 0) temp_val = HOST_FRAME_NUM; else temp_val -= 1; HWTrace(0x1111); HWData(temp_val); return temp_val;}/***************************************************************** * * Function Name: cy67x00_get_next_frame_number * * This function is board specific. It reads the frame number * from Lyberty for the specified sie. * * Input: * cy_priv cy67x00 private data * sie sie number * * Return: * Next Frame Number * *****************************************************************/int cy67x00_get_next_frame_number (cy_priv_t * cy_priv, int port_num){ unsigned short temp_val = 0; if ((port_num == PORT0) || (port_num == PORT1)) { lcd_read_reg(SIE1_USB_FRAME_NO, &temp_val, cy_priv); } else { lcd_read_reg(SIE2_USB_FRAME_NO, &temp_val, cy_priv); } temp_val &= HOST_FRAME_NUM; HWTrace(0x1112); HWData(temp_val); return temp_val;}/***************************************************************** * * Function Name: init_irq * * This function is board specific. It sets up the interrupt to * be an edge trigger and trigger on the rising edge * * Input: none * * Return value : none * *****************************************************************/void init_irq(void){ GPDR0 &= ~GPIO_bit(7); set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(IRQ_GPIO_EZHOST), GPIO_RISING_EDGE); }/******************************************************************/static int cy67x00_hw_reset (){ int val; #if 0 /* read the expansion card present reg */ val = inw(SBC_EXP_PORT_PRESENT_REG); if (val == CP_PRESENT) { /* Enable Lyberty. By default, Lyberty will hold in reset mode. This will take Lyberty out of reset */ writew (0x1, SBC_EXP_PORT_RESET); /* Set the reset to settle. This requires about 500 ms */ mdelay(500); return SUCCESS; } else { cy_err("no Lyberty card present"); return ERROR; }#endif return SUCCESS;}module_init (hci_hcd_init);module_exit (hci_hcd_cleanup);MODULE_AUTHOR ("<usbapps@cypress.com>");MODULE_DESCRIPTION ("CY7C67200/300 USB Host/Peripheral Embedded Controller Driver");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?