1
0
mirror of https://github.com/marqs85/ossc.git synced 2024-11-12 04:05:12 +00:00
ossc/software/sys_controller/it6613/HDMI_TX.c
marqs 9d14cc776e Misc small fixes and improvements
* Disable 480p scanlines in auto mode
* Remove inoperable 3x/4x processing modes from 1080i list
* Add 640x512 mode to 480p group and limit 480p sampler option to 525-line modes
* Fix occasional pixel repetion issue after HDMI<->DVI TX switch
* Add "Allow upsample2x" option
* Add comments to some unclear sections
2017-08-10 00:06:35 +03:00

333 lines
9.9 KiB
C

//#include "terasic_includes.h"
//#include "mcu.h"
#include <unistd.h>
#include "it6613_sys.h"
#include "hdmitx.h"
#include "HDMI_TX.h"
#include "edid.h"
int TX_HDP = FALSE;
extern BYTE bOutputColorMode;
extern BYTE bInputColorMode;
extern BOOL bChangeMode;
extern RX_CAP RxCapability;
extern BOOL bHDMIMode;
extern BOOL bAudioEnable;
BOOL ParseEDID();
INSTANCE InitInstanceData =
{
0,0, //I2C_DEV, I2C_ADDR
0, //bIntType (TxCLK active, Push-Pull Mode, INT active low)
0,/* | T_MODE_CCIR656 | T_MODE_SYNCEMB | T_MODE_INDDR */ // bInputVideoSignalType
B_AUDFMT_STD_I2S, // bOutputAudioMode, 0x00, standard i2s, rising edge to sample ws/i2s, not full packet mode REG[0xE1]
0,// bAudioChannelSwap
B_AUD_EN_I2S0 | B_AUD_I2S | M_AUD_16BIT, // bAudioChannelEnable, 0x01, REG[0xE0], defined in it6613_drv.h
AUDFS_48KHz, //0, //bAudFs,
0, // TMDSClock
TRUE,//bAuthenticated
TRUE,// bHDMIMode
FALSE,// bIntPOL
FALSE // bHPD
} ;
bool HDMITX_ChipVerify(void){
bool bPass = FALSE;
alt_u8 szID[4];
int i;
for(i=0;i<4;i++)
szID[i] = HDMITX_ReadI2C_Byte(i);
// if (szID[0] == 0x00 && szID[1] == 0xCA && szID[1] == 0x13 && szID[1] == 0x06) szID[0] ???
if ((szID[1] == 0xCA && szID[2] == 0x13 && szID[3] == 0x06) || (szID[1] == 0xCA && szID[2] == 0x13 && szID[3] == 0x16)){
bPass = TRUE;
printf("TX Chip Revision ID: %d\n", szID[0]);
}else{
printf("NG, Read TX Chip ID:%02X%02X%02X%02Xh (expected:00CA1306h)\n", szID[0], szID[1], szID[2], szID[3]);
}
return bPass;
}
bool HDMITX_Init(void){
bool bSuccess = TRUE;
HDMITX_Reset();
usleep(500*1000);
if (!HDMITX_ChipVerify()){
OS_PRINTF("Failed to find IT6613 HDMI-TX Chip.\n");
bSuccess = FALSE;
//return 0;
}
HDMITX_InitInstance(&InitInstanceData) ;
InitIT6613() ;
return bSuccess;
}
bool HDMITX_HPD(void){
if (TX_HDP)
return TRUE;
return FALSE;
}
void HDMITX_SetAVIInfoFrame(alt_u8 VIC, bool b16x9, bool ITU709, bool ITC, alt_u8 pixelrep)
{
AVI_InfoFrame AviInfo;
OS_PRINTF("HDMITX_SetAVIInfoFrame: VIC=%d, Aspect-Ratio=%s, ITU709=%s, ITC=%s, pixelrep=%u\n",
VIC, b16x9?"16:9":"4:3", ITU709?"Yes":"No", ITC?"Yes":"No", pixelrep);
AviInfo.pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
AviInfo.pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
AviInfo.pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
/*switch(OutputColorMode)
{
case F_MODE_YUV444:
// AviInfo.info.ColorMode = 2 ;
AviInfo.pktbyte.AVI_DB[0] = (2<<5)|(1<<4) ;
break ;
case F_MODE_YUV422:
// AviInfo.info.ColorMode = 1 ;
AviInfo.pktbyte.AVI_DB[0] = (1<<5)|(1<<4) ;
break ;
case F_MODE_RGB444:
default:
// AviInfo.info.ColorMode = 0 ;
AviInfo.pktbyte.AVI_DB[0] = (0<<5)|(1<<4) ;
break ;
}*/
AviInfo.pktbyte.AVI_DB[0] = (0<<5)|(1<<4) ;
AviInfo.pktbyte.AVI_DB[0] |= 2; // indicate "no overscan"
AviInfo.pktbyte.AVI_DB[1] = 8 ;
//AviInfo.pktbyte.AVI_DB[1] |= (!b16x9)?(1<<4):(2<<4) ; // 4:3 or 16:9
AviInfo.pktbyte.AVI_DB[1] |= (!ITU709)?(1<<6):(2<<6) ; // ITU709 or ITU601
AviInfo.pktbyte.AVI_DB[2] = ((1<<3) | (ITC<<7)) ; // indicate "full-range RGB", setup ITC bit
AviInfo.pktbyte.AVI_DB[3] = VIC ;
AviInfo.pktbyte.AVI_DB[4] = pixelrep & 3 ;
AviInfo.pktbyte.AVI_DB[5] = 0 ;
AviInfo.pktbyte.AVI_DB[6] = 0 ;
AviInfo.pktbyte.AVI_DB[7] = 0 ;
AviInfo.pktbyte.AVI_DB[8] = 0 ;
AviInfo.pktbyte.AVI_DB[9] = 0 ;
AviInfo.pktbyte.AVI_DB[10] = 0 ;
AviInfo.pktbyte.AVI_DB[11] = 0 ;
AviInfo.pktbyte.AVI_DB[12] = 0 ;
EnableAVIInfoFrame(TRUE, (unsigned char *)&AviInfo) ;
}
void HDMITX_ChangeVideoTiming(int VIC){
int OutputVideoTiming = VIC;
int HdmiColorMode;
switch(bOutputColorMode)
{
case F_MODE_YUV444:
HdmiColorMode = HDMI_YUV444;
break ;
case F_MODE_YUV422:
HdmiColorMode = HDMI_YUV422;
break ;
case F_MODE_RGB444:
default:
HdmiColorMode = HDMI_RGB444;
break ;
}
HDMITX_ChangeDisplayOption(OutputVideoTiming, HdmiColorMode); // just modify variable. Take effect when HDMITX_SetOutput is called in HDMITX_DevLoopProc
}
void HDMITX_ChangeVideoTimingAndColor(int VIC, COLOR_TYPE Color){
int OutputVideoTiming = VIC;
int HdmiColorMode;
switch(Color)
{
case COLOR_YUV444:
HdmiColorMode = HDMI_YUV444;
break ;
case COLOR_YUV422:
HdmiColorMode = HDMI_YUV422;
break ;
case COLOR_RGB444:
default:
HdmiColorMode = HDMI_RGB444;
break ;
}
HDMITX_ChangeDisplayOption(OutputVideoTiming, HdmiColorMode);
}
void HDMITX_DisableVideoOutput(void){
DisableVideoOutput();
}
void HDMITX_EnableVideoOutput(void){
HDMITX_SetOutput();
}
void HDMITX_SetColorSpace(COLOR_TYPE InputColor, COLOR_TYPE OutputColor){
// DisableVideoOutput();
bInputColorMode = InputColor;
bOutputColorMode = OutputColor;
// HDMITX_SetOutput();
}
bool HDMITX_IsSinkSupportYUV444(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
(RxCapability.VideoMode & CEA_SUPPORT_YUV444))
bSupport = TRUE;
return bSupport;
}
bool HDMITX_IsSinkSupportYUV422(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
(RxCapability.VideoMode & CEA_SUPPORT_YUV422))
bSupport = TRUE;
return bSupport;
}
bool HDMITX_IsSinkSupportColorDepth36(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
RxCapability.dc.info.DC_36Bit)
bSupport = TRUE;
return bSupport;
}
bool HDMITX_IsSinkSupportColorDepth30(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
RxCapability.dc.info.DC_30Bit)
bSupport = TRUE;
return bSupport;
}
void HDMITX_SetOutputColorDepth(int ColorDepth){
SetOutputColorDepthPhase(ColorDepth, 0);
}
bool HDMITX_DevLoopProc()
{
static BYTE PreHPDChange = 0;
static BYTE PreHPD = 0;
BYTE HPD, HPDChange ;
// Richard CheckHDMI(&HPD,&HPDChange) ;
CheckHDMITX(&HPD,&HPDChange) ;
if (HPD == PreHPD && HPDChange) // richard add
return FALSE;
TX_HDP = HPD;
PreHPD = HPD;
PreHPDChange = HPDChange;
if( HPDChange )
{
OS_PRINTF("HPDChange\n");
if( HPD )
{
OS_PRINTF("HPD=ON\n");
RxCapability.Valid = ParseEDID() ;
//bOutputColorMode = F_MODE_YUV444; //F_MODE_RGB444; // richard node. users can change color space here according to HDMI sink
if( RxCapability.Valid && RxCapability.ValidHDMI )
{
OS_PRINTF("HDMI Display found\n");
bHDMIMode = TRUE ;
if(RxCapability.VideoMode & (1<<6))
{
bAudioEnable = TRUE ;
}
#if 0 // richard, don't care edid, the output always RGB444
if( RxCapability.VideoMode & (1<<5))
{
bOutputColorMode &= ~F_MODE_CLRMOD_MASK ;
bOutputColorMode |= F_MODE_YUV444;
}
else if (RxCapability.VideoMode & (1<<4))
{
bOutputColorMode &= ~F_MODE_CLRMOD_MASK ;
bOutputColorMode |= F_MODE_YUV422 ;
}
#endif
}
else if (!RxCapability.Valid)
{
OS_PRINTF("Failed to read EDID\n");
// enable it when edid fail
bHDMIMode = TRUE ;
bAudioEnable = TRUE ;
}
else
{
OS_PRINTF("Invalid HDMI Display\n");
bHDMIMode = FALSE ;
bAudioEnable = FALSE ;
}
OS_PRINTF("HDMITX_SetOutput\n");
//HDMITX_SetOutput() ;
}
else
{
OS_PRINTF("HPD=OFF\n");
// unplug mode, ...
OS_PRINTF("DisableVideoOutput\n");
//DisableVideoOutput() ;
RxCapability.Valid = FALSE; // richard add
RxCapability.ValidHDMI = FALSE; // richard add
RxCapability.ValidCEA = FALSE; // richard add
}
}
else // no stable but need to process mode change procedure
{
if(bChangeMode && HPD)
{
OS_PRINTF("HDMITX_SetOutput\n");
HDMITX_SetOutput() ;
}
}
return HPDChange;
}
void HDMITX_SetAudioInfoFrame(BYTE bAudioDwSampling)
{
Audio_InfoFrame AudioInfo;
AudioInfo.info.Type = AUDIO_INFOFRAME_TYPE;
AudioInfo.info.Ver = AUDIO_INFOFRAME_VER;
AudioInfo.info.Len = AUDIO_INFOFRAME_LEN;
AudioInfo.info.AudioChannelCount = 1; // 2 channels
AudioInfo.info.AudioCodingType = 1; // PCM
AudioInfo.info.SampleSize = 3; // 24bit
AudioInfo.info.SampleFreq = bAudioDwSampling ? 3 : 5; //48kHz or 96kHz
AudioInfo.info.SpeakerPlacement = 0; // Front left and front right
AudioInfo.info.LevelShiftValue = 0;
AudioInfo.info.DM_INH = 0; // Down-mix Inhibit Flag; 0=Permitted or no information about any assertion of this
EnableAudioInfoFrame(TRUE, (BYTE *) &AudioInfo);
}