📄 dtvvsb2.c
字号:
/* 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(¶m);
/* 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(®Entry));
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 + -