📄 sii9031.c
字号:
} }}RMstatus cap_SiI9031_handle_int( struct cap_SiI9031_instance *pSiI9031, struct cap_update *pUpdate, struct cap_hdmi_update *pHDMIUpdate){ RMstatus err; RMuint8 reg, mask, type; //RMDBGLOG((FUNCNAME, "%s\n",__func__)); // Check HDCP status cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x32, ®); { RMbool auth, crypt; auth = (reg & 0x10); crypt = (reg & 0x20); if (auth != pSiI9031->last_auth) { pSiI9031->last_auth = auth; RMDBGLOG((ENABLE, "[SiI9031] HDCP: devices are %sauthenticated\n", auth ? "" : "not ")); if (auth && pSiI9031->break_hdcp) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x31, 0x80); // break HDCP } if (crypt != pSiI9031->last_crypt) { pSiI9031->last_crypt = crypt; RMDBGLOG((ENABLE, "[SiI9031] HDCP: video is %sencrypted\n", crypt ? "" : "not ")); } } // Check if any interrupts are pending cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x70, ®); if (reg & 0x01) { // Check INTR1 cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x71, ®); if (reg) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x71, reg & ~0x10); // clear intr, except for acrpllul if (reg & pSiI9031->intr_mask[0]) { //RMDBGLOG((ENABLE, "INTR1: 0x%02lX\n", reg)); if (pSiI9031->verbouse) { if (reg & 0x80) { RMuint8 cts[3]; cap_i2c_read_data(pSiI9031, pSiI9031->BaseDevice + 8, 0x0C, cts, 3); RMDBGLOG((ENABLE, "INTR1.7 - New CTS: 0x%01X%02X%02X\n", cts[2] & 0x0F, cts[1], cts[0])); } if (reg & 0x40) { RMuint8 n[3]; cap_i2c_read_data(pSiI9031, pSiI9031->BaseDevice + 8, 0x06, n, 3); RMDBGLOG((ENABLE, "INTR1.6 - New N: 0x%01X%02X%02X\n", n[2] & 0x0F, n[1], n[0])); } if (reg & 0x20) RMDBGLOG((ENABLE, "INTR1.5 - N/CTS decode error!\n")); if (reg & 0x10) RMDBGLOG((ENABLE, "INTR1.4 - Audio PLL unlocked!\n")); if (reg & 0x08) RMDBGLOG((ENABLE, "INTR1.3 - AudioFIFO error!\n")); if (reg & 0x04) RMDBGLOG((ENABLE, "INTR1.2 - ECC data island error!\n")); if (reg & 0x02) RMDBGLOG((ENABLE, "INTR1.1 - HDCP authentication started\n")); if (reg & 0x01) RMDBGLOG((ENABLE, "INTR1.0 - HDCP authentication done\n")); } if (reg & 0x04) { // TODO need to soft-reset chip? } if ((reg & 0x10) && pSiI9031->audio_pll_locked) { RMDBGLOG((ENABLE, "\n\nACR PLL is now UNLOCKED\n\n\n")); pSiI9031->audio_pll_locked = FALSE; } if ((reg & 0x08) && (pSiI9031->audio_state == audio_state_on)) { RMuint64 now = RMGetTimeInMicroSeconds(); if (RMCyclesElapsed64(pSiI9031->audio_guard_time, now) >= 5 * 1000 * 1000) { RMDBGLOG((ENABLE, "Audio FIFO error, restarting audio\n")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } } } // Check INTR2 cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x72, ®); if (reg) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x72, reg & ~0x04); // clear intr except CTS if (reg & pSiI9031->intr_mask[1]) { //RMDBGLOG((ENABLE, "INTR2: 0x%02lX\n", reg)); if (pSiI9031->verbouse) { if (reg & 0x80) RMDBGLOG((ENABLE, "INTR2.7 - HDMI/DVI mode change\n")); if (reg & 0x40) RMDBGLOG((ENABLE, "INTR2.6 - vsync active edge detected\n")); if (reg & 0x20) RMDBGLOG((ENABLE, "INTR2.5 - software interrupt\n")); if (reg & 0x10) RMDBGLOG((ENABLE, "INTR2.4 - video clock detect changed\n")); if (reg & 0x08) RMDBGLOG((ENABLE, "INTR2.3 - sync/DE detect changed\n")); if (reg & 0x04) RMDBGLOG((ENABLE, "INTR2.2 - received CTS packet\n")); if (reg & 0x02) RMDBGLOG((ENABLE, "INTR2.1 - received audio packet\n")); if (reg & 0x01) RMDBGLOG((ENABLE, "INTR2.0 - video clock frequency changed\n")); } if (reg & 0x80) { cap_SiI9031_detect_mode(pSiI9031, &(pSiI9031->hdmi_mode)); } if (reg & 0x19) { cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x06, &mask); { RMbool power, clock, sync; power = (mask & 0x08); clock = (mask & 0x02); sync = (mask & 0x01); if (power != pSiI9031->last_power) { pSiI9031->last_power = power; RMDBGLOG((ENABLE, "connector power %s\n", power ? "up" : "down")); } if (clock != pSiI9031->last_clock) { pSiI9031->last_clock = clock; RMDBGLOG((ENABLE, "video clock %s\n", clock ? "present" : "lost")); } if (sync != pSiI9031->last_sync) { pSiI9031->last_sync = sync; RMDBGLOG((ENABLE, "video sync %s\n", sync ? "present" : "lost")); if (sync) { cap_SiI9031_detect_mode(pSiI9031, &(pSiI9031->hdmi_mode)); cap_SiI9031_init_audio_clock(pSiI9031, pSiI9031->hdmi_mode == cap_hdmi_mode_HDMI, pSiI9031->mclk_factor); if (pSiI9031->hdmi_mode == cap_hdmi_mode_HDMI) { if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } else { if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioOff = TRUE; } } } else { if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->FlushScaler = TRUE; pUpdate->AudioOff = TRUE; } cap_SiI9031_init_audio_clock(pSiI9031, FALSE, pSiI9031->mclk_factor); if (pHDMIUpdate && (pHDMIUpdate->APIVersion >= 1)) { pHDMIUpdate->AVIInfoFrameInvalidate = TRUE; } } } // HDMI/DVI mode detection and set up if ((reg & 0x09) && clock && sync) { RMDBGLOG((ENABLE, "clock and sync are now present, detecting video mode.\n")); pSiI9031->update_videomode = TRUE; } } } } // Check INTR3 cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x73, ®); if (reg) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x73, reg); // clear intr if (reg & pSiI9031->intr_mask[2]) { //RMDBGLOG((ENABLE, "INTR3: 0x%02lX\n", reg)); if (reg & 0x1F) { // Further ints on changed frame only cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, &mask); if (mask & reg & 0x1F) { cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, mask & ~(reg & 0x1F)); } } if (reg & 0x01) { // AVI Info Frame if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR3.0 - new or changed AVI Info Frame detected.\n")); if (pHDMIUpdate && (pHDMIUpdate->APIVersion >= 1)) { pHDMIUpdate->AVIInfoFrameUpdate = TRUE; } } if (reg & 0x02) { // SPD Info Frame if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR3.1 - new or changed SPD Info Frame detected.\n")); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0x60, &type); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0x7F, &mask); if (type == mask) { cap_SiI9031_set_packet_update(mask, pHDMIUpdate); } else { // try again if (pSiI9031->verbouse) RMDBGLOG((ENABLE, " Unexpected type in SPD receive area: 0x%02X\n", type)); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, &mask); if (! (mask & 0x02)) { cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, mask | 0x02); } } } if (reg & 0x04) { // Audio Info Frame if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR3.2 - new or changed Audio Info Frame detected.\n")); if (pHDMIUpdate && (pHDMIUpdate->APIVersion >= 1)) { pHDMIUpdate->AudioInfoFrameUpdate = TRUE; } } if (reg & 0x08) { // MPEG Info Frame cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0xA0, &type); if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR3.3 - new or changed other (MPEG)) Info Frame detected, type=0x%02X.\n", type)); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0xBF, &mask); if (type == mask) { cap_SiI9031_set_packet_update(mask, pHDMIUpdate); } else { // try again if (pSiI9031->verbouse) RMDBGLOG((ENABLE, " Unexpected type in MPEG receive area: 0x%02X\n", type)); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, &mask); if (! (mask & 0x08)) { cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, mask | 0x08); } } } if (reg & 0x10) { // Other Info Frame if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR3.4 - new or changed other Info Frame detected.\n")); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0xC0, &mask); cap_SiI9031_set_packet_update(mask, pHDMIUpdate); } if (pSiI9031->verbouse && (reg & 0x20)) RMDBGLOG((ENABLE, "INTR3.5 - SPDIF parity error\n")); if (pSiI9031->verbouse && (reg & 0x40)) RMDBGLOG((ENABLE, "INTR3.6 - HDMI A/V Mute!\n")); if (pSiI9031->verbouse && (reg & 0x80)) RMDBGLOG((ENABLE, "INTR3.7 - General CP received\n"));#ifndef CHECK_TRIANGLE if ((reg & 0x20) && (pSiI9031->audio_state == audio_state_on)) { RMuint64 now = RMGetTimeInMicroSeconds(); if (RMCyclesElapsed64(pSiI9031->audio_guard_time, now) >= 5 * 1000 * 1000) { RMDBGLOG((ENABLE, "SPDIF parity error, restarting audio\n")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } }#endif } // Check INTR4 cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x74, ®); if (reg) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x74, reg); // clear intr if (reg & pSiI9031->intr_mask[3]) { //RMDBGLOG((ENABLE, "INTR4: 0x%02lX\n", reg)); if (reg & 0x40) { if (pSiI9031->last_hdcp_ok) { if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR4.6 - hdcp link quality error\n")); pSiI9031->last_hdcp_ok = FALSE; } } else { if (! pSiI9031->last_hdcp_ok) { if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR4.6 - hdcp link quality is now OK\n")); pSiI9031->last_hdcp_ok = TRUE; } } if (reg & 0x10) { if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR4.4 - no AVI info frame received!\n")); //if (pSiI9031->last_avi.valid) RMDBGLOG((ENABLE, "Lost AVI InfoFrames!\n")); // TODO pSiI9031->last_avi.valid = FALSE; } if (pSiI9031->verbouse && (reg & 0x08)) RMDBGLOG((ENABLE, "INTR4.3 - a CTS value has been dropped.\n")); if (pSiI9031->verbouse && (reg & 0x04)) RMDBGLOG((ENABLE, "INTR4.2 - a CTS value has been re-used.\n")); if (pSiI9031->verbouse && (reg & 0x02)) RMDBGLOG((ENABLE, "INTR4.1 - Audio FIFO Overrun.\n")); if (pSiI9031->verbouse && (reg & 0x01)) RMDBGLOG((ENABLE, "INTR4.0 - Audio FIFO Underrun.\n")); //if ((reg & 0x03) && (pSiI9031->audio_state == audio_state_on)) { // RMuint64 now = RMGetTimeInMicroSeconds(); // if (RMCyclesElapsed64(pSiI9031->audio_guard_time, now) >= 5 * 1000 * 1000) { // RMDBGLOG((ENABLE, "Audio FIFO Over/Underrun, restarting audio\n")); // if (pUpdate && (pUpdate->APIVersion >= 1)) { // pUpdate->AudioRestart = TRUE; // } // } //} } // Check INTR5 cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7B, ®); if (reg) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7B, reg); // clear intr if (reg & pSiI9031->intr_mask[4]) { //RMDBGLOG((ENABLE, "INTR5: 0x%02lX\n", reg)); if (pSiI9031->verbouse) { if (reg & 0x80) RMDBGLOG((ENABLE, "INTR5.7 - ACR ref. clk has changed\n")); if (reg & 0x40) RMDBGLOG((ENABLE, "INTR5.6 - audio auto config has muted the audio\n")); if (reg & 0x20) RMDBGLOG((ENABLE, "INTR5.5 - audio-related link error!\n")); if (reg & 0x10) RMDBGLOG((ENABLE, "INTR5.4 - vertical resolution has changed\n")); if (reg & 0x08) RMDBGLOG((ENABLE, "INTR5.3 - horizontal resolution has changed\n")); if (reg & 0x04) RMDBGLOG((ENABLE, "INTR5.2 - sync polarity has changed\n")); if (reg & 0x02) RMDBGLOG((ENABLE, "INTR5.1 - progressive/interlaced has changed\n")); if (reg & 0x01) RMDBGLOG((ENABLE, "INTR5.0 - audio fs has changed\n")); } if (reg & 0x1E) { RMDBGLOG((ENABLE, "Video signal timing has changed!\n")); pSiI9031->update_videomode = TRUE; }#ifndef CHECK_TRIANGLE if ((reg & 0x81) && (pSiI9031->audio_state == audio_state_on)) { RMDBGLOG((ENABLE, "Audio fs change, restarting audio\n")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } if ((reg & 0x20) && (pSiI9031->audio_state == audio_state_on)) { RMuint64 now = RMGetTimeInMicroSeconds(); if (RMCyclesElapsed64(pSiI9031->audio_guard_time, now) >= 2 * 1000 * 1000) { RMDBGLOG((ENABLE, "Audio error, restarting audio\n")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } }#endif } // Check INTR6 cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7C, ®); if (reg) cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7C, reg & 0x05); // clear intr if (reg & pSiI9031->intr_mask[5]) { //RMDBGLOG((ENABLE, "INTR6: 0x%02lX\n", reg)); if (reg & 0x04) { // Audio Content Protection Frame if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR6.2 - new or changed Audio Content Protection Info Frame detected.\n")); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0xE0, &type); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice + 8, 0xFF, &mask); if (type == mask) { cap_SiI9031_set_packet_update(mask, pHDMIUpdate); // Further ints on changed frame only cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, &mask); cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, mask & ~0x20); } else { // try again if (pSiI9031->verbouse) RMDBGLOG((ENABLE, " Unexpected type in ACP receive area: 0x%02X\n", type)); cap_i2c_read_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, &mask); if (! (mask & 0x20)) { cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7A, mask | 0x20); } } } if (pSiI9031->last_hotplug == (reg & 0x01)) { pSiI9031->last_hotplug = ! (reg & 0x01); if (pSiI9031->verbouse) RMDBGLOG((ENABLE, "INTR6.0 - %splug\n", (reg & 0x01) ? "un" : "")); if (reg & 0x01) { if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->FlushScaler = TRUE; pUpdate->AudioOff = TRUE; } cap_SiI9031_init_audio_clock(pSiI9031, FALSE, pSiI9031->mclk_factor); if (pHDMIUpdate && (pHDMIUpdate->APIVersion >= 1)) { pHDMIUpdate->AVIInfoFrameInvalidate = TRUE; } pSiI9031->hdmi_mode = cap_hdmi_mode_unknown; } else { cap_SiI9031_detect_mode(pSiI9031, &(pSiI9031->hdmi_mode)); if (pSiI9031->hdmi_mode == cap_hdmi_mode_HDMI) { cap_SiI9031_init_audio_clock(pSiI9031, TRUE, pSiI9031->mclk_factor); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } } } } } if (pSiI9031->update_videomode) { RMbool update = FALSE;// RMascii *StandardName; enum EMhwlibTVStandard TVStandard; RMDBGLOG((ENABLE, "%s video mode detection!\n", (pSiI9031->hdmi_mode == cap_hdmi_mode_HDMI) ? "HDMI" : "DVI")); pSiI9031->update_videomode = FALSE; do { TVStandard = pSiI9031->TVStandard; err = cap_SiI9031_measure_video_format(pSiI9031, NULL, NULL, &(pSiI9031->TVStandard), NULL, NULL, NULL); if (RMSUCCEEDED(err) && (TVStandard != pSiI9031->TVStandard)) update = TRUE; } while (RMSUCCEEDED(err) && (TVStandard != pSiI9031->TVStandard)); // need to detect the same mode twice cap_SiI9031_detect_mode(pSiI9031, &(pSiI9031->hdmi_mode)); if (pSiI9031->hdmi_mode == cap_hdmi_mode_HDMI) { if (pHDMIUpdate && (pHDMIUpdate->APIVersion >= 1)) { pHDMIUpdate->AVIInfoFrameUpdate = TRUE; } } else if (update) { if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->TVStandardValid = TRUE; pUpdate->TVStandardUpdate = TRUE; pUpdate->TVStandard = pSiI9031->TVStandard; } } /* if (update) { err = close_input(dcc_info, ppVideoSource, capture_opt, disp_opt, pSiI9031, input); if (pHDMI->TVStandard != EMhwlibTVStandard_Custom) { if (pSiI9031->hdmi_mode == cap_hdmi_mode_DVI) { if (pInputColorSpace) *pInputColorSpace = EMhwlibColorSpace_RGB_0_255; if (pInputColorFormat) *pInputColorFormat = EMhwlibInputColorFormat_24BPP; if (pUpsample422) *pUpsample422 = FALSE; if (pZoomX) *pZoomX = ZOOM_0; if (pZoomY) *pZoomY = ZOOM_0; if (pZoomW) *pZoomW = ZOOM_1; if (pZoomH) *pZoomH = ZOOM_1; // determine aspect ratio from video mode if (pPictureAspectRatio) { get_aspect_ratio_from_video_mode( TVStandard, NULL, Wide, &(PictureAspectRatio.X), &(PictureAspectRatio.Y)); RMDBGLOG((ENABLE, "[hdmi] Aspect Ratio from Video Mode: %lu:%lu\n", PictureAspectRatio.X, PictureAspectRatio.Y)); *pPictureAspectRatio = PictureAspectRatio; } prepare_dvi_mode(pSiI9031, capture_opt, FALSE); } err = setup_input(dcc_info, ppVideoSource, capture_opt, disp_opt, audio_opt, pSiI9031, input); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "FATAL: Error setting up capture!\n")); exit(1); } if ((pHDMI->hdmi_mode == cap_hdmi_mode_HDMI) && (audio_opt->AudioIn)) { RMDBGLOG((ENABLE, "Video mode has changed, restarting audio\n")); if (pUpdate && (pUpdate->APIVersion >= 1)) { pUpdate->AudioRestart = TRUE; } } } if (RMSUCCEEDED(GetTVStandardName(capture_opt->TVStandard, &StandardName))) { RMDBGLOG((LOCALDBG, "New TV Standard: %s\n", StandardName)); } else { RMDBGLOG((LOCALDBG, "New TV Standard: # %d\n", capture_opt[input].TVStandard)); } TVStandard = capture_opt->TVStandard; err = get_format_SiI9031(dcc_info, capture_opt, pSiI9031, 0x30, pSiI9031->i2c_video_delay, &update); if (RMFAILED(err) || (TVStandard == capture_opt->TVStandard)) { cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x72, 0x01); // clear intr cap_i2c_write_dev(pSiI9031, pSiI9031->BaseDevice, 0x7B, 0x1E); // clear intr pSiI9031->update_videomode = FALSE; } } else { pSiI9031->update_videomode = FALSE; } */ } return RM_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -