📄 dvi_hdmi.c.070605.int
字号:
DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0xD0, 0);
}
break;
//~jjtseng 07/01/02
default:
if (HDMI) { // attempt to enable HDMI mode on DVI chipset
if (! manutest) fprintf(stderr, "[HDMI] ERROR: Can not enable HDMI mode on DVI chipset!\n");
return RM_ERROR;
}
break;
}
return RM_OK;
}
RMstatus DHSetEDIDMode(struct DH_control *pDH,
enum DH_EDID_select EDID_select,
RMuint32 EDID_selection, // preferred entry in VIC table
RMuint32 EDID_vfreq, // preferred vsync frequency (50, 59, 60 etc.)
RMuint32 EDID_hsize, // preferred horizontal active size
RMuint32 EDID_vsize, // preferred vertical active size
RMbool EDID_intl) // preferred interlaced (TRUE) / progressive (FALSE) mode
{
CHECK_pDH("DHSetEDIDMode");
pDH->EDID_select = EDID_select;
pDH->EDID_selection = EDID_selection;
pDH->EDID_vfreq = EDID_vfreq;
pDH->EDID_hsize = EDID_hsize;
pDH->EDID_vsize = EDID_vsize;
pDH->EDID_intl = EDID_intl;
// TODO adjust video mode, if changed
return RM_OK;
}
RMstatus DHSetEDIDForceMask(struct DH_control *pDH,
RMuint64 EDID_force_mask) // try these VICs first (bit 1 = VIC 1, bit 2 = VIC 2 etc.)
{
CHECK_pDH("DHSetEDIDForceMask");
pDH->EDID_force_mask = EDID_force_mask;
return RM_OK;
}
RMstatus DHSetEDIDExcludeMask(struct DH_control *pDH,
RMuint64 EDID_exclude_mask) // never use these VICs
{
CHECK_pDH("DHSetEDIDExcludeMask");
pDH->EDID_exclude_mask = EDID_exclude_mask;
return RM_OK;
}
RMstatus DHSetEDIDFrequencyLimits(struct DH_control *pDH,
RMuint32 EDID_max_pixclk,
RMuint32 EDID_min_pixclk,
RMuint32 EDID_max_hfreq,
RMuint32 EDID_min_hfreq,
RMuint32 EDID_max_vfreq,
RMuint32 EDID_min_vfreq)
{
CHECK_pDH("DHSetEDIDFrequencyLimits");
pDH->EDID_max_pixclk = EDID_max_pixclk;
pDH->EDID_min_pixclk = EDID_min_pixclk;
pDH->EDID_max_hfreq = EDID_max_hfreq;
pDH->EDID_min_hfreq = EDID_min_hfreq;
pDH->EDID_max_vfreq = EDID_max_vfreq;
pDH->EDID_min_vfreq = EDID_min_vfreq;
return RM_OK;
}
static RMstatus DHGetInfoFrameEnable(struct DH_control *pDH, RMuint32 *info_frame_enable)
{
RMstatus err;
RMuint8 reg;
err = DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx2), 0x3E, ®);
if (RMFAILED(err)) {
reg = pDH->info_frame_enable & 0xFF;
} else {
if (reg & 0x01) reg |= 0x02; else reg &= ~0x02;
if (reg & 0x04) reg |= 0x08; else reg &= ~0x08;
if (reg & 0x10) reg |= 0x20; else reg &= ~0x20;
if (reg & 0x40) reg |= 0x80; else reg &= ~0x80;
}
*info_frame_enable = reg;
err = DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx2), 0x3F, ®);
if (RMFAILED(err)) {
reg = (pDH->info_frame_enable >> 8) & 0xFF;
} else {
if (reg & 0x01) reg |= 0x02; else reg &= ~0x02;
if (reg & 0x04) reg |= 0x08; else reg &= ~0x08;
if (reg & 0x10) reg |= 0x20; else reg &= ~0x20;
}
*info_frame_enable |= (reg << 8);
return RM_OK;
}
static RMstatus DHSetInfoFrameEnable(struct DH_control *pDH, RMuint32 mask)
{
RMstatus err, err1, err2;
RMuint32 info_frame_enable;
//err = DHGetInfoFrameEnable(pDH, &info_frame_enable);
info_frame_enable = pDH->info_frame_enable;
info_frame_enable |= mask;
pDH->info_frame_enable = info_frame_enable;
err1 = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx2), 0x3E, info_frame_enable & 0xFF);
err2 = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx2), 0x3F, (info_frame_enable >> 8) & 0xFF);
if (mask & 0x00FF) err = err1;
else if (mask & 0xFF00) err = err2;
else err = RM_OK;
if (RMSUCCEEDED(err)) RMDBGLOG((LOCALDBG, "info_frame_enable now 0x%04X\n", info_frame_enable));
else RMDBGLOG((ENABLE, "Failed to write info_frame_enable!\n"));
return err;
}
static RMstatus DHClearInfoFrameEnable(struct DH_control *pDH, RMuint32 mask)
{
RMstatus err, err1, err2;
RMuint32 info_frame_enable;
//err = DHGetInfoFrameEnable(pDH, &info_frame_enable);
info_frame_enable = pDH->info_frame_enable;
info_frame_enable &= ~mask;
pDH->info_frame_enable = info_frame_enable;
err1 = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx2), 0x3E, info_frame_enable & 0xFF);
err2 = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx2), 0x3F, (info_frame_enable >> 8) & 0xFF);
if (mask & 0x00FF) err = err1;
else if (mask & 0xFF00) err = err2;
else err = RM_OK;
if (RMSUCCEEDED(err)) RMDBGLOG((LOCALDBG, "info_frame_enable now 0x%04X\n", info_frame_enable));
else RMDBGLOG((ENABLE, "Failed to write info_frame_enable!\n"));
return err;
}
RMstatus DHGetState(struct DH_control *pDH,
enum DH_device_state *pDevState,
enum DH_connection *pConnection)
{
CHECK_pDH("DHGetState");
if (pDevState != NULL) *pDevState = pDH->state;
if (pConnection != NULL) *pConnection = pDH->cable;
return RM_OK;
}
// 2007/01/02 added by jj_tseng@chipadvanced.com [CAT6611]
static RMstatus
DHAbortDDC_cat6611(struct DH_control *pDH)
{
RMuint8 data;
int count ;
RMDBGLOG((ENABLE,"DHAbortDDC_cat6611()\n")) ;
DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0x16, &data) ;
if((data & 0xA8) ==0x80)
{
RMDBGLOG((ENABLE,"reg0x16 = 0x%02X, no need to abort.\n",data)) ;
return RM_OK ;
}
DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0x10, &data) ;
if( (data & 1 ) == 0 )
{
RMDBGLOG((ENABLE,"DDC master is HDCP Tx core.\n",data)) ;
DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0x04, &data) ;
data |= 1 ; // hdcp reset
DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x04, data) ;
}
DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x10, 1) ;
DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x15, 0xF) ; // abort DDC command
for( count = 0 ; count < 100 ; count++ )
{
RMMicroSecondSleep(20*1000);
DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0x16, &data) ;
RMDBGLOG((ENABLE,"DDC master is HDCP Tx core. %dth reg16=%x\n",count,data)) ;
if( (data & 0xA8) == 0x80 )
{
DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0x15, &data) ;
if( (data & 0xC0) == 0xC0 )
{
return RM_OK ;
}
else
{
RMDBGLOG((ENABLE,"reg15 value %d is not available.\n",data)) ;
}
}
}
return RM_ERROR ;
}
static RMstatus
DHSoftReset_cat6611(struct DH_control *pDH)
{
RMstatus err = RM_OK ;
DH_Switch_6611BANK(pDH, 0) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x04, 0x3D) ;
RMMicroSecondSleep(1000);
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x04, 0x1D) ; // reset RCLK, but still reset other registers.
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x61, 0x30) ; // reset PLL and Power down.
return err ;
}
static RMstatus
DHSetAFE_cat6611(struct DH_control *pDH, RMbool bHighFreq)
{
RMstatus err = RM_OK ;
if( !pDH )
{
return RM_INVALID_PARAMETER ;
}
DH_Switch_6611BANK(pDH, 0) ;
if( bHighFreq )
{
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x62, 0x88) ; // if 1080p, AFE should set as 0x88, however, need to check how to identify the mode.
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x63, 0x01) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x64, 0x56) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x65, 0x00) ;
}
else
{
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x62, 0x18) ; // if 1080p, AFE should set as 0x88, however, need to check how to identify the mode.
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x63, 0x01) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x64, 0x1E) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x65, 0x00) ;
}
return err;
}
static RMstatus
DHFireAFE_cat6611(struct DH_control *pDH)
{
RMstatus err = RM_OK ;
if( !pDH )
{
return RM_INVALID_PARAMETER ;
}
DH_Switch_6611BANK(pDH, 0) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x61, 0x4) ; // if 1080p, AFE should set as 0x88, however, need to check how to identify the mode.
return err;
}
// 2007/03/08 added by jj_tseng@chipadvanced.com
static RMstatus DHSetIntMask_cat6611(struct DH_control *pDH)
{
RMstatus err = RM_OK;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x09, 0) ; // get HPD status
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x0A, 0xF8) ; // KSVListChkMask | AuthDonMask | AuthFailMask
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x0B, 0xF7) ; // VidStable
return err ;
}
//~jj_tseng@chipadvanced.com
static RMstatus DHInitChip_cat6611(struct DH_control *pDH)
{
RMstatus err = RM_OK;
err = DHSoftReset_cat6611(pDH) ;
// Set interrupt mask to get status from interrupt status registers
// 2007/03/08 modified by jj_tseng@chipadvanced.com
// err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x09, 0) ; // get HPD status
// err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x0A, 0xF8) ; // KSVListChkMask | AuthDonMask | AuthFailMask
// err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x0B, 0xF7) ; // VidStable
err = DHSetIntMask_cat6611(pDH) ;
//~jj_tseng@chipadvanced.com
return err ;
}
static RMstatus
DHEnableHDMIOutput_cat6611(struct DH_control *pDH, RMbool bHDMI)
{
RMstatus err ;
DH_Switch_6611BANK(pDH, 0) ;
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0xC0, (bHDMI)?1:0);
return err ;
}
// DHEnable_cat6611() should do after DHInitChip_cat6611()
static RMstatus DHEnable_cat6611(struct DH_control *pDH)
{
RMstatus err = RM_OK;
RMuint8 data;
RMDBGLOG((ENABLE, "Enable CAT 6611 DVI output, %s\n", RMstatusToString(err)));
// err = DHSoftReset_cat6611(pDH) ;
// AFE clocl control registers setting.
err = DHSetAFE_cat6611(pDH, (pDH->VideoPixelClock>=80000000)) ;
// Set interrupt mask to get status from interrupt status registers
// 2007/03/08 modified by jj_tseng@chipadvanced.com
// err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x09, 0xff) ; // get HPD status
// err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x0A, 0xff) ; // KSVListChkMask | AuthDonMask | AuthFailMask
// err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x0B, 0xff) ; // VidStable
err = DHSetIntMask_cat6611(pDH) ;
//~jj_tseng@chipadvanced.com
DHEnableHDMIOutput_cat6611(pDH, pDH->HDMI_mode) ;
// enable packet
// enable Video out
err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0x04, 0x07) ; // enable video on
DH_Clear_cat6611_AVMute(pDH);
RMMicroSecondSleep(10000);
DH_i2c_read(pDH->pRUA,&(pDH->i2c_tx),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -