//================================================================================================= // Header files area. //================================================================================================= #include "adc_global.h" #include "adc_inittbl.h" #include "adc_333.h" //================================================================================================= // Internal variables area. //================================================================================================= #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) struct semaphore adc_ioctl_semaphore; #endif struct cdev *cdev_adc; struct timer_list ADCtimer; ADC_CONTEXT ADCContext; AdcInfo sAdcInfo; VIP_InterfaceKIC sSendInfo,*psSendInfo; VesaTiming ADC_InputVesaTiming, ADC_DetectTiming; ADCCalibrate_OSDGainOffset_t ADCCalibrate_OSDGainOffset; #ifdef DRV_ENABLE_CVD2 UINT8 ucCVD2PowerEnable=FALSE; #endif adc_ap_data gAdcAp; BOOL bDisablePCAutoAdjust = FALSE; UINT8 uc_reset_ADI_Lock[1] = {0}; wait_queue_head_t reset_ADI_wait[1]; INT32 iEnlargeWidthRate=1; UINT8 ucBestLocation=0, ucCompareTimes, ucComparethd; LONG lPhase2[32]; UINT8 static ucBestPhase[32]; UINT8 static ucBestPhaseIndex=0; BOOL bAutoAdjust = FALSE, bCheckVIPHttl = FALSE, bAutoColorCalibrationDone =FALSE; UINT8 ucLastInputMode=0xf; static stADCTimingTable g_stADCTimingTbl; InputVideoConf_st adc_InputSrcPin; UINT16 usVIPHttlMax = 0, usVIPHttlMin = 0; FirstTimeSearchGain Source[5]; BOOL bAutoWB = FALSE; BOOL FactoryModeAWB = FALSE; UINT8 SMT_mergin = 0; //workqueue static void ADC_SyncDetection(void *); static struct workqueue_struct *pADC_WQSyncDetection; static DECLARE_DELAYED_WORK(ADCSyncDetectionThread, (void*)&ADC_SyncDetection); static void ADC_InterruptProcess(void *); static struct workqueue_struct *pADC_WQInterruptProcess; static DECLARE_DELAYED_WORK(ADCInterruptProcessThread, (void*)&ADC_InterruptProcess); static void ADC_TunerStrength(void *); static struct workqueue_struct *pADC_WQTunerStrength; static DECLARE_DELAYED_WORK(ADCTunerStrengthThread, (void*)&ADC_TunerStrength); extern void VIP_ADIReset(void); extern void VIP_ResetADIEnable(void); extern INT32 GetCustomerData(INT8 *pcTableName, INT8 **tablestart, UINT32 *tablesize); #ifndef INIT_BY_KMF INT32 __init DRV_ADC_Linuxinit(void); void __exit DRV_ADC_Linuxexit(void); #endif UINT32 ADCTimerInfo[][2]= { {TimerVsyncloss, 0}, {TimerSignaloff, 0}, {TimerModeChange, 0}, {TimerTunerStrength, 0}, }; //================================================================================================= // Internal function definition area //================================================================================================= static inline void ADC_StartTimerFun(PADC_CONTEXT pADCContext, void *func) { init_timer(&ADCtimer); ADCtimer.expires = jiffies + HZ/512; ADCtimer.data = (ULONG)pADCContext; ADCtimer.function = (void (*)(ULONG))func; add_timer(&ADCtimer); sAdcInfo.bTimerHandlerBusy = FALSE; } static inline void ADC_RestartTimerFun(PADC_CONTEXT pADCContext) { mod_timer(&ADCtimer, jiffies + HZ/512); } static __inline__ void ADC_StopTimerFun(PADC_CONTEXT pADCContext) { del_timer_sync(&ADCtimer); } void ADC_DelayMS(UINT32 ulDelayMS ) { if( in_interrupt() || in_irq() ) mdelay(ulDelayMS); else msleep(ulDelayMS); } static void ADC_TunerStrength(void *unuse) { #ifdef DRV_ENABLE_TUNER UINT8 ucStrength = 0; ADC_DelayMS(1000); DRV_FrontendCtrl(FRONTEND_CMD_GET_SIGNAL_STRENGTH,&ucStrength); if( ucStrength == 0) { DRV_CVD2_Enable_CVBSO_Gain( FALSE ); } else { DRV_CVD2_Enable_CVBSO_Gain( TRUE ); } #endif } static void ADC_TimerFun(PADC_CONTEXT pADCContext) { static UINT8 ucPollingHcntVcnt = 0; static BOOL bScreenMode = FALSE; volatile UINT16 usVIPHttl=0, usVIPVcnt=0; if( ADC_Read(ADC_REG_dbg_temp)& BIT0 ) { // ADC_DebugMsg("Skip TimerFun\n"); ADC_RestartTimerFun(pADCContext); return; } if(ADCTimerInfo[TimerVsyncloss][1] == 1) { if(ADC_Read(ADC_STA_vs_active) == 0) { if( !(sAdcInfo.bInterruptHappen || sAdcInfo.bInterruptHappenAgain || sAdcInfo.bModeDetection || sAdcInfo.bModeChange )) { ADC_SyncDetectCreate(); ADCTimerInfo[TimerVsyncloss][1] = 0; } } } if(ADCTimerInfo[TimerSignaloff][1] == 1) { ADC_Write(ADC_REG_cs2_sog_rst, 0x3); ADC_Write(ADC_REG_cs2_sog_rst, 0x0); ADCTimerInfo[TimerSignaloff][1] = 0; } if( sAdcInfo.bAutoGain && ( (abs(sAdcInfo.ucRegLowWidth - ADC_Read(ADC_STA_low_wdth) ) < 10) && (abs(sAdcInfo.ucRegLineWidth - ADC_Read(ADC_STA_line_wdth) ) < 20) ) ) { // ADC_DebugMsg("[pass] Mode change \n"); // ADC_DebugMsg(" Low = 0x%x, mLow = 0x%x, Line = 0x%x, mLine = 0x%x \n\n", // ADC_Read(ADC_STA_low_wdth), ADC_Read(ADC_STA_mlow_wdth), // ADC_Read(ADC_STA_line_wdth), ADC_Read(ADC_STA_mline_wdth) ); } else if(ADCTimerInfo[TimerModeChange][1] == 1) { usVIPHttl = *((volatile UINT16*)(0xbe1cf010)); usVIPVcnt = *((volatile UINT16*)(0xbe1cf014)); if( sAdcInfo.ucSource != Adc_kSourceVGA ) { if(abs(sAdcInfo.usHcount - usVIPHttl) > (sAdcInfo.usHcountModeChange+10)|| abs(sAdcInfo.usVcount - usVIPVcnt) > sAdcInfo.usVcountModeChange) { if( (SMT_mergin == 0) && ( (sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_480I60)||(sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_576I50) || (sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_480P60)||(sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_576P50) ) ) { sAdcInfo.ucInputMode = UNSTABLE_MODE; sAdcInfo.bModeChange = TRUE; ADC_SyncDetectCreate(); ADCTimerInfo[TimerModeChange][1] = 0; ucPollingHcntVcnt = 0; bScreenMode = FALSE; SMT_mergin = sAdcInfo.ucTimingModeIndex & 0xff; printk(KERN_EMERG " #### <0x%x> Ignore [0] Mode change & Set SMT = 0x%x\n", SMT_mergin, ADC_Read(ADC_REG_sog_smthr12v)); } else { if(abs(sAdcInfo.usHcount - usVIPHttl) > (sAdcInfo.usHcountModeChange+20)) { printk(KERN_EMERG "[0] Mode change \n"); printk(KERN_EMERG "AdcInfo: Hcount=%d, Vcount=%d\n", sAdcInfo.usHcount, sAdcInfo.usVcount); printk(KERN_EMERG "VIPHttl=%d, VIPVcnt=%d\n", usVIPHttl, usVIPVcnt); sAdcInfo.ucInputMode = UNSTABLE_MODE; sAdcInfo.bModeChange = TRUE; ADC_SyncDetectCreate(); ADCTimerInfo[TimerModeChange][1] = 0; ucPollingHcntVcnt = 0; bScreenMode = FALSE; } else if((sAdcInfo.ucScreenMode == NormalScreen) && (bScreenMode == FALSE)) { printk(KERN_EMERG "AdcInfo: Hcount=%d, Vcount=%d\n", sAdcInfo.usHcount, sAdcInfo.usVcount); printk(KERN_EMERG "VIPHttl=%d, VIPVcnt=%d\n", usVIPHttl, usVIPVcnt); ADC_ScreenMode(BlackScreen); bScreenMode = TRUE; } SMT_mergin = 0; } ucPollingHcntVcnt++; if(ucPollingHcntVcnt == 3) { printk(KERN_EMERG "[1] Mode change \n"); printk(KERN_EMERG "AdcInfo: Hcount=%d, Vcount=%d\n", sAdcInfo.usHcount, sAdcInfo.usVcount); printk(KERN_EMERG "VIPHttl=%d, VIPVcnt=%d\n", usVIPHttl, usVIPVcnt); sAdcInfo.ucInputMode = UNSTABLE_MODE; sAdcInfo.bModeChange = TRUE; ADC_SyncDetectCreate(); ADCTimerInfo[TimerModeChange][1] = 0; ucPollingHcntVcnt = 0; bScreenMode = FALSE; } } else { if(ucPollingHcntVcnt > 0) { if((sAdcInfo.ucScreenMode == BlackScreen) && (bScreenMode == TRUE)&&(bAutoColorCalibrationDone== TRUE)) { ADC_ScreenMode(NormalScreen); bScreenMode = FALSE; } ucPollingHcntVcnt--; } } } } if(ADCTimerInfo[TimerTunerStrength][1] == 1) queue_delayed_work(pADC_WQTunerStrength, &ADCTunerStrengthThread, 0); if (bCheckVIPHttl == TRUE) { usVIPHttl = *((volatile UINT16*)(0xbe1cf008)); if (usVIPHttl > usVIPHttlMax) usVIPHttlMax = usVIPHttl; else if (usVIPHttl < usVIPHttlMin) usVIPHttlMin = usVIPHttl; if ((usVIPHttlMax - usVIPHttlMin) > 0) { if(ucBestPhaseIndex<5) { // Find the phase with high ranking from the list, and the neighboring of current phase would be excluded. for(ucBestPhaseIndex = 0; ucBestPhaseIndex < 5; ucBestPhaseIndex++) { if( abs(sAdcInfo.ucUserPhase - ucBestPhase[ucBestPhaseIndex]) > 1 && abs(sAdcInfo.ucUserPhase - ucBestPhase[ucBestPhaseIndex]) < 31 ) { sAdcInfo.ucUserPhase = ucBestPhase[ucBestPhaseIndex]; break; } } } else { sAdcInfo.ucUserPhase = ucBestPhase[0]; } ADC_SetPhaseDirdect(sAdcInfo.ucUserPhase); ADC_ResetADI_Unlock(); printk(KERN_EMERG" ===== VIPHttl issue, No. %d phase value would be adopted ===== \n", ucBestPhaseIndex + 1 ); printk(KERN_EMERG" ===== VIPHttlMin = %d, VIPHttlMax = %d, Best phase = %d ===== \n", usVIPHttlMin, usVIPHttlMax, sAdcInfo.ucUserPhase); bCheckVIPHttl = FALSE; } } ADC_RestartTimerFun(pADCContext); } UINT32 ADC_Read(UINT32 uiAdr) { UINT32 uiStartBit=31,uiEndBit=0,uiLeftSpaceBits,uiMask=0xffffffff; UINT32 uiADCAdr, uiADCDat=0; UINT8 ucByteMask=0xff; if( (*(UINT8*)(0xbe000180)&BIT2) ) { printk(KERN_EMERG "MMIO_R_Err\n"); return 0; } uiADCAdr = uiAdr & 0xffff; switch( uiAdr >> 28 ) { case 0: uiADCAdr |= MMIOAddrADC; break; case 1: uiADCAdr |= 0xbe000000; break; default: printk(KERN_EMERG "MMIO_W_Err\n"); return 0; } if( (uiAdr&0x03ff0000)==0x03e00000 ) // one dword write { uiADCDat=readl((UINT32*)uiADCAdr); } else // bits write { uiStartBit = (uiAdr&0x001f0000)>>16; uiEndBit = (uiAdr&0x03e00000)>>21; if( (uiEndBit-uiStartBit)<8 ) { uiLeftSpaceBits = 7-uiEndBit; ucByteMask <<= uiLeftSpaceBits; ucByteMask >>= (uiLeftSpaceBits+uiStartBit); ucByteMask <<= uiStartBit; uiADCDat=readb((UINT8*)uiADCAdr) & ucByteMask; uiADCDat >>= uiStartBit; } else { uiADCAdr &= 0xfffffffc; uiStartBit += 8*(uiAdr&0x3); uiEndBit += 8*(uiAdr&0x3); uiLeftSpaceBits = 31-uiEndBit; uiMask <<= uiLeftSpaceBits; uiMask >>= (uiLeftSpaceBits+uiStartBit); uiMask <<= uiStartBit; uiADCDat=readl((UINT32*)uiADCAdr) & uiMask; uiADCDat >>= uiStartBit; } } return uiADCDat; } void ADC_Write(UINT32 uiAdr, UINT32 uiDat) { UINT32 uiStartBit=31,uiEndBit=0,uiLeftSpaceBits,uiMask=0xffffffff; UINT32 uiADCAdr, uiADCDat=0; UINT8 ucByteMask=0xff; if( (*(UINT8*)(0xbe000180)&BIT2) ) { printk(KERN_EMERG "MMIO_W_Err\n"); return; } uiADCAdr = uiAdr & 0xffff; switch( uiAdr >> 28 ) { case 0: uiADCAdr |= MMIOAddrADC; break; case 1: uiADCAdr |= 0xbe000000; break; default: printk(KERN_EMERG "MMIO_W_Err\n"); return; } if( (uiAdr&0x03ff0000)==0x03e00000 ) // one dword write { uiADCDat=uiDat; writel(uiADCDat, (UINT32*)uiADCAdr); } else // bits write { uiStartBit = (uiAdr & 0x001f0000)>>16; uiEndBit = (uiAdr & 0x03e00000)>>21; if( (uiEndBit-uiStartBit)<8 ) { uiLeftSpaceBits = 7-uiEndBit; ucByteMask <<= uiLeftSpaceBits; ucByteMask >>= (uiLeftSpaceBits+uiStartBit); ucByteMask <<= uiStartBit; uiDat <<= uiStartBit; uiADCDat=readb((UINT8*)uiADCAdr); uiADCDat &= (~ucByteMask); uiADCDat |= (uiDat&ucByteMask); writeb((uiADCDat&0xff), (UINT8*)uiADCAdr); } else { uiADCAdr &= 0xfffffffc; uiStartBit += 8*(uiAdr&0x3); uiEndBit += 8*(uiAdr&0x3); uiLeftSpaceBits = 31-uiEndBit; uiMask <<= uiLeftSpaceBits; uiMask >>= (uiLeftSpaceBits+uiStartBit); uiMask <<= uiStartBit; uiDat <<= uiStartBit; uiADCDat=readl((UINT32*)uiADCAdr); uiADCDat &= (~uiMask); uiADCDat |= (uiDat&uiMask); writel(uiADCDat, (UINT32*)uiADCAdr); } } } void print_meminfo(INT8 *msg) { #ifdef MemTest struct sysinfo i; #define K(x) ((x) << (PAGE_SHIFT - 10)) si_meminfo(&i); printk( KERN_INFO "MemTotal: %8lu kB\n" "MemFree: %8lu kB at point %s\n\n", K(i.totalram), K(i.freeram),msg ); #endif } UINT32 ADC_MClk(void) { UINT32 ulADC_MClk = 0; // ADC device clock ulADC_MClk= drv_get_device_clock(YPP200MCLK); ulADC_MClk = ulADC_MClk/1000 ; printk(KERN_EMERG" Clock YPP200M(%d) \n ", ulADC_MClk); return ulADC_MClk; } void ADC_NoticeKmf(INT32 msgType, BOOL bActive, BOOL bNotSupport) { InputPathStatus_t sInputPathStatus_t1={0}; switch(msgType) { case ADCMSG_INPUTPATHSTATUS: sInputPathStatus_t1.bActive=bActive; sInputPathStatus_t1.bNotSupport=bNotSupport; sInputPathStatus_t1.bSub=NULLOP; sInputPathStatus_t1.msgfromVIP = FALSE; sInputPathStatus_t1.path = (sAdcInfo.ucSource == Adc_kSourceVGA) ? INPUTPATH_PC : INPUTPATH_COMPONENT; noticekmf(KMF2UMF_EVID_DRV, KMF2UMF_EVTYPE_DRV_INFORM_SIGNALSTATUS, (UINT8*)&sInputPathStatus_t1, sizeof(InputPathStatus_t)); break; case NOTICEMSG_ADC_TURNOFFSOUND: noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_TURNOFFSOUND, &bActive, sizeof(BOOL)); break; } } void ADC_ResetAdcInfoSetting(void) { ADCTimerInfo[TimerVsyncloss][1] = 0; ADCTimerInfo[TimerSignaloff][1] = 0; ADCTimerInfo[TimerModeChange][1] = 0; ADCTimerInfo[TimerTunerStrength][1] = 0; sAdcInfo.bAutoGain = FALSE; sAdcInfo.bAutoOffset= FALSE; sAdcInfo.bReSearchGain= FALSE; sAdcInfo.bReSearchOffset= FALSE; sAdcInfo.usHcount = 0; sAdcInfo.usVcount = 0; sAdcInfo.ucSogThdHigh = 60; sAdcInfo.ucSogThdLow = 40; } void ADC_ResetApSetting(void) { gAdcAp.bAutoFlow = TRUE; gAdcAp.bApUse = FALSE; gAdcAp.bDisableInterrupt = FALSE; gAdcAp.ucMatchTable = 0; gAdcAp.ucColor = 0; gAdcAp.ulApPosition = 0; } void ADC_ScreenMode(UINT8 ucScreenMode) { if ( (ucLastInputMode == sAdcInfo.ucInputMode) && (ucScreenMode == sAdcInfo.ucScreenMode) ) return; switch(ucScreenMode) { case NormalScreen: if (sAdcInfo.ucInputMode == NOSIGNAL_MODE || sAdcInfo.ucInputMode == UNSUPPORT_MODE) return; ADC_DebugMsg("N_Screen\n"); VIP_UnmuteScreen(); break; case BlackScreen: ADC_DebugMsg("B_Screen\n"); VIP_MuteScreenDirectly(); //VIP_MuteScreen_ISR(); ADC_NoticeKmf(NOTICEMSG_ADC_TURNOFFSOUND, FALSE, FALSE); ADC_DebugMsg("TURN OFF SOUND...\n"); break; default: ucScreenMode = BlueScreen; ADC_NoticeKmf(ADCMSG_INPUTPATHSTATUS, FALSE, TRUE); ADC_DebugMsg("U_Screen\n"); break; } ucLastInputMode = sAdcInfo.ucInputMode; sAdcInfo.ucScreenMode = ucScreenMode; } INT32 DRV_ADC_power(INT32 bPowerOn) { static BOOL bADCPowerEnable = FALSE; if (bPowerOn == TRUE && bADCPowerEnable == FALSE) { drv_gated_clk_ctrl(GATED_F24MCLK_YPPADC, GATED_PASS_CLK); drv_gated_clk_ctrl(GATED_MMIOCLK_YPP, GATED_PASS_CLK); drv_gated_clk_ctrl(GATED_DVCLK_YPPADC, GATED_PASS_CLK); drv_gated_clk_ctrl(GATED_F24MCLK_ATV, GATED_PASS_CLK); DRV_ADC_YppShareBandGap_Power(TRUE); // 3d[0]=0 ADC_Write(ADC_REG_sch_pwdn_r,0); //59[2:0]=0x0 ADC_Write(ADC_REG_sch_pwdn_g,0); // ADC_Write(ADC_REG_sch_pwdn_b,0); // ADC_Write(ADC_REG_pll_rstn,1); //32[0]=1 ADC_Write(ADC_REG_pll_pwdn,1); //32[1]=1 ADC_Write(ADC_REG_lcg_pwdn,0); //50[0]=0 ADC_Write(ADC_REG_sog_pwdn,0); //6e[4]=0 //----------------------------------------- bADCPowerEnable = TRUE; } else if (bPowerOn == FALSE && bADCPowerEnable == TRUE) { //bandgap powerdown can't generate for LVDS&PLL current DRV_ADC_YppShareBandGap_Power(FALSE); // 3d[0]=1 ADC_Write(ADC_REG_sch_pwdn_r,1); //59[2:0]=0x7 ADC_Write(ADC_REG_sch_pwdn_g,1); // ADC_Write(ADC_REG_sch_pwdn_b,1); // ADC_Write(ADC_REG_pll_rstn,0); //32[0]=0 ADC_Write(ADC_REG_pll_pwdn,0); //32[1]=0 ADC_Write(ADC_REG_lcg_pwdn,1); //50[0]=1 ADC_Write(ADC_REG_sog_pwdn,1); //6e[4]=1 //----------------------------------------- //2011-04-19 add when CVD2 power off. ADC_Write(ADC_REG_CVBSO_PWD12 , 1); ADC_Write(ADC_REG_pwdny, 1); DRV_ADC_Pll_Divider_Power(FALSE); // 147[5] = 0 Power down dual loop divider drv_gated_clk_ctrl(GATED_F24MCLK_ATV, GATED_STOP_CLK); drv_gated_clk_ctrl(GATED_DVCLK_YPPADC, GATED_STOP_CLK); drv_gated_clk_ctrl(GATED_MMIOCLK_YPP, GATED_STOP_CLK); drv_gated_clk_ctrl(GATED_F24MCLK_YPPADC, GATED_STOP_CLK); bADCPowerEnable = FALSE; } else { ADC_DebugMsg("Recall ADC_Pwr\n"); } return TRUE; } EXPORT_SYMBOL(DRV_ADC_power); void ADC_SyncDetectCreate(void) { if(sAdcInfo.ucScreenMode == NormalScreen) ADC_ScreenMode(BlackScreen); if( sAdcInfo.bSyncDetection == FALSE) { sAdcInfo.bSyncDetection=TRUE; sAdcInfo.bModeDetection=TRUE; queue_delayed_work(pADC_WQSyncDetection, &ADCSyncDetectionThread, 0); } else if( sAdcInfo.bModeDetection==FALSE ) sAdcInfo.bModeChange = TRUE; } void ADC_StatusUpdate(void) { if(ADC_DetectTiming.usHFrequency != 0) sAdcInfo.usHcount= ( (CRYSTAL_CLK*1000/10)/ADC_DetectTiming.usHFrequency ) * SYS_CRYS_CLK_RATIO_PRECISE_3 /1000; else sAdcInfo.usHcount=0; sAdcInfo.usVcount=ADC_DetectTiming.usVcount; ADC_DebugMsg("AdcInfo: Hcount = %d, Vcount = %d\n",sAdcInfo.usHcount, sAdcInfo.usVcount); } void ADC_UpdateFlag(UINT8 ucFlag) { sAdcInfo.bVpol = (ucFlag & BIT1)? 1:0; sAdcInfo.bHpol = (ucFlag & BIT2)? 1:0; sAdcInfo.bInterlace = (ucFlag & BIT0)? 1:0; if( sAdcInfo.ucSource==Adc_kSourceVGA ) ADC_DetectTiming.ucFlag |= (0x10 << (ucFlag >> 1)); ADC_DebugMsg("AdcInfo: Hpol=%d Vpol=%d Interlace=%d\n",sAdcInfo.bHpol, sAdcInfo.bVpol, sAdcInfo.bInterlace); ADC_DebugMsg("DetTiming_Flag=0x%x\n", ADC_DetectTiming.ucFlag); } BOOL ADC_Frequency_Filter(void) { BOOL fRetValue = TRUE; if (sAdcInfo.ucSource == Adc_kSourceVGA) { if ((ADC_DetectTiming.ucVFrequency < 45) || (ADC_DetectTiming.ucVFrequency > 88)) { sAdcInfo.ucInputMode = UNSUPPORT_MODE; fRetValue = FALSE; } } else { if ((ADC_DetectTiming.ucVFrequency < 20) || (ADC_DetectTiming.ucVFrequency > 88)) { sAdcInfo.ucInputMode = UNSUPPORT_MODE; fRetValue = FALSE; } } if (fRetValue == FALSE) { ADC_DebugMsg("VsFreq unsupport\n"); // torlance 3 } return fRetValue; } BOOL ADC_NeedToCheckPolarity(void) { BOOL bMustCheckPolarity=FALSE; VesaTiming* VgaModeTable = g_stADCTimingTbl.pVgaVideoTimingTable; //640x350@70 conflict with 720x400@70 if ((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount == 449) && ((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+5)/10 == 315 ) && (VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency == 70)) bMustCheckPolarity=TRUE; //640x350@85 conflict with 720x400@85 or 640x400@85 if ((abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount-445)<2) && ((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+5)/10 == 379 ) && (VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency == 85)) bMustCheckPolarity=TRUE; //1024x768_80M conflict with 1280x768_102M or 1360x768_109M if ((abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount-805) < 2) && (abs((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+5)/10-603) < 2) && (VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency == 75)) bMustCheckPolarity=TRUE; //1920X1080@60 in chroma 22293 timing 261 conflict with timing 2001 if ( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount == 1125 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1920 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==1080 )) bMustCheckPolarity=TRUE; //640x480@75 conflict if ( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==640 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==480 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency==75) ) bMustCheckPolarity=TRUE; return bMustCheckPolarity; } BOOL ADC_NeedCheckVsyncWidth(void) { BOOL bMustCheckVsyncWidth=FALSE; VesaTiming* VgaModeTable = g_stADCTimingTbl.pVgaVideoTimingTable; //720x400@85 conflict with 640x400@85 if (( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==400 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency==85 )) bMustCheckVsyncWidth=TRUE; //1280x768 conflict with 1360x768 or 1366x768 if (( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1280 ) || ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1360 ) || ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1366 ) ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==768 )) bMustCheckVsyncWidth=TRUE; //1400X1050 conflict with 1680X1050 if (( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1400 ) || ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1680 ) ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==1050 )) bMustCheckVsyncWidth=TRUE; //1024x768@60 conflict with 1280x768@60 or 1360x768@60 if ((abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount-790) < 2) && (abs((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+5)/10-473) < 2) && (VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency == 60)) bMustCheckVsyncWidth=TRUE; //1024x768@85 conflict with 1280x768@85 or 1360x768@85 if ((abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount-808) < 2) && (abs((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+5)/10-686) < 2) && (VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency == 85)) bMustCheckVsyncWidth=TRUE; //1440X900@60 conflict with 1600X900@60 if (( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1600 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==900 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency==60) )|| ( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1440 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==900 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency==60) )) bMustCheckVsyncWidth=TRUE; //1280x768@75 conflict with 1024X768@75 if (( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1024 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==768 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency==75) )|| ( ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive==1280 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive==768 ) && ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency==75) )) bMustCheckVsyncWidth=TRUE; return bMustCheckVsyncWidth; } BOOL ADC_NeedCheckHsyncWidth(void) { BOOL bCheckHsyncWidth=TRUE; VesaTiming* VgaModeTable = g_stADCTimingTbl.pVgaVideoTimingTable; if ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1280x960x60) { //1280X960@60 conflict with 1600X900@60, check HsyncWidth if (sAdcInfo.usHsyncWidth < 165) bCheckHsyncWidth=FALSE; } else if ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1600x900x60) { //1600X900@60 conflict with 1280X960@60, check HsyncWidth if (sAdcInfo.usHsyncWidth >166) bCheckHsyncWidth=FALSE; } else if ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1280x1024x60) { //1280x1024@60 has different Htotal, check HsyncWidth if (sAdcInfo.usHsyncWidth >222) bCheckHsyncWidth=FALSE; } else if ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1280x1024x60B) { //1280x1024@60 has different Htotal, check HsyncWidth if (sAdcInfo.usHsyncWidth < 223) bCheckHsyncWidth=FALSE; } else if ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1680x1050x60) { //1680x1050@60 has different Htotal, check HsyncWidth if ((sAdcInfo.usHsyncWidth >243) && (sAdcInfo.ulVsyncWidth > 17500) ) bCheckHsyncWidth=FALSE; } else if ( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1680x1050x60B) { //1680x1050@60 has different Htotal, check HsyncWidth if ((sAdcInfo.usHsyncWidth < 244) && (sAdcInfo.ulVsyncWidth > 17501) ) bCheckHsyncWidth=FALSE; } if (bCheckHsyncWidth == FALSE) { ADC_DebugMsg("Different HsyncWidth, check the other timing \n"); } return bCheckHsyncWidth; } BOOL ADC_NeedCheckSwitchRef24M(void) { BOOL bSwitchToOSC = FALSE; VesaTiming* VgaModeTable = g_stADCTimingTbl.pVgaVideoTimingTable; switch( VgaModeTable[sAdcInfo.ucMatchTablePtr].ucADCTableIndex) { case PLF_VIDEO_TIMING_ID_640x350x70: case PLF_VIDEO_TIMING_ID_640x480x60: case PLF_VIDEO_TIMING_ID_800x600x75: case PLF_VIDEO_TIMING_ID_800x600x85: case PLF_VIDEO_TIMING_ID_848x480x60: case PLF_VIDEO_TIMING_ID_1680x1050x60_RB: // Switch CLK source to OSC directly for preventing water ripple interference bSwitchToOSC = TRUE; break; default: // Keep CLK source from CCPLL bSwitchToOSC = FALSE; break; } return bSwitchToOSC; } void ADC_CheckVGATable(void) { UINT16 usDeltaVcount, usDeltaHFreq; UINT8 ucDeltaVFreq,ucDeltaPol; UINT32 ulDeltaValue; INT32 iCheckVsyncWidthDelta; VesaTiming* VgaModeTable = g_stADCTimingTbl.pVgaVideoTimingTable; usDeltaHFreq=abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency -ADC_DetectTiming.usHFrequency); ucDeltaVFreq=abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency -ADC_DetectTiming.ucVFrequency); usDeltaVcount=abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount - ADC_DetectTiming.usVcount); ucDeltaPol=abs((VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucFlag>>4) & (ADC_DetectTiming.ucFlag>>4)); ulDeltaValue = usDeltaHFreq + ucDeltaVFreq + usDeltaVcount; // Boundary for Delta Vf smaller than 2 // Delta Hf < 1.5% of Hf on table for boundary if ( ucDeltaVFreq < 2 && usDeltaHFreq <= (VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+66)/67 && usDeltaVcount<3 ) { ADC_DebugMsg("--- TblEntry = %d --- %d x %d @ %d \n", sAdcInfo.ucVesaModeTableEntry, VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHactive, VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVactive, VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency); if( ADC_NeedCheckHsyncWidth()== FALSE) return; if (ADC_NeedToCheckPolarity() == TRUE) { ADC_DebugMsg("ChkPol = %d, Table_Flag = 0x%x, DetTiming_Flag = 0x%x\n", ucDeltaPol, VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucFlag, ADC_DetectTiming.ucFlag); if (ucDeltaPol == 0) return; } if( ADC_NeedCheckVsyncWidth()==TRUE) { iCheckVsyncWidthDelta = abs(VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency*10/VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVs_Width - sAdcInfo.ulMClk*SYS_CRYS_CLK_RATIO_PRECISE_3/(sAdcInfo.ulVsyncWidth)); ADC_DebugMsg("ChkVsWidth diff = %d\n", iCheckVsyncWidthDelta); //1680x1050x60C conflict with 1400x1050x60B if ((( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1680x1050x60C ) && (sAdcInfo.ulVsyncWidth < 9033)) || (( VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucADCTableIndex == PLF_VIDEO_TIMING_ID_1400x1050x60B ) && (sAdcInfo.ulVsyncWidth > 9033))) return; if( sAdcInfo.iCheckVsyncWidthDelta > iCheckVsyncWidthDelta ) { sAdcInfo.ulDeltaValue = ulDeltaValue; sAdcInfo.iCheckVsyncWidthDelta = iCheckVsyncWidthDelta; sAdcInfo.ucMatchTablePtr = sAdcInfo.ucVesaModeTableEntry; } else return; } else { ADC_DebugMsg("ChkTblDeltaVal = %d\n", ulDeltaValue); if(sAdcInfo.ulDeltaValue > ulDeltaValue) { sAdcInfo.ulDeltaValue = ulDeltaValue; sAdcInfo.ucMatchTablePtr = sAdcInfo.ucVesaModeTableEntry; } else return; } ADC_DebugMsg("HFdiff = %d, VFdiff = %d, VCdiff = %d, TotalDelta = %d\n", usDeltaHFreq, ucDeltaVFreq, usDeltaVcount, ulDeltaValue); ADC_DebugMsg("HFreq = %d, VFreq = %d, VCount = %d, HS_Width = %d\n", VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency, VgaModeTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency, VgaModeTable[sAdcInfo.ucVesaModeTableEntry].usVcount, sAdcInfo.usHsyncWidth); if(sAdcInfo.ulDeltaValue == 0 && ADC_NeedCheckVsyncWidth()==FALSE) sAdcInfo.ucVesaModeTableEntry = g_stADCTimingTbl.VgaVideoTimingTblSize; } } void ADC_CheckYPPTable(void) { UINT16 usDeltaHFreq; UINT8 ucDeltaVFreq; usDeltaHFreq=abs(g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency -ADC_DetectTiming.usHFrequency/10); ucDeltaVFreq=abs(g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency -ADC_DetectTiming.ucVFrequency); // Boundary for Delta Vf smaller than 2 // Delta Hf < 1.5% of Hf on table for boundary if (sAdcInfo.ulDeltaValue > usDeltaHFreq && ucDeltaVFreq < 2 && usDeltaHFreq <= (g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency+66)/67 && sAdcInfo.bInterlace == (g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].ucFlag&0x1)) { ADC_DebugMsg("--- TblEntry = %d --- %d x %d @ %d\n", sAdcInfo.ucVesaModeTableEntry, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].usHactive, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].usVactive, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency); if ( (abs(ADC_DetectTiming.usVcount - 625) < 5) && (sAdcInfo.ucRegLowWidth < 250 ) ) { ADC_DebugMsg( "Unsupported 1080i@50Hz 295 RegLowWidth = %d \n", sAdcInfo.ucRegLowWidth); return; } ADC_DebugMsg("HFdiff = %d, VFdiff = %d\n", usDeltaHFreq, ucDeltaVFreq); ADC_DebugMsg("HFreq = %d, VFreq = %d, VCount = %d\n", g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].usHFrequency, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].ucVFrequency, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucVesaModeTableEntry].usVcount); sAdcInfo.ulDeltaValue=usDeltaHFreq; sAdcInfo.ucMatchTablePtr=sAdcInfo.ucVesaModeTableEntry; if(sAdcInfo.ulDeltaValue == 0) sAdcInfo.ucVesaModeTableEntry = g_stADCTimingTbl.YppVideoTimingTblSize; } } void ADC_CheckInputMatch(UINT8 ucTable) { switch (ucTable) { case VESA_MODE: ADC_CheckVGATable(); break; case YPP_MODE: ADC_CheckYPPTable(); break; } } UINT8 ADC_FindTimingModeTable(void) { BOOL bFound=FALSE; UINT32 ulMaxPixelClock; ulMaxPixelClock=175; sAdcInfo.ucVesaModeTableEntry = 0; sAdcInfo.ulDeltaValue = 100; sAdcInfo.iCheckVsyncWidthDelta = 100000; if( sAdcInfo.ucSource==Adc_kSourceVGA ) { // The following are for PC mode ADC_DebugMsg("Find PC_Tbl\n"); while (sAdcInfo.ucVesaModeTableEntry < g_stADCTimingTbl.VgaVideoTimingTblSize ) { ADC_CheckInputMatch(VESA_MODE); sAdcInfo.ucVesaModeTableEntry++; } if (g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucPixelClock > ulMaxPixelClock) { printk(KERN_EMERG"Table PixClk %d M(> %d)\n", g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucPixelClock, ulMaxPixelClock); return UNSUPPORT_MODE; } bFound = (sAdcInfo.ulDeltaValue != 100) ? TRUE:FALSE; if (bFound == TRUE && g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].bSupport == 1) { if(ADC_NeedCheckSwitchRef24M()) { ADC_Write(GLB_REG_VADC_REF_SEL_24M, 1); // 0xbe000149[6] 24 MHz reference selector. 0: CPLL, 1: Crystal 24M ADC_DebugMsg(" Switch 24 MHz reference selector (0xbe000149[6]) as Crystal\n"); } ADC_DebugMsg("--- PC_MODE Match in %d --- %d x %d @ %d \n", sAdcInfo.ucMatchTablePtr, g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHactive, g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usVactive, g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucVFrequency); return VESA_MODE; } else return UNSUPPORT_MODE; } else { ADC_DebugMsg("Find YPP_Tbl\n"); while (sAdcInfo.ucVesaModeTableEntry < g_stADCTimingTbl.YppVideoTimingTblSize) { ADC_CheckInputMatch(YPP_MODE); sAdcInfo.ucVesaModeTableEntry++; } bFound = (sAdcInfo.ulDeltaValue != 100) ? TRUE:FALSE; if(bFound == TRUE) { #ifdef DRV_ENABLE_CVD2 if(ucCVD2PowerEnable==FALSE) { DRV_CVD2_Power_Setting(TRUE); DRV_CVD2_Enable_Ypp_CC(); ucCVD2PowerEnable=TRUE; } #endif ADC_DebugMsg("--- YPP_MODE Match in %d --- %d x %d @ %d\n", sAdcInfo.ucMatchTablePtr, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHactive, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].usVactive, g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucVFrequency); return YPP_MODE; } else return UNSUPPORT_MODE; } return UNSUPPORT_MODE; } BOOL ADC_Detect_Mode(void) { if(ADC_Frequency_Filter()==FALSE) { ADC_StatusUpdate(); return FALSE; } sAdcInfo.ucInputMode = ADC_FindTimingModeTable(); if(sAdcInfo.ucInputMode == UNSUPPORT_MODE) { ADC_StatusUpdate(); return FALSE; } else return TRUE; } void ADC_LoadVesaTable(UINT8 ucTablePtr) { VesaTiming* VgaModeTable = g_stADCTimingTbl.pVgaVideoTimingTable; ADC_InputVesaTiming.usHtotal = VgaModeTable[ucTablePtr].usHtotal*iEnlargeWidthRate; ADC_InputVesaTiming.usVcount = VgaModeTable[ucTablePtr].usVcount; ADC_InputVesaTiming.usHFrequency = VgaModeTable[ucTablePtr].usHFrequency; ADC_InputVesaTiming.ucVFrequency = VgaModeTable[ucTablePtr].ucVFrequency; ADC_InputVesaTiming.ucPixelClock = VgaModeTable[ucTablePtr].ucPixelClock*iEnlargeWidthRate; ADC_InputVesaTiming.usHactive = VgaModeTable[ucTablePtr].usHactive*iEnlargeWidthRate; ADC_InputVesaTiming.usVactive = VgaModeTable[ucTablePtr].usVactive; ADC_InputVesaTiming.usHstart= VgaModeTable[ucTablePtr].usHstart*iEnlargeWidthRate; ADC_InputVesaTiming.usVstart= VgaModeTable[ucTablePtr].usVstart; ADC_InputVesaTiming.usHs_Width = VgaModeTable[ucTablePtr].usHs_Width*iEnlargeWidthRate; ADC_InputVesaTiming.ucFlag=ADC_DetectTiming.ucFlag; if( sAdcInfo.bHpol==0 ) ADC_InputVesaTiming.usHstart -= ADC_InputVesaTiming.usHs_Width; ADC_DetectTiming.usHstart=ADC_InputVesaTiming.usHstart + ADI_CENTERING_HOR_DELAY; ADC_DetectTiming.usVstart=ADC_InputVesaTiming.usVstart; ADC_DetectTiming.usHactive=ADC_InputVesaTiming.usHactive; ADC_DetectTiming.usVactive=ADC_InputVesaTiming.usVactive; } void ADC_LoadYPPTable(UINT8 ucTablePtr) { ADC_InputVesaTiming.ucPixelClock=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].ucPixelClock*iEnlargeWidthRate; ADC_InputVesaTiming.usVcount=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usVcount; ADC_InputVesaTiming.usHFrequency=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usHFrequency*10; ADC_InputVesaTiming.ucVFrequency=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].ucVFrequency; ADC_InputVesaTiming.usHtotal=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usHtotal*iEnlargeWidthRate; ADC_InputVesaTiming.usHstart=(g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usHstart*iEnlargeWidthRate); ADC_InputVesaTiming.usVstart=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usVstart; ADC_InputVesaTiming.usHactive=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usHactive*iEnlargeWidthRate; ADC_InputVesaTiming.usVactive=g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usVactive; ADC_InputVesaTiming.usHs_Width = g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].usHs_Width*iEnlargeWidthRate; ADC_InputVesaTiming.ucFlag=ADC_DetectTiming.ucFlag; if (sAdcInfo.bInterlace) ADC_InputVesaTiming.usVactive/=2; ADC_DetectTiming.usHstart=ADC_InputVesaTiming.usHstart; ADC_DetectTiming.usVstart=ADC_InputVesaTiming.usVstart; ADC_DetectTiming.usHactive=ADC_InputVesaTiming.usHactive; ADC_DetectTiming.usVactive=ADC_InputVesaTiming.usVactive; if( (g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].ucADCTableIndex == PLF_VIDEO_TIMING_ID_DTV_480I60) || (g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].ucADCTableIndex == PLF_VIDEO_TIMING_ID_DTV_480P60) || (g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].ucADCTableIndex == PLF_VIDEO_TIMING_ID_DTV_576I50) || (g_stADCTimingTbl.pYppVideoTimingTable[ucTablePtr].ucADCTableIndex == PLF_VIDEO_TIMING_ID_DTV_576P50)) ADC_DetectTiming.usHs_Width = sAdcInfo.ucRegLowWidth*1000000/sAdcInfo.ulMClk*ADC_InputVesaTiming.ucPixelClock/1000; else ADC_DetectTiming.usHs_Width = sAdcInfo.ucRegLowWidth*1000000/sAdcInfo.ulMClk*ADC_InputVesaTiming.ucPixelClock/1000*2; } BOOL ADC_CheckLoadTableValueRange(void) { BOOL bLoadDataOK=FALSE; ADC_DebugMsg("========= [%s MatchIdx = %3d] ==========", ( sAdcInfo.ucSource==Adc_kSourceVGA )?" VGA ":" YPP ", sAdcInfo.ucMatchTablePtr); ADC_DebugMsg("| Htotal = %4d Vcount = %3d |", ADC_InputVesaTiming.usHtotal, ADC_InputVesaTiming.usVcount); ADC_DebugMsg("| Hactive = %4d Vactive = %4d |", ADC_DetectTiming.usHactive, ADC_DetectTiming.usVactive); ADC_DebugMsg("| Hstart = %3d Vstart = %3d |", ADC_DetectTiming.usHstart, ADC_DetectTiming.usVstart); ADC_DebugMsg("| HFrequency = %4d VFrequency = %3d |", ADC_InputVesaTiming.usHFrequency, ADC_InputVesaTiming.ucVFrequency); ADC_DebugMsg("| PixelClock = %3d ucFlag = 0x%02x |", ADC_InputVesaTiming.ucPixelClock, ADC_InputVesaTiming.ucFlag); ADC_DebugMsg("| Hs_Width = %3d EnlargeRate = %d |\n", ADC_DetectTiming.usHs_Width, iEnlargeWidthRate); ADC_DebugMsg("============================================="); return bLoadDataOK; } BOOL ADC_CheckSyncStable(UINT8 ucTimeOut) { UINT8 ucLoop=0; BOOL bStable=FALSE; UINT8 ucTimeOut2=4; while( ucLoop++ <= ucTimeOut ) { if( VIP_InputActiveDetect(EXTS)==0x0f ) { bStable = TRUE; break; } ADC_DelayMS(20); // 25ms } while( ucTimeOut2 > 0 && bStable == TRUE) { if( VIP_InputActiveDetect(EXTS)!=0x0f ) { ADC_DebugMsg("Round 2: VIP_Sync Unstable! Time is %d\n", (4 - ucTimeOut2)); bStable = FALSE; break; } udelay(1000); // 1ms ucTimeOut2--; } if (bStable == FALSE) ADC_DebugMsg("VIP_Sync Unstable! Status=0x%x\n", VIP_InputActiveDetect(EXTS)); else { ADC_DebugMsg("VIP_Sync Stable\n"); } return bStable; } BOOL ADC_GetExtsInfo(UINT8 ucStableCnt, UINT8 ucTimeOut, UINT8 ucMdelay) { VesaTiming InputBaseTiming; UINT8 ChkCnt,OkCnt,ucFlag; volatile UINT16 ucMLineWidth; BOOL RetVal,bPolarityInverse, bSignalStable=FALSE; SYNC_DETECT sSyncInfo={0}; InputBaseTiming.ucFlag=InputBaseTiming.usVcount=0; InputBaseTiming.ucVFrequency=InputBaseTiming.usHFrequency=0; ADC_DetectTiming.usVcount=ADC_DetectTiming.ucFlag=0; ADC_DetectTiming.ucVFrequency=ADC_DetectTiming.usHFrequency=0; sAdcInfo.ulVsyncWidth=0; RetVal = ADC_CheckSyncStable(8); if(!sAdcInfo.bADCEnable) return FALSE; if(RetVal == TRUE) { ChkCnt=OkCnt=0; bPolarityInverse = ADC_Read(ADC_REG_e_hsync_pol); while (OkCnt < ucStableCnt && ChkCnt++ < ucTimeOut) { //ADC_DelayMS(ucMdelay); if(VIP_InputSyncDetect(NULLOP, SOURCE_EXTS, &sSyncInfo) == SYNC_OK) { RetVal=TRUE; // 2010/12/30 modify by patrick if(sAdcInfo.ucSource == Adc_kSourceVGA) ucFlag = ((ADC_Read(ADC_STA_hs_plrty)^bPolarityInverse)<<2) | (ADC_Read(ADC_STA_vs_plrty)<<1); else ucFlag = sSyncInfo.ucADCInterlaceMode; if((abs(InputBaseTiming.usVcount-(sSyncInfo.usVSyncCnt&0x07ff)) < 5) && (abs(InputBaseTiming.ucVFrequency-(sSyncInfo.usVFreq+5)/10) < 3) && (abs(InputBaseTiming.usHFrequency-sSyncInfo.usHFreq) < (sSyncInfo.usHFreq+66)/67) && (abs(InputBaseTiming.ucFlag-ucFlag) == 0) ) { ADC_DetectTiming.usVcount=(ADC_DetectTiming.usVcount+(sSyncInfo.usVSyncCnt&0x07ff))/2; ADC_DetectTiming.ucVFrequency=(ADC_DetectTiming.ucVFrequency+(sSyncInfo.usVFreq+5)/10)/2; ADC_DetectTiming.usHFrequency=(ADC_DetectTiming.usHFrequency+sSyncInfo.usHFreq)/2; } else { ADC_DetectTiming.usVcount=InputBaseTiming.usVcount=sSyncInfo.usVSyncCnt&0x07ff; ADC_DetectTiming.ucFlag=InputBaseTiming.ucFlag=ucFlag; ADC_DetectTiming.ucVFrequency=InputBaseTiming.ucVFrequency=(sSyncInfo.usVFreq+5)/10; ADC_DetectTiming.usHFrequency=InputBaseTiming.usHFrequency=sSyncInfo.usHFreq; OkCnt = 0; } OkCnt++; } else { OkCnt=0; RetVal=FALSE; } } if( sAdcInfo.ucSource==Adc_kSourceVGA ) { sAdcInfo.usHsyncWidth= ADC_Read(ADC_STA_shp_width)* SYS_CRYS_CLK_RATIO_PRECISE_3 /1000; sAdcInfo.ulVsyncWidth = ADC_Read(ADC_STA_svp_width)* SYS_CRYS_CLK_RATIO_PRECISE_3 /1000; sAdcInfo.usHsyncWidth = sAdcInfo.usHsyncWidth; sAdcInfo.ulVsyncWidth = sAdcInfo.ulVsyncWidth; bSignalStable = ADC_Read(ADC_STA_cstable_i2); } else { sAdcInfo.ucRegLineWidth = ADC_Read(ADC_STA_line_wdth); sAdcInfo.ucRegLowWidth = ADC_Read(ADC_STA_low_wdth); ucMLineWidth = ADC_Read(ADC_STA_mline_wdth); if (abs(sAdcInfo.ucRegLineWidth -ucMLineWidth) > 4 ) { ADC_DebugMsg("Fail: mLine_width < threshold\n"); ADC_DebugMsg("RegLineWidth=%d ucMLineWidth=%d\n", sAdcInfo.ucRegLineWidth, ucMLineWidth); //bSignalStable = FALSE; } else { //<--Workaround for COMP1080p pattern BURST of quantumdata. bSignalStable = (ADC_Read(ADC_STA_cur_state)==0xd0)? TRUE:FALSE; if(bSignalStable == FALSE) { ADC_DebugMsg("Fail: Sog Unstable\n"); } } if ( (sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) && (bSignalStable == TRUE) ) bSignalStable = ADC_CheckInterlaceMode(); } if (bSignalStable == TRUE) { if (abs(ADC_DetectTiming.usVcount - 562) < 5 ) ADC_Write(ADC_REG_cs_vslp, 0); } ADC_Clear_Interrupt(0xdfff); if(ChkCnt > ucTimeOut || bSignalStable==FALSE) { ADC_DetectTiming.usVcount=ADC_DetectTiming.ucFlag=0; ADC_DetectTiming.ucVFrequency=ADC_DetectTiming.usHFrequency=0; sAdcInfo.ulVsyncWidth=0; RetVal = FALSE; } } ADC_DebugMsg("ADC_DetectTiming from VIP_InputSyncDetect:\n HF = %d, VF = %d, Vcount = %d, Flag = 0x%x\n", ADC_DetectTiming.usHFrequency, ADC_DetectTiming.ucVFrequency, ADC_DetectTiming.usVcount, ADC_DetectTiming.ucFlag); if( sAdcInfo.ucSource == Adc_kSourceVGA ) { ADC_DebugMsg("AdcInfo: HS_Width = %d, VS_Width = %d\n",sAdcInfo.usHsyncWidth, sAdcInfo.ulVsyncWidth); } else { ADC_DebugMsg("AdcInfo: Line_Width = %d, Low_Width = %d\n",sAdcInfo.ucRegLineWidth, sAdcInfo.ucRegLowWidth); } if(sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { if(sAdcInfo.ucRegLineWidth< 2500) { ADC_DebugMsg("Fail: AdcInfo:RegLineWidth < 2500 !!!!!!!!!\n"); //ADC_DelayMS(4500); ADC_Write(ADC_REG_cs2_pll_sw_rst, 0x1); ADC_Write(ADC_REG_cs2_pll_sw_rst, 0x0); udelay(1000); // 1ms RetVal = FALSE; } } ADC_UpdateFlag(ADC_DetectTiming.ucFlag); return RetVal; } BOOL ADC_ModeStable(void) { UINT8 ucLoop=0; ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); while (ucLoop++ < 10) { if (ADC_CheckSyncStable(6) == TRUE) { ADC_DebugMsg("%dth VIP Sync chk\n", ucLoop); ucLoop=100; } } if (ucLoop <= 11) { ADC_DebugMsg("Sync UnStable TimeOut\n"); return FALSE; } return TRUE; } void ADC_ModeSetting(void) { UINT16 usPtr; UINT32 ADCReg=0, ADCValue=0, ulHStart=0, ucIndex; ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); ADC_OverSample(); if (sAdcInfo.ucSource == Adc_kSourceVGA) { ucIndex = g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucADCTableIndex; ADC_LoadVesaTable(sAdcInfo.ucMatchTablePtr); } else { ucIndex = g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucADCTableIndex; ADC_LoadYPPTable(sAdcInfo.ucMatchTablePtr); } if( ADC_CheckLoadTableValueRange()==FALSE ) sAdcInfo.bDoAuto = TRUE; sAdcInfo.ucTimingModeIndex = ucIndex; for (usPtr=0;usPtr Revise SMT = 0x%x\n", SMT_mergin, ADC_Read(ADC_REG_sog_smthr12v)); } } else ADC_Write(ADC_REG_aof_pstart, (ulHStart<255?ulHStart:254)); SMT_mergin = 0; } else if (sAdcInfo.ucSource == Adc_kSourceVGA) { if ( ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHactive==1920 ) && ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usVactive==1080 )) { ADC_Write(ADC_REG_cs2_r_clamp_width, 0x5); ADC_Write(ADC_REG_cs2_g_clamp_width, 0x5); ADC_Write(ADC_REG_cs2_b_clamp_width, 0x5); } else if( ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHactive==1920 ) && ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usVactive==1200 ) ) { ADC_Write(ADC_REG_cs2_r_clamp_width, 0x3); ADC_Write(ADC_REG_cs2_g_clamp_width, 0x3); ADC_Write(ADC_REG_cs2_b_clamp_width, 0x3); } else { ADC_Write(ADC_REG_cs2_r_clamp_width, 0x7); ADC_Write(ADC_REG_cs2_g_clamp_width, 0x7); ADC_Write(ADC_REG_cs2_b_clamp_width, 0x7); } //clamppdn edge different by Hpol if (sAdcInfo.bHpol == 1) ADC_Write(ADC_REG_clamppdn_edge, 0x1); else ADC_Write(ADC_REG_clamppdn_edge, 0); // Interference for 1600 x 1200 @60Hz (Switch to Audio) if( ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHactive==1600 ) && ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usVactive==1200 ) && ( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucVFrequency==60 )) { ADC_Write(ADC_REG_cal_sw_ctrl_th, 0x1d); } } } BOOL ADC_Signal_Status(void) { INT32 iTimeOut1 = 0, iTimeOut2 = 0, iTimeOut3 = 0; BOOL bStable1 = FALSE, bStable2=FALSE; UINT8 ucDetectTimeOut=8, ucSogStableTimes=0, ucCurState=0, ucMid=0, ucMin=0, ucTipHeightcount =0; UINT32 ulTipHeight=0; UINT8 cur_source = sAdcInfo.ucSource; VIP_ADCIntClear(); do{ iTimeOut1 = 0; iTimeOut2 = 0; if(!sAdcInfo.bADCEnable) return FALSE; ADC_ClearWatchDog; if(sAdcInfo.ucSource != Adc_kSourceVGA) { ADC_SOG_Slicer_Backup(); ADC_DelayMS(30); // waiting 2 vsync for sog stable while( iTimeOut1++ < 4) { ucCurState = (UINT8)ADC_Read(ADC_STA_cur_state); if( ucCurState == 0x60) { iTimeOut3++; break; } else if( ucCurState == 0xd0 ) { bStable1 = TRUE; ADC_DebugMsg("DetTimeRound %d: Sog stable\n", (9 - ucDetectTimeOut)); break; } else if( ucCurState == 0xfd ) break; else udelay(1000); //25ms } if( iTimeOut3 == 5) { ADC_Write(ADC_REG_vs_acc_enter_th, 0x2); ADC_Write(ADC_REG_vs_skip_mline_wdth, 0x1); } if((iTimeOut1 == 5 && bStable1 == FALSE) || ucCurState == 0xfd) { ADC_DebugMsg("DetTimeRound %d: Sog unstable, CurState: 0x%x\n", (9 - ucDetectTimeOut), ucCurState); continue; } else if ((ucCurState == 0xd0) && ( ADC_Read(ADC_STA_mline_wdth) == 0x20)) { ADC_DebugMsg("DetTimeRound %d: mline_width < threshold\n", (9 - ucDetectTimeOut)); continue; } //tip Height ucMid = ADC_Read(ADC_STA_mid_find); ucMin = ADC_Read(ADC_STA_min_find); ulTipHeight = (((UINT32)(ucMid-ucMin)*1000)/8/20); //unit: mV ADC_DebugMsg("TimeRound %d: Tip Height=%d \n", ucTipHeightcount, ulTipHeight); if(ulTipHeight < 200 ) { if(ucTipHeightcount < 3 ) { ucTipHeightcount++; continue; } ADC_DebugMsg("TipHeight<200, new smthr\n"); if (sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { ADC_Write(ADC_REG_st_iir1_strength, 0x3); ADC_Write(ADC_REG_vs_synct_base_opt, 0x1); ADC_Write(ADC_REG_vs_synct_th, 0x9); ADC_Write(ADC_REG_vblank_ini_length, 0); ADC_Write(ADC_REG_st_top_cgplus, 0x1); } } else if (ulTipHeight > 400 ) { if (sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { ADC_DebugMsg("TipHeight>400\n"); /* ADC_DebugMsg("Reset ucDetectTimeOut count to 8\n"); if (ulTipHeight > 500 ) { ADC_DebugMsg("TipHeight>500\n"); ADC_DebugMsg("Add Delay 500ms\n"); ADC_DelayMS(500); } ucDetectTimeOut=8; continue;*/ } } } if(cur_source != sAdcInfo.ucSource) { ADC_DebugMsg("### source change %d => %d , break signal status checking ###\n", cur_source, sAdcInfo.ucSource); break; } ADC_DelayMS(40); // waiting 2 vsync for coast stable, 30ms while( iTimeOut2++ < 8) { if( ADC_Read(ADC_STA_cstable_i2) == 0x1 ) { ADC_DebugMsg("DetTimeRound %d: Coast stable\n", (9 - ucDetectTimeOut)); bStable2 = TRUE; if (sAdcInfo.ucSource != Adc_kSourceVGA) { ADC_Write(ADC_REG_stb1_sc_wdth_opt, 3); } break; } else { if (sAdcInfo.ucSource != Adc_kSourceVGA) { //because only one vsync, set to "original signal" replace "regeneration signal" if(ulTipHeight > 200 ) ADC_Write(ADC_REG_source_sel, 0x1); ADC_DelayMS(25); } else ADC_DelayMS(10); } } if(iTimeOut2 == 9 && bStable2== FALSE) { ADC_DebugMsg("DetTimeRound %d: Coast unstable\n", (9 - ucDetectTimeOut)); if( ( ADC_Read(ADC_STA_cur_state) & 0x30) != 0) { ADC_DebugMsg("## cur_state!= {0x10, 0x20, 0x30} ~ Reset ucDetectTimeOut count to 8\n"); ucDetectTimeOut=8; } continue; } if( ADC_GetExtsInfo(4, 10, 32)==TRUE ) { ADC_DebugMsg("DetTimeRound %d: GetExtsInfo success\n", (9 - ucDetectTimeOut)); return TRUE; } else { ADC_DebugMsg("DetTimeRound %d: GetExtsInfo fail\n", (9 - ucDetectTimeOut)); } //??reset digital block if( sAdcInfo.ucSource!=Adc_kSourceVGA ) { //It's for Macro vision or worse csync. if( ADC_Read(ADC_STA_cur_state)==0xd0 ) { ucSogStableTimes++; if( ucSogStableTimes==4 ) { ADC_Write(ADC_REG_dg_l2h_thold, 0x1a); ADC_Write(ADC_REG_dg_h2l_thold, 0x1a); } } } VIP_ResetADI(); }while ( --ucDetectTimeOut>0 ); ADC_DebugMsg("No stable signal=%x\n", VIP_InputActiveDetect(EXTS)); sAdcInfo.ucInputMode = NOSIGNAL_MODE; return FALSE; } UINT8 ADC_Mode_Setup( void ) { UINT8 ucPixelClock = 0; UINT16 usHTotal = 0; ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); if(ADC_Signal_Status()==FALSE) return VIP_No_Signal; if(ADC_Detect_Mode()==FALSE) return Unsupported_Timing; //Set PLL, Clamp and mode setting ADC_ModeSetting(); if(sAdcInfo.ucSource == Adc_kSourceVGA) { ucPixelClock = g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucPixelClock*iEnlargeWidthRate; usHTotal = g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHtotal*iEnlargeWidthRate; } else { ucPixelClock = g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucPixelClock*iEnlargeWidthRate; usHTotal = g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHtotal*iEnlargeWidthRate; } //ADC_PllSetting(ucPixelClock, usHTotal); ADC_CheckPllResetSequence(ucPixelClock, usHTotal); //Hsync output by PLL ADC_Write(ADC_REG_o_hsync_sel,0); udelay(1000); //10ms if(ADC_CheckSyncStable(6) ==FALSE) { sAdcInfo.ucInputMode = NOSIGNAL_MODE; return Mode_Change_Again; } ADC_StatusUpdate(); FactoryModeAWB = FALSE; return Mode_Change_Stable; } void ADC_SourceInit(void) { UINT16 usPtr; UINT32 ADCReg=0, ADCValue=0; UINT8 ucCheckInputPIN; ADC_ScreenMode(BlackScreen); ADC_Write(GLB_REG_VADC_REF_SEL_24M, 0); // 0xbe000149[6] 24 MHz reference selector. 0: CPLL, 1: Crystal 24M //ADC Clock 200MHz on. ADC_Write(GLB_REG_YPP200MCLK_DIV, 3); ADC_Write(GLB_REG_YPP200MCLK_DIV_RSTN, 1); ADC_Write(GLB_REG_DEMOD_PWDN_BG, 1 ); // power down DMADC's BGP ADC_Write(GLB_REG_VCLK_DIV_RSTN, 1 ); // Set ADC_PLL reference divider reset as normal mode //VIP bypass input = Hsync(0:sog) ADC_Write(GLB_REG_ALWAYS_HSI, 1); //internal coast select ADC_Write(GLB_REG_ECO_FIELD_SEL, 1); ADC_Write(ADC_REG_ss_mode, 1); //Bandgap setting sAdcInfo.ucBandgap = 0x5; ADC_Write(ADC_REG_vbg_v_ctrl, sAdcInfo.ucBandgap); *((volatile UINT8*)0xbe1cf082) = 0x1f; sAdcInfo.ulMClk=0; sAdcInfo.ulMClk = ADC_MClk(); ADC_DebugMsg("MClk=%d\n",sAdcInfo.ulMClk); if (sAdcInfo.ucSource == Adc_kSourceVGA) ucCheckInputPIN = adc_InputSrcPin.rgb.g_pin; else ucCheckInputPIN = adc_InputSrcPin.ypbpr.y_pin; if (ucCheckInputPIN == INPUT_PIN_COMP_G1) { ADC_Write(ADC_REG_lcg_rch_sel, 0x1); ADC_Write(ADC_REG_lcg_gch_sel, 0x1); ADC_Write(ADC_REG_lcg_bch_sel, 0x1); ADC_Write(ADC_REG_sog_ch_sel, 0x2); ADC_Write(ADC_REG_sog_clamp_sel, 0x2); // Differential mode setting ADC_Write(ADC_REG_r_refch12v, 1); ADC_Write(ADC_REG_g_refch12v, 1); ADC_Write(ADC_REG_b_refch12v, 1); ADC_Write(ADC_REG_y_refch12v, 1); } else if (ucCheckInputPIN== INPUT_PIN_COMP_G2) { ADC_Write(ADC_REG_lcg_rch_sel, 0x2); ADC_Write(ADC_REG_lcg_gch_sel, 0x2); ADC_Write(ADC_REG_lcg_bch_sel, 0x2); ADC_Write(ADC_REG_sog_ch_sel, 0x2); ADC_Write(ADC_REG_sog_clamp_sel, 0x2); // Differential mode setting ADC_Write(ADC_REG_r_refch12v, 2); ADC_Write(ADC_REG_g_refch12v, 2); ADC_Write(ADC_REG_b_refch12v, 2); ADC_Write(ADC_REG_y_refch12v, 2); } else if (ucCheckInputPIN == INPUT_PIN_COMP_G3) { ADC_Write(ADC_REG_lcg_rch_sel, 0x3); ADC_Write(ADC_REG_lcg_gch_sel, 0x3); ADC_Write(ADC_REG_lcg_bch_sel, 0x3); ADC_Write(ADC_REG_sog_ch_sel, 0x4); ADC_Write(ADC_REG_sog_clamp_sel, 0x3); // Differential mode setting ADC_Write(ADC_REG_r_refch12v, 3); ADC_Write(ADC_REG_g_refch12v, 3); ADC_Write(ADC_REG_b_refch12v, 3); ADC_Write(ADC_REG_y_refch12v, 3); } else { // For default VGA setting (ucCheckInputPIN == INPUT_PIN_NO_USE) ADC_Write(ADC_REG_lcg_rch_sel, 0x0); ADC_Write(ADC_REG_lcg_gch_sel, 0x0); ADC_Write(ADC_REG_lcg_bch_sel, 0x0); ADC_Write(ADC_REG_sog_ch_sel, 0x0); ADC_Write(ADC_REG_sog_clamp_sel, 0x0); // Differential mode setting ADC_Write(ADC_REG_r_refch12v, 0); ADC_Write(ADC_REG_g_refch12v, 0); ADC_Write(ADC_REG_b_refch12v, 0); ADC_Write(ADC_REG_y_refch12v, 0); } // Pull down unused RGB ADC_Write(ADC_REG_r_pden12v, 1); ADC_Write(ADC_REG_g_pden12v, 1); ADC_Write(ADC_REG_b_pden12v, 1); ADC_Write(ADC_REG_r_tswmiden12v, 1); ADC_Write(ADC_REG_g_tswmiden12v, 1); ADC_Write(ADC_REG_b_tswmiden12v, 1); //ADCSouceInitBaseTable for (usPtr=0;usPtr= 720) ? YPP : YCC; sSendInfo.ucDataFormat = YUV_444; sSendInfo.ucAspectRatio = ASPECT_NON; } ADC_DebugMsg("ColorStandard=%d \n", sSendInfo.ucColorimetry); VIP_SendInformation(&sSendInfo); if( sAdcInfo.ucSource==Adc_kSourceVGA ) { if(ADC_InputVesaTiming.usHactive == 834 && ADC_InputVesaTiming.usVactive == 624) //Add by Jason. H active is defined 832, but the the actuality is 834. VIP_EXTS_SetOriActive(832, ADC_InputVesaTiming.usVactive); else VIP_EXTS_SetOriActive(ADC_InputVesaTiming.usHactive, ADC_InputVesaTiming.usVactive); } else { if( sAdcInfo.bInterlace ) VIP_EXTS_SetOriActive(ADC_InputVesaTiming.usHactive, ADC_InputVesaTiming.usVactive*2); else VIP_EXTS_SetOriActive(ADC_InputVesaTiming.usHactive, ADC_InputVesaTiming.usVactive); } ADC_DebugMsg("========= InputSource = %s ======== SubSource = %s =========", (sSendInfo.ucInputSource==EXTS)?" EXTS ":"UNKNOWN", (sSendInfo.ucSubInputSource == Adc_kSourceVGA)?" VGA ":" YPP "); ADC_DebugMsg("| Hactive = %4d, Hstart = %3d, Hend = %4d, HFreq = %4d, Hpol = %d |", sSendInfo.uiHactive, sSendInfo.uiHstart, sSendInfo.uiHend, sSendInfo.uiHfreq, sSendInfo.ucHpol ); ADC_DebugMsg("| Vactive = %4d, Vstart = %3d, Vend = %4d, VFreq = %2d , Vpol = %d |", sSendInfo.uiVactive, sSendInfo.uiVstart, sSendInfo.uiVend, sSendInfo.uiVfreq, sSendInfo.ucVpol); ADC_DebugMsg("| Colorimetry = %s, DataFormat = %s AspectRatio = %s, Interlace = %s |", (sSendInfo.ucColorimetry==RGB)?"RGB":(sSendInfo.ucColorimetry==YPP)?"YPP":"YCC", (sSendInfo.ucDataFormat==RGB)?" RGB ":"YUV_444", (sSendInfo.ucAspectRatio==ASPECT_NON)?"NON":"N/A", sSendInfo.bInterlace?"T":"F"); ADC_DebugMsg("| TableIdx = %6d, Htotal = %4d, Hstart = %3d, HsWidth = %3d, Vstart = %d |", sSendInfo.uiTimingIndex, sSendInfo.uiHtotal, sSendInfo.uiTableHstart, sSendInfo.uiHsync_width, sSendInfo.uiTableVstart); } void ADC_Centering(BOOL bDoCentering) { VIP_RECT rcCenter; UINT8 RetValue; ADC_DebugMsg("Do Auto Centering: %d\n", bDoCentering); if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) { ADC_DebugMsg(" Skip %s when mode change... \n", __FUNCTION__); return; } RetValue = VIP_Centering(&rcCenter, bDoCentering); if(RetValue == CENTERING_FAIL) { ADC_DebugMsg("Do Auto Centering ERROR\n"); } else { ADC_DebugMsg("Centering Result is %s Mode.\n", (RetValue==CENTERING_H)?"[H]":(RetValue==CENTERING_V)?"[V]":"[HV]"); } if(bDoCentering && RetValue) { ADC_DetectTiming.usHstart = rcCenter.ulHStart; ADC_DetectTiming.usVstart = rcCenter.ulVStart; ADC_DetectTiming.usHactive = rcCenter.ulHEnd - rcCenter.ulHStart; ADC_DetectTiming.usVactive = rcCenter.ulVEnd - rcCenter.ulVStart; } else if(!bDoCentering && RetValue) { ADC_DetectTiming.usHstart= rcCenter.ulHStart; ADC_DetectTiming.usVstart= rcCenter.ulVStart; ADC_DetectTiming.usHactive= ADC_InputVesaTiming.usHactive; ADC_DetectTiming.usVactive= ADC_InputVesaTiming.usVactive; } ADC_DebugMsg("ADC_DetectTiming: Hstart=%d Vstart=%d Hactive=%d Vactive=%d\n", ADC_DetectTiming.usHstart, ADC_DetectTiming.usVstart, ADC_DetectTiming.usHactive, ADC_DetectTiming.usVactive); ADC_DebugMsg("ADC_InputVesaTiming: Hstart=%d Vstart=%d Hactive=%d Vactive=%d\n", ADC_InputVesaTiming.usHstart, ADC_InputVesaTiming.usVstart, ADC_InputVesaTiming.usHactive, ADC_InputVesaTiming.usVactive); return; } UINT8 ADC_FullPhaseDetected(void) { UINT16 VIPttl_backup = 0, VIPttl_current = 0; UINT8 i = 0; UINT16 array[200] = {0}; BOOL check[32] = {FALSE}; UINT32 ulTestPhase, ulPreSummation=0, ulNowSummation=0, lPhase1[32]; UINT8 ucPhaseRef=32, ucCompareTimes, ucZeroCnt, ucZeroMaxCnt, ucBest=0, ucDelay; ADC_DebugMsg("%s\n", __FUNCTION__); if (sAdcInfo.bInterlace) ucCompareTimes = 2; else ucCompareTimes = 1; ucComparethd = 0; ucDelay = 0; if(gAdcAp.bApUse == TRUE) { if(gAdcAp.ulTimes != 0xffffffff) ucCompareTimes = gAdcAp.ulTimes; if(gAdcAp.ulData != 0xffffffff) ucComparethd = gAdcAp.ulData; } ADC_DebugMsg("ucCompareTimes = %d(0x%x), ucComparethd = %d(0x%x)\n", ucCompareTimes, ucCompareTimes, ucComparethd, ucComparethd); if(gAdcAp.bApUse == TRUE && gAdcAp.ucPhase != 0xff) { ADC_SetPhaseDirdect(gAdcAp.ucPhase); ADC_DelayMS(ucDelay); ADC_ResetADI_Unlock(); ADC_DebugMsg("Sum_Cmp22Value[%2d]=%d\n", gAdcAp.ucPhase, VIP_FrameCompare(ucCompareTimes, ucComparethd)); VIPttl_backup = *((volatile UINT16*)(0xbe1cf008)); for(i = 0; i< 200 ; i++) { VIPttl_current = *((volatile UINT16*)(0xbe1cf008)); array[i] = (VIPttl_current > VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current); //printk(KERN_EMERG" %d ", (VIPttl_current > VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current)); if(array[i] >= 1) check[gAdcAp.ucPhase] = TRUE; VIPttl_backup = VIPttl_current; } for(i = 0; i < 20; i++) { ADC_DebugMsg(" %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ", array[i*10], array[i*10+1], array[i*10+2], array[i*10+3], array[i*10+4], array[i*10+5], array[i*10+6], array[i*10+7], array[i*10+8], array[i*10+9]); } return gAdcAp.ucPhase; } else { //Frame compare result collection for(ulTestPhase=0; ulTestPhase VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current); //printk(KERN_EMERG" %d ", (VIPttl_current > VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current)); if(array[i] >= 1) check[ulTestPhase] = TRUE; VIPttl_backup = VIPttl_current; } for(i = 0; i < 20; i++) { ADC_DebugMsg(" %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ", array[i*10], array[i*10+1], array[i*10+2], array[i*10+3], array[i*10+4], array[i*10+5], array[i*10+6], array[i*10+7], array[i*10+8], array[i*10+9]); } ADC_DebugMsg("\n"); } } ADC_DebugMsg("-----------------Frame compare phase detecrt result ---------------- \n"); for(ulTestPhase=0;ulTestPhaseulNowSummation ) { ulPreSummation = ulNowSummation; ucBest = ulTestPhase; } } } } else { ucZeroCnt = 0; for(ulTestPhase=0;ulTestPhase 140) && (sAdcInfo.ucSource == Adc_kSourceVGA)) ucCompareTimes = 2; else ucCompareTimes = 1; } ucComparethd = 0; ucDelay = 0; // 500*3/ADC_DetectTiming.ucVFrequency; if(gAdcAp.bApUse == TRUE) { if(gAdcAp.ulTimes != 0xffffffff) ucCompareTimes = gAdcAp.ulTimes; if(gAdcAp.ulData != 0xffffffff) ucComparethd = gAdcAp.ulData; } ADC_DebugMsg("Frame compare (Time/TH) in round 1: (%d/0x%x)\n", ucCompareTimes, ucComparethd); if(gAdcAp.bApUse == TRUE && gAdcAp.ucPhase != 0xff) { ADC_SetPhaseDirdect(gAdcAp.ucPhase); //ADC_DelayMS(ucDelay); //argument1:compare times, argument2:compare thd ADC_ResetADI_Unlock(); ADC_DebugMsg("Sum_Cmp22Value[%2d]=%d\n", gAdcAp.ucPhase, VIP_FrameCompare(ucCompareTimes, ucComparethd)); return gAdcAp.ucPhase; } else { //Frame compare result collection if(bAutoAdjust == FALSE) { for(ulTestPhase=0; ulTestPhase VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current); //printk(KERN_EMERG" %d ", (VIPttl_current > VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current)); if(array[idx] >= 1) check[(ulTestPhase<<5)/ucPhaseRef] = TRUE; VIPttl_backup = VIPttl_current; } if(check[(ulTestPhase<<5)/ucPhaseRef]) check_cnt++; } } } if(bAutoAdjust == FALSE) { for(ulTestPhase=0;ulTestPhase (lPhase1[ulTestPhase] + lPhase1[(ulTestPhase+2)&0x7])) { ucBestLocation = ulTestPhase; ulNowSummation = (lPhase1[ulTestPhase] + lPhase1[(ulTestPhase+2)&0x7]); if ((lPhase1[ulTestPhase]) > (lPhase1[(ulTestPhase+2)&0x7])) ucBest = (((ucBestLocation+2)&0x7)<<2); else ucBest = ((ucBestLocation&0x7)<<2); } } lPhase2[(ucBestLocation<<2)] =lPhase1[ucBestLocation]; lPhase2[((ucBestLocation+2)&0x7)<<2] =lPhase1[(ucBestLocation+2)&0x7]; } else { //Find the best location with the least P[n-1]+P[n]+P[n+1] ulPreSummation=0xffffffff; for(ulTestPhase=0; ulTestPhase P[%d] is selected and expanded 8 to the 2nd round.\n", (ucBestLocation<<5)/ucPhaseRef); // P2[Q0] = P1[n-2] lPhase2[0] = lPhase1[(ucBestLocation-sample_cnt) & (ucPhaseRef-1)]; // P2[Q1] = P1[n-1] lPhase2[ sample_cnt * (32/ucPhaseRef) - (32/ucPhaseRef)] = lPhase1[(ucBestLocation-1) & (ucPhaseRef-1)]; // P2[Q2] = P1[n] lPhase2[ sample_cnt * (32/ucPhaseRef)] = lPhase1[ucBestLocation]; // P2[Q3] = P1[n+1] lPhase2[ sample_cnt * (32/ucPhaseRef) + (32/ucPhaseRef)] = lPhase1[(ucBestLocation+1) & (ucPhaseRef-1)]; // P2[Q4] = P1[n+2] lPhase2[ sample_cnt * (32/ucPhaseRef<<1)] = lPhase1[(ucBestLocation+sample_cnt) & (ucPhaseRef-1)]; ADC_DebugMsg("Frame compare TH in round 2: 0x%x\n", ucComparethd); for(ulTestPhase=0; ulTestPhase<= sample_cnt * (32/ucPhaseRef*2); ulTestPhase++) { if( (ulTestPhase % (32/ucPhaseRef)) == 0 ) continue; if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) return 0; ADC_SetPhaseDirdect((ulTestPhase + ((ucBestLocation-sample_cnt)<<5)/ucPhaseRef) & 0x1f); ADC_DelayMS(ucDelay); ADC_ResetADI_Unlock(); lPhase2[ulTestPhase]= VIP_FrameCompare(ucCompareTimes, ucComparethd); //argument1:compare times, argument2:compare thd // Check whether horizontal total is defect. VIPttl_backup = *((volatile UINT16*)(0xbe1cf008)); for(idx = 0; idx< 1000 ; idx++) { VIPttl_current = *((volatile UINT16*)(0xbe1cf008)); array[idx] = (VIPttl_current > VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current); //printk(KERN_EMERG" %d ", (VIPttl_current > VIPttl_backup)?(VIPttl_current - VIPttl_backup):(VIPttl_backup - VIPttl_current)); if(array[idx] >= 1) check[(ulTestPhase + ((ucBestLocation-sample_cnt)<<5)/ucPhaseRef) & 0x1f] = TRUE; VIPttl_backup = VIPttl_current; } if(check[(ulTestPhase + ((ucBestLocation-sample_cnt)<<5)/ucPhaseRef) & 0x1f]) check_cnt++; } for(ulTestPhase=0; ulTestPhase<= sample_cnt * (32/ucPhaseRef*2); ulTestPhase++) { ADC_DebugMsg("P2[%2d] = %8ld %s\n", (ulTestPhase + ((ucBestLocation-sample_cnt)<<5)/ucPhaseRef) & 0x1f, lPhase2[ulTestPhase], (check[(ulTestPhase + ((ucBestLocation-sample_cnt)<<5)/ucPhaseRef) & 0x1f])?"NG":" " ); sum = sum + lPhase2[ulTestPhase]; ucBestPhase[ulTestPhase]=(ulTestPhase + ((ucBestLocation-sample_cnt)<<5)/ucPhaseRef) & 0x1f; } if(sum != 0) { ADC_DebugMsg("Best Phase average Sum=%d\n", sum / ((sample_cnt * (32/ucPhaseRef*2)+1)) ); } // Extending the skipping range according to the checked number of defect phase. // For only one defect phase, mark itself and neighboring two, i.e. [n-2]~[n+2]; // Otherwise, mark itself and neighboring one, i.e. [n-1]~[n+1]. for(idx=0; idx<32; idx++) { if(check[idx]) { // Defect phase itself final_check[idx] = TRUE; // Defect phase neighbor with distance 1 final_check[(idx+1)%32] = TRUE; if(idx < 1) final_check[31+idx] = TRUE; else final_check[(idx-1)%32] = TRUE; ADC_DebugMsg(KERN_EMERG"Extending P[%d] with distance = 1 to P[%d] and P[%d]\n", idx , (idx+1)%32 ,(idx < 1)?(31+idx):((idx-1)%32) ); // Defect phase neighbor with distance 2 if(check_cnt == 1) { final_check[(idx+2)%32] = TRUE; if(idx < 2) final_check[30+idx] = TRUE; else final_check[(idx-2)%32] = TRUE; ADC_DebugMsg(KERN_EMERG"Extending P[%d] with distance = 2 to P[%d] and P[%d]\n", idx , (idx+2)%32 ,(idx < 1)?(30+idx):((idx-2)%32) ); } } } //Best phase selection => Sorting ucBestPhase for(i = 0;i < sample_cnt * (32/ucPhaseRef*2); i++) { for(j = i+1;j <= sample_cnt * (32/ucPhaseRef*2); j++) { if(final_check[ucBestPhase[j]]) continue; t=i; if( (lPhase2[t] > lPhase2[j]) || final_check[ucBestPhase[i]] ) { t=j; } if(t !=i) { Temp=lPhase2[t]; lPhase2[t] = lPhase2[i]; lPhase2[i] = Temp; tmp = ucBestPhase[t]; ucBestPhase[t] = ucBestPhase[i]; ucBestPhase[i] = tmp; } } } /* for(i = 0;i <= sample_cnt * (32/ucPhaseRef*2); i++) { ADC_DebugMsg("Best Phase Ranking No.%d = P[%d] %s\n", i+1, ucBestPhase[i], final_check[ucBestPhase[i]]?"NG":" "); } */ ADC_DebugMsg("Best Phase Ranking \n No.1 = P[%d], No.2 = P[%d], No.3 = P[%d], No.4 = P[%d]", ucBestPhase[0], ucBestPhase[1], ucBestPhase[2], ucBestPhase[3]); ucBest=ucBestPhase[0] ; ucBestPhaseIndex=0; } //Still input phase setting ADC_SetPhaseDirdect(ucBest); ADC_DelayMS(ucDelay); //Set phase would be unstable. Wait pll stable. ADC_ResetADI_Unlock(); ADC_DebugMsg("Best Phase=%d\n", ucBest); if( bAutoAdjust == FALSE) { if (sAdcInfo.ucSource == Adc_kSourceVGA) { if( g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr ].ucPixelClock > 130 ) ADC_PhaseDetectedSecond(); } else if(sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { if( g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr ].ucPixelClock > 60 ) ADC_PhaseDetectedSecond(); } } ADC_Clear_Interrupt(0x80); ADC_Write(ADC_REG_int_mask_byte, usInterruptStatus); usVIPHttlMin = usVIPHttlMax = *((volatile UINT16*)(0xbe1cf008)); return ucBest; } void ADC_PhaseDetectedSecond(void) { UINT8 ucBest, i,j,t, tmp;//ulTestPhase, INT32 Temp; if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) return; ADC_SetPhaseDirdect(((ucBestLocation<<2)+2)); ADC_ResetADI_Unlock(); lPhase2[(ucBestLocation<<2)+2] =VIP_FrameCompare(ucCompareTimes, ucComparethd); ucBestPhase[1]=(ucBestLocation<<2)+2; ADC_SetPhaseDirdect(((ucBestLocation<<2)+4)); ADC_ResetADI_Unlock(); lPhase2[(ucBestLocation<<2)+4] =VIP_FrameCompare(ucCompareTimes, ucComparethd); ucBestPhase[2]=(ucBestLocation<<2)+4; ADC_SetPhaseDirdect(((ucBestLocation<<2)+6)); ADC_ResetADI_Unlock(); lPhase2[(ucBestLocation<<2)+6] =VIP_FrameCompare(ucCompareTimes, ucComparethd); ucBestPhase[3]=(ucBestLocation<<2)+6; ADC_DebugMsg("Between phase[%d] & phase[%d]\n", (ucBestLocation<<2), ((ucBestLocation+2)&0x7)<<2); ADC_DebugMsg("Sum_Cmp32Value[%d] =%ld\n", (ucBestLocation<<2), lPhase2[ (ucBestLocation<<2)]); ADC_DebugMsg("Sum_Cmp32Value[%d] =%ld\n", (ucBestLocation<<2)+2, lPhase2[ (ucBestLocation<<2)+2]); ADC_DebugMsg("Sum_Cmp32Value[%d] =%ld\n", (ucBestLocation<<2)+4, lPhase2[ (ucBestLocation<<2)+4]); ADC_DebugMsg("Sum_Cmp32Value[%d] =%ld\n", (ucBestLocation<<2)+6, lPhase2[ (ucBestLocation<<2)+6]); ADC_DebugMsg("Sum_Cmp32Value[%d] =%ld\n", ((ucBestLocation+2)&0x7)<<2, lPhase2[ (((ucBestLocation+2)&0x7)<<2)]); ucBestPhase[4]= (((ucBestLocation+2)&0x7)<<2); ucBest = (ucBestLocation<<2); tmp = lPhase2[(ucBestLocation<<2)]; ucBestPhase[0]=ucBest ; for(i = 0;i < 5; i++) { for(j = i+1;j < 5; j++) { t=i; if(lPhase2[ucBestPhase[t]] > lPhase2[ucBestPhase[j]]) { t=j; } if(t!=i) { Temp=lPhase2[t]; lPhase2[t] = lPhase2[i]; lPhase2[i] = Temp; tmp = ucBestPhase[i]; ucBestPhase[i] = ucBestPhase[j]; ucBestPhase[j] = tmp; } } } ucBest=ucBestPhase[0] ; ucBestPhaseIndex=0; for(i = 0;i < 5; i++) { ADC_DebugMsg("Best Phase[%d]=%d\n", i, ucBestPhase[i]); } //Still input phase setting ADC_SetPhaseDirdect(ucBest); ADC_ResetADI_Unlock(); ADC_DebugMsg("Best Phase=%d\n", ucBest); } BOOL ADC_DoAuto(UINT8 ucPath, BOOL bEnable, UINT8 ucMode) { BOOL RetValue=TRUE; UINT8 value = 0; //fix system handup if no signal or unsupported mode if((sAdcInfo.ucInputMode == UNSUPPORT_MODE) || (sAdcInfo.ucInputMode == NOSIGNAL_MODE)) return FALSE; if (bEnable) { // if ((ADC_InputVesaTiming.ucPixelClock > 140) && (sAdcInfo.ucSource == Adc_kSourceVGA)) bAutoAdjust = TRUE; sAdcInfo.ucUserPhase = ADC_PhaseDetected(); // if ((ADC_InputVesaTiming.ucPixelClock > 140) && (sAdcInfo.ucSource == Adc_kSourceVGA)) bAutoAdjust = FALSE; } else ADC_SetPhaseDirdect(sAdcInfo.ucUserPhase); if ((sAdcInfo.ucSource == Adc_kSourceVGA) || (ucMode == 2)) //"ucMode=2" is a special case, it means PC & YPP sources can all do centering in factory mode { if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) return 0; if (ucMode == 2) { ucMode = 1; //"ucMode=0" means tune only Hstart & Vstart values; "ucMode=1" means tune all Hstart & Vstart & Hactive & Vactive values } ADC_Centering(FALSE); noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_PCSETUPDATE, &value, 1); } return RetValue; } void ADC_TimerWork(void *unuse) { if(ADCTimerInfo[TimerSignaloff][1] == 1) { ADC_Write(ADC_REG_cs2_sog_rst, 0x3); ADC_Write(ADC_REG_cs2_sog_rst, 0x0); } sAdcInfo.bTimerHandlerBusy=FALSE; } void ADC_InterruptProcess(void *unuse) { volatile UINT16 ucLowWidth, ucLineWidth; if( ADC_Read(ADC_REG_dbg_temp)& BIT4 ) { // ADC_DebugMsg("Skip InterruptProcess\n"); return; } sAdcInfo.bInterruptHappen = TRUE; sAdcInfo.bInterruptHappenAgain = FALSE; switch( sAdcInfo.ucInterruptEvent ) { case CheckSogWidth: ADC_DelayMS(1000/(ADC_DetectTiming.ucVFrequency+1)); if( sAdcInfo.bInterruptHappenAgain || sAdcInfo.bModeDetection || sAdcInfo.bModeChange ) return; ADC_SOG_Slicer_Backup(); ADC_DelayMS(1000/(ADC_DetectTiming.ucVFrequency+1)); if( sAdcInfo.bInterruptHappenAgain || sAdcInfo.bModeDetection || sAdcInfo.bModeChange ) return; ucLineWidth = ADC_Read(ADC_STA_line_wdth); ucLowWidth = ADC_Read(ADC_STA_low_wdth); if( abs(sAdcInfo.ucRegLowWidth-ucLowWidth)>15 || abs(sAdcInfo.ucRegLineWidth-ucLineWidth)!=0 ) { printk(KERN_EMERG "[2] Mode change \n"); printk(KERN_EMERG "RegLowWidth=%d, ADC_STA_low_width=%d\n", sAdcInfo.ucRegLowWidth, ucLowWidth); printk(KERN_EMERG "RegLineWidth=%d, ADC_STA_line_width=%d\n", sAdcInfo.ucRegLineWidth, ucLineWidth); ADC_SyncDetectCreate(); return; } ADC_DelayMS(1000/(ADC_DetectTiming.ucVFrequency+1)*2); if( sAdcInfo.bInterruptHappenAgain || sAdcInfo.bModeDetection || sAdcInfo.bModeChange) return; break; case HandlerHSOut: break; case ResetCoast: ADC_Coast_Gen_Backup(); break; case CheckSyncStable: do{ if(sAdcInfo.bInterruptHappenAgain || sAdcInfo.bModeDetection || sAdcInfo.bModeChange) return; if (VIP_InputActiveDetect(EXTS)!=0x0f) ADC_DelayMS(16); else break; }while(sAdcInfo.bInterruptHappen); break; } if( sAdcInfo.bInterruptHappenAgain==FALSE && sAdcInfo.bModeDetection==FALSE && sAdcInfo.bModeChange==FALSE ) { if( sAdcInfo.bSyncDetection==FALSE ) { if ( sAdcInfo.ucInputMode == UNSUPPORT_MODE) VIP_NoticeModeNotSupport(EXTS, ENABLE); else if (sAdcInfo.ucInputMode == NOSIGNAL_MODE) VIP_NoticeModeNotSupport(EXTS, DISABLE); else { ADC_ScreenMode(NormalScreen); VIP_SetAutoTuneStatus(TRUE); } } if(sAdcInfo.ucSource == Adc_kSourceVGA) { ADCTimerInfo[TimerVsyncloss][1] = 1; ADC_Interrupt(ENABLE, 0x7030); } else { ADC_Interrupt(ENABLE, 0x478f); ADCTimerInfo[TimerModeChange][1] = 1; } } sAdcInfo.bInterruptHappen = FALSE; } void ADC_SearchDigitalOffset(void) { VIP_RECT rcRect; UINT8 ucColor, ucStep; UINT32 ulCurrentOffset[MaxColor], ulBestOffset[MaxColor]; UINT32 ulTargetValue[MaxColor], ulOutputValue[MaxColor], ulCurrentDelta; #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE UINT8 ulMaxTime = 9, ucTotalCnt; WBDbgMsg OffsetDebug[MaxColor][ulMaxTime]; #endif BOOL bFound[MaxColor]; UINT32 AvgOffset[MaxColor] = {0}; UINT32 loop_time = 0, MaxAvgTime = 3; ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); if((sAdcInfo.ucInputMode == UNSUPPORT_MODE) || (sAdcInfo.ucInputMode == NOSIGNAL_MODE) || (sAdcInfo.ucInputMode == UNSTABLE_MODE)) { return ; } /// Setup target values and an rectangle AWB region for calculating compenstaion. if(sAdcInfo.ucSource == Adc_kSourceVGA) { ulTargetValue[RED] = OffsetRGBTarget; ulTargetValue[GREEN] = OffsetRGBTarget; ulTargetValue[BLUE] = OffsetRGBTarget; if( sAdcInfo.bHpol==1 ) rcRect.ulHStart = ADC_InputVesaTiming.usHs_Width + ((ADC_DetectTiming.usHstart-ADC_InputVesaTiming.usHs_Width)*3)/4; else rcRect.ulHStart = ((ADC_DetectTiming.usHstart)*3)/4; rcRect.ulHEnd = rcRect.ulHStart + 10*iEnlargeWidthRate; rcRect.ulVStart = ADC_InputVesaTiming.usVstart; rcRect.ulVEnd = ADC_InputVesaTiming.usVstart + ADC_InputVesaTiming.usVactive; } else { ulTargetValue[GREEN] = OffsetYTarget; ulTargetValue[RED] = OffsetCbCrTarget; ulTargetValue[BLUE] = OffsetCbCrTarget; rcRect.ulHStart = ADC_InputVesaTiming.usHs_Width + ((ADC_InputVesaTiming.usHstart-ADC_InputVesaTiming.usHs_Width)*3)/4; rcRect.ulHEnd = rcRect.ulHStart + 10*iEnlargeWidthRate; rcRect.ulVStart = ADC_InputVesaTiming.usVstart + ADC_InputVesaTiming.usVactive/4; rcRect.ulVEnd = ADC_InputVesaTiming.usVstart + ADC_InputVesaTiming.usVactive*3/4; } if( gAdcAp.bApUse && gAdcAp.ulApPosition!=0xffffffff ) { rcRect.ulHStart = gAdcAp.ulApPosition; rcRect.ulHEnd = rcRect.ulHStart+21; } if(gAdcAp.bApUse) { for(ucColor = RED; ucColor Best Offset = (Delta * 512) / (512 + Gain) / 10 \n "); for(ucColor=RED; ucColor AvgOffset[ucColor]) { if (ucColor==RED) ADC_Write(ADC_REG_dofst_r, 0x1); else if(ucColor==GREEN) ADC_Write(ADC_REG_dofst_g, 0x1); else if(ucColor==BLUE) ADC_Write(ADC_REG_dofst_b, 0x1); } else { if (ucColor==RED) ADC_Write(ADC_REG_dofst_r, 0x0); else if(ucColor==GREEN) ADC_Write(ADC_REG_dofst_g, 0x0); else if(ucColor==BLUE) ADC_Write(ADC_REG_dofst_b, 0x0); } ulBestOffset[ucColor] = ulCurrentDelta * 512 / ( ADC_GetGain(ucColor) + 512 ) / 10; bFound[ucColor] = TRUE; } else { #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE OffsetDebug[ucColor][ucStep].ulCurrentSearch = 0; OffsetDebug[ucColor][ucStep].ulCurrentSearchValue = 0; OffsetDebug[ucColor][ucStep].ulDelta= 0; #endif } } ucStep++; } sAdcInfo.bAutoOffset = FALSE; for(ucColor=RED; ucColor= 511)) return TRUE; else return FALSE; } void ADC_SyncDetection(void *unuse) { UINT8 retval; UINT8 value = 0; UINT8 ucPixelClock = 0; UINT16 usHTotal = 0; BOOL AutoAdjustStatus = FALSE; ADC_Clear_Interrupt(0xffff); do{ if(!sAdcInfo.bADCEnable) break; sAdcInfo.bSyncDetection=TRUE; sAdcInfo.bModeDetection=TRUE; bCheckVIPHttl = FALSE; bAutoColorCalibrationDone =FALSE; ADC_Interrupt(DISABLE, 0); #ifdef DRV_ENABLE_CVD2 if (sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { if(ucCVD2PowerEnable==TRUE) { DRV_CVD2_Power_Setting(FALSE); //component cc will open cvd2 ucCVD2PowerEnable=FALSE; } } #endif ADC_ResetAdcInfoSetting(); if(!sAdcInfo.bADCEnable) break; ADC_SourceInit(); udelay(1000); //ADC initialize. Wait 2 V-sync 30ms if(!sAdcInfo.bADCEnable) break; if(gAdcAp.bAutoFlow == FALSE)//For test { sAdcInfo.ucMatchTablePtr = sAdcInfo.ucVesaModeTableEntry = gAdcAp.ucMatchTable; ADC_ModeSetting(); if(sAdcInfo.ucSource == Adc_kSourceVGA) { ucPixelClock = g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucPixelClock*iEnlargeWidthRate; usHTotal = g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHtotal*iEnlargeWidthRate; } else { ucPixelClock = g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucPixelClock*iEnlargeWidthRate; usHTotal = g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].usHtotal*iEnlargeWidthRate; } //ADC_PllSetting(ucPixelClock, usHTotal); if(sAdcInfo.ucSource == Adc_kSourceVGA) { ADC_DetectTiming.usVcount=ADC_InputVesaTiming.usVcount; ADC_DetectTiming.ucVFrequency=ADC_InputVesaTiming.ucVFrequency; ADC_DetectTiming.usHFrequency=ADC_InputVesaTiming.usHFrequency; ADC_DetectTiming.ucFlag=ADC_InputVesaTiming.ucFlag=g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucFlag; } else { ADC_DetectTiming.usVcount=ADC_InputVesaTiming.usVcount; ADC_DetectTiming.ucVFrequency=ADC_InputVesaTiming.ucVFrequency; ADC_DetectTiming.usHFrequency=ADC_InputVesaTiming.usHFrequency; ADC_DetectTiming.ucFlag=ADC_InputVesaTiming.ucFlag=g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr].ucFlag; } ADC_UpdateFlag(ADC_DetectTiming.ucFlag); ADC_CheckPllResetSequence(ucPixelClock, usHTotal); if(sAdcInfo.ucSource == Adc_kSourceVGA) { ADC_Write(ADC_REG_o_hsync_sel,0); ADC_Write(ADC_REG_o_vsync_sel,0x01); } else { ADC_Write(ADC_REG_o_hsync_sel,0); ADC_Write(ADC_REG_o_vsync_sel,0); } retval = Mode_Change_Stable; } else { retval = ADC_Mode_Setup(); } sAdcInfo.bModeDetection=FALSE; sAdcInfo.bModeChange = FALSE; sAdcInfo.bInterruptHappen = FALSE; ADC_Clear_Interrupt(0x80); if(!sAdcInfo.bADCEnable) break; //??interrupt by KMF switch (retval) { case Current_state_Failed: case Csync_stable_i2_failed: case VIP_No_Signal: case Unstable_Timing_Setting: //Added by Jason to clear H and V count for pollingHandler(). sAdcInfo.usHcount = 0; sAdcInfo.usVcount = 0; ADC_DebugMsg("Input Sync unstable\n"); VIP_NoticeModeNotSupport(EXTS, DISABLE); ADC_NoticeKmf(ADCMSG_INPUTPATHSTATUS, FALSE, FALSE); ucLastInputMode = sAdcInfo.ucInputMode; if(sAdcInfo.ucSource == Adc_kSourceVGA) { ADCTimerInfo[TimerVsyncloss][1] = 0; ADC_Interrupt(ENABLE, 0x2000); } else { sAdcInfo.bSyncDetection=FALSE; ADC_Interrupt(ENABLE, 0x02); ADCTimerInfo[TimerSignaloff][1] = 1; } ADCTimerInfo[TimerTunerStrength][1] = 0; break; case Unsupported_Timing: if(ucLastInputMode != UNSUPPORT_MODE) { ADC_DebugMsg("Not support\n"); VIP_NoticeModeNotSupport(EXTS, ENABLE); ADC_NoticeKmf(ADCMSG_INPUTPATHSTATUS, FALSE, TRUE); ADC_DelayMS(100); } ucLastInputMode = sAdcInfo.ucInputMode; if(sAdcInfo.bModeChange) break; if(sAdcInfo.ucSource == Adc_kSourceVGA) { ADCTimerInfo[TimerVsyncloss][1] = 1; ADC_Interrupt(ENABLE, 0x7030); } else { ADCTimerInfo[TimerModeChange][1] = 1; ADC_Interrupt(ENABLE, 0x478f); } ADCTimerInfo[TimerTunerStrength][1] = 0; break; case Mode_Change_Again: sAdcInfo.bModeChange = TRUE; break; case Mode_Change_Stable: if(gAdcAp.bAutoFlow != FALSE) { if(sAdcInfo.ucSource == Adc_kSourceVGA) { ADCTimerInfo[TimerVsyncloss][1] = 1; ADC_Interrupt(ENABLE, 0x7030); } else { ADCTimerInfo[TimerModeChange][1] = 1; ADC_Interrupt(ENABLE, 0x478f); } ADC_DelayMS(60); } //ADCTimerInfo[TimerTunerStrength][1] = 1; ADC_NoticeKmf(ADCMSG_INPUTPATHSTATUS, TRUE, FALSE); ADC_SendInfo(); if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) break; if (sAdcInfo.ucSource != Adc_kSourceVGA) { ADC_Write(ADC_REG_cs2_r_clamp_ref_edge, 0); ADC_Write(ADC_REG_cs2_g_clamp_ref_edge, 0); ADC_Write(ADC_REG_cs2_b_clamp_ref_edge, 0); } else { ADC_Write(ADC_REG_cs2_r_clamp_ref_edge, 1); ADC_Write(ADC_REG_cs2_g_clamp_ref_edge, 1); ADC_Write(ADC_REG_cs2_b_clamp_ref_edge, 1); } if(sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { if( (sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_480I60 ) || (sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_576I50)) { //avoid touch sync or data, clamp width = 280ns ADC_Write(ADC_REG_cs2_r_clamp_start, 0x10); ADC_Write(ADC_REG_cs2_r_clamp_width, 0x10); ADC_Write(ADC_REG_cs2_g_clamp_start, 0x10); ADC_Write(ADC_REG_cs2_g_clamp_width, 0x10); ADC_Write(ADC_REG_cs2_b_clamp_start, 0x10); ADC_Write(ADC_REG_cs2_b_clamp_width, 0x10); } else if ((sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_480P60) || (sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_576P50)) { ADC_Write(ADC_REG_cs2_r_clamp_start, 0xd); ADC_Write(ADC_REG_cs2_r_clamp_width, 0xd); ADC_Write(ADC_REG_cs2_g_clamp_start, 0xd); ADC_Write(ADC_REG_cs2_g_clamp_width, 0xd); ADC_Write(ADC_REG_cs2_b_clamp_start, 0xd); ADC_Write(ADC_REG_cs2_b_clamp_width, 0xd); } else { if (sAdcInfo.bInterlace) { ADC_Write(ADC_REG_cs2_r_clamp_start, 0xa); ADC_Write(ADC_REG_cs2_r_clamp_width, 0x6); ADC_Write(ADC_REG_cs2_g_clamp_start, 0xa); ADC_Write(ADC_REG_cs2_g_clamp_width, 0x6); ADC_Write(ADC_REG_cs2_b_clamp_start, 0xa); ADC_Write(ADC_REG_cs2_b_clamp_width, 0x6); } else { if ((sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_1080P50) ||(sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_1080P60)) { ADC_Write(ADC_REG_cs2_r_clamp_start, 0x6); ADC_Write(ADC_REG_cs2_g_clamp_start, 0x6); ADC_Write(ADC_REG_cs2_b_clamp_start, 0x6); } else { ADC_Write(ADC_REG_cs2_r_clamp_start, 0xa); ADC_Write(ADC_REG_cs2_g_clamp_start, 0xa); ADC_Write(ADC_REG_cs2_b_clamp_start, 0xa); } ADC_Write(ADC_REG_cs2_r_clamp_width, 0x4); ADC_Write(ADC_REG_cs2_g_clamp_width, 0x4); ADC_Write(ADC_REG_cs2_b_clamp_width, 0x4); } } } else { ADC_Write(ADC_REG_r_sb1, 0x13); ADC_Write(ADC_REG_g_sb1, 0x13); ADC_Write(ADC_REG_b_sb1, 0x13); } ADC_Write(ADC_REG_csgen_start, 0x26); ADC_Write(ADC_REG_cvbs_clamp_mode_g, 0); sAdcInfo.bWBUpdate=TRUE; if(sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2) { DRV_ADC_SetGain(RED,435); DRV_ADC_SetGain(GREEN,420); DRV_ADC_SetGain(BLUE,427); DRV_ADC_SetOffset(RED,407); DRV_ADC_SetOffset(GREEN,107); DRV_ADC_SetOffset(BLUE,422); } else { DRV_ADC_SetGain(RED,310); DRV_ADC_SetGain(GREEN,299); DRV_ADC_SetGain(BLUE,306); DRV_ADC_SetOffset(RED,181); DRV_ADC_SetOffset(GREEN,191); DRV_ADC_SetOffset(BLUE,196); } ADC_Write(ADC_REG_lcg_refdbg_sel_temp, 0); sAdcInfo.bWBUpdate=FALSE; if( sAdcInfo.bInterlace ) VIP_TopDetect(SOURCE_EXTS); if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) break; bAutoWB = TRUE; ADC_AutoColorCalibration(); //move normal screen before doing phase and centering to make display time shorter if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) break; else { ADC_ScreenMode(NormalScreen); VIP_SetAutoTuneStatus(TRUE); } if(!FactoryModeAWB || sAdcInfo.ucSource == Adc_kSourceVGA) { AutoAdjustStatus = TRUE; noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_AUTOADJUST, &AutoAdjustStatus, 1); } #ifndef CONFIG_QSD if(!FactoryModeAWB) // Skip phase detection when AWB in factory mode. { bAutoAdjust = TRUE; sAdcInfo.ucUserPhase = ADC_PhaseDetected(); bAutoAdjust = FALSE; ADC_DelayMS(50); ADC_SearchDigitalOffset(); bCheckVIPHttl = TRUE; } #endif if ( sAdcInfo.ucSource == Adc_kSourceVGA ) { if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) break; ADC_Centering(FALSE); // Set FALSE for ignoring mute mechanism when size is revised during centering procedure. noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_PCSETUPDATE, &value, 1); } if(!FactoryModeAWB || sAdcInfo.ucSource == Adc_kSourceVGA) { AutoAdjustStatus = FALSE; noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_AUTOADJUST, &AutoAdjustStatus, 1); } //ADC_DelayMS(300); // signal is unstable when switching timing on Chroma_22293. if(sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { if (sAdcInfo.ucTimingModeIndex == PLF_VIDEO_TIMING_ID_DTV_576I50) { ADC_Write(ADC_REG_iir_fbpn1_i_8, 0); ADC_Write(ADC_REG_iir_fbppn1_i_8, 1); } } break; } sAdcInfo.bSyncDetection=FALSE; if(gAdcAp.bDisableInterrupt) { sAdcInfo.bModeChange = FALSE; ADC_Interrupt(DISABLE, 0); ADCTimerInfo[TimerSignaloff][1] = 0; } }while(sAdcInfo.bModeChange && sAdcInfo.bADCEnable); //interrupt flag that needs to handle } void ADC_SourceSelect(UINT8 ucSubInputSource, BOOL bEnable) { BOOL cancel_result = FALSE; ADC_DebugMsg("%s\n", __FUNCTION__); if(sAdcInfo.bADCEnable == bEnable) return; sAdcInfo.bFactoryMode = FALSE; // Set default VGA-WAKEUP Bottom Range Number *((volatile UINT8*)0xbe0f0700) = 0x2e; sAdcInfo.bADCEnable = bEnable; sAdcInfo.ucSource = ucSubInputSource; sAdcInfo.bInterruptHappen = FALSE; sAdcInfo.bInterruptHappenAgain = FALSE; sAdcInfo.ucScreenMode = 0xf; ucLastInputMode = 0xf; sAdcInfo.ucInputMode = 0xf; ADC_Clear_Interrupt(0xffff); ADC_Interrupt(DISABLE, 0); ADC_ResetApSetting(); if(sAdcInfo.ucSource == Adc_kSourceVGA) { sAdcInfo.usHcountModeChange = 8; sAdcInfo.usVcountModeChange = 5; } else { sAdcInfo.usHcountModeChange = 30; sAdcInfo.usVcountModeChange = 15; } if(sAdcInfo.bADCEnable == ENABLE) { ADC_DebugMsg("ADC on\n"); DRV_ADC_power(ENABLE); ADC_Write(GLB_REG_global_reset, 0); udelay(1000); //Wait MMIO write data in register. 1ms ADC_Write(GLB_REG_global_reset, 1); ADC_StartTimerFun(&ADCContext, ADC_TimerFun); sAdcInfo.bSyncDetection=TRUE; queue_delayed_work(pADC_WQSyncDetection, &ADCSyncDetectionThread, 0); } else { cancel_result = cancel_delayed_work(&ADCTunerStrengthThread); if(cancel_result) flush_workqueue(pADC_WQTunerStrength); ADC_StopTimerFun(&ADCContext); cancel_result = cancel_delayed_work(&ADCSyncDetectionThread); if(cancel_result) flush_workqueue(pADC_WQSyncDetection); DRV_ADC_power(DISABLE); ADC_DebugMsg("ADC off\n"); } } void ADC_Open(void) { printk(KERN_EMERG"%s:\n",__FUNCTION__); Source[Adc_kSourceVGA].bFirstTime = TRUE; Source[Adc_kSourceCOMP1].bFirstTime = Source[Adc_kSourceCOMP2].bFirstTime = Source[Adc_kSourceCOMP3].bFirstTime = TRUE; } void ADC_Close(void) { printk(KERN_EMERG"%s:\n",__FUNCTION__); if(sAdcInfo.bADCEnable == TRUE) { sAdcInfo.bADCEnable = FALSE; ADC_Interrupt(DISABLE, 0); ADC_StopTimerFun(&ADCContext); #ifdef DRV_ENABLE_CVD2 if (sAdcInfo.ucSource == Adc_kSourceCOMP1 || sAdcInfo.ucSource == Adc_kSourceCOMP2 || sAdcInfo.ucSource == Adc_kSourceCOMP3) { if(ucCVD2PowerEnable==TRUE) { DRV_CVD2_Disable_Ypp_CC(); DRV_CVD2_Power_Setting(FALSE); //component cc will open cvd2 ucCVD2PowerEnable=FALSE; } } #endif flush_workqueue(pADC_WQSyncDetection); flush_workqueue(pADC_WQTunerStrength); DRV_ADC_power(DISABLE); } } void ADC_InfoSet(UINT8 ucFunID, INT32 iValue) { } INT32 ADC_InfoGet(UINT8 ucFunID) { INT32 iValue= -1; return iValue; } void DRV_ADC_GetAutoColorValue(ADCCalibrate_OSDGainOffset_t* pstConfig) { ADC_UpdateWBOSDvalue(); pstConfig->scOSDRGainValue=ADCCalibrate_OSDGainOffset.scOSDRGainValue; pstConfig->scOSDGGainValue=ADCCalibrate_OSDGainOffset.scOSDGGainValue; pstConfig->scOSDBGainValue=ADCCalibrate_OSDGainOffset.scOSDBGainValue; pstConfig->scOSDROffsetValue=ADCCalibrate_OSDGainOffset.scOSDROffsetValue; pstConfig->scOSDGOffsetValue=ADCCalibrate_OSDGainOffset.scOSDGOffsetValue; pstConfig->scOSDBOffsetValue=ADCCalibrate_OSDGainOffset.scOSDBOffsetValue; pstConfig->bResult=ADCCalibrate_OSDGainOffset.bResult; } EXPORT_SYMBOL(DRV_ADC_GetAutoColorValue); void ADC_SearchGain(BOOL bAutoGainMode) { VIP_RECT rcRect; UINT8 ucColor, ucStep, ucTotalCnt; UINT8 ucRegChannelSel[MaxColor]={0}, ucClampWidth[MaxColor]={0}, ucRegClampExt=0, ucClampPwdMode; UINT32 ulCurrentGain[MaxColor], ulBestGain[MaxColor], ulTargetValue[MaxColor]; UINT32 ulHighValue[MaxColor] = {0}, ulLowValue[MaxColor] = {0}, ulCodeDiff; #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE UINT8 ulMaxTime = 8; WBDbgMsg GainDebug[MaxColor][ulMaxTime]; #endif BOOL bFound[MaxColor]; UINT32 Buf[MaxColor] = {0}, BufDelta[MaxColor] = {0}, AvgHigh[MaxColor] = {0},AvgLow[MaxColor] = {0}; BOOL AWB_Stable; UINT8 AWB_TH = 30, Avg_cnt = 3, Avg_loop = 0; ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); // Disable enhance pull down before switching RGB input select ADC_Write(ADC_REG_r_epd12v, 0); ADC_DelayMS(10); if(sAdcInfo.ucSource == Adc_kSourceVGA) { // In order to get correct region for AWB, setup offset before centering. DRV_ADC_SetOffset(RED,0); DRV_ADC_SetOffset(GREEN,0); DRV_ADC_SetOffset(BLUE,0); ADC_Write(ADC_REG_lcg_r33vcm_sel,7); ADC_Write(ADC_REG_lcg_g33vcm_sel,7); ADC_Write(ADC_REG_lcg_b33vcm_sel,7); //Get VIP ADC_DetectTiming Info //ADC_Centering(0); ADC_Write(ADC_REG_lcg_r33vcm_sel,1); ADC_Write(ADC_REG_lcg_g33vcm_sel,1); ADC_Write(ADC_REG_lcg_b33vcm_sel,1); } else { // Enable SoG clamp ADC_Write(ADC_REG_sc_stb_vs_sth, 7); // Disable data clamp ADC_Write(ADC_REG_g_clamppdn_mod, 3); // Adjsut clamp level to 500 mV ADC_Write(ADC_REG_g_sb1, 0x19); } /// Setup target values and an rectangle AWB region for calculating compenstaion. if(sAdcInfo.ucSource == Adc_kSourceVGA) { ulTargetValue[RED] = GainRGBCodeDiff; ulTargetValue[GREEN] = GainRGBCodeDiff; ulTargetValue[BLUE] = GainRGBCodeDiff; if( sAdcInfo.bHpol==1 ) rcRect.ulHStart = ADC_InputVesaTiming.usHs_Width + ((ADC_DetectTiming.usHstart-ADC_InputVesaTiming.usHs_Width)*3)/4; else rcRect.ulHStart = ((ADC_DetectTiming.usHstart)*3)/4; rcRect.ulHEnd = rcRect.ulHStart + 10*iEnlargeWidthRate; rcRect.ulVStart = ADC_InputVesaTiming.usVstart; rcRect.ulVEnd = ADC_InputVesaTiming.usVstart + ADC_InputVesaTiming.usVactive; } else { ulTargetValue[RED] = GainCbCrCodeDiff; ulTargetValue[GREEN] = GainYCodeDiff; ulTargetValue[BLUE] = GainCbCrCodeDiff; rcRect.ulHStart = ADC_InputVesaTiming.usHs_Width + ((ADC_InputVesaTiming.usHstart-ADC_InputVesaTiming.usHs_Width)*3)/4; rcRect.ulHEnd = rcRect.ulHStart + 10*iEnlargeWidthRate; rcRect.ulVStart = ADC_InputVesaTiming.usVstart + ADC_InputVesaTiming.usVactive/4; rcRect.ulVEnd = ADC_InputVesaTiming.usVstart + ADC_InputVesaTiming.usVactive*3/4; } if( gAdcAp.bApUse && gAdcAp.ulApPosition!=0xffffffff ) { rcRect.ulHStart = gAdcAp.ulApPosition; rcRect.ulHEnd = rcRect.ulHStart+21; } if(gAdcAp.bApUse) { for(ucColor = RED; ucColor 5) { ADC_DebugMsg("### Cannot get stable compensation results. ###\n\n"); break; } ADC_DelayMS(10); if((sAdcInfo.ucInputMode == 0xf) ||(sAdcInfo.ucInputMode == UNSUPPORT_MODE) || (sAdcInfo.ucInputMode == NOSIGNAL_MODE) || (sAdcInfo.ucInputMode == UNSTABLE_MODE)) break; if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) break; // Backup previous sampling point compensation result, value would be 0 in the first round. for(ucColor=RED; ucColor 5) { ADC_DebugMsg("### Cannot get stable compensation results. ###\n\n"); break; } ADC_DelayMS(10); if((sAdcInfo.ucInputMode == 0xf) ||(sAdcInfo.ucInputMode == UNSUPPORT_MODE) || (sAdcInfo.ucInputMode == NOSIGNAL_MODE) || (sAdcInfo.ucInputMode == UNSTABLE_MODE)) break; if(sAdcInfo.bModeChange || !sAdcInfo.bADCEnable || sAdcInfo.bModeDetection) break; // Backup previous sampling point compensation result, value would be 0 in the first round. for(ucColor=RED; ucColor ( ( ( (Target * 1.5)/CodeDiff - 1) * 512) ) - 1 \n "); for(ucColor=RED; ucColor sAdcInfo.usHcountModeChange || abs(sAdcInfo.usVcount-usAdcVcnt) > sAdcInfo.usVcountModeChange|| sAdcInfo.bHpol != ucHPol || sAdcInfo.bVpol != ucVPol || abs(sAdcInfo.ulVsyncWidth-ulVsyncWidth)>10) { printk(KERN_EMERG "[3] Mode change\n"); printk(KERN_EMERG "AdcInfo: Hcount=%d Vcount=%d Hpol=%d Vpol=%d VsyncWidth=%d\n", sAdcInfo.usHcount, sAdcInfo.usVcount, sAdcInfo.bHpol, sAdcInfo.bVpol, sAdcInfo.ulVsyncWidth); printk(KERN_EMERG "AdcHttl=%d AdcVcnt=%d HPol=%d VPol=%d VsyncWidth=%d\n", usAdcHttl, usAdcVcnt, ucHPol, ucVPol, ulVsyncWidth); ucAction = 1; } } else { UINT16 usAdcHttl=0, usAdcVcnt=0; usAdcHttl = ADC_Read(ADC_STA_latched_stable_htotal); usAdcVcnt = ADC_Read(ADC_STA_latched_stable_vtotal); if(abs(sAdcInfo.usHcount-usAdcHttl) > sAdcInfo.usHcountModeChange || abs(sAdcInfo.usVcount-usAdcVcnt) > sAdcInfo.usVcountModeChange) { printk(KERN_EMERG "[4] Mode change\n"); printk(KERN_EMERG "AdcInfo: usHcount=%d Vcount=%d\n", sAdcInfo.usHcount, sAdcInfo.usVcount); printk(KERN_EMERG "AdcHttl=%d AdcVcnt=%d\n", usAdcHttl, usAdcVcnt); ucAction = 1; } else if( abs(sAdcInfo.ucRegLowWidth - ADC_Read(ADC_STA_low_wdth) ) > 10 || abs(sAdcInfo.ucRegLineWidth - ADC_Read(ADC_STA_line_wdth) ) > 1 ) { printk(KERN_EMERG "[5] Mode change\n"); printk(KERN_EMERG "sAdcInfo: RegLowWidth=%d ADC_STA_low_wdth=%d\n", sAdcInfo.ucRegLowWidth, ADC_Read(ADC_STA_low_wdth)); printk(KERN_EMERG "sAdcInfo: RegLineWidth=%d ADC_STA_line_wdth=%d\n", sAdcInfo.ucRegLineWidth, ADC_Read(ADC_STA_line_wdth)); ucAction = 1; } } if( ucAction!=1 && sAdcInfo.bSyncDetection==FALSE ) { //PC source change mode has serious flicker and garbage issue VIP_ADIReset(); //1080p23 change to 1080p24, 1080p29 change to 1080p30, OSD show no signal if (VIP_InputActiveDetect(EXTS)!=0x0f) { printk(KERN_EMERG "Sync Unstable\n"); ucAction = 5; } else { if (sAdcInfo.ucInputMode == UNSUPPORT_MODE) break; else { ADC_ScreenMode(NormalScreen); VIP_SetAutoTuneStatus(TRUE); } } } break; } if(sAdcInfo.ucSource == Adc_kSourceVGA) { if((usStatus&0x10) == 0x10) { printk(KERN_EMERG "HSYNC NON-ACTIVE\n"); ucAction = 1; break; } } else { if((usStatus&0x0100) == 0x0100) { printk(KERN_EMERG "CSync NON-ACTIVE\n"); sAdcInfo.ucInputMode = UNSTABLE_MODE; sAdcInfo.bModeChange = TRUE; ucAction = 1; break; } else if((usStatus&0x0400) == 0x0400) { //Qisheng DVD-8170_ 576I Change mode to 576P fail printk(KERN_EMERG "I->P detected\n"); ucAction = 1; break; } } if((usStatus&0x1) == 0x1) { if(ADC_Read(ADC_STA_cs_active) == 0) { printk(KERN_EMERG "SOG no signal\n"); ucAction = 1; } else { printk(KERN_EMERG "Wait CS non-active interrupt\n"); ucAction = 2; } } else if( (usStatus&0xc)>0 ) { if((usStatus&0xc) == 0x8) { if(ucLossSyncCount == 4) { printk(KERN_EMERG "Hsync loss\n"); ADC_Write(ADC_REG_loss_sync_update, 0); ADC_Write(ADC_REG_synct_too_low_update, 0); ucLossSyncCount=0; } else ucLossSyncCount++; } printk(KERN_EMERG "Loss sync\n"); if (sAdcInfo.ucInputMode == UNSUPPORT_MODE) ucAction = 1; else ucAction = 2; } else if(ADC_Read(ADC_STA_cstable_i2) == 0 && (usStatus&0x1000) == 0x1000) { //1080i50 & 1080i59 timing switch, 1080i50 HS out fail if( sAdcInfo.ucSource !=Adc_kSourceVGA ) ucAction = 2; if( sAdcInfo.bSyncDetection==FALSE && sAdcInfo.ucInputMode != UNSUPPORT_MODE) ADC_ScreenMode(BlackScreen); printk(KERN_EMERG "Coast fail! Dig_rst\n"); } else if( (usStatus&0x80)==0x80 ) { printk(KERN_EMERG "HS out fail\n"); //1080i50 & 1080i59 timing switch, 1080i50 HS out fail if( sAdcInfo.bSyncDetection== false && abs( sAdcInfo.ucRegLowWidth - ADC_Read(ADC_STA_low_wdth) ) > 10) { if( sAdcInfo.bSyncDetection== false && abs( sAdcInfo.ucRegLowWidth - ADC_Read(ADC_STA_low_wdth) ) > 10) { if( sAdcInfo.bSyncDetection== false && abs( sAdcInfo.ucRegLowWidth - ADC_Read(ADC_STA_low_wdth) ) > 10) { printk(KERN_EMERG "[6] Mode change\n"); printk(KERN_EMERG "sAdcInfo: RegLowWidth=%d ADC_STA_low_wdth=%d\n", sAdcInfo.ucRegLowWidth, ADC_Read(ADC_STA_low_wdth)); printk(KERN_EMERG "sAdcInfo: RegLineWidth=%d ADC_STA_line_wdth=%d\n", sAdcInfo.ucRegLineWidth, ADC_Read(ADC_STA_line_wdth)); ucAction = 1; break; } } } usVIPHttl = *((volatile UINT16*)(0xbe1cf010)); usVIPVcnt = *((volatile UINT16*)(0xbe1cf014)); if( sAdcInfo.ucSource != Adc_kSourceVGA ) { if(abs(sAdcInfo.usHcount - usVIPHttl) > sAdcInfo.usHcountModeChange || abs(sAdcInfo.usVcount - usVIPVcnt) > sAdcInfo.usVcountModeChange) { printk(KERN_EMERG "[7] Mode change\n"); printk(KERN_EMERG "sAdcInfo: Hcount=%d Vcount=%d\n", sAdcInfo.usHcount, sAdcInfo.usVcount); printk(KERN_EMERG "VIPHttl=%d VIPVcnt=%d\n", usVIPHttl, usVIPVcnt); ucAction = 1; } } } else if( (usStatus & 0x4000) == 0x4000) { if( sAdcInfo.ucSource !=Adc_kSourceVGA ) ucAction = 2; if( sAdcInfo.bSyncDetection==FALSE && sAdcInfo.ucInputMode != UNSUPPORT_MODE) ADC_ScreenMode(BlackScreen); printk(KERN_EMERG "Hsync Miss\n"); } break; } printk(KERN_EMERG "CurSta=%x\n", ucCurState); printk(KERN_EMERG "STAInt=%x\n", usStatus); printk(KERN_EMERG "Action = <0x%x>\n", ucAction); switch(ucAction) { case 0: sAdcInfo.bSyncDetection=TRUE; queue_delayed_work(pADC_WQSyncDetection, &ADCSyncDetectionThread, 0); break; case 1: ADC_SyncDetectCreate(); break; case 2: queue_delayed_work(pADC_WQInterruptProcess, &ADCInterruptProcessThread, 0); ADC_Interrupt(ENABLE, 0x000d); sAdcInfo.ucInterruptEvent = CheckSogWidth; if( sAdcInfo.bSyncDetection==FALSE ) ADC_ScreenMode(BlackScreen); if( sAdcInfo.bInterruptHappen==TRUE ) sAdcInfo.bInterruptHappenAgain = TRUE; sAdcInfo.bInterruptHappen = TRUE; return; case 5: queue_delayed_work(pADC_WQInterruptProcess, &ADCInterruptProcessThread, 0); ADC_Interrupt(ENABLE, 0x000d); sAdcInfo.ucInterruptEvent = CheckSyncStable; sAdcInfo.bInterruptHappen = TRUE; return; case 0xff: break; } } static irqreturn_t ADC_Isr(INT32 irq, void* dev_id, struct pt_regs *regs) { ADC_InterruptHandler(); return IRQ_HANDLED; } static struct irqaction adc_irqaction = { .handler = (void*)&ADC_Isr, .flags = 0,//SA_INTERRUPT, .name = "adc", }; static void ADC_Dispatch(struct pt_regs *regs) { do_IRQ(ADC_SYNC_IRQ);//,regs); } static irqreturn_t ADC_VGA_WakeupIsr(INT32 irq, void* dev_id, struct pt_regs *regs) { static UINT8 debounce = 0; static BOOL VGAPlugStatus = FALSE; //printk("\n >>>> VGA Wake up !!! (%d) ===> 0x703 = 0x%x , 0x70f = 0x%x ####\n", VGAPlugStatus, *((volatile UINT8*)0xbe0f0703), *((volatile UINT8*)0xbe0f070f) ); if( !VGAPlugStatus ) { if( (sAdcInfo.bFactoryMode||(debounce > 1) ) && ((*((volatile UINT8*)0xbe0f070f)) & 1) ) { VGAPlugStatus = TRUE; printk("\n << VGA >> Notice Plug in\n\n"); noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_VGAPLUGIN, &VGAPlugStatus, sizeof(BOOL)); // Clear interrupt status => byte 0xbe0f0703 0xe0 *((volatile UINT8*)0xbe0f0703) = 0xe0; // Disable connect event interrupt *((volatile UINT8*)0xbe0f0703) = 0x00; // Enable disconnect event interrupt *((volatile UINT8*)0xbe0f070f) = 0xd0; debounce = 0; } else { // Clear interrupt status and enable connect event for debounce confirm debounce++; *((volatile UINT8*)0xbe0f0703) = 0xe0; *((volatile UINT8*)0xbe0f070f) = 0x30; } } else { if( (sAdcInfo.bFactoryMode||(debounce > 1) ) && ((*((volatile UINT8*)0xbe0f070f)) & 1) ) { VGAPlugStatus = FALSE; printk("\n << VGA >> Notice Plug out\n\n"); noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_VGAPLUGIN, &VGAPlugStatus, sizeof(BOOL)); // Clear interrupt status => byte 0xbe0f070f 0xf0 *((volatile UINT8*)0xbe0f070f) = 0xf0; // Disable disconnect event interrupt *((volatile UINT8*)0xbe0f070f) = 0x10; // Enable connect event interrupt *((volatile UINT8*)0xbe0f0703) = 0xc0; debounce = 0; } else { // Clear interrupt status and enable disconnect event for debounce confirm debounce++; *((volatile UINT8*)0xbe0f070f) = 0xf0; *((volatile UINT8*)0xbe0f0703) = 0x20; } } //printk("\n <<<< VGA Wake up !!! (%d) ===> 0x703 = 0x%x , 0x70f = 0x%x ####\n", VGAPlugStatus, *((volatile UINT8*)0xbe0f0703), *((volatile UINT8*)0xbe0f070f) ); return IRQ_HANDLED; } static struct irqaction adc_vga_irqaction = { .handler = (void*)&ADC_VGA_WakeupIsr, .flags = 0,//SA_INTERRUPT, .name = "VGA_Wakeup", }; static void ADC_VGA_Plug(struct pt_regs *regs) { do_IRQ(ADC_VGA_WAKEUP_IRQ);//,regs); } void ADC_Standby(void) { sAdcInfo.bFactoryMode = TRUE; // For easier wake up during standby state, decrease VGA-WAKEUP Bottom Range Number *((volatile UINT8*)0xbe0f0700) = 0x01; printk("\n >>>>>>> ADC Standby \n\n\n"); } void ADC_WakeUp(void) { sAdcInfo.bFactoryMode = FALSE; *((volatile UINT8*)0xbe0f0700) = 0x2e; printk("\n >>>>>>> ADC Wake Up \n\n\n"); } void ADC_ResetADI_Unlock(void) { //ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); if(ADC_DetectTiming.ucVFrequency == 0) return; VIP_ResetADIEnable(); } void ADC_SystemChipID(void) { sAdcInfo.ulChipID = ((*((UINT32 *)0xbe000000)&0xffff0000)>>8) | *((UINT8 *)0xbe000005); ADC_DebugMsg("Chip ID=%x \n", sAdcInfo.ulChipID); } UINT8 DRV_ADC_DgSourceStatus(void) { //For the component CC 1 line shift issue return ADC_Read(ADC_REG_source_sel); } EXPORT_SYMBOL(DRV_ADC_DgSourceStatus); void ADC_OverSample(void) { if (sAdcInfo.ucSource == Adc_kSourceVGA) { if(g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr ].usHtotal<= 1024 && g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr ].ucPixelClock<42) iEnlargeWidthRate = 1; else if (((g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr ].usHtotal> 1024)&& (g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr ].usHtotal<= 2048) ) && (g_stADCTimingTbl.pVgaVideoTimingTable[sAdcInfo.ucMatchTablePtr ].ucPixelClock<84 ) ) iEnlargeWidthRate = 1; else iEnlargeWidthRate = 1; } else { if(g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr ].usHtotal<= 1024 && g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr ].ucPixelClock<42) iEnlargeWidthRate = 1; else if (((g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr ].usHtotal> 1024)&& (g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr ].usHtotal<= 2048) ) && (g_stADCTimingTbl.pYppVideoTimingTable[sAdcInfo.ucMatchTablePtr ].ucPixelClock<84 ) ) iEnlargeWidthRate = 1; else iEnlargeWidthRate =1; } } BOOL ADC_CheckInterlaceMode(void) { ADC_DebugMsg("%s %d\n", __FUNCTION__,__LINE__); if ((abs(ADC_DetectTiming.usVcount - 262) <5 ) || (abs(ADC_DetectTiming.usVcount - 312) <5 ) || (abs(ADC_DetectTiming.usVcount - 562) <5 )) { ADC_DebugMsg( "Advance check Interlace Mode=%d \n", (ADC_DetectTiming.ucFlag & BIT0)); // ADC_DetectTiming.ucFlag |= 1; return ((ADC_DetectTiming.ucFlag & BIT0)? 1:0); } else if ((abs(ADC_DetectTiming.usVcount - 525) <5 ) || (abs(ADC_DetectTiming.usVcount - 750) <5 )|| (abs(ADC_DetectTiming.usVcount - 1125) <5 )) { ADC_DebugMsg( "Advance check Progressive Mode=%d \n", (ADC_DetectTiming.ucFlag & BIT0)); // ADC_DetectTiming.ucFlag |= 0; return ((ADC_DetectTiming.ucFlag & BIT0)? 0:1); } else if (abs(ADC_DetectTiming.usVcount - 625) <5 ) { ADC_DebugMsg( "1050i@50Hz conflict with 576i@50hz use RegLowWidth=%d \n", sAdcInfo.ucRegLowWidth); if (sAdcInfo.ucRegLowWidth < 250 ) ADC_DetectTiming.ucFlag = 1; else ADC_DetectTiming.ucFlag = 0; return TRUE; } else return FALSE; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) LONG adc_ioctl(struct file *file,UINT32 cmd,ULONG arg) #else ssize_t adc_ioctl(struct inode *inode,struct file *file,UINT32 cmd,ULONG arg) #endif { adc_ioctl_data parameter; UINT8 ucColor, value = 0; UINT16 usData[MaxColor]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) down (&adc_ioctl_semaphore); #endif switch(cmd) { case ADC_IOCTL0: //Get data from user space //copy_from_user(¶meter,(void*)arg,sizeof(adc_ioctl_data)); //Do something ... //printk("Get data from user application : 0x%08x\n",parameter.data);//example //printk(KERN_EMERG"arg=%ld\n",arg); //parameter.data&=0xffff0000; //example //Write data into user space //copy_to_user((void*)arg,¶meter,sizeof(adc_ioctl_data)); break; case ADC_IOCTL1: break; case ADC_CHANGE_FLOW: copy_from_user(¶meter,(pAdc_ioctl_data)arg,sizeof(adc_ioctl_data)); printk(KERN_EMERG"Auto flow=%d\n", parameter.bChangeFlow); printk(KERN_EMERG"Timing=%d\n", parameter.ucMatchTablePtr); if(sAdcInfo.ucSource == Adc_kSourceVGA) { if(parameter.ucMatchTablePtr < g_stADCTimingTbl.VgaVideoTimingTblSize) { gAdcAp.bAutoFlow = parameter.bChangeFlow; gAdcAp.ucMatchTable = parameter.ucMatchTablePtr; ADC_SyncDetectCreate(); } } else { if(parameter.ucMatchTablePtr < g_stADCTimingTbl.YppVideoTimingTblSize) { gAdcAp.bAutoFlow = parameter.bChangeFlow; gAdcAp.ucMatchTable = parameter.ucMatchTablePtr; ADC_SyncDetectCreate(); } } break; case ADC_AUTO_GAIN: copy_from_user(¶meter,(pAdc_ioctl_data)arg,sizeof(adc_ioctl_data)); printk(KERN_EMERG "Auto Gain\n"); for(ucColor = RED; ucColor= KERNEL_VERSION(3,0,8) up(&adc_ioctl_semaphore); #endif return 0; } struct file_operations adc_fops = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) .unlocked_ioctl = adc_ioctl, #else .ioctl = adc_ioctl, #endif .owner = THIS_MODULE, }; INT32 __init DRV_ADC_Linuxinit(void) { INT32 err,devno; UINT32 CPLL_MClk = 0; UINT32 ratio = 0; printk(KERN_EMERG"%s: \n",__FUNCTION__); ADC_SystemChipID(); DRV_ADC_power(ENABLE); devno=MKDEV(ADC_DEV_MAJOR,0); cdev_adc = cdev_alloc(); cdev_adc->owner = THIS_MODULE; cdev_adc->ops = &adc_fops; err = cdev_add (cdev_adc,devno,1); set_vi_handler(ADC_SYNC_IRQ,(void*)&ADC_Dispatch); setup_irq(ADC_SYNC_IRQ,&adc_irqaction); set_vi_handler(ADC_VGA_WAKEUP_IRQ, (void*)&ADC_VGA_Plug); setup_irq(ADC_VGA_WAKEUP_IRQ,&adc_vga_irqaction); // Enable VGA-WAKEUP Function & Interrupt *((volatile UINT8*)0xbe0f0703) = 0xc0; // Setup Top Range Number for VGA WAKEUP event trigering *((volatile UINT8*)0xbe0f0701) = 0xff; // VGA INTERUPT SELECTION(0x70f[4]) // 1: To detect vsync or hsync / 0: To detect vsync and hsync *((volatile UINT8*)0xbe0f070f) = 0x10; pADC_WQSyncDetection=create_workqueue("adc"); flush_workqueue(pADC_WQSyncDetection); print_meminfo("Register SyncDetection WorkQueue Done"); pADC_WQInterruptProcess=create_workqueue("adc_interrupt"); flush_workqueue(pADC_WQInterruptProcess); print_meminfo("Register InterruptProcess WorkQueue Done"); pADC_WQTunerStrength=create_workqueue("adc_TunerStrength"); flush_workqueue(pADC_WQTunerStrength); print_meminfo("Register TunerStrength WorkQueue Done"); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8) sema_init(&adc_ioctl_semaphore, 1); #endif if (err) printk(KERN_NOTICE "ADC Init Failed\n"); // Get 2x CPLL CLK CPLL_MClk= drv_get_device_clock(CPLL_CLK); CPLL_MClk = CPLL_MClk/1000; // Convert to 1x ratio for 24.576 ratio = CPLL_MClk / System_CLK / 2 ; // CPU PLL Divider ADC_Write(GLB_REG_A1ECO_CPLL_CEN_COMP, 1); ADC_Write(GLB_REG_A1ECO_CPLL_PTXCLK_DIV, ratio - 1 ); printk(KERN_EMERG" ratio = CPLL / 24576. Clock CPLL(%d) , ratio = (PTXCLK_DIV + 1) = %d \n ", CPLL_MClk, ratio); ADC_Open(); ADC_Write(GLB_REG_global_reset, 1); sAdcInfo.bFirstPowerOn = TRUE; DRV_ADC_power(DISABLE); printk(KERN_EMERG"%s: return\n",__FUNCTION__); return 0; } INT32 adc_AdjustFunction(UINT8 ucFunID, INT32 iValue) { //ptv_base_t ptv = getptvdev(); INT32 retval = 0; UINT8 value = 0; switch(ucFunID) { case ADC_CMD_AUTOADJUST: #ifdef CONFIG_AutoAdjust_BlackScreen ADC_ScreenMode(BlackScreen); #endif bAutoAdjust = TRUE; bCheckVIPHttl = FALSE; DRV_ADC_SetHTotal(ADC_InputVesaTiming.usHtotal); //richie add, Before do Autotune, need reset Adc Pll clock to default value, or PC Autotune is sometimes wrong #ifdef CONFIG_SUPPORT_ACTION_SHOW_BLUE_SCREEN_EXCEPT_MEDIA { VIP_Mute_Flag_st stStauts; VIP_GetMuteStatus(&stStauts); if (stStauts.fTVFEMuteFlag == FALSE && stStauts.fAppMuteFlag == FALSE && stStauts.fVIPMuteFlag == FALSE) { VIP_SetVideoMuteColor(0,0,0); } } #endif ADC_DoAuto(NULLOP, iValue, 2); //YPP & PC source will do centering by 2 in factory mode noticekmf(KMF2UMF_EVID_ADC, KMF2UMF_EVTYPE_ADC_PCSETUPDATE, &value, 1); bCheckVIPHttl = TRUE; bAutoAdjust = FALSE; #ifdef CONFIG_AutoAdjust_BlackScreen ADC_ScreenMode(NormalScreen); #endif break; case ADC_CMD_PHASE: DRV_ADC_SetPhase(iValue); break; case ADC_CMD_GAIN_R: DRV_ADC_SetGain(RED,iValue); break; case ADC_CMD_GAIN_G: DRV_ADC_SetGain(GREEN,iValue); break; case ADC_CMD_GAIN_B: DRV_ADC_SetGain(BLUE,iValue); break; case ADC_CMD_OFFSET_R: DRV_ADC_SetOffset(RED,iValue); break; case ADC_CMD_OFFSET_G: DRV_ADC_SetOffset(GREEN,iValue); break; case ADC_CMD_OFFSET_B: DRV_ADC_SetOffset(BLUE,iValue); break; case ADC_CMD_WHITEBALANCE: bAutoWB = TRUE; FactoryModeAWB = TRUE; ADC_AutoColorCalibration(); FactoryModeAWB = FALSE; bAutoWB = FALSE; break; #ifdef CONFIG_DDC_CI_SUPPORT case ADC_CMD_DDCCI_OSD_PHASE: sAdcInfo.DDCCI_OSDPhase = iValue; break; case ADC_CMD_DDCCI_OSD_CLOCK: sAdcInfo.DDCCI_OSDClock = iValue; break; #endif default: //KMFDBG(0,"kmf_ioctl_adjustADC: Error occur %d\n", ucFunID); retval = -EFAULT; break; } return retval; } void __exit DRV_ADC_Linuxexit(void) { ADC_Close(); destroy_workqueue(pADC_WQSyncDetection); destroy_workqueue(pADC_WQInterruptProcess); destroy_workqueue(pADC_WQTunerStrength); cdev_del(cdev_adc); free_irq(ADC_SYNC_IRQ, NULL); } void ADC_GetVideoTimingTable(void) { GetCustomerData("YppModeTable", (void *)&g_stADCTimingTbl.pYppVideoTimingTable, &g_stADCTimingTbl.YppVideoTimingTblSize); GetCustomerData("VgaModeTable", (void *)&g_stADCTimingTbl.pVgaVideoTimingTable, &g_stADCTimingTbl.VgaVideoTimingTblSize); //Calc Table Size g_stADCTimingTbl.YppVideoTimingTblSize = g_stADCTimingTbl.YppVideoTimingTblSize/sizeof(VesaTiming); g_stADCTimingTbl.VgaVideoTimingTblSize = g_stADCTimingTbl.VgaVideoTimingTblSize/sizeof(VesaTiming); } void DRV_ADC_SetAdcPinConfig(UINT32 itype, InputVideoConf_st InputSrcPin) { ADC_DebugMsg("%s: \n",__FUNCTION__); switch (itype) { case INPUT_TYPE_AV: ADC_DebugMsg("AV soruce: (%d)\n", InputSrcPin.cvbs.pin); adc_InputSrcPin.cvbs.pin =InputSrcPin.cvbs.pin; break; case INPUT_TYPE_SV: ADC_DebugMsg("SV soruce: (%d, %d)\n", InputSrcPin.svideo.y_pin, InputSrcPin.svideo.c_pin); adc_InputSrcPin.svideo.y_pin = InputSrcPin.svideo.y_pin; adc_InputSrcPin.svideo.c_pin = InputSrcPin.svideo.c_pin; break; case INPUT_TYPE_COMPONENT: ADC_DebugMsg("YPP soruce: (%d, %d, %d, %d)\n", InputSrcPin.ypbpr.y_pin, InputSrcPin.ypbpr.pb_pin, InputSrcPin.ypbpr.pr_pin, InputSrcPin.ypbpr.soy_pin); adc_InputSrcPin.ypbpr.y_pin = InputSrcPin.ypbpr.y_pin; break; case INPUT_TYPE_PC: ADC_DebugMsg("PC soruce: (%d, %d, %d)\n", InputSrcPin.rgb.r_pin, InputSrcPin.rgb.g_pin, InputSrcPin.rgb.b_pin); adc_InputSrcPin.rgb.r_pin = InputSrcPin.rgb.r_pin; adc_InputSrcPin.rgb.g_pin = InputSrcPin.rgb.g_pin; adc_InputSrcPin.rgb.b_pin = InputSrcPin.rgb.b_pin; default: break; } } EXPORT_SYMBOL(DRV_ADC_SetAdcPinConfig); #ifndef INIT_BY_KMF module_init(DRV_ADC_Linuxinit); module_exit(DRV_ADC_Linuxexit); #endif EXPORT_SYMBOL(DRV_ADC_Linuxinit); EXPORT_SYMBOL(DRV_ADC_Linuxexit); MODULE_LICENSE("ADC Driver 07.01.2009");