📄 play_capture_tw.c
字号:
err = write_i2c(pInstance, delay, dev, 0x05, 0xD2); // reset of audio FIFO, put HDCP and ACR in auto-reset err = write_i2c(pInstance, delay, dev, 0x05, 0xD0); // end reset return RM_OK;}static RMstatus tristate_AD9883( struct RUA *pInstance, RMuint8 delay, RMuint8 dev){ RMstatus err; err = write_i2c(pInstance, delay, dev, 0x0F, 0x4C); // power down AD9883A return err;}static RMstatus tristate_SiI9031( struct RUA *pInstance, RMuint8 delay, RMuint8 dev){ RMstatus err; err = write_i2c(pInstance, delay, dev, 0x08, 0x04); // power down SiI9031 err = write_i2c(pInstance, delay, dev, 0x09, 0x00); // tri-state SiI9031 err = write_i2c(pInstance, delay, dev + 4, 0x27, 0x01); // Disable I2S out and MClk err = write_i2c(pInstance, delay, dev + 4, 0x29, 0x18); // Disable I2S signals err = write_i2c(pInstance, delay, dev + 4, 0x3C, 0x00); // power down and tri-state chip. err = write_i2c(pInstance, delay, dev + 4, 0x3E, 0x00); // power down and tri-state chip. err = write_i2c(pInstance, delay, dev + 4, 0x3F, 0x00); // power down and tri-state chip. return err;}static RMstatus tristate_SAA7119( struct RUA *pInstance, RMuint8 delay, RMuint8 dev){ RMstatus err; err = write_i2c(pInstance, delay, dev, 0x83, 0x10); // tri-state xport err = write_i2c(pInstance, delay, dev, 0x87, 0x10); // tri-state iport err = write_i2c(pInstance, delay, dev, 0x88, 0x0D); // reset and power down scaler, tri-state audio clocks return err;}static RMstatus init_capture_AD9883( struct RUA *pInstance, struct capture_cmdline *capture_opt, struct local_cmdline *local_opt, RMuint8 dev, RMuint8 delay){ RMstatus err; RMuint8 range, current; struct EMhwlibTVFormatDigital fmt; RMuint32 vcogain, postdiv, plldiv, bp; RMreal c; RMbool yuv; // Analog Devices 9883 setup RMuint8 i2c_data[][2] = { {0x01, 0x69}, // PLL Div MSB {0x02, 0xD0}, // PLL Div LSB {0x03, 0x48}, // VCO {0x04, 0x80}, // Phase adj. {0x05, 0x80}, // Clamp plcemnt. {0x06, 0x80}, // Clamp dur. {0x07, 0x20}, // HSync out width {0x08, 0x80}, // R gain {0x09, 0x80}, // G gain {0x0a, 0x80}, // B gain {0x0b, 0x80}, // R offs. {0x0c, 0x80}, // G offs. {0x0d, 0x80}, // B offs. {0x0e, 0x40}, // Sync ctrl. {0x0f, 0x6E}, // Ctrl. {0x10, 0xB8}, // SOG Thr. {0x11, 0x20}, // Sync Sep. Thr. {0x12, 0x01}, // Pre-Coast {0x13, 0x01}, // Post-Coast {0x15, 0xFE}, // Test reg. }; err = RUAExchangeProperty(pInstance, DisplayBlock, RMDisplayBlockPropertyID_TVFormatDigital, &(capture_opt->TVStandard), sizeof(capture_opt->TVStandard), &fmt, sizeof(fmt)); if (RMFAILED(err)) fprintf(stderr, "Failed to get TV format, %s\n", RMstatusToString(err)); vcogain = 150; postdiv = 1; if (fmt.PixelClock < 32000000) { range = 0; postdiv = 4; } else if (fmt.PixelClock < 64000000) { range = 1; postdiv = 2; } else if (fmt.PixelClock < 125000000) { range = 2; } else { range = 3; vcogain = 180; } plldiv = fmt.HTotalSize; // Formula from AD's Excel sheet 249461068RevAD9883_PLL.xls: // c=((HFreq*6.28/((PixClk<32000000)?12.5:15))^2*((0.082*0.000001*plldiv*postdiv)/(vcogain*1000000))*1000000 c = fmt.PixelClock; c *= 6.28 / fmt.HTotalSize; c /= ((fmt.PixelClock < 32000000) ? 12.5 : 15.0); c *= c; c *= (0.082 * plldiv * postdiv) / (vcogain * 1000000.0); current = (c < 75.0) ? 0 : (c < 125.0) ? 1 : (c < 200.0) ? 2 : (c < 300.0) ? 3 : (c < 425.0) ? 4 : (c < 625.0) ? 5 : (c < 1125.0) ? 6 : 7; fprintf(stderr, "AD9883 calc - PixClk=%lu range=%u c=%f current=%u\n", fmt.PixelClock, range, c, current); bp = fmt.XOffset - fmt.HSyncWidth; // BackPorch yuv = (local_opt->i2c_port == cap_Component1); // sync on green i2c_data[0x01 - 1][1] = (plldiv >> 4) & 0xFF; i2c_data[0x02 - 1][1] = (plldiv << 4) & 0xF0; i2c_data[0x03 - 1][1] = (range << 6) | (current << 3); i2c_data[0x05 - 1][1] = (bp >= 4) ? 0x04 : (bp / 4); // clamp placement i2c_data[0x06 - 1][1] = (bp >= 4) ? (bp - 8) : (bp / 2); // clamp duration //i2c_data[0x07 - 1][1] = fmt.HSyncWidth; // TODO i2c_data[0x07 - 1][1] = 0x10; // set contrast i2c_data[0x08 - 1][1] = yuv ? 0x80 : 0xF0; // R gain i2c_data[0x09 - 1][1] = yuv ? 0x80 : 0xF0; // G gain i2c_data[0x0A - 1][1] = yuv ? 0x80 : 0xF0; // B gain // set brightness i2c_data[0x0B - 1][1] = yuv ? 0x60 : 0x80; // R offs i2c_data[0x0C - 1][1] = yuv ? 0x80 : 0x80; // G offs i2c_data[0x0D - 1][1] = yuv ? 0x60 : 0x80; // B offs i2c_data[0x0E - 1][1] |= yuv ? 0x1B : 0x10; // select sync source, sog or h-sync. force vsync from sog for yuv. i2c_data[0x10 - 1][1] |= yuv ? 0x05 : 0x00; // clamp red and blue to center for YUV err = init_i2c(pInstance, delay, dev, i2c_data, sizeof(i2c_data) / sizeof (RMuint8) / 2); return err;}static RMstatus set_cable_comp_SiI9031( struct RUA *pInstance, struct capture_cmdline *capture_opt, struct local_cmdline *local_opt, RMuint8 dev, RMuint8 delay){ RMuint8 eq; eq = local_opt->cable_eq & 0x0F; eq = (eq << 4) | (0x0F - eq); return write_i2c(pInstance, delay, dev, 0x81, eq);}static RMstatus set_422_to_444_upsampling_SiI9031( struct RUA *pInstance, RMbool upsampling, RMuint8 dev, RMuint8 delay){ RMstatus err; RMuint32 reg; err = read_i2c(pInstance, delay, dev, 0x4A, ®); if (RMFAILED(err)) reg = 0x01; // default value if (upsampling) reg |= 0x04; else reg &= ~0x04; err = write_i2c(pInstance, delay, dev, 0x4A, reg); return err;}static RMstatus set_blanking_color_SiI9031( struct RUA *pInstance, struct capture_cmdline *capture_opt, struct local_cmdline *local_opt, RMuint8 dev, RMuint8 delay){ RMstatus err; RMuint8 r, g, b; r = g = b = 0x00; if ( (capture_opt->InputColorSpace != EMhwlibColorSpace_RGB_0_255) && (capture_opt->InputColorSpace != EMhwlibColorSpace_RGB_16_235) ) { //rgb_to_yuv(r, g, b, &g, &b, &r); g = 0x10; r = b = 0x80; } err = write_i2c(pInstance, delay, dev, 0x4B, b); if (RMFAILED(err)) RMDBGLOG((ENABLE, "Error writing I2C!\n")); err = write_i2c(pInstance, delay, dev, 0x4C, g); if (RMFAILED(err)) RMDBGLOG((ENABLE, "Error writing I2C!\n")); err = write_i2c(pInstance, delay, dev, 0x4D, r); if (RMFAILED(err)) RMDBGLOG((ENABLE, "Error writing I2C!\n")); return RM_OK;}static RMstatus get_spdif_codec( struct dcc_context *dcc_info, struct audio_cmdline *audio_opt, struct AudioEngine_InputSPDIFStatus_type *stat){ if ((stat->ChannelStatus & 0x0002) && ((stat->Pc & 0x1F) == 0)) return RM_OK; // Null data, no change audio_opt->auto_detect_codec = TRUE; fprintf(stderr, "Audio Input channel status [18:0]: 0x%05lX Pc:%04X Pd:%04X Pe:%04X Pf:%04X\n", stat->ChannelStatus, stat->Pc, stat->Pd, stat->Pe, stat->Pf); audio_opt->auto_detect_codec = FALSE; if (stat->ChannelStatus & 0x0002) { fprintf(stderr, "Detected Codec: "); switch (stat->Pc & 0x1F) { default: fprintf(stderr, "Unknown or reserved codec type: %u\n", stat->Pc & 0x1F); if (0) case 0: fprintf(stderr, "Null Data\n"); if (0) case 3: fprintf(stderr, "Pause\n"); if (0) case 2: fprintf(stderr, "SMPTE 338M Time Stamp Data\n"); if (0) case 27: fprintf(stderr, "SMPTE 338M KLV Data\n"); if (0) case 28: fprintf(stderr, "SMPTE 338M Dolby E Data\n"); if (0) case 29: fprintf(stderr, "SMPTE 338M Captioning Data\n"); if (0) case 30: fprintf(stderr, "SMPTE 338M User Data\n"); audio_opt->auto_detect_codec = TRUE; break; case 1: fprintf(stderr, "AC3\n"); audio_opt->Codec = AudioDecoder_Codec_AC3; audio_opt->Ac3Params.OutputChannels = Ac3_LR; break; case 4: fprintf(stderr, "MPEG 1 Layer 1\n"); audio_opt->Codec = AudioDecoder_Codec_MPEG1; break; case 5: fprintf(stderr, "MPEG 1 Layer 2 or 3, MPEG 2 w/o extension\n"); audio_opt->Codec = AudioDecoder_Codec_MPEG1; break; case 6: fprintf(stderr, "MPEG 2 w/ extension\n"); audio_opt->Codec = AudioDecoder_Codec_MPEG1; break; case 7: fprintf(stderr, "MPEG 2 AAC\n"); audio_opt->Codec = AudioDecoder_Codec_AAC; // TODO 0, 1, 2 or 3? audio_opt->AACParams.InputFormat = 0; audio_opt->AACParams.OutputChannels = Aac_LR; break; case 8: fprintf(stderr, "MPEG 2 Layer 1\n"); audio_opt->Codec = AudioDecoder_Codec_MPEG1; break; case 9: fprintf(stderr, "MPEG 2 Layer 2\n"); audio_opt->Codec = AudioDecoder_Codec_MPEG1; break; case 10: fprintf(stderr, "MPEG 2 Layer 3\n"); audio_opt->Codec = AudioDecoder_Codec_MPEG1; break; case 11: fprintf(stderr, "DTS Type I\n"); audio_opt->Codec = AudioDecoder_Codec_DTS; audio_opt->DtsParams.OutputChannels = Dts_LR; break; case 12: fprintf(stderr, "DTS Type II\n"); audio_opt->Codec = AudioDecoder_Codec_DTS; audio_opt->DtsParams.OutputChannels = Dts_LR; break; case 13: fprintf(stderr, "DTS Type III\n"); audio_opt->Codec = AudioDecoder_Codec_DTS; audio_opt->DtsParams.OutputChannels = Dts_LR; break; case 14: fprintf(stderr, "ATRAC (unsupported)\n"); audio_opt->auto_detect_codec = TRUE; //audio_opt->Codec = ; break; case 15: fprintf(stderr, "ATRAC 2/3 (unsupported)\n"); audio_opt->auto_detect_codec = TRUE; //audio_opt->Codec = ; break; case 18: fprintf(stderr, "WMA Pro\n"); audio_opt->Codec = AudioDecoder_Codec_WMAPRO; break; case 31: switch (stat->Pe) { default: fprintf(stderr, "Unknown extended data-type: %u\n", stat->Pe); audio_opt->auto_detect_codec = TRUE; break; } break; } } else { fprintf(stderr, "Detected Codec: PCM\n"); audio_opt->auto_detect_codec = FALSE; audio_opt->Codec = AudioDecoder_Codec_PCM; audio_opt->SubCodec = 1; audio_opt->LpcmVobParams.ChannelAssign = LpcmVob2_LR; audio_opt->LpcmVobParams.BitsPerSample = 16; audio_opt->OutputChannels = Audio_Out_Ch_LR; } return RM_OK;}// Read sample frequency from HDMI chip and set audio_opt->SampleRatestatic RMstatus setup_HDMI_audio( struct dcc_context *dcc_info, struct local_cmdline *local_opt, struct audio_cmdline *audio_opt, RMuint8 dev, RMuint8 delay){ RMstatus err; RMuint32 pclk; RMuint8 data[5]; init_capture_SiI9031_amclk(dcc_info->pRUA, dev, delay, local_opt->hdmi_mode == mode_HDMI); if (local_opt->hdmi_mode != mode_HDMI) { audio_opt->SamplingFrequency = 0; audio_opt->SampleRate = 0; return RM_OK; } //err = read_i2c(dcc_info->pRUA, delay, dev + 4, 0x17, &pclk); //if (RMFAILED(err)) return err; err = read_i2c_data(dcc_info->pRUA, delay, dev + 4, 0x2A, &data[0], 3); if (RMFAILED(err)) return err; err = read_i2c_data(dcc_info->pRUA, delay, dev + 4, 0x30, &data[3], 2); if (RMFAILED(err)) return err; fprintf(stderr, "SiI9031 audio channel status [39:0]: %02X.%02X.%02X.%02X.%02X\n", data[4], data[3], data[2], data[1], data[0]); fprintf(stderr, "\n\n"); pclk = data[3] & 0x0F; fprintf(stderr, "\tAudio fs: %s\n", (pclk == 0) ? "44.1 kHz" : (pclk == 1) ? "<unknown>" : (pclk == 2) ? "48 kHz" : (pclk == 3) ? "32 kHz" : (pclk == 4) ? "22.05 kHz <invalid>" : (pclk == 5) ? "11.025 kHz <invalid>" :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -