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

📄 dtvvsb2.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    /* set AI MMIO registers */
    val = param->sRate * 256; /* 256 * sampleRate */
    val = 0.5 + (477218588.0 * (val / CPUClock));    /* 2**32 / 9 */
    aiSetFREQM(aiMMIOBase, ((UInt) val) | 0x80000000);
    
    aiDisableSER_MASTERM(aiMMIOBase);       /* TM is slave of clock */
    microsleep(2);                          /* wait until internal state of audio in unit is stable */
    
    aiSetWSDIVM(aiMMIOBase, 63);            /* we still have to set the correct clock ratios */
    aiSetSCKDIVM(aiMMIOBase, 3);
    aiSetCAP_MODEM(aiMMIOBase, 3);          /* Stereo 16 bits per sample */
    aiDisableSIGN_CONVERTM(aiMMIOBase);
    aiMsbFirstM(aiMMIOBase);                /* MSB first */
    aiSetFRAMEMODEM(aiMMIOBase, 0);         /* ignore valid bit */
    aiSampleRisingCLOCK_EDGEM(aiMMIOBase);  /* sample on rising edge */
    aiStartFallingEdgeWSM(aiMMIOBase);      /* left sample starts on neg. AI_WS */
    aiSetSSPOSM(aiMMIOBase, 0);    
    aiSetLEFTPOSM(aiMMIOBase, 0);            
    aiSetRIGHTPOSM(aiMMIOBase, 32);
    aiSetSIZEM(aiMMIOBase, param->size);

#ifdef __LITTLE_ENDIAN__
    aiEnableLITTLE_ENDIANM(aiMMIOBase);
#else
    aiDisableLITTLE_ENDIANM(aiMMIOBase);
#endif

    /* store parameters */
    dtvVsb2Ai2AudioTypeFormat   = param->audioTypeFormat;       
    dtvVsb2Ai2AudioSbtypeFormat = param->audioSubtypeFormat;
    dtvVsb2Ai2SRate             = param->sRate;
    dtvVsb2Ai2Size              = param->size;

dtvVsb2AI2InitExit:

    iicDirectionUnSelect(vsb2IICDirection);

    return err;

}

/* called in aiClose().  Should leave audio input system shut down */
static tmLibdevErr_t dtvVsb2AI2Term(void)
{
    return TMLIBDEV_OK;
}

/* called in aiStart(). */
static tmLibdevErr_t dtvVsb2AI2Start(void)
{
    aiEnableCAP_ENABLEM(aiMMIOBase);
    
    return TMLIBDEV_OK;
}

/* called in aiStop(). */
static tmLibdevErr_t dtvVsb2AI2Stop(void)
{
    aiDisableCAP_ENABLEM(aiMMIOBase);

    return TMLIBDEV_OK;
}

/* called from aiSetSampleRate(). */
static tmLibdevErr_t dtvVsb2AI2SetSrate(Float sRate)
{
    tmLibdevErr_t err;

    err = iicDirectionSelect(vsb2IICDirection);
    if (err != TMLIBDEV_OK)
        return err;

    err = tda8980AiSetSRate(0, sRate);
    if (err == TMLIBDEV_OK)
        dtvVsb2Ai2SRate = sRate;

    iicDirectionUnSelect(vsb2IICDirection);

    return err;
}

/* called from aiGetSampleRate(). */
static tmLibdevErr_t dtvVsb2AI2GetSrate(Float * sRate)
{
    tmAssert(sRate, TMLIBDEV_ERR_NULL_PARAMETER);

    *sRate = dtvVsb2Ai2SRate;

    return TMLIBDEV_OK;
}

/* called from aiSetInput() */
static tmLibdevErr_t dtvVsb2AI2SetInput(tmAudioAnalogAdapter_t input)
{
    boardAIParam_t  param;
    UInt            err;
    static Bool     capEnable = False;
    UInt32          buf1         = MMIO(aiMMIOBase + AI_BASE1_OFFSET);
    UInt32          buf2         = MMIO(aiMMIOBase + AI_BASE2_OFFSET);
    UInt32          size         = MMIO(aiMMIOBase + AI_SIZE_OFFSET);
    UInt32          aiIntControl = MMIO(aiMMIOBase + AI_CTL_OFFSET) & (AI_BUF1_INTEN | AI_BUF2_INTEN | AI_OVR_INTEN | AI_HBE_INTEN);
    
    /* check if we realy have to change the input */
    if (input == dtvVsb2Ai2Input)
    {
        return TMLIBDEV_OK;
    }
    
    /* stop audio in */
    if (MMIO(aiMMIOBase + AI_CTL_OFFSET) & AI_CAP_ENABLE)
    {
        aiDisableCAP_ENABLEM(aiMMIOBase);
        capEnable = True;
    }
    
    param.audioTypeFormat      = dtvVsb2Ai2AudioTypeFormat;       
    param.audioSubtypeFormat   = dtvVsb2Ai2AudioSbtypeFormat;
    param.sRate                = dtvVsb2Ai2SRate;
    param.size                 = dtvVsb2Ai2Size;
    param.input                = input;
    dtvVsb2Ai2Input            = input;
    
    
    err = dtvVsb2AI2Init(&param);

    /* restore MMIO registers */
    MMIO(aiMMIOBase + AI_BASE1_OFFSET)  = buf1;
    MMIO(aiMMIOBase + AI_BASE2_OFFSET)  = buf2;
    MMIO(aiMMIOBase + AI_SIZE_OFFSET)   = size;
    MMIO(aiMMIOBase + AI_CTL_OFFSET)   |= aiIntControl;
    
    if (err)
    {
        return err;
    }
    
    if (capEnable)
    {
        aiEnableCAP_ENABLEM(aiMMIOBase);
    }
    
    return TMLIBDEV_OK;
}

/* called from aiGetInput() */
static tmLibdevErr_t dtvVsb2AI2GetInput(tmAudioAnalogAdapter_t * input)
{
    tmAssert(input, TMLIBDEV_ERR_NULL_PARAMETER);
    
    *input = dtvVsb2Ai2Input;
    
    return TMLIBDEV_OK;
}

/* called from aiGetInputFormat */
static tmLibdevErr_t dtvVsb2AI2GetFormat(ptmAudioFormat_t inputFormat)
{
    Float   sRate;
    Int     err;
    Char    statusReg[2] = {0,0};

    /* initialize the inputFormat */
    inputFormat->size           = sizeof(tmAudioFormat_t);
    inputFormat->dataClass      = avdcAudio;
    inputFormat->dataType       = atfNone;
    inputFormat->dataSubtype    = apfNone;
    inputFormat->sampleRate     = 0.0;
    
    /* get sample rate, if sample rate is 0.0 -> TDA 1315 is not locked */
    err = dtvVsb2AI2GetSrate(&sRate);
    if (err) return err;
    
    if (sRate == 0.0)
    {
        return TMLIBDEV_OK;
    }
    
    inputFormat->sampleRate     = sRate;
    inputFormat->dataType       = atfLinearPCM;
    inputFormat->dataSubtype    = apfStereo16;

    return TMLIBDEV_OK;
}

/* a backdoor to support features not forseen in the initial design */
static tmLibdevErr_t dtvVsb2AI2Config(UInt32 subaddr, Pointer value)
{
    return TMLIBDEV_OK;
}

/*****************************************************************************************/
static tmLibdevErr_t dtvVsb2Activate(pcomponent_t comp)
{
    TRY(dtvVsb2Detect());

    TRY(dtvVsb2Init());

    TRY(dtvVsb2Register());

    return TMLIBDEV_OK;
}

#undef RESET_WORKAROUND /* do reset in detect function instead of after detecting the board */
/*****************************************************************************************/
static tmLibdevErr_t dtvVsb2Init(void)
{
    UInt8           iicd;
    tda8980Param_t  mpocParams;
    tda8961Param_t  tda8961Params;

    TRY(iicDirectionSelect(vsb2IICDirection));

#ifndef RESET_WORKAROUND

    /* initialize board */
    iicPortA = 0x04; /* default value for ATSC reception, reset is low */
    TRY_UNSELECT(iicWriteReg(CATALINA_IIC_EXPANDER_A, -1, iicPortA));
    iicPortA |= 0x02; /* raise reset, everything out of reset */
    TRY_UNSELECT(iicWriteReg(CATALINA_IIC_EXPANDER_A, -1, iicPortA));

    /* do software reset for VSB II chip */
    iicd = 0x02;
    TRY_UNSELECT(iicWriteReg(TDA8961_IIC_ADDRESS_0, -1, iicd));

    /* wait 400 milliseconds for the VSB 2 chip to get out of reset. */
    microsleep(400000);

#endif

    /* initialize VSB 2 chip */
    tda8961Params.iicAddress = TDA8961_IIC_ADDRESS_0;
    TRY_UNSELECT(tda8961Init(0, &tda8961Params));

    /* get version of the MPOC chip */
    TRY_UNSELECT(iicReadReg(IIC_EEPROM_ADDRESS, 0xfc, &mpocVersion));

    /* initialize mpoc chip */
    mpocParams.iicAddress  = TDA8980_IIC_ADDRESS_0;
    mpocParams.mpocVersion = mpocVersion;
    TRY_UNSELECT(tda8980Init(0, &mpocParams));

    iicDirectionUnSelect(vsb2IICDirection);

    return TMLIBDEV_OK;
}

#define PATH_STRING_LENGTH 256
/*****************************************************************************************/
static tmLibdevErr_t dtvVsb2Register(void)
{
    UInt32              daughterboardsNumberOfUnits;
    UInt32              tvTunerNumberOfUnits;
    UInt32              tvDigDemNumberOfUnits;
    UInt32              tvAudDemNumberOfUnits;
    Char                pathString[PATH_STRING_LENGTH];
    Char                daughterboardName[] = "VSB 2 board";
    tsaRegDataEntry_t   dataEntry   = {redtChar, 0, Null};
    tsaRegEntryAdd_t    regEntry;

    DP(("dtvVsb2Register\n"));

    /* register VI */
    dtvVsb2Vi.vDec.iicDirection = vsb2IICDirection;
    if (vsb2IICDirection == IIC_DIRECTION_NIM1)
    {
        dtvVsb2Vi.mmioBase      = VI_STATUS;
        dtvVsb2Vi.intNumber     = intVIDEOIN;
        dtvVsb2Vi.gpioFirstPin  = GPIO_VI1_CLK;
        dtvVsb2Vi.gpioLastPin   = GPIO_VI1_DATA9;
        TRY(tsaBoardRegisterVI(unit0, &dtvVsb2Vi));
    }
    else
        TRY(tsaBoardRegisterVI(unit1, &dtvVsb2Vi));

    /* register AI */
    if (vsb2IICDirection == IIC_DIRECTION_NIM1)
    {
        aiMMIOBase              = AI_STATUS;
        ai2Config.mmioBase      = AI_STATUS;
        ai2Config.intNumber     = intAUDIOIN;
        ai2Config.gpioFirstPin  = GPIO_AI1_OSCLK;
        ai2Config.gpioLastPin   = GPIO_AI1_WS;
        TRY(tsaBoardRegisterAI(unit0, &ai2Config));
    }
    else
        TRY(tsaBoardRegisterAI(unit1, &ai2Config));

    /* get number of existing daughterboards, tvTuners and tvAudDems */
    TRY(getNumberOfUnits(&daughterboardsNumberOfUnits, "/bsp/daughterboard/*"));
    TRY(getNumberOfUnits(&tvDigDemNumberOfUnits, "/bsp/TvDigDem/*"));
    TRY(getNumberOfUnits(&tvAudDemNumberOfUnits, "/bsp/TvAudDem/*"));
    TRY(getNumberOfUnits(&tvTunerNumberOfUnits, "/bsp/TvTuner/*"));

    /* register digital demodulator */
    digDemConfig.tunerID = tvTunerNumberOfUnits;
    if (vsb2IICDirection == IIC_DIRECTION_NIM1)
        digDemConfig.tpUnit = unit0;
    TRY(tsaBoardRegisterTvDigDem(tvDigDemNumberOfUnits, &digDemConfig));

    /* register tuner */
    tunerConfig.connections.digDemUnit = tvDigDemNumberOfUnits;
    tunerConfig.connections.audDemUnit = tvAudDemNumberOfUnits;
    if (vsb2IICDirection == IIC_DIRECTION_NIM1)
        tunerConfig.connections.viUnit = unit0;
    TRY(tsaBoardRegisterTvTuner(tvTunerNumberOfUnits, &tunerConfig));

    /* register audio demodulator */
    audDemConfig1.tunerID   = tvTunerNumberOfUnits;
    if (vsb2IICDirection == IIC_DIRECTION_NIM1)
        audDemConfig1.aiUnit = unit0;
    TRY(tsaBoardRegisterTvAudDem(tvAudDemNumberOfUnits, &audDemConfig1));
    
    /* register daughter board */
    memset(pathString, 0, PATH_STRING_LENGTH);

    dataEntry.data          = daughterboardName;
    dataEntry.dataLength    = strlen(daughterboardName) + 1;
    regEntry.path           = pathString;
    regEntry.entryType      = recData;
    regEntry.entrySize      = 0;
    regEntry.entry          = &dataEntry;    
    regEntry.flags          = TSA_REG_CREATE_ALWAYS;
    strcpy(regEntry.keyString, daughterboardName);
    sprintf(regEntry.path, "bsp/daughterboard/%02d", daughterboardsNumberOfUnits);
    TRY(tsaRegAddEntry(&regEntry));

    return TMLIBDEV_OK;
}


/*****************************************************************************************/
static tmLibdevErr_t dtvVsb2Detect(void)
{
    UInt32        ID;
    Char          *boardName;
    UInt          iicd;

    DP(("dtvVsb2Detect\n"));

    TRY(tsaBoardGetBoard(&ID, &boardName));
    DP((" connected to board: %s (ID = %#x)\n", boardName, ID));

    /* not supported on Ref2, Ref3 and TTR/TR boards */
    if ((ID == BOARD_VERSION_PHILIPS_DTV_TTR)  ||
        (ID == BOARD_VERSION_PHILIPS_DTV_TR)   ||
        (ID == BOARD_VERSION_PHILIPS_DTV_REF2) ||
        (ID == BOARD_VERSION_PHILIPS_DTV_REF3))
    {
        return -1;
    }

    /* on the Saturn board the IIC direction is NIM1 */
    if (ID == BOARD_VERSION_PHILIPS_DTV_REF5)
        vsb2IICDirection = IIC_DIRECTION_NIM1;

    /* check on NIM 2 connector */
    TRY(iicDirectionSelect(vsb2IICDirection));

    /* first check if tuner is there */
    TRY_UNSELECT(iicReadReg(TD1536_IIC_ADDRESS_0, -1, &iicd));
    DP(("  tuner present\n"));

    /* check if PCF 8591 is there */
    TRY_UNSELECT(iicReadReg(0x90, -1, &iicd));
    DP(("  PCF 8591 present\n"));

    /* check if BTSC stereo decoder is there */
    TRY_UNSELECT(iicReadReg(TDA9851_IIC_ADDRESS, -1, &iicd));
    DP(("  BTSC stereo decoder present\n"));

    /* check if MPOC is there */
    TRY_UNSELECT(iicReadReg(TDA8980_IIC_ADDRESS_0, -1, &iicd));
    DP(("  MPOC present\n"));

    /* check if IIC expander A  is there */
    TRY_UNSELECT(iicReadReg(CATALINA_IIC_EXPANDER_A, -1, &iicd));
    DP(("  IIC expander A present\n"));

    /* check if IIC expander B  is there */
    TRY_UNSELECT(iicReadReg(CATALINA_IIC_EXPANDER_B, -1, &iicd));
    DP(("  IIC expander B present\n"));

    /* check if IIC expander C  is there */
    TRY_UNSELECT(iicReadReg(CATALINA_IIC_EXPANDER_C, -1, &iicd));
    DP(("  IIC expander C present\n"));

#ifdef RESET_WORKAROUND
    /* reset and initialize board, needs to be done here because of problems
       with the TDA 8961 */
    DP((" initializing VSB II board.\n"));
    iicPortA = 0x04; /* default value for ATSC reception, reset is low */
    TRY_UNSELECT(iicWriteReg(CATALINA_IIC_EXPANDER_A, -1, iicPortA));
    iicPortA |= 0x02; /* raise reset to get everything out of reset */
    TRY_UNSELECT(iicWriteReg(CATALINA_IIC_EXPANDER_A, -1, iicPortA));
    microsleep(300000);

    /* do software reset for VSB II chip */
    iicd = 0x02;
    TRY_UNSELECT(iicWriteReg(TDA8961_IIC_ADDRESS_0, -1, iicd));

    /* wait 400 milliseconds for the VSB 2 chip to get out of reset. */
    microsleep(400000);

#endif

    /* check if VSB II chip is there */
    TRY_UNSELECT(iicReadReg(TDA8961_IIC_ADDRESS_0, -1, &iicd));
    DP(("  VSB present\n"));

    iicDirectionUnSelect(vsb2IICDirection);

    return TMLIBDEV_OK;
}


/*****************************************************************************************/
TSA_COMP_DEF_IO_COMPONENT(vsb2Board, 
                          TSA_COMP_BUILD_ARG_LIST_1("bsp/boardID"), 
                          TSA_COMP_BUILD_ARG_LIST_1("bsp/daughterboard"), 
                          dtvVsb2Activate);

⌨️ 快捷键说明

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