⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cy7c67200_300_otg.c

📁 linux嵌入式课程实践中的一个关于声卡驱动程序 。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* File: otg.c *//* This file implements the OTG state diagram. *//* Included files. */#include <linux/kernel.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/timer.h>#include "cy7c67200_300_otg.h"#include "cy7c67200_300_lcd.h"#include "usbd/bi/cy7c67200_300_pcd.h"#include "cy7c67200_300_debug.h"#include "67300.h" /* Data definitions */#define START_SOF          10#define STOP_SOF          11#define RAISE_VBUS          20#define DROP_VBUS          21/* global */char *state_names[] ={    "a_idle",    "a_wait_vrise",    "a_wait_bcon",    "a_host",    "a_suspend",    "a_peripheral",    "a_wait_vfall",    "a_vbus_err",    "b_idle",    "b_srp_init",    "b_peripheral",    "b_wait_acon",    "b_host"};extern void detected_hnp_accepted(void);extern void hcd_switch_role(int new_role, cy_priv_t * cy_priv);extern void handle_device_insertion (cy_priv_t * cy_priv, int port_num);extern void handle_device_removal (cy_priv_t * cy_priv, int port_num);extern void handle_remote_wakeup (cy_priv_t * cy_priv, int port_num);static cy_priv_t * otg_cy_priv = NULL;/* forware declaration */static void a_host_state(otg_t * otg);static void a_idle_state(otg_t * otg);static void a_peripheral_state(otg_t * otg);static void a_suspend_state(otg_t * otg);static void a_vbus_err_state(otg_t * otg);static void a_wait_bcon_state(otg_t * otg);static void a_wait_vfall_state(otg_t * otg);static void a_wait_vrise_state(otg_t * otg);static void b_host_state(otg_t * otg);static void b_idle_state(otg_t * otg);static void b_peripheral_state(otg_t * otg);static void b_srp_init_state(otg_t * otg);static void b_wait_acon_state(otg_t * otg);/* Functionality. *//* *  FUNCTION: Timer utilities * *  DESCRIPTION: *    These functions are used to support timeout functionality for *    the otg state diagram. */struct timer_list to_timer;// FIXME check these times/* The following enumerations are in jiffies. */typedef enum timeout_times{    Ta_wait_vrise =  10,    // 100ms    Ta_wait_bcon  =  -1,    // infinite    Ta_aidl_bdis  =  35,    // 350ms    Tb_ase0_brst  =  31,  //  We need 3.125 ms} OTG_Timeouts;void otg_timeout(unsigned long data){    cy_err("timeout");    *((boolean*)data) = TRUE;    update_otg_state( (otg_t*)otg_cy_priv->otg );}static void otg_start_timer(boolean *state, OTG_Timeouts time){    if( time < 0 )    {        return;    }    if( timer_pending(&to_timer) )    {        cy_err("ERROR: timer in use - restarting");    }    *state = FALSE;    to_timer.data = (unsigned long)state;    mod_timer( &to_timer, jiffies + time );}static void otg_cancel_timer(boolean *state){    *state = FALSE;    del_timer(&to_timer);}/* * */void switch_role(int new_role){    const char * const name[] =     {        "HOST_ROLE",        "PERIPHERAL_ROLE",        "HOST_INACTIVE_ROLE"    };    HWTrace (0x3100);    //cy_err("Switch role to %s", name[new_role]);    switch (new_role)    {    case PERIPHERAL_ROLE:        HWTrace (0x3101);        hcd_switch_role(new_role, otg_cy_priv);        pcd_switch_role(new_role, otg_cy_priv);                break;    case HOST_ROLE:        HWTrace (0x3102);    case HOST_INACTIVE_ROLE:        HWTrace (0x3103);        pcd_switch_role(new_role, otg_cy_priv);                hcd_switch_role(new_role, otg_cy_priv);        break;#if 0    case HOST_INACTIVE_ROLE:        {            unsigned short intStat;                        HWTrace (0x3103);            lcd_write_reg(0xc08a, 0x380, otg_cy_priv);                        // Setup interrupt steering            intStat = 0;            intStat |=  SOFEOP1_TO_CPU_EN;            intStat |=  SOFEOP2_TO_CPU_EN;            intStat |=  VBUS_TO_HPI_EN;            intStat |=  ID_TO_HPI_EN;            lcd_write_reg(HPI_SIE_IE, intStat, otg_cy_priv);                        // Turn on VBUS and ID interrupts            lcd_read_reg (SIE1_INT_EN_REG, &intStat, otg_cy_priv);            intStat |= VBUS_IRQ_EN;            intStat |= ID_IRQ_EN;            intStat |= 0xa00; // MSE & SOF, IROS pg 103            lcd_write_reg(SIE1_INT_EN_REG, intStat, otg_cy_priv);        }        break;#endif    }    HWTrace (0x3104);    otg_cy_priv->system_mode[SIE0] = new_role; }void otg_print_state(void){	unsigned short intStat;    if (otg_cy_priv != NULL && otg_cy_priv->otg != NULL)     {        otg_t * otg = otg_cy_priv->otg;        printk("\n");        printk("\n");        printk("\n");        printk("state              = %s\n",                 state_names[otg->state]);        printk("id                 = %s\n",                 otg->id == A_DEV ? "A_DEV" : "B_DEV");        printk("a_srp_det          = %s\n",                 otg->a_srp_det == 0 ? "false" : "true");        printk("a_set_b_hnp_en     = %s\n",                 otg->a_set_b_hnp_en == 0 ? "false" : "true");        printk("b_conn             = %s\n",                 otg->b_conn == 0 ? "false" : "true");        printk("a_bus_drop         = %s\n",                 otg->a_bus_drop == 0 ? "false" : "true");        printk("a_bus_req          = %s\n",                 otg->a_bus_req == 0 ? "false" : "true");        printk("a_suspend_req      = %s\n",                 otg->a_suspend_req == 0 ? "false" : "true");        printk("b_bus_suspend      = %s\n",                 otg->b_bus_suspend == 0 ? "false" : "true");        printk("b_bus_resume       = %s\n",                 otg->b_bus_resume == 0 ? "false" : "true");        printk("a_sess_vld         = %s\n",                 otg->a_sess_vld == 0 ? "false" : "true");        printk("a_vbus_vld         = %s\n",                 otg->a_vbus_vld == 0 ? "false" : "true");        printk("a_wait_vrise_tmout = %s\n",                 otg->a_wait_vrise_tmout == 0 ? "false" : "true");        printk("a_wait_bcon_tmout  = %s\n",                 otg->a_wait_bcon_tmout == 0 ? "false" : "true");        printk("a_aidl_bdis_tmout  = %s\n",                 otg->a_aidl_bdis_tmout == 0 ? "false" : "true");        printk("b_bus_req          = %s\n",                 otg->b_bus_req == 0 ? "false" : "true");        printk("b_sess_end         = %s\n",                 otg->b_sess_end == 0 ? "false" : "true");        printk("b_se0_srp          = %s\n",                 otg->b_se0_srp == 0 ? "false" : "true");        printk("b_srp_done         = %s\n",                 otg->b_srp_done == 0 ? "false" : "true");        printk("b_sess_vld         = %s\n",                 otg->b_sess_vld == 0 ? "false" : "true");        printk("a_bus_resume       = %s\n",                 otg->a_bus_resume == 0 ? "false" : "true");        printk("b_hnp_en           = %s\n",                 otg->b_hnp_en == 0 ? "false" : "true");        printk("a_bus_suspend      = %s\n",                 otg->a_bus_suspend == 0 ? "false" : "true");        printk("b_se0_brst_tmout   = %s\n",                 otg->b_se0_brst_tmout == 0 ? "false" : "true");        printk("a_conn             = %s\n",                 otg->a_conn == 0 ? "false" : "true");        printk("b_ase0_brst_tmout  = %s\n",                 otg->b_ase0_brst_tmout == 0 ? "false" : "true");        printk("b_wait_acon_tmout  = %s\n",                 otg->b_wait_acon_tmout == 0 ? "false" : "true");        lcd_read_reg (SIE1_INT_EN_REG, &intStat, otg_cy_priv);        printk("SIE1_INT_EN_REG = 0x%X\n", intStat);        printk("\n");        printk("\n");    }}int otg_state(int * state){    if (otg_cy_priv != NULL && otg_cy_priv->otg != NULL)     {        *state = ((otg_t*)otg_cy_priv->otg)->state;        return 0;    }    return -1;}int otg_id(int * id){    int ret = -1;    otg_t * otg;    if (otg_cy_priv != NULL) {        if (otg_cy_priv->otg != NULL) {            otg = otg_cy_priv->otg;            *id = otg->id;            ret = 0;        }    }    return ret;}int otg_start_session(void){    int ret = -1;    otg_t * otg;    if (otg_cy_priv != NULL) {        if (otg_cy_priv->otg != NULL) {            otg = otg_cy_priv->otg;            otg->a_bus_drop = FALSE;            otg->a_bus_req    = TRUE;            /*            cy_err("otg_start_session: state = %s",                     state_names[otg->state]);                    */            update_otg_state(otg);            ret = 0;        }    }    return ret;}int otg_end_session(void){    int ret = -1;    otg_t * otg;    if (otg_cy_priv != NULL) {        if (otg_cy_priv->otg != NULL) {            otg = otg_cy_priv->otg;            otg->a_bus_drop = TRUE;            otg->a_bus_req  = FALSE;            otg->a_srp_det = FALSE;            /*            cy_err("otg_end_session: state = %s",                     state_names[otg->state]);                    */            update_otg_state(otg);            ret = 0;        }    }    return ret;}int otg_offer_hnp(void){    int ret = -1;    otg_t * otg;    if (otg_cy_priv != NULL)     {        if (otg_cy_priv->otg != NULL)         {            otg = otg_cy_priv->otg;            if( otg->state == a_host )            {                otg->a_set_b_hnp_en = TRUE;                otg->a_bus_req = FALSE;                otg->b_bus_resume = FALSE;                update_otg_state(otg);                ret = 0;            }        }    }    return ret;}int otg_end_hnp(void){    int ret = -1;    otg_t * otg;    if (otg_cy_priv != NULL)     {        if (otg_cy_priv->otg != NULL)         {            otg = otg_cy_priv->otg;            if(otg->state == b_host)            {                otg->b_bus_req = FALSE;                update_otg_state(otg);                ret = 0;            }        }    }    return ret;}void otg_init(cy_priv_t * cy_priv){    unsigned short otg_ctl = 0;    otg_t * otg;        /* store the cy_priv to our global cy_priv structure */    otg_cy_priv = cy_priv;    /* alloc and initialize OTG data structure */    otg = (otg_t *) kmalloc (sizeof(otg_t), GFP_KERNEL);    memset(otg, 0, sizeof(otg_t));    /* Initialize timeout timer */    init_timer(&to_timer);    to_timer.function = otg_timeout;    /* Disable VBUS */    lcd_command(LCD_DISABLE_OTG_VBUS, 0, PORT0, NULL, 0, otg_cy_priv);    /* read the OTG ID pin */    lcd_read_reg(OTG_CTL_REG, &otg_ctl, cy_priv);     if (otg_ctl & OTG_ID_STAT)    {        otg->state = b_idle;        otg->id = B_DEV;        otg->b_sess_end = TRUE;    }    else    {        otg->state = a_idle;        otg->id = A_DEV;    }    cy_priv->otg = otg;}void a_idle_state(otg_t * otg){    HWTrace (0x3020);    if (otg->state != a_idle)     {        HWTrace (0x3021);        otg->a_bus_drop = FALSE;        otg->state = a_idle;    }        switch (otg->id)    {    case A_DEV:        if ((otg->a_bus_drop == 0) && (otg->a_bus_req || otg->a_srp_det))         {            HWTrace (0x3022);            /*            cy_err("a_bus_drop:%d, a_bus_req:%d, a_srp_det:%d",                    otg->a_bus_drop, otg->a_bus_req, otg->a_srp_det);                     */            switch_role(HOST_ROLE);            a_wait_vrise_state(otg);        }        HWTrace (0x3023);        break;    case B_DEV:        HWTrace (0x3024);        b_idle_state(otg);        break;    }}void a_wait_vrise_state(otg_t * otg){    unsigned short otg_ctl;    HWTrace (0x3030);    if (otg->state != a_wait_vrise)     {        otg->state = a_wait_vrise;        /* start a_wait_vrise timer */        otg_start_timer( &otg->a_wait_vrise_tmout, Ta_wait_vrise );        /* Notify the app if SRP detected */        if (otg->a_srp_det)        {            HWTrace (0x3031);            otg->a_srp_det = FALSE;        }            HWTrace (0x3032);        /* driver VBUS */        lcd_command(LCD_ENABLE_OTG_VBUS, 0, PORT0, NULL, 0, otg_cy_priv);    }        if( otg->a_wait_vrise_tmout )    {        unsigned short value;        lcd_read_reg(OTG_CTL_REG, &value, otg_cy_priv);        if (value & VBUS_VALID_FLG)        {            otg->a_vbus_vld = TRUE;            // HPI can not distinguish between the two thresholds.            otg->a_sess_vld = otg->b_sess_vld = TRUE;            otg->a_wait_vrise_tmout = FALSE;        }        else        {             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;        }    }    HWData(otg->a_vbus_vld);    switch (otg->id)    {    case A_DEV:        if (otg->a_bus_drop || otg->a_vbus_vld || otg->a_wait_vrise_tmout)         {            HWTrace (0x3033);            otg_cancel_timer( &otg->a_wait_vrise_tmout );            a_wait_bcon_state(otg);        }        HWTrace (0x3034);        break;    case B_DEV:        HWTrace (0x3035);        otg_cancel_timer( &otg->a_wait_vrise_tmout );        a_wait_bcon_state(otg);        break;    } }void a_wait_bcon_state(otg_t * otg){    HWTrace (0x3040);    if (otg->state != a_wait_bcon)     {        unsigned short usb_ctl_val;        /* Check for B-connected */        lcd_read_reg(USB1_CTL_REG, &usb_ctl_val, otg_cy_priv);        /* if device is connected */        if ( usb_ctl_val & (A_DP_STAT | A_DM_STAT) )        {            otg->b_conn = TRUE;        }        if (otg->state == a_host && otg->a_bus_req == TRUE)        {            HWTrace (0x3041);            /* the previous state is a_host. This means that device has been              * removed              */            handle_device_removal(otg_cy_priv, PORT0);        }                HWTrace (0x3042);        otg_start_timer( &otg->a_wait_bcon_tmout, Ta_wait_bcon );        otg->state = a_wait_bcon;        otg->b_bus_suspend = FALSE;    }         switch (otg->id)    {    case A_DEV:        if (otg->a_bus_drop || otg->a_wait_bcon_tmout)         {            HWTrace (0x3043);            otg_cancel_timer( &otg->a_wait_bcon_tmout );            a_wait_vfall_state(otg);        }        else if (!otg->a_vbus_vld)        {            HWTrace (0x3044);            otg_cancel_timer( &otg->a_wait_bcon_tmout );            a_vbus_err_state(otg);        }        else if (otg->b_conn)        {            HWTrace (0x3045);            otg_cancel_timer( &otg->a_wait_bcon_tmout );            a_host_state(otg);        }        break;    case B_DEV:        HWTrace (0x3046);        otg_cancel_timer( &otg->a_wait_bcon_tmout );        a_wait_vfall_state(otg);        break;    } }void a_host_state(otg_t * otg){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -