mirror of
https://github.com/marqs85/ossc.git
synced 2024-11-18 14:06:03 +00:00
197 lines
5.7 KiB
C
197 lines
5.7 KiB
C
#include "hdmitx.h"
|
|
#include "edid.h"
|
|
|
|
#ifdef SUPPORT_EDID
|
|
static SYS_STATUS EDIDCheckSum(BYTE *pEDID) ;
|
|
|
|
static SYS_STATUS
|
|
EDIDCheckSum(BYTE *pEDID)
|
|
{
|
|
BYTE CheckSum ;
|
|
int i ;
|
|
|
|
if( !pEDID )
|
|
{
|
|
return ER_FAIL ;
|
|
}
|
|
for( i = 0, CheckSum = 0 ; i < 128 ; i++ )
|
|
{
|
|
CheckSum += pEDID[i] ; CheckSum &= 0xFF ;
|
|
}
|
|
|
|
return (CheckSum == 0)?ER_SUCCESS:ER_FAIL ;
|
|
}
|
|
|
|
SYS_STATUS
|
|
ParseVESAEDID(BYTE *pEDID)
|
|
{
|
|
if( ER_SUCCESS != EDIDCheckSum(pEDID) ) return ER_FAIL ;
|
|
|
|
if( pEDID[0] != 0 ||
|
|
pEDID[7] != 0 ||
|
|
pEDID[1] != 0xFF ||
|
|
pEDID[2] != 0xFF ||
|
|
pEDID[3] != 0xFF ||
|
|
pEDID[4] != 0xFF ||
|
|
pEDID[5] != 0xFF ||
|
|
pEDID[6] != 0xFF )
|
|
{
|
|
return ER_FAIL ; // not a EDID 1.3 standard block.
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////
|
|
// if need to parse EDID property , put here.
|
|
/////////////////////////////////////////////////////////
|
|
|
|
return ER_SUCCESS ;
|
|
|
|
}
|
|
|
|
SYS_STATUS
|
|
ParseCEAEDID(BYTE *pCEAEDID, RX_CAP *pRxCap)
|
|
{
|
|
BYTE offset,End ;
|
|
BYTE count ;
|
|
BYTE tag ;
|
|
int i ;
|
|
|
|
if( !pCEAEDID || !pRxCap ) return ER_FAIL ;
|
|
|
|
pRxCap->ValidCEA = FALSE ;
|
|
|
|
if( ER_SUCCESS != EDIDCheckSum(pCEAEDID) ) return ER_FAIL ;
|
|
|
|
if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) return ER_SUCCESS ; // not a CEA BLOCK.
|
|
End = pCEAEDID[2] ; // CEA description.
|
|
pRxCap->VideoMode = pCEAEDID[3] ;
|
|
|
|
if (pRxCap->VideoMode & CEA_SUPPORT_YUV444)
|
|
OS_PRINTF("Support Color: YUV444\n");
|
|
if (pRxCap->VideoMode & CEA_SUPPORT_YUV422)
|
|
OS_PRINTF("Support Color: YUV422\n");
|
|
|
|
for( offset = 0 ; offset < 0x80 ; offset ++ )
|
|
{
|
|
if( (offset % 0x10) == 0 )
|
|
{
|
|
ErrorF("[%02X]", offset ) ;
|
|
}
|
|
else if((offset%0x10)==0x08)
|
|
{
|
|
ErrorF( " -" ) ;
|
|
}
|
|
ErrorF(" %02X",pCEAEDID[offset]) ;
|
|
if((offset%0x10)==0x0f)
|
|
{
|
|
ErrorF("\n") ;
|
|
}
|
|
}
|
|
|
|
pRxCap->VDOModeCount = 0 ;
|
|
pRxCap->idxNativeVDOMode = 0xff ;
|
|
for( offset = 4 ; offset < End ; )
|
|
{
|
|
tag = pCEAEDID[offset] >> 5 ;
|
|
count = pCEAEDID[offset] & 0x1f ;
|
|
switch( tag )
|
|
{
|
|
case 0x01: // Audio Data Block ;
|
|
pRxCap->AUDDesCount = count/3 ;
|
|
offset++ ;
|
|
for( i = 0 ; i < pRxCap->AUDDesCount ; i++ )
|
|
{
|
|
pRxCap->AUDDes[i].uc[0] = pCEAEDID[offset++] ;
|
|
pRxCap->AUDDes[i].uc[1] = pCEAEDID[offset++] ;
|
|
pRxCap->AUDDes[i].uc[2] = pCEAEDID[offset++] ;
|
|
|
|
}
|
|
|
|
break ;
|
|
|
|
case 0x02: // Video Data Block ;
|
|
//pRxCap->VDOModeCount = 0 ;
|
|
offset ++ ;
|
|
for( i = 0,pRxCap->idxNativeVDOMode = 0xff ; i < count ; i++, offset++ )
|
|
{
|
|
BYTE VIC ;
|
|
VIC = pCEAEDID[offset] & (~0x80) ;
|
|
OS_PRINTF("HDMI Sink VIC(Video Identify Code)=%d\n", VIC);
|
|
// if( FindModeTableEntryByVIC(VIC) != -1 )
|
|
{
|
|
pRxCap->VDOMode[pRxCap->VDOModeCount] = VIC ;
|
|
if( pCEAEDID[offset] & 0x80 )
|
|
{
|
|
pRxCap->idxNativeVDOMode = (BYTE)pRxCap->VDOModeCount ;
|
|
// iVideoModeSelect = pRxCap->VDOModeCount ;
|
|
}
|
|
|
|
pRxCap->VDOModeCount++ ;
|
|
}
|
|
}
|
|
break ;
|
|
case 0x03: // Vendor Specific Data Block ;
|
|
offset ++ ;
|
|
pRxCap->IEEEOUI = (ULONG)pCEAEDID[offset+2] ;
|
|
pRxCap->IEEEOUI <<= 8 ;
|
|
pRxCap->IEEEOUI += (ULONG)pCEAEDID[offset+1] ;
|
|
pRxCap->IEEEOUI <<= 8 ;
|
|
pRxCap->IEEEOUI += (ULONG)pCEAEDID[offset] ;
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// For HDMI 1.3 extension handling.
|
|
///////////////////////////////////////////////////////////
|
|
|
|
pRxCap->dc.uc = 0 ;
|
|
pRxCap->MaxTMDSClock = 0 ;
|
|
pRxCap->lsupport.uc = 0 ;
|
|
pRxCap->ValidHDMI = (pRxCap->IEEEOUI==HDMI_IEEEOUI)? TRUE:FALSE ;
|
|
if( (pRxCap->ValidHDMI) && (count > 5 ))
|
|
{
|
|
// HDMI 1.3 extension
|
|
pRxCap->dc.uc = pCEAEDID[offset+5] ;
|
|
pRxCap->MaxTMDSClock = pCEAEDID[offset+6] ;
|
|
pRxCap->lsupport.uc = pCEAEDID[offset+7] ;
|
|
|
|
if(pRxCap->lsupport.info.Latency_Present)
|
|
{
|
|
pRxCap->V_Latency = pCEAEDID[offset+9] ;
|
|
pRxCap->A_Latency = pCEAEDID[offset+10] ;
|
|
}
|
|
|
|
if(pRxCap->lsupport.info.I_Latency_Present)
|
|
{
|
|
pRxCap->V_I_Latency = pCEAEDID[offset+11] ;
|
|
pRxCap->A_I_Latency = pCEAEDID[offset+12] ;
|
|
}
|
|
|
|
}
|
|
|
|
offset += count ; // ignore the remaind.
|
|
break ;
|
|
|
|
case 0x04: // Speaker Data Block ;
|
|
offset ++ ;
|
|
pRxCap->SpeakerAllocBlk.uc[0] = pCEAEDID[offset] ;
|
|
pRxCap->SpeakerAllocBlk.uc[1] = pCEAEDID[offset+1] ;
|
|
pRxCap->SpeakerAllocBlk.uc[2] = pCEAEDID[offset+2] ;
|
|
offset += 3 ;
|
|
break ;
|
|
case 0x05: // VESA Data Block ;
|
|
offset += count+1 ;
|
|
break ;
|
|
case 0x07: // Extended Data Block ;
|
|
offset += count+1 ; //ignore
|
|
break ;
|
|
default:
|
|
offset += count+1 ; // ignore
|
|
}
|
|
}
|
|
|
|
pRxCap->ValidCEA = TRUE ;
|
|
return ER_SUCCESS ;
|
|
}
|
|
|
|
|
|
|
|
#endif // SUPPORT_EDID
|