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, &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, &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 + -
显示快捷键?