void EP956Controller_Initial(PEP956C_REGISTER_MAP pEP956C_RegMap, EP956C_CALLBACK IntCall) { // Save the Logical Hardware Assignment pEP956C_Registers = pEP956C_RegMap; EP956C_GenerateInt = IntCall; // Reset all EP956C registers memset(pEP956C_Registers, 0, sizeof(EP956C_REGISTER_MAP)); pEP956C_Registers->Video_Interface[0] = 0x80; pEP956C_Registers->Power_Control = EP956E_Power_Control__PD_HDMI; pEP956C_Registers->Audio_Interface = 0x10; // 2 Channel audio // Update Version Registers pEP956C_Registers->VendorID = 0x177A; pEP956C_Registers->DeviceID = 0x0956; pEP956C_Registers->Version_Major = EP956C_VERSION_MAJOR; pEP956C_Registers->Version_Minor = EP956C_VERSION_MINOR; // Initial HDCP Info memset(pEP956C_Registers->HDCP_AKSV, 0x00, sizeof(pEP956C_Registers->HDCP_AKSV)); memset(pEP956C_Registers->HDCP_BKSV, 0x00, sizeof(pEP956C_Registers->HDCP_BKSV)); // Set Revocation List address memcpy(pEP956C_Registers->Revocation_List, Revocation_List, sizeof(pEP956C_Registers->Revocation_List)); HDCP_Assign_RKSV_List(pEP956C_Registers->Revocation_List, sizeof(pEP956C_Registers->Revocation_List)); HDCP_Extract_BKSV(pEP956C_Registers->HDCP_BKSV); HDCP_Extract_BCAPS3(pEP956C_Registers->HDCP_BCAPS3); HDCP_Extract_FIFO((unsigned char*)pEP956C_Registers->HDCP_KSV_FIFO, sizeof(pEP956C_Registers->HDCP_KSV_FIFO)); HDCP_Stop(); // Reset EP956 Control Program EP956Controller_Reset(); }
void EP932Controller_Initial(PEP932C_REGISTER_MAP pEP932C_RegMap, EP932C_CALLBACK IntCall) { // Save the Logical Hardware Assignment pEP932C_Registers = pEP932C_RegMap; EP932C_GenerateInt = IntCall; // EP932 Reset Control EP_EP932M_Reset(); EP932_EnableHPInit(); // Initial IIC EP932_If_Initial(); // Reset Variables // bit is_Cap_HDMI = 0; is_Cap_YCC444 = is_Cap_YCC422 = 0; is_Connected = 0; is_VideoChanging = 0; is_AudioChanging = 0; // data TX_State = TXS_Search_EDID; HTP_TimeCount = 0; Process_Dispatch_ID = 0; VideoChg_TimeCount = 0; AudioChg_TimeCount = 0; ReadEDID_TimeCount = 0; HP_ChangeCount = 0; RSEN_ChangeCount = 0; memset(Gamut_Packet_Header_Backup, 0, 3); // Reset all EP932C registers memset(pEP932C_Registers, 0, sizeof(EP932C_REGISTER_MAP)); pEP932C_Registers->Video_Interface[0] = 0x80; pEP932C_Registers->Power_Control = EP932E_Power_Control__PD_HDMI; pEP932C_Registers->Audio_Interface = 0x10; // 2 Channel audio // Update Version Registers pEP932C_Registers->VendorID = 0x177A; pEP932C_Registers->DeviceID = 0x0932; pEP932C_Registers->Version_Major = VERSION_MAJOR; pEP932C_Registers->Version_Minor = VERSION_MINOR; DBG_printf(("Version %d.%d\r\n", (int)VERSION_MAJOR, (int)VERSION_MINOR )); // Initial HDCP Info memset(pEP932C_Registers->HDCP_AKSV, 0x00, sizeof(pEP932C_Registers->HDCP_AKSV)); memset(pEP932C_Registers->HDCP_BKSV, 0x00, sizeof(pEP932C_Registers->HDCP_BKSV)); // Update Configuration Registers EP932_Reg_Read(EP932_Configuration, DDC_Data, 1); pEP932C_Registers->Configuration = DDC_Data[0]; // Set Revocation List address HDCP_Extract_BKSV_BCAPS3(pEP932C_Registers->HDCP_BKSV); HDCP_Extract_FIFO((unsigned char*)pEP932C_Registers->HDCP_KSV_FIFO, sizeof(pEP932C_Registers->HDCP_KSV_FIFO)); HDCP_Stop(); // Reset EP932 Control Program EP932Controller_Reset(); }
void TXS_RollBack_HDCP(void) { DBG_printf(("\r\nState Rollback: Stop HDCP -> [TXS_Stream]\r\n")); HDCP_Stop(); pEP932C_Registers->HDCP_Status = 0; pEP932C_Registers->HDCP_State = 0; }
unsigned char EP956Controller_Task(void) { // // Read from EP956 and Report Status // // Polling Interrupt Flag and updat the internal information EP956Controller_Interrupt(); // Polling Hot-Plug (MHL Link) / RSEN every 55ms EP956Control_Link_Task(); // // Update some controls from the user any time // // Power Control if(pEP956C_Registers->Power_Control & (EP956E_Power_Control__PD_HDMI | EP956E_Power_Control__PD_TOT) ) { is_Source_Ready = 0; pEP956C_Registers->Power_Control |= EP956E_Power_Control__PD_HDMI; #ifndef MHL_CODE EP956_Reg_Set_Bit(EP956_TX_PHY_Control_1, EP956_TX_PHY_Control_1__RSEN_DIS); #endif } else { #ifndef MHL_CODE EP956_Reg_Clear_Bit(EP956_TX_PHY_Control_1, EP956_TX_PHY_Control_1__RSEN_DIS); #endif if( is_VideoChanging || is_AudioChanging || (pEP956C_Registers->Video_Input_Format[0] == 0) ) { is_Source_Ready = 0; // if(ConnectionState == CBUS_LINK_STATE__Connected) { // MHL_MSC_Cmd_MSC_MSG(MSC_RAP, RAP_CONTENT_OFF); // } } else { is_Source_Ready = 1; // if(ConnectionState == CBUS_LINK_STATE__Connected) { // MHL_MSC_Cmd_MSC_MSG(MSC_RAP, RAP_CONTENT_ON); // } } } // Mute Control if( (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__AUDIO_DIS) || (TX_State < TXS_Stream) ) { HDMI_Tx_AMute_Enable(); } else { HDMI_Tx_AMute_Disable(); } if( (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__VIDEO_DIS) || (TX_State < TXS_Stream) ) { HDMI_Tx_VMute_Enable(); } else { HDMI_Tx_VMute_Disable(); } // Auto Handle AVMute Handle_AVMute(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__AVMUTE_EN); // // Handle the main HDMI Link State and HDCP Authentication State // The state transition: [Search_EDID] => [Wait_Upstream] => [Stream] => [HDCP] // switch(TX_State) { case TXS_Search_EDID: if(is_Connected && is_PATH_EN) { //if(ReadEDID_TimeCount > 200/EP956C_TIMER_PERIOD) //EP_DEV_DBG("delay 200ms+\n"); delay_100ms(2); //EP_DEV_DBG("delay 200ms-\n"); { unsigned char EDID_DDC_Status; static BYTE detectCount = 0; // Confirm Hot-Plug (time-out after 1s) if(!is_Hot_Plug) { //if(ReadEDID_TimeCount <= 1000/EP956C_TIMER_PERIOD) break; if(detectCount++ < 5) break; detectCount = 0; EP_DEV_DBG("Err: EDID detected without Hot-Plug for 1s\n"); } // Read EDID EP_DEV_DBG("State Transist: Read EDID -> [TXS_Wait_Upstream]\n"); memset(pEP956C_Registers->Readed_EDID, 0xFF, 256); EDID_DDC_Status = Downstream_Rx_read_EDID(pEP956C_Registers->Readed_EDID); if(EDID_DDC_Status) { static BYTE failCount = 0; EP_DEV_DBG("Err: EDID read failed 0x%02X\n", (int)EDID_DDC_Status); //if(ReadEDID_TimeCount <= 500/EP956C_TIMER_PERIOD) break; if(failCount++ < 3) break; failCount = 0; } //ReadEDID_TimeCount = 0; // Set Output if(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__FORCE_HDMI_CAP) { is_Cap_HDMI = 1; } else { is_Cap_HDMI = EDID_GetHDMICap(pEP956C_Registers->Readed_EDID); } if(is_Cap_HDMI) { EP_DEV_DBG("Support HDMI"); // Default Capability is_Cap_YCC444 = is_Cap_YCC422 = 0; pEP956C_Registers->EDID_ASFreq = 0x07; pEP956C_Registers->EDID_AChannel_PCM = 1; pEP956C_Registers->EDID_VideoDataAddr = 0x00; pEP956C_Registers->EDID_AudioDataAddr = 0x00; pEP956C_Registers->EDID_SpeakerDataAddr = 0x00; pEP956C_Registers->EDID_VendorDataAddr = 0x00; if(!EDID_DDC_Status) { if(pEP956C_Registers->Readed_EDID[131] & 0x20) { // Support YCC444 is_Cap_YCC444 = 1; EP_DEV_DBG(" YCC444"); } if(pEP956C_Registers->Readed_EDID[131] & 0x10) { // Support YCC422 is_Cap_YCC422 = 1; EP_DEV_DBG(" YCC422"); } EP_DEV_DBG("\n"); pEP956C_Registers->EDID_ASFreq = EDID_GetPCMFreqCap(pEP956C_Registers->Readed_EDID); pEP956C_Registers->EDID_AChannel_PCM = EDID_GetChannelCap(pEP956C_Registers->Readed_EDID, 1); // Get PCM Max Channel pEP956C_Registers->EDID_AChannel_DSD = EDID_GetChannelCap(pEP956C_Registers->Readed_EDID, 9); // Get DSD Max Channel pEP956C_Registers->EDID_VideoDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x40); pEP956C_Registers->EDID_AudioDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x20); pEP956C_Registers->EDID_SpeakerDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x80); pEP956C_Registers->EDID_VendorDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x60); } } else { EP_DEV_DBG("Support DVI RGB only\n"); is_Cap_YCC444 = is_Cap_YCC422 = 0; pEP956C_Registers->EDID_ASFreq = pEP956C_Registers->EDID_AChannel_PCM = 0; } if(is_Cap_HDMI) pEP956C_Registers->EDID_Status = EDID_DDC_Status | EP956E_EDID_Status__HDMI; else pEP956C_Registers->EDID_Status = EDID_DDC_Status; EP_DEV_DBG("Support Max PCM Audio Channel %d\n", (int)pEP956C_Registers->EDID_AChannel_PCM+1); EP_DEV_DBG("Support Audio Freq 0x%02X\n", (int)pEP956C_Registers->EDID_ASFreq); // Report EDID Change pEP956C_Registers->Interrupt_Flags |= EP956E_Interrupt_Flags__EDID_CHG; if(EP956C_GenerateInt && (pEP956C_Registers->Interrupt_Enable & EP956E_Interrupt_Enable__EDID_CHG) ) EP956C_GenerateInt(); TX_State = TXS_Wait_Upstream; } } else { pEP956C_Registers->EDID_Status = EDID_STATUS_NoAct; //ReadEDID_TimeCount = 0; } break; case TXS_Wait_Upstream: if(!is_Connected || !is_PATH_EN) { TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(is_Source_Ready && is_ReceiverSense) { // EP956 can detect RSEN in power down mode EP_DEV_DBG("State Transist: Power Up -> [TXS_Stream]\n"); // Set to DVI mode HDMI_Tx_DVI(); // Power Up HDMI_Tx_Power_Up(); is_HDMI_Mode_Set = 1; //HDMI_Mode_Set_TimeCount = 0; TX_State = TXS_Stream; } else { // Check Force HDMI BOOL if(!is_Cap_HDMI) { if(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__FORCE_HDMI_CAP) { TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } } } break; case TXS_Stream: //if(HDMI_Mode_Set_TimeCount > 10/EP956C_TIMER_PERIOD) //EP_DEV_DBG("delay 10ms+\n"); //EP_DEV_DBG("delay 10ms-\n"); if(is_HDMI_Mode_Set) { delay_1ms(10); //HDMI_Mode_Set_TimeCount = 0; is_HDMI_Mode_Set = 0; // HDMI Mode if(!is_Cap_HDMI || (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDMI_DIS) ) { HDMI_Tx_DVI(); // Set to DVI mode (The Info Frame and Audio Packets would not be send) } else { HDMI_Tx_HDMI(); // Set to HDMI mode } #ifdef MHL_CODE if(EP956_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type > PIX_FREQ_74250KHz) { is_PackedPixelMode = 1; if(is_PATH_EN) MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__PacketPixel | PATH_EN); else MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__PacketPixel); MHL_Clock_Mode(1); } else { is_PackedPixelMode = 0; if(is_PATH_EN) MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__Normal | PATH_EN); else MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__Normal); MHL_Clock_Mode(0); } #endif } if(!is_Connected || !is_PATH_EN) { TXS_RollBack_Stream(); TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(!is_Source_Ready || !is_ReceiverSense) { TXS_RollBack_Stream(); TX_State = TXS_Wait_Upstream; } else if(!(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDCP_DIS)) { if(is_HDMI_Mode_Set == 0) { EP_DEV_DBG("State Transist: Start HDCP -> [TXS_HDCP]\n"); // Enable mute for transmiter video and audio HDMI_Tx_Mute_Enable(); TX_State = TXS_HDCP; } } if(Dump_Timer++ > 2000/EP956C_TIMER_PERIOD) { Dump_Timer = 0; EP956_Reg_Read(EP956_CTS, Temp_Byte, 3); EP_DEV_DBG("CTS %02X %02X %02X\n", Temp_Byte[0], Temp_Byte[1], Temp_Byte[2]); EP956_Reg_Read(EP956_N, Temp_Byte, 3); EP_DEV_DBG("N %02X %02X %02X\n", Temp_Byte[0], Temp_Byte[1], Temp_Byte[2]); EP956_Reg_Read(EP956_Color_Space_Control, Temp_Byte, 1); EP_DEV_DBG("EP956_Color_Space_Control %X\n", Temp_Byte[0]); EP956_Reg_Read(EP956_General_Control_8, Temp_Byte, 1); EP_DEV_DBG("EP956_General_Control_8 %X\n", Temp_Byte[0]); EP956_Reg_Read(EP956_IIS_Control, Temp_Byte, 1); EP_DEV_DBG("EP956_IIS_Control %X\n", Temp_Byte[0]); HDMI_Dump_Status(); } break; case TXS_HDCP: if(!is_Connected || !is_PATH_EN) { TXS_RollBack_HDCP(); TXS_RollBack_Stream(); TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(!is_Source_Ready || !is_ReceiverSense) { TXS_RollBack_HDCP(); TXS_RollBack_Stream(); TX_State = TXS_Wait_Upstream; } else if(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDCP_DIS) { TXS_RollBack_HDCP(); TX_State = TXS_Stream; } else if(!is_Hot_Plug || is_VideoChanging || (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__VIDEO_DIS) ) { // Enable mute for transmiter video and audio HDMI_Tx_Mute_Enable(); HDCP_Stop(); } else { pEP956C_Registers->HDCP_State = HDCP_Authentication_Task(); pEP956C_Registers->HDCP_Status = HDCP_Get_Status(); } break; } // // Combine the EDID capability and the source information to set the EP956 video/audio settings // // // Update Video Params // // Video Interface Video_Params.Interface = pEP956C_Registers->Video_Interface[0]; // Video Timing if(pEP956C_Registers->Video_Input_Format[0]) { // Semi Auto Detect Video Timing if(pEP956C_Registers->Video_Input_Format[0] < 128) { if(pEP956C_Registers->Video_Input_Format[0] < 112) { Video_Params.VideoSettingIndex = pEP956C_Registers->Video_Input_Format[0]; } else { Video_Params.VideoSettingIndex = pEP956C_Registers->Video_Input_Format[0] - (112 - EP956_VDO_Settings_Rep_Start); } } else { Video_Params.VideoSettingIndex = pEP956C_Registers->Video_Input_Format[0] - (128 - EP956_VDO_Settings_IT_Start); } } // Select Sync Mode Video_Params.SyncMode = (pEP956C_Registers->Video_Interface[1] & EP956E_Video_Interface_Setting_1__SYNC) >> 2; // Select Color Space switch(pEP956C_Registers->Video_Interface[1] & EP956E_Video_Interface_Setting_1__COLOR) { default: case EP956E_Video_Interface_Setting_1__COLOR__Auto: switch(Video_Params.VideoSettingIndex) { case 4: case 5: case 16: case 19: case 20: case 31: case 32: case 33: case 34: case 39: case 40: case 41: case 46: case 47: // HD Timing Video_Params.ColorSpace = COLORSPACE_709; break; default: if(Video_Params.VideoSettingIndex && Video_Params.VideoSettingIndex < EP956_VDO_Settings_IT_Start) { // SD Timing Video_Params.ColorSpace = COLORSPACE_601; } else { // IT Timing Video_Params.ColorSpace = COLORSPACE_709; } } break; case EP956E_Video_Interface_Setting_1__COLOR__601: Video_Params.ColorSpace = COLORSPACE_601; break; case EP956E_Video_Interface_Setting_1__COLOR__709: Video_Params.ColorSpace = COLORSPACE_709; break; } // Set Input Format switch(pEP956C_Registers->Video_Interface[1] & EP956E_Video_Interface_Setting_1__VIN_FMT) { default: case EP956E_Video_Interface_Setting_1__VIN_FMT__RGB: Video_Params.FormatIn = COLORFORMAT_RGB; break; case EP956E_Video_Interface_Setting_1__VIN_FMT__YCC444: Video_Params.FormatIn = COLORFORMAT_YCC444; break; case EP956E_Video_Interface_Setting_1__VIN_FMT__YCC422: Video_Params.FormatIn = COLORFORMAT_YCC422; break; } // Set Output Format switch(pEP956C_Registers->Video_Input_Format[2] & EP956E_Video_Output_Format_2__VOUT_FMT) { default: case EP956E_Video_Output_Format_2__VOUT_FMT__Auto: if(is_Cap_YCC444) { Video_Params.FormatOut = COLORFORMAT_YCC444; } else if(is_Cap_YCC422) { Video_Params.FormatOut = COLORFORMAT_YCC422; } else { Video_Params.FormatOut = COLORFORMAT_RGB; } break; case EP956E_Video_Output_Format_2__VOUT_FMT__YCC444: Video_Params.FormatOut = COLORFORMAT_YCC444; break; case EP956E_Video_Output_Format_2__VOUT_FMT__YCC422: Video_Params.FormatOut = COLORFORMAT_YCC422; break; case EP956E_Video_Output_Format_2__VOUT_FMT__RGB: Video_Params.FormatOut = COLORFORMAT_RGB; break; } #ifdef MHL_CODE // Pack Pixel Mode if(EP956_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type > PIX_FREQ_74250KHz) { // Force to YCC422 Video_Params.FormatOut = COLORFORMAT_YCC422; } #endif // DVI mode settings overwrite if(!is_Cap_HDMI || (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDMI_DIS) ) { Video_Params.FormatOut = COLORFORMAT_RGB; } // AFAR Video_Params.AFARate = ((pEP956C_Registers->Video_Input_Format[1] & EP956E_Video_Output_Format_1__AFAR) >> 4) | 0x08; // Video Change if(memcmp(&Video_Params, &pEP956C_Registers->Video_Params_Backup, 4) != 0) { // Timing change that AVMute is needed pEP956C_Registers->Video_Params_Backup = Video_Params; //VideoChg_TimeCount = 0; is_VideoChanging = 1; EP_DEV_DBG("Video Changing......\n"); } else if(memcmp(&Video_Params, &pEP956C_Registers->Video_Params_Backup, sizeof(VDO_PARAMS)) != 0) { // Format change which can by applied immediately pEP956C_Registers->Video_Params_Backup = Video_Params; HDMI_Tx_VideoFMT_Config(&Video_Params); } // Video Change Debouncing if(is_VideoChanging) { //if(VideoChg_TimeCount > AV_STABLE_TIME/EP956C_TIMER_PERIOD) //EP_DEV_DBG("delay 500ms+\n"); delay_100ms(5); //EP_DEV_DBG("delay 500ms-\n"); { HDMI_Tx_Video_Config(&Video_Params); is_VideoChanging = 0; //VideoChg_TimeCount = 0; // Report Video Change pEP956C_Registers->Interrupt_Flags |= EP956E_Interrupt_Flags__VIDEO_CHG; if(EP956C_GenerateInt && (pEP956C_Registers->Interrupt_Enable & EP956E_Interrupt_Enable__VIDEO_CHG) ) EP956C_GenerateInt(); } } // // Update Audio Params // Audio_Params.Interface = pEP956C_Registers->Audio_Interface & 0x8F; // DSDCK_POL, ..., SD_DIR, WS_M, WS_POL, SCK_POL Audio_Params.VideoSettingIndex = Video_Params.VideoSettingIndex; // Update Audio Type Audio_Params.AudioType = (pEP956C_Registers->Audio_Input_Format[0] & EP956E_Audio_Output_Format__AUDIO_TYPE) >> 6; // Update Audio Channel Number if(Audio_Params.AudioType == AUDIO_TYPE_IIS) { if(EP956_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type <= PIX_FREQ_27027KHz) { Audio_Params.ChannelNumber = 1; } else { Audio_Params.ChannelNumber = min(((pEP956C_Registers->Audio_Interface & 0x70) >> 4), pEP956C_Registers->EDID_AChannel_PCM); } } else if(Audio_Params.AudioType == AUDIO_TYPE_DSD) {