📄 tda8961.c
字号:
/*
* Copyright (c) 1999 by TriMedia Technologies.
*
* +-------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such a |
* | license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided |
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | This code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +-------------------------------------------------------------------+
*
*
* Module name : tda8961.c 1.7
*
* Last update : 18:43:48 - 00/11/09
*
* Description :
*
*/
#include "tda8961.h"
#include <tmlib/dprintf.h>
#include <tmlib/tmtypes.h>
#include <tm1/tmAssert.h>
#include <tm1/tmIIC.h>
#include <tm1/tmProcessor.h>
#define N_VSB_CNTR_REGS 54
#define N_VSB_STAT_REGS 13
#define CHECK_OUTPUT_ATSC(x, y) if(vsbStatus->outputMode != omAtsc) {x = tda8961DigDemInit(unitID); y;}
typedef struct
{
UInt32 iicAddress;
UInt8 vsbIICTable[N_VSB_CNTR_REGS];
tda8961OutputMode_t outputMode;
Bool iicWorkaround;
Int clusterPositions[4];
}tda8961Status_t, *ptda8961Status_t;
static UInt8 vsb2ControlDefault[N_VSB_CNTR_REGS] = {
0x00, 0x00, 0x00, 0x00, 0x00, /* General Settings */
0x01, /* SRC */
0x20, /* AGC */
0x0E, /* AGC/Carrier recovery */
0x04, 0x00, 0x00, /* Timing recovery */
0x00, 0x00, 0x44,0x24,0x00, /* Sync Enhancer */
0x80, /* Sync recovery */
0x02, 0x80, 0x00, 0xCA, 0xFC, 0x96, 0x66, 0x22, /* EQ/Correlator */
0x2F, 0x00, 0xFC, 0x96, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60,
0x00, 0x00, 0x00, 0x00,
0x02, 0x00, /* NTSC cc filter */
0x04, /* Trellis decoder */
0x38, 0x00, 0x00, 0x00, /* Transport stream IF */
0x00, /* Diagnostics */
0x00 /* Debug */
};
static Int eqTaps[148];
static tda8961Status_t statusArray[4];
static Int clusterTaps[32 * 4];
static tsaTvDigDemEqCluster_t staticClusterArray[4] =
{
{0, 32, &clusterTaps[0]},
{0, 32, &clusterTaps[32]},
{0, 32, &clusterTaps[64]},
{0, 32, &clusterTaps[96]}
};
static tmLibdevErr_t writeRegisters(ptda8961Status_t vsbStatus, Int n);
/******************************************************************************/
static tmLibdevErr_t writeRegisters(ptda8961Status_t vsbStatus, Int n)
{
iicRequest_t req;
tmLibdevErr_t err;
Int iicInstance;
DP(("tda8961 writeRegisters\n"));
/* TM1100 1.2 cannot do writing of 5, 9, 13, ..., 4n+1, ... bytes */
if (vsbStatus->iicWorkaround)
{
if ((n - ((n >> 2) << 2)) == 1)
n += 1;
}
req.address = vsbStatus->iicAddress;
req.byteCount = n;
req.direction = IIC_WRITE;
req.type = IIC_SIMPLE;
req.data = vsbStatus->vsbIICTable;
req.numRetries = 1;
req.waitBeforeRetry = 200;
req.mode = IIC_Synchronous_By_Polling;
req.completion_function = Null;
err = iicOpen(&iicInstance);
if (err != TMLIBDEV_OK)
return err;
err = iicDispatch(iicInstance, &req);
if (err != TMLIBDEV_OK)
return err;
err = iicClose(iicInstance);
if (err != TMLIBDEV_OK)
return err;
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961Init(UInt32 unitID, ptda8961Param_t params)
{
tmLibdevErr_t err;
ptda8961Status_t vsbStatus = &statusArray[unitID];
Int i;
pprocCapabilities_t procCaps;
tmAssert(params, TMLIBDEV_ERR_NULL_PARAMETER);
err = procGetCapabilities(&procCaps);
if (err)
{
DP(("tda8961Init: Error %d in line %d\n", err, __LINE__));
return err;
}
vsbStatus->outputMode = omNoneSelected;
vsbStatus->iicWorkaround = True;
if ((procCaps->deviceID == PROC_DEVICE_TM1100) &&
(procCaps->revisionID >= PROC_REVISION_1_3))
{
vsbStatus->iicWorkaround = False;
}
vsbStatus->iicAddress = params->iicAddress;
for (i = 0; i < N_VSB_CNTR_REGS; i++)
vsbStatus->vsbIICTable[i] = vsb2ControlDefault[i];
/* write default values into registers */
err = writeRegisters(vsbStatus, N_VSB_CNTR_REGS);
if (err != TMLIBDEV_OK)
return err;
vsbStatus->clusterPositions[0] = 0;
vsbStatus->clusterPositions[1] = 32;
vsbStatus->clusterPositions[2] = 64;
vsbStatus->clusterPositions[3] = 96;
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961Term(UInt32 unitID)
{
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961DigDemInit(UInt32 unitID)
{
ptda8961Status_t vsbStatus = &statusArray[unitID];
tmLibdevErr_t err;
vsbStatus->vsbIICTable[0x30] |= 0x10;
vsbStatus->vsbIICTable[0x31] = 0x00;
/* write changed values into registers */
err = writeRegisters(vsbStatus, 0x32);
if (err != TMLIBDEV_OK)
return err;
vsbStatus->outputMode = omAtsc;
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961Start(UInt32 unitID)
{
tmLibdevErr_t err;
ptda8961Status_t vsbStatus = &statusArray[unitID];
DP(("tda8961Start\n"));
CHECK_OUTPUT_ATSC(err, return err);
err = writeRegisters(vsbStatus, N_VSB_CNTR_REGS);
if (err != TMLIBDEV_OK)
return err;
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961Stop(UInt32 unitID)
{
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961GetStatus(UInt32 unitID, ptsaTvDigDemStatus_t status)
{
iicRequest_t req;
tmLibdevErr_t err;
Int iicInstance;
UInt8 iica[6];
ptda8961Status_t vsbStatus = &statusArray[unitID];
DP(("tda8961GetStatus\n"));
CHECK_OUTPUT_ATSC(err, return err);
req.address = vsbStatus->iicAddress;
req.byteCount = 6;
req.direction = IIC_READ;
req.type = IIC_SIMPLE;
req.data = iica;
req.numRetries = 1;
req.waitBeforeRetry = 200;
req.mode = IIC_Synchronous_By_Polling;
req.completion_function = Null;
err = iicOpen(&iicInstance);
if (err != TMLIBDEV_OK)
return err;
err = iicDispatch(iicInstance, &req);
if (err != TMLIBDEV_OK)
return err;
err = iicClose(iicInstance);
if (err != TMLIBDEV_OK)
return err;
status->lockIndicator = (iica[0] & 0x04)?True:False;
status->eqLockIndicator = (iica[0] & 0x02)?True:False;
status->mse = ((UInt) iica[4]) << 8;
status->mse |= iica[5];
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961GetTapsAndStatus(UInt32 unitID, ptsaTvDigDemStatus_t status)
{
iicRequest_t req;
tmLibdevErr_t err;
Int iicInstance;
UInt8 iica[154];
Int i;
ptda8961Status_t vsbStatus = &statusArray[unitID];
CHECK_OUTPUT_ATSC(err, return err);
/* set control register to enable taps read */
vsbStatus->vsbIICTable[2] |= 0x02;
err = writeRegisters(vsbStatus, 3);
if (err != TMLIBDEV_OK)
{
vsbStatus->vsbIICTable[2] &= 0xfd;
return err;
}
req.address = vsbStatus->iicAddress;
req.byteCount = 148 + 7;
req.direction = IIC_READ;
req.type = IIC_SIMPLE;
req.data = iica;
req.numRetries = 1;
req.waitBeforeRetry = 200;
req.mode = IIC_Synchronous_By_Polling;
req.completion_function = Null;
err = iicOpen(&iicInstance);
if (err != TMLIBDEV_OK)
return err;
err = iicDispatch(iicInstance, &req);
if (err != TMLIBDEV_OK)
return err;
err = iicClose(iicInstance);
if (err != TMLIBDEV_OK)
return err;
status->lockIndicator = (iica[0] & 0x04)?True:False;
status->eqLockIndicator = (iica[0] & 0x02)?True:False;
status->mse = ((UInt) iica[4]) << 8;
status->mse |= iica[5];
for (i = 0; i < 148; i++)
eqTaps[i] = (Int8) iica[7 + i];
status->numEqTaps = 148;
status->eqTaps = eqTaps;
/* set control register to disable taps read */
vsbStatus->vsbIICTable[2] &= 0xfd;
err = writeRegisters(vsbStatus, 3);
if (err != TMLIBDEV_OK)
return err;
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961GetOffset(UInt32 unitID, Int *offset)
{
iicRequest_t req;
tmLibdevErr_t err;
Int iicInstance;
UInt8 iica[2];
ptda8961Status_t vsbStatus = &statusArray[unitID];
CHECK_OUTPUT_ATSC(err, return err);
req.address = vsbStatus->iicAddress;
req.byteCount = 2;
req.direction = IIC_READ;
req.type = IIC_SIMPLE;
req.data = iica;
req.numRetries = 1;
req.waitBeforeRetry = 200;
req.mode = IIC_Synchronous_By_Polling;
req.completion_function = Null;
err = iicOpen(&iicInstance);
if (err != TMLIBDEV_OK)
return err;
err = iicDispatch(iicInstance, &req);
if (err != TMLIBDEV_OK)
return err;
err = iicClose(iicInstance);
if (err != TMLIBDEV_OK)
return err;
*offset = (Int) (1250 * (Int8) iica[1]);
return TMLIBDEV_OK;
}
/******************************************************************************/
extern tmLibdevErr_t tda8961GetClusters(UInt32 unitID, ptsaTvDigDemEqCluster_t *clusterArray)
{
iicRequest_t req;
tmLibdevErr_t err;
Int iicInstance;
UInt8 iica[154];
Int i;
ptda8961Status_t vsbStatus = &statusArray[unitID];
tmAssert(clusterArray, TMLIBDEV_ERR_NULL_PARAMETER);
CHECK_OUTPUT_ATSC(err, return err);
/* set control register to enable cluster taps read */
vsbStatus->vsbIICTable[2] |= 0x01;
/* reset equalizer - HW problem workaround */
vsbStatus->vsbIICTable[0] |= 0x08;
err = writeRegisters(vsbStatus, 3);
if (err != TMLIBDEV_OK)
{
vsbStatus->vsbIICTable[2] &= 0xfe;
return err;
}
/* wait 90ms - HW problem workaround */
microsleep(90000);
req.address = vsbStatus->iicAddress;
req.byteCount = 128 + 8;
req.direction = IIC_READ;
req.type = IIC_SIMPLE;
req.data = iica;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -