cy7c67200_300_pcd.c
来自「linux嵌入式课程实践中的一个关于声卡驱动程序 。」· C语言 代码 · 共 2,215 行 · 第 1/5 页
C
2,215 行
//pcd_dbg("pcd_irq_sofeop1 enter"); // not initialized yet, ignore interrupt if(sie_var == NULL) { return; } if( sie_var->sie_number == SIE0 ) { /* Peripheral received SOF*/ /* Check if this is a valid SOF, or a missing SOF interrupt, we check the frame number register. */ lcd_read_reg(DEV1_FRAME_REG, ®_value, cy_priv); if( 0 ) //(reg_value & 0xf000) == 0xf000 ) { pcd_dbg("pcd_irq_sofeop1: suspend"); sie_var->udc_suspended = TRUE; otg->a_bus_suspend = TRUE; usbd_device_event_irq(sie_var->bus->device, DEVICE_BUS_INACTIVE, 0); } else if( (reg_value & 0x8000) == 0 && sie_var->udc_suspended == TRUE) { pcd_dbg("pcd_irq_sofeop1: active"); sie_var->udc_suspended = FALSE; otg->a_bus_suspend = FALSE; usbd_device_event_irq(sie_var->bus->device, DEVICE_BUS_ACTIVITY, 0); } //FIXME update_otg_state(otg); } /* Acknowledge interrupt */ // Acknowledged by BIOS //lcd_write_reg(HOST1_STAT_REG, SOF_EOP_IRQ_FLG, cy_priv);#endif}/*****************************************************************/void pcd_irq_sofeop2(cy_priv_t *cy_priv){#if 0 sie_info *sie_var = (sie_info *)cy_priv->pcdi; unsigned short reg_value; otg_t * otg = cy_priv->otg; //pcd_dbg("pcd_irq_sofeop2 enter"); // not initialized yet, ignore interrupt if(sie_var == NULL) { return; } if( sie_var->sie_number == SIE1 ) { /* Peripheral received SOF*/ /* Check if this is a valid SOF, or a missing SOF interrupt, we check the frame number register. */ lcd_read_reg(DEV1_FRAME_REG, ®_value, cy_priv); if( (reg_value & 0xf000) == 0xF000) { sie_var->udc_suspended = TRUE; otg->a_bus_suspend = TRUE; usbd_device_event_irq(sie_var->bus->device, DEVICE_BUS_INACTIVE, 0); } else if( (reg_value & 0x8000) == 0 && sie_var->udc_suspended == TRUE) { sie_var->udc_suspended = FALSE; otg->a_bus_suspend = FALSE; usbd_device_event_irq(sie_var->bus->device, DEVICE_BUS_ACTIVITY, 0); } update_otg_state(otg); } /* Acknowledge interrupt */ // Acknowledged by BIOS#endif}/*****************************************************************/void pcd_irq_rst1(cy_priv_t *cy_priv){ sie_info *sie_var = (sie_info *)cy_priv->pcdi; pcd_dbg("pcd_irq_rst1 enter"); // not initialized yet, ignore interrupt if(sie_var == NULL) { return; } if( sie_var->sie_number == SIE0 ) { sie_var->usb_address = 0; usbd_device_event(sie_var->bus->device, DEVICE_RESET, 0); } /* clear the associated interrupt */ lcd_write_reg(HOST1_STAT_REG, RST_IRQ_FLG, cy_priv);}/*****************************************************************/void pcd_irq_rst2(cy_priv_t *cy_priv){ sie_info *sie_var = (sie_info *)cy_priv->pcdi; pcd_dbg("pcd_irq_rst2 enter"); // not initialized yet, ignore interrupt if(sie_var == NULL) { return; } if( sie_var->sie_number == SIE1 ) { sie_var->usb_address = 0; usbd_device_event(sie_var->bus->device, DEVICE_RESET, 0); } /* clear the associated interrupt */ lcd_write_reg(HOST2_STAT_REG, RST_IRQ_FLG, cy_priv);}/*****************************************************************//* OTG 4.4V Peripheral Mode only */void vbus_timeout(unsigned long data){ cy_priv_t *cy_priv = (cy_priv_t*)data; unsigned short value; otg_t *otg = cy_priv->otg; boolean prev_a_vbus_vld; boolean prev_a_sess_vld; lcd_read_reg(OTG_CTL_REG, &value, cy_priv); prev_a_vbus_vld = otg->a_vbus_vld; prev_a_sess_vld = otg->a_sess_vld; if (value & VBUS_VALID_FLG) { pcd_dbg("pcd_irq_vbus enter, VBUS_VLD, otg_reg:0x%04x", value); otg->a_vbus_vld = TRUE; // HPI can not distinguish between the two thresholds. otg->a_sess_vld = otg->b_sess_vld = TRUE; otg->b_sess_end = FALSE; } else { pcd_dbg("pcd_irq_vbus enter, !vbus_vld, otg_reg:0x%04x", value); otg->a_vbus_vld = FALSE; // HPI can not distinguish between the two thresholds. otg->a_sess_vld = otg->b_sess_vld = (value & OTG_DATA_STAT) ? TRUE : FALSE; otg->b_sess_end = (value & OTG_DATA_STAT) ? FALSE : TRUE; } if( prev_a_vbus_vld != otg->a_vbus_vld || prev_a_sess_vld != otg->a_sess_vld ) { update_otg_state(otg); } lcd_read_reg (SIE1_INT_EN_REG, &value, cy_priv); value |= VBUS_IRQ_EN; lcd_write_reg(SIE1_INT_EN_REG, value, cy_priv);}void pcd_irq_vbus(cy_priv_t *cy_priv){ unsigned short intStat; lcd_read_reg (SIE1_INT_EN_REG, &intStat, cy_priv); intStat &= ~VBUS_IRQ_EN; lcd_write_reg(SIE1_INT_EN_REG, intStat, cy_priv); /* Acknowledge interrupt */ lcd_write_reg(HOST1_STAT_REG, VBUS_IRQ_FLG, cy_priv); if( cy_priv->lcd_priv == NULL || cy_priv->otg == NULL ) { return; } vbus_timer.function = vbus_timeout; vbus_timer.data = (unsigned long)cy_priv; mod_timer( &vbus_timer, jiffies + 3 ); // 50 ms}/*****************************************************************/void pcd_irq_id(cy_priv_t *cy_priv){ unsigned short otg_stat_reg; otg_t *otg = cy_priv->otg; int prev_otg_id; pcd_dbg("pcd_irq_id enter"); /* Acknowledge interrupt */ // Need to do this first since there is no conditioning on the // interrupt. lcd_write_reg(HOST1_STAT_REG, ID_IRQ_FLG, cy_priv); // not initialized if( cy_priv->lcd_priv == NULL || otg == NULL ) { return; } /* OTG ID has changed - we think */ /* Read the OTG ID Status bit USB Status Register for OTG ID pin */ lcd_read_reg(OTG_CTL_REG, &otg_stat_reg, cy_priv); prev_otg_id = otg->id; if (otg_stat_reg & OTG_ID_STAT) { otg->id = B_DEV; } else { otg->id = A_DEV; } if( prev_otg_id != otg->id ) { update_otg_state(otg); }}/*****************************************************************/void pcd_irq_mb_in(cy_priv_t *cy_priv){ //pcd_dbg("pcd_irq_mb_in enter"); // currently not used}/*****************************************************************//*static void set_mbx_bit(int sie, size_t bit, int state, cy_priv_t *cy_priv){ const unsigned short mbx_addr[] = { HPI_MBX_SIE1, HPI_MBX_SIE2 }; unsigned short mbx; lcd_read_reg(mbx_addr[sie], &mbx, cy_priv); mbx = (state == 0) ? mbx & ~(1<<bit) : mbx | (1<<bit); lcd_write_reg(mbx_addr[sie], mbx, cy_priv);}*/void pcd_irq_mb_out(unsigned int message, int sie, cy_priv_t * cy_priv){ unsigned i; /* loop index */ unsigned short msg_id; /* message id field */ unsigned short value; /* variable for lcd_read_reg calls */ unsigned short ep_number; struct usb_endpoint_instance * endpoint; sie_info *sie_var = (sie_info *)cy_priv->pcdi; otg_t * otg = cy_priv->otg; static Act_Susp_States as_state = act_susp_state_1; HWTrace(0x7575); HWData(message); HWData(sie); // not initialized yet, or wrong sie, ignore interrupt if( sie_var == NULL || sie_var->sie_number != sie || sie_var->bus == NULL ) { return; } for( i=1,ep_number=0; i!=0; ep_number++, i<<=1 ) { //pcd_dbg("i:0x%04x, ep_num:%d", i, ep_number); switch( message & i ) { case SUSB_EP0_MSG: /* ignore ep0 */ default: break; case SUSB_EP1_MSG: /* endpoint done */ case SUSB_EP2_MSG: case SUSB_EP3_MSG: case SUSB_EP4_MSG: case SUSB_EP5_MSG: case SUSB_EP6_MSG: case SUSB_EP7_MSG: //pcd_dbg("EP_DONE_MSG_ID RECEIVED. Endpoint: %d", ep_number); endpoint = &sie_var->bus->endpoint_array[ep_number]; if (endpoint->endpoint_address & USB_DIR_IN) { HWTrace(0x7573); usbd_tx_complete_irq(endpoint, 0); if( endpoint->tx_urb ) { udc_start_in_irq(endpoint, endpoint->tx_urb->device); } } else { HWTrace(0x7574); ep_receive_data(endpoint, sie, cy_priv); } break; case SUSB_RST_MSG: /* reset */ pcd_dbg("SUSB_RST_MSG"); //cy_err("SUSB_RST_MSG"); usbd_device_event(sie_var->bus->device, DEVICE_RESET, 0); if( otg != NULL ) { as_state = act_susp_state_1; HWTrace(0x7008); //cy_err("RST:state 1"); otg->b_hnp_en = FALSE; otg->a_bus_suspend = FALSE; otg->b_bus_suspend = FALSE; update_otg_state(otg); } break; case SUSB_SOF_MSG: /* active */ pcd_dbg("SUSB_SOF_MSG"); //cy_err("SUSB_SOF_MSG"); usbd_device_event(sie_var->bus->device, DEVICE_BUS_ACTIVITY, 0); if( otg != NULL ) { as_state = act_susp_state_1; HWTrace(0x7007); //cy_err("SOF:state 1"); otg->a_bus_suspend = FALSE; otg->b_bus_suspend = FALSE; update_otg_state(otg); } break; case SUSB_CFG_MSG: /* configured */ pcd_dbg("SUSB_CFG_MSG"); //cy_err("SUSB_CFG_MSG"); usbd_device_event(sie_var->bus->device, DEVICE_BUS_ACTIVITY, 0); usbd_device_event(sie_var->bus->device, DEVICE_CONFIGURED, 0); if( otg != NULL ) { as_state = act_susp_state_1; HWTrace(0x7006); //cy_err("CFG:state 1"); otg->a_bus_suspend = FALSE; otg->b_bus_suspend = FALSE; update_otg_state(otg); } break; case SUSB_SUS_MSG: /* suspend */ pcd_dbg("SUSB_SUS_MSG"); //cy_err("SUSB_SUS_MSG"); usbd_device_event(sie_var->bus->device, DEVICE_BUS_INACTIVE, 0);#if 0 if( otg != NULL ) { HWTrace(0x7002); lcd_read_reg(USB1_CTL_REG, &value, cy_priv); if (value & (A_DP_STAT | A_DM_STAT)) { if( as_state == act_susp_state_1 ) { as_state = act_susp_state_2; HWTrace(0x7003); //cy_err("SUS:state 2"); } else if( as_state == act_susp_state_2 ) { as_state = act_susp_state_3; HWTrace(0x7004); //cy_err("SUS:state 3"); otg->a_bus_suspend = TRUE; otg->b_bus_suspend = TRUE; otg->b_bus_req = TRUE; update_otg_state(otg); } } else if( as_state != act_susp_state_1 ) { as_state = act_susp_state_1; HWTrace(0x7005); //cy_err("SUS:state 1"); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?