📄 play_capture_saa7119.c
字号:
switch (pUpdate->TVStandard) { case EMhwlibTVStandard_ITU_Bt656_625: case EMhwlibTVStandard_ITU_Bt656_288p: case EMhwlibTVStandard_PAL_BG: case EMhwlibTVStandard_PAL_BG_702: case EMhwlibTVStandard_PAL_N: case EMhwlibTVStandard_PAL_N_702: // 50Hz capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x5a, 0x03); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x5b, 0x03); break; case EMhwlibTVStandard_ITU_Bt656_525: case EMhwlibTVStandard_ITU_Bt656_240p: case EMhwlibTVStandard_NTSC_M_Japan: case EMhwlibTVStandard_NTSC_M_Japan_714: case EMhwlibTVStandard_NTSC_M: case EMhwlibTVStandard_NTSC_M_714: case EMhwlibTVStandard_PAL_60: case EMhwlibTVStandard_PAL_60_714: case EMhwlibTVStandard_PAL_M: case EMhwlibTVStandard_PAL_M_714: // 59.94Hz capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x09, 0x00); break; case EMhwlibTVStandard_480p59: case EMhwlibTVStandard_480p59_714: case EMhwlibTVStandard_576p50: case EMhwlibTVStandard_576p50_702: capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x02, 0x33); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x03, 0xFC); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x04, (pUpdate->TVStandard == EMhwlibTVStandard_576p50) ? 0x6c : 0x72); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x08, 0xa0); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x09, 0x01); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x15, 0x01); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x16, 0x03); capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x17, 0x00); break; case EMhwlibTVStandard_720p60: case EMhwlibTVStandard_720p59: case EMhwlibTVStandard_720p50: capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x09, 0x13); // TODO break; case EMhwlibTVStandard_1080i60: case EMhwlibTVStandard_1080i59: case EMhwlibTVStandard_1080i50: capsam_i2c_write_dev(pSAA7119, pSAA7119->BaseDevice, 0x09, 0x0b); // TODO break; default: break; } return err;}RMstatus capsam_SAA7119_init_audio(struct capsam_SAA7119_instance *pSAA7119) { RMuint32 mclk = 0, acpf = 0, acni = 0; RMuint8 i2c_data[][2] = { {0x30, 0x00}, // 0 [7:0] acfp = mclk / v-freq {0x31, 0xc0}, // 1 [15:8] {0x32, 0x03}, // 2 [17:16] {0x34, 0xce}, // 3 [7:0] acni = mclk * 2^23 / xtal_clk {0x35, 0xfb}, // 4 [15:8] {0x36, 0x30}, // 5 [21:16] {0x38, 0x01}, // 6 sdiv = (mclk / (2 * sclk)) - 1; {0x39, 0x20}, // 7 lrdiv = sclk / lrclk / 2 {0x3a, 0x00}, // 8 80:use CG2, 08:freerunning/00:fieldlocked {0x3b, 0x3f}, // 3b-3f recommended values {0x3c, 0xd1}, {0x3d, 0x31}, {0x3e, 0x03}, }; mclk = pSAA7119->SampleRate * pSAA7119->MclkFactor; // Audio PLL --> MClk,SClk,LRClk acpf = (RMuint32)((((RMuint64)pSAA7119->vfreq_m * (RMuint64)mclk) + (pSAA7119->vfreq_n / 2)) / pSAA7119->vfreq_n); acni = nominal_increment(mclk, pSAA7119->XtalClock, 23); i2c_data[0][1] = RMunshiftBits(acpf, 8, 0); i2c_data[1][1] = RMunshiftBits(acpf, 8, 8); i2c_data[2][1] = RMunshiftBits(acpf, 2, 16); i2c_data[3][1] = RMunshiftBits(acni, 8, 0); i2c_data[4][1] = RMunshiftBits(acni, 8, 8); i2c_data[5][1] = RMunshiftBits(acni, 6, 16); capsam_i2c_init(pSAA7119, pSAA7119->BaseDevice, i2c_data); return RM_OK;}RMstatus capsam_SAA7119_setup_audio(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate){ RMstatus err = RM_OK; RMuint32 mclk = 0, acpf = 0, acni = 0; RMbool isNTSC; RMuint8 i2c_data[][2] = { {0x30, 0x00}, // 0 [7:0] acfp = mclk / v-freq {0x31, 0xc0}, // 1 [15:8] {0x32, 0x03}, // 2 [17:16] {0x34, 0xce}, // 3 [7:0] acni = mclk * 2^23 / xtal_clk {0x35, 0xfb}, // 4 [15:8] {0x36, 0x30}, // 5 [21:16] {0x38, 0x01}, // 6 sdiv = (mclk / (2 * sclk)) - 1; {0x39, 0x20}, // 7 lrdiv = sclk / lrclk / 2 {0x3a, 0x00}, // 8 80:use CG2, 08:freerunning/00:fieldlocked {0x3b, 0x3f}, // 3b-3f recommended values {0x3c, 0xd1}, {0x3d, 0x31}, {0x3e, 0x03}, }; RMuint8 i2c_data_ext[][2] = { {0xE0, 0x00}, // 0 [7:0] splpl = clk_lfco / h-freq * 2 {0xE1, 0x08}, // 1 [3:0]sppi=0, [1:0]spmod=2 [9:8]splpl {0xE2, 0x03}, // 2 [7:0] spninc = 2^17 * clk_lfco / xtal_clk {0xE3, 0xce}, // 3 [15:8]spninc {0xE4, 0x88}, // 4 [3:0]spthrl=8, [3:0]spthrm=8 {0xE5, 0x00}, // 5 spbypns=0, [6:0]cg2fbd {0xE6, 0xd0}, // 6 cg2divres=1, cg2en=1, sphsel=0, [2:0]cg2ckdl=4, [1:0]cg2od {0xE7, 0x31}, // 7 [3:0]cg2r=3, [3:0]cg2i=1 {0xE8, 0x03}, // 8 [4:0]cg2p=3 }; RMDBGLOG((FUNCNAME, "%s\n",__func__)); if(pUpdate == NULL){ return RM_FATALINVALIDPOINTER; } /* * Philips SAA 7119 audio PLL setup * mclk = sample_clk * mclk_f * sclk = sample_clk * 64 * lrclk = sample_clk */ if (pUpdate->AudioSampleRateValid && pUpdate->AudioSampleRateUpdate) { pSAA7119->SampleRate = pUpdate->AudioSampleRate; } if (pUpdate->AudioMclkFactorValid && pUpdate->AudioMclkFactorUpdate ){ switch(pUpdate->AudioMclkFactor){ case MClkFactor_128Xfs: pSAA7119->MclkFactor = 128; break; case MClkFactor_256Xfs: pSAA7119->MclkFactor = 256; break; default: break; } } mclk = pSAA7119->SampleRate * pSAA7119->MclkFactor; /* * Determine field rate * expect output video format (digital) as input parameter TVStandard */ if (pUpdate->TVStandardValid && pUpdate->TVStandardUpdate) { IsNTSC(pUpdate->TVStandard, isNTSC); if(isNTSC){ /* 59.94Hz */ pSAA7119->vfreq_n = 60000; pSAA7119->vfreq_m = 1001; pSAA7119->pixel_clk = 13500000; pSAA7119->h_total_size = 858; }else{ /* 50Hz */ pSAA7119->vfreq_n = 50000; pSAA7119->vfreq_m = 1000; pSAA7119->pixel_clk = 13500000; pSAA7119->h_total_size = 864; } } /* * Determine register value to set */ if (pUpdate->SAA7119CG2Valid && pUpdate->SAA7119CG2Update && pUpdate->SAA7119UseCG2) { // Audio PLL --> CG2 PLL --> MClk,SClk,LRClk RMuint32 LFCO_freq, k; RMuint32 splpl, spninc, cg2fbd, cg2od; if(!pSAA7119->XtalClock){ return RM_ERROR; } k = (mclk + (pSAA7119->XtalClock / 2)) / (pSAA7119->XtalClock); if (k < 4) k = 4; LFCO_freq = mclk / k; acpf = (RMuint32)(((RMuint64)pSAA7119->vfreq_m * (RMuint64)LFCO_freq * 2) /pSAA7119->vfreq_n); acni = nominal_increment(LFCO_freq, pSAA7119->XtalClock, 24); // mclk = LFCO_freq * 2 * (cg2fbd + 1) / (cg2od + 1) / 4, cg2fbd=31..92(94?), cg2od=0..3 for (cg2od = 0; cg2od < 4; cg2od++) { cg2fbd = k * 4 * (cg2od + 1) / 2 - 1; // LFCO_freq * 2 * mclk / (cg2od + 1) / 4 - 1; if ((cg2fbd >= 31) && (cg2fbd <= 94)) { // Check PLL internal frequency range, for square pixel mode only //RMuint32 clk_int = LFCO_freq * 2 * (cg2fbd + 1); //if ((clk_int >= 275000000) && (clk_int <= 550000000)) break; break; } } if (cg2od >= 4) { fprintf(stderr, "Can not use CG2, fall back to audio PLL\n"); pUpdate->SAA7119UseCG2 = FALSE; } else { splpl = (RMuint32)(((RMuint64)LFCO_freq * (RMuint64)pSAA7119->h_total_size * 2) / pSAA7119->pixel_clk); spninc = nominal_increment(LFCO_freq, pSAA7119->XtalClock, 17); i2c_data_ext[0][1] = RMunshiftBits(splpl, 8, 0); i2c_data_ext[1][1] |= RMunshiftBits(splpl, 2, 8); i2c_data_ext[2][1] = RMunshiftBits(spninc, 8, 0); i2c_data_ext[3][1] = RMunshiftBits(spninc, 8, 8); i2c_data_ext[5][1] |= RMunshiftBits(cg2fbd, 7, 0); i2c_data_ext[6][1] |= RMunshiftBits(cg2od, 2, 0); capsam_i2c_init(pSAA7119, pSAA7119->BaseDevice + 4, i2c_data_ext); i2c_data[8][1] = 0x80; // enable CG2 } } if(! pUpdate->SAA7119UseCG2){ // Audio PLL --> MClk,SClk,LRClk acpf = (RMuint32)((((RMuint64)pSAA7119->vfreq_m * (RMuint64)mclk) + (pSAA7119->vfreq_n / 2)) / pSAA7119->vfreq_n); acni = nominal_increment(mclk, pSAA7119->XtalClock, 23); } i2c_data[0][1] = RMunshiftBits(acpf, 8, 0); i2c_data[1][1] = RMunshiftBits(acpf, 8, 8); i2c_data[2][1] = RMunshiftBits(acpf, 2, 16); i2c_data[3][1] = RMunshiftBits(acni, 8, 0); i2c_data[4][1] = RMunshiftBits(acni, 8, 8); i2c_data[5][1] = RMunshiftBits(acni, 6, 16); capsam_i2c_init(pSAA7119, pSAA7119->BaseDevice, i2c_data); return err;}RMstatus capsam_SAA7119_setup_output(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate){ RMstatus err = RM_OK; RMDBGLOG((FUNCNAME, "%s\n",__func__)); // Sanity checks if(pSAA7119 == NULL){ return RM_FATALINVALIDPOINTER; } if(pUpdate == NULL){ return RM_FATALINVALIDPOINTER; } /* * Most of the settings are done automatically * */ return err;}RMstatus capsam_SAA7119_check_int(struct capsam_SAA7119_instance *pSAA7119){ RMstatus err = RM_OK; RMuint32 reg1e = 0; RMuint32 reg1f = 0; RMuint32 reg8f = 0; RMuint32 hd_reg1f = 0; //RMDBGLOG((FUNCNAME, "%s\n",__func__)); /* read status register caused by interrupt from SAA7119 */ capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x1e, ®1e); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x1f, ®1f); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x1f, ®8f); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice + 8, 0x1f, &hd_reg1f); if( (reg1e != pSAA7119->state_sd_0x1e) || (reg1f != pSAA7119->state_sd_0x1f) || (reg8f != pSAA7119->state_0x8f) || (hd_reg1f != pSAA7119->state_hd_0x1f)) { err = RM_OK; }else{ err = RM_ERROR; } if( pSAA7119->state == INIT){ // this will force the interrupt handling err = RM_OK; } return err;}RMstatus capsam_SAA7119_handle_int(struct capsam_SAA7119_instance *pSAA7119, struct capsam_update *pUpdate){ RMstatus err = RM_OK; RMuint32 reg1e = 0; RMuint32 reg1f = 0; RMuint32 reg8f = 0; RMuint32 hd_reg1f = 0; //RMDBGLOG((FUNCNAME, "%s\n",__func__)); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x1e, ®1e); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x1f, ®1f); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice, 0x1f, ®8f); capsam_i2c_read_dev(pSAA7119, pSAA7119->BaseDevice + 8, 0x1f, &hd_reg1f); if(pSAA7119->state == INIT){ Handle_RDCAP(pSAA7119, pUpdate, reg1f); Handle_COPROP(pSAA7119, pUpdate, reg1f); Handle_COLSTR(pSAA7119, pUpdate, reg1f); Handle_TYPE3(pSAA7119, pUpdate, reg1f); Handle_INTL_FIDT(pSAA7119, pUpdate, reg1f); Handle_HLVLN(pSAA7119, pUpdate, reg1f); Handle_DCSTD(pSAA7119, pUpdate, reg1e); Handle_HLCK(pSAA7119, pUpdate, reg1e); Handle_HFLD(pSAA7119, pUpdate, reg1e); Handle_ERROF(pSAA7119, pUpdate, reg8f); Handle_VBI_IRQ(pSAA7119, pUpdate, reg8f); Handle_PRD_ON(pSAA7119, pUpdate, reg8f); Handle_HD_COPRO(pSAA7119, pUpdate, hd_reg1f); Handle_HD_RDCAP(pSAA7119, pUpdate, hd_reg1f); Handle_HD_HL(pSAA7119, pUpdate, hd_reg1f); //pSAA7119->state = RUN; //RMDBGLOG((LOCALDBG, "state = RUN \n")); }else{ /* * 0x1f interrupt status */ /* RDCAP */ if( (reg1f & (1<<0)) != (pSAA7119->state_sd_0x1f & (1<<0)) ){ Handle_RDCAP(pSAA7119, pUpdate, reg1f); } /* COPRO */ if( (reg1f & (1<<1)) != (pSAA7119->state_sd_0x1f & (1<<1)) ){ Handle_COPROP(pSAA7119, pUpdate, reg1f); } /* COLSTR */ if( (reg1f & (1<<2)) != (pSAA7119->state_sd_0x1f & (1<<2)) ){ Handle_COLSTR(pSAA7119, pUpdate, reg1f); } /* TYPE3*/ if( (reg1f & (1<<3)) != (pSAA7119->state_sd_0x1f & (1<<3)) ){ Handle_TYPE3(pSAA7119, pUpdate, reg1f); } /* FIDT */ if( (reg1f & (1<<5)) != (pSAA7119->state_sd_0x1f & (1<<5)) ){ Handle_INTL_FIDT(pSAA7119, pUpdate, reg1f); } /* HLVLN */ if( (reg1f & (1<<6)) != (pSAA7119->state_sd_0x1f & (1<<6)) ){ Handle_HLVLN(pSAA7119, pUpdate, reg1f); } /* INTL */ if( (reg1f & (1<<7)) != (pSAA7119->state_sd_0x1f & (1<<7)) ){ Handle_INTL_FIDT(pSAA7119, pUpdate, reg1f); } /* * 0x1e interrupt status */ /* DCSTD */ if( (reg1e & (3<<0)) != (pSAA7119->state_sd_0x1e & (3<<0)) ){ Handle_DCSTD(pSAA7119, pUpdate, reg1e); } /* HLCK */ if( (reg1e & (1<<6)) != (pSAA7119->state_sd_0x1e & (1<<6)) ){ Handle_HLCK(pSAA7119, pUpdate, reg1e); } /* NFLD */ if( (reg1f & (1<<7)) != (pSAA7119->state_sd_0x1e & (1<<7)) ){ Handle_HFLD(pSAA7119, pUpdate, reg1e); } /* * 0x8f interrupt status */ /* ERROF */ if( (reg8f & (1<<2)) != (pSAA7119->state_0x8f & (1<<2)) ){ Handle_ERROF(pSAA7119, pUpdate, reg8f); } /* VBI_IRQ */ if( (reg8f & (1<<4)) != (pSAA7119->state_0x8f & (1<<4)) ){ Handle_VBI_IRQ(pSAA7119, pUpdate, reg8f); } /* PRD_ON */ if( (reg8f & (1<<3)) != (pSAA7119->state_0x8f & (1<<3)) ){ Handle_PRD_ON(pSAA7119, pUpdate, reg8f); } /* * HD - sub address 4A/48 */ /* HD_COPRO */ if( (hd_reg1f & (1<<1)) != (pSAA7119->state_hd_0x1f & (1<<1)) ){ Handle_HD_COPRO(pSAA7119, pUpdate, hd_reg1f); } /* HD_RDCAP */ if( (hd_reg1f & (1<<0)) != (pSAA7119->state_hd_0x1f & (1<<0)) ){ Handle_HD_RDCAP(pSAA7119, pUpdate, hd_reg1f); } /* HD_HL */ if( (hd_reg1f & (1<<6)) != (pSAA7119->state_hd_0x1f & (1<<6)) ){ Handle_HD_HL(pSAA7119, pUpdate, hd_reg1f); } } // update new state pSAA7119->state_sd_0x1e = reg1e; pSAA7119->state_sd_0x1f = reg1f; pSAA7119->state_hd_0x1f = hd_reg1f; pSAA7119->state_0x8f = reg8f; return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -