📄 tw98.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 : tw98.c 1.2
*
* Last update : 18:43:51 - 00/11/09
*
* Description :
*
*/
#include <tm1/tmIIC.h>
#include <tm1/tmAvFormats.h>
#include <tm1/tmVImmio.h>
#include <tm1/tmVIboard.h>
#include <tmlib/dprintf.h>
#include <tm1/tmBoardDef.h>
#include "tw98.h"
#define W98_NUM_REGS 21
#define W98_NUM_REGS_DIF 23
static UInt8 defaultIICRegs[W98_NUM_REGS * 2] =
{
0x02, 0x28, /* 0x30(?) - s-video, 0x28 - middle composite */
0x03, 0x92, /* change from 0xA2 to 0x92 */
0x04, 0x80,
0x05, 0x01,
0x06, 0x00,
0x0b, 0xd0,
0x0c, 0x01,
0x0d, 0x00,
0x0e, 0x01,
0x10, 0xd0,
0x11, 0x30,
0x12, 0x14,
0x13, 0x71,
0x14, 0x50,
0x15, 0x20,
0x16, 0xd0,
0x17, 0x00,
0x18, 0x00,
0x19, 0x98,
0x1a, 0x40,
0x1c, 0x10
};
/*NTSC 0x01_E2_BE_2F_E7 0x01_E2_E2_46_9B 0x01_E2_9D_39_97 0xB4
PAL 0x01_85_BF_D5_04 0x01_85_D6_57_70 0x01_85_A9_55_32 0xC0 */
static UInt8 ntscValues[W98_NUM_REGS_DIF * 2] =
{
0x07, 0x12,
0x08, 0x18,
0x09, 0xe5,
0x0a, 0x00,
0x0f, 0x10,
0xc1, 0x01,
0xc2, 0xe2,
0xc3, 0xbe,
0xc4, 0x2f,
0xc5, 0xe7,
0xc7, 0x01,
0xc8, 0xe2,
0xc9, 0xe2,
0xca, 0x46,
0xcb, 0x9b,
0xcd, 0x01,
0xce, 0xe2,
0xcf, 0x9d,
0xd0, 0x39,
0xd1, 0x97,
0xdc, 0x14,
0xdf, 0xb4,
0xe1, 0x38
};
static UInt8 palValues[W98_NUM_REGS_DIF * 2] =
{
0x07, 0x22,
0x08, 0x24,
0x09, 0x40,
0x0a, 0x04,
0x0f, 0x50,
0xc1, 0x01,
0xc2, 0x85,
0xc3, 0xbf,
0xc4, 0xd5,
0xc5, 0x04,
0xc7, 0x01,
0xc8, 0x85,
0xc9, 0xd6,
0xca, 0x57,
0xcb, 0x70,
0xcd, 0x01,
0xce, 0x85,
0xcf, 0xa9,
0xd0, 0x55,
0xd1, 0x32,
0xdf, 0xc0,
0xe1, 0x28
};
typedef enum
{
w98ChipIdR = 0x00,
w98ChipStatusR = 0x01,
w98InputFormatR = 0x02,
w98OutputFormatControlR = 0x03,
w98HorizontalSyncLengthR = 0x04,
w98OutputPolarityR = 0x05,
w98AnalogControlR = 0x06,
w98CroppingHighR = 0x07,
w98VerticalDelayLowR = 0x08,
w98VerticalActiveLowR = 0x09,
w98HorizontalDelayLowR = 0x0a,
w98HorizontalActiveLowR = 0x0b,
w98VerticalScalingHighR = 0x0c,
w98VerticalScalingLowR = 0x0d,
w98HorizontalScalingHighR = 0x0e,
w98HorizontalScalingLowR = 0x0f,
w98BrightnessControlR = 0x10,
w98ContrastControlR = 0x11,
w98SharpnessControlR = 0x12,
w98ChromaUGainR = 0x13,
w98ChromaVGainR = 0x14,
w98HueControlR = 0x15,
w98ColorKillControlR = 0x16,
w98CoringControlR = 0x17,
w98VBIControlR = 0x19,
w98CC_EDSStatusR = 0x1a
} w98Regs_t;
/********************************************************************************************/
static Bool getRegIndex(UInt8 iicRegister, Int *index);
static tmLibdevErr_t setTW98Reg(UInt8 iicRegister, UInt8 value);
static tmLibdevErr_t getTW98Reg(UInt8 iicRegister, UInt8 *value);
static tmLibdevErr_t mapAdapterInput (pboardVIDec_t pVD, pboardVIParam_t param, UInt *mode);
/********************************************************************************************/
static Bool getRegIndex(UInt8 iicRegister, Int *index)
{
Int i;
for (i = 0; i < W98_NUM_REGS; i++)
{
if (defaultIICRegs[i * 2] == iicRegister)
break;
}
if (i >= W98_NUM_REGS)
return False;
*index = i;
return True;
}
/******************************************************************************/
static tmLibdevErr_t mapAdapterInput (pboardVIDec_t pVD, pboardVIParam_t param, UInt *mode)
{
UInt i;
/* If the adapter is vaaNone then use the default adapter */
if (param->adapterType == vaaNone)
{
*mode = pVD->adapterTable[0].decInput;
return TMLIBDEV_OK;
}
for (i = 0; i < pVD->numAdapters; i++)
{
/* Find the right instance of the adapter */
if ((pVD->adapterTable[i].instNum == param->adapterInstance) &&
(pVD->adapterTable[i].adapterType == param->adapterType))
{
*mode = pVD->adapterTable[i].decInput;
return TMLIBDEV_OK;
}
}
/* No adapter instance found. If it's unqual to zero */
/* -> try with instance zero... */
if (param->adapterInstance != 0)
{
param->adapterInstance = 0;
return mapAdapterInput(pVD, param, mode);
}
/* Right adapter was not found -> return error */
return BOARD_ERR_UNSUPPORTED_ADAPTER;
}
/********************************************************************************************/
static tmLibdevErr_t setTW98Reg(UInt8 iicRegister, UInt8 value)
{
tmLibdevErr_t err = TMLIBDEV_OK;
Int iicIndex;
err = iicWriteReg(TW98_IIC_ADDRESS, iicRegister, value);
if (err != TMLIBDEV_OK)
return err;
if (getRegIndex(iicRegister, &iicIndex))
defaultIICRegs[(iicIndex * 2) + 1] = value;
return TMLIBDEV_OK;
}
/********************************************************************************************/
static tmLibdevErr_t getTW98Reg(UInt8 iicRegister, UInt8 *value)
{
tmLibdevErr_t err = TMLIBDEV_OK;
Int iicIndex;
UInt iicd;
if (getRegIndex(iicRegister, &iicIndex))
*value = defaultIICRegs[(iicIndex * 2) + 1];
else
{
err = iicReadReg(TW98_IIC_ADDRESS, iicRegister, &iicd);
*value = (UInt8) iicd;
}
return err;
}
/********************************************************************************************/
extern tmLibdevErr_t tw98Init(pboardVIDec_t pVD, pboardVIParam_t param)
{
UInt i, rval = 0;
UInt inputMode;
DP(("tw98Init\n"));
viSetSELFCLOCKM(param->mmioBase, 0);
/* Copy video standard to internal variable */
pVD->curVideoStandard = param->videoStandard;
if (param->videoStandard == vasNone)
return TMLIBDEV_OK;
if ( !(param->videoStandard & (vasNTSC | vasPAL)) )
return BOARD_ERR_UNSUPPORTED_STANDARD;
if (! ((param->adapterType == vaaNone) ||
(param->adapterType & (vaaCVBS|vaaSvideo))))
return BOARD_ERR_UNSUPPORTED_ADAPTER;
/* write default values to tw98 IIC registers */
for (i = 0; i < W98_NUM_REGS; i++)
{
rval |= iicWriteReg(TW98_IIC_ADDRESS, defaultIICRegs[i * 2], defaultIICRegs[(i * 2) + 1]);
if (rval)
DP(("at %d, IIC write to %x, %x returned error %x\n",
i, TW98_IIC_ADDRESS, defaultIICRegs[i * 2], rval));
}
if (rval != TMLIBDEV_OK)
return rval;
/* set video standard */
rval = tw98SetStandard(pVD, param->videoStandard);
if (rval != TMLIBDEV_OK)
return rval;
/* Make sure the adapter's instance is valid on this board and we get a valid mode */
if (mapAdapterInput (pVD, param, &inputMode) != TMLIBDEV_OK)
return BOARD_ERR_INVALID_ADAPTER_INSTANCE;
/* Set input of video accordingly */
rval = tw98SetAnalogInput (pVD, inputMode);
if (rval != TMLIBDEV_OK)
return rval;
return (tmLibdevErr_t) rval;
}
/********************************************************************************************/
extern tmLibdevErr_t tw98SetBrightness(pboardVIDec_t pVD, UInt val)
{
return setTW98Reg(w98BrightnessControlR, val);
}
/********************************************************************************************/
extern tmLibdevErr_t tw98SetContrast(pboardVIDec_t pVD, UInt val)
{
return setTW98Reg(w98ContrastControlR, val);
}
/********************************************************************************************/
extern tmLibdevErr_t tw98SetHue(pboardVIDec_t pVD, UInt val)
{
return setTW98Reg(w98HueControlR, val);
}
/********************************************************************************************/
extern tmLibdevErr_t tw98SetAnalogInput(pboardVIDec_t pVD, UInt num)
{
UInt8 iicd;
tmLibdevErr_t err;
err = getTW98Reg(w98InputFormatR, &iicd);
if (err != TMLIBDEV_OK)
return err;
iicd &= 0xe3;
if (num < 4)
iicd |= num << 2;
else if (num < 8)
{
iicd |= (num & 0x03) << 2;
iicd |= 0x10;
}
else
return VI_ERR_INVALID_DECODER_INIT;
return setTW98Reg(w98InputFormatR, iicd);;
}
/********************************************************************************************/
extern tmLibdevErr_t tw98GetAnalogInput(pboardVIDec_t pVD, UInt *num)
{
UInt8 iicd;
tmLibdevErr_t err;
err = getTW98Reg(w98InputFormatR, &iicd);
if (err != TMLIBDEV_OK)
return err;
*num = (iicd >> 2) & 0x03;
if (iicd & 0x10)
*num += 4;
return TMLIBDEV_OK;
}
/********************************************************************************************/
extern tmLibdevErr_t tw98SetStandard(pboardVIDec_t pVD, tmVideoAnalogStandard_t standard)
{
UInt8 iicd;
tmLibdevErr_t err;
UInt8 *iicValues;
Int i;
DP(("tw98SetStandard\n"));
err = getTW98Reg(w98InputFormatR, &iicd);
if (err != TMLIBDEV_OK)
return err;
iicd &= 0xfc;
switch (standard)
{
case vasNTSC:
iicValues = ntscValues;
break;
case vasPAL:
iicValues = palValues;
iicd |= 0x01;
break;
default:
return VI_ERR_STANDARD_NOT_SUPPORTED;
}
pVD->curVideoStandard = standard;
err = setTW98Reg(w98InputFormatR, iicd);;
if (err != TMLIBDEV_OK)
return err;
/* write default values to tw98 IIC registers */
for (i = 0; i < W98_NUM_REGS_DIF; i++)
{
err |= iicWriteReg(TW98_IIC_ADDRESS, iicValues[i * 2], iicValues[(i * 2) + 1]);
}
return err;
}
/********************************************************************************************/
extern tmLibdevErr_t tw98GetDefaultAcquisitionWnd(pboardVIDec_t pVD, UInt *beginX, UInt *beginY, UInt *endX, UInt *endY)
{
switch (pVD->curVideoStandard)
{
case vasNTSC:
/* Set default acquisition window for NTSC */
*beginX = 0;
*beginY = 0;
*endX = *beginX + 719;
*endY = *beginY + 239;
break;
case vasPAL:
/* Set default acquisition window for PAL */
*beginX = 0;
*beginY = 0;
*endX = *beginX + 719;
*endY = *beginY + 287;
break;
default:
return BOARD_ERR_COLOR_STANDARD_NOT_DETECTED;
}
return TMLIBDEV_OK;
}
extern tmLibdevErr_t tw98Configure(pboardVIDec_t pVD, UInt32 subaddr, UInt32 value)
{
return setTW98Reg(subaddr, (UInt8) value);
}
/********************************************************************************************/
extern tmLibdevErr_t tw98GetVSyncFallingEdge(pboardVIDec_t pVD, UInt *line)
{
switch (pVD->curVideoStandard)
{
case vasNTSC:
*line = 22; /* NOT!!! CCIR-656 conform; might be changed later */
break;
case vasPAL:
*line = 23; /* first guess, we never tested pal with this chip */
break;
default:
DP(("tm98: BOARD_ERR_COLOR_STANDARD_NOT_DETECTED\n"));
return BOARD_ERR_COLOR_STANDARD_NOT_DETECTED;
}
return TMLIBDEV_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -