📄 ad9380.c
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc. * All Rights Reserved. Proprietary and Confidential. * *//** @file AD9380.c @brief Interface to access the AD9380 HDMI capture chip @author Christian Wolff, Sean.Sekwon.Choi @date 2007-07-16*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 1#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "common.h"#include "hdmi.h"#include "AD9380.h"#include "i2c.h"//#include "AD9380_YUVDATA.h"//#include "AD9380_VGADATA.h"//#include "AD9380_HDMIDATA.h"//#include "AD9380_CSCDATA.h"struct cap_AD9380_instance { // Access struct RUA *pRUA; RMuint32 I2CModuleID; struct EMhwlibI2CDeviceParameter I2CDevice; RMuint8 BaseDevice; // State enum EMhwlibTVStandard TVStandard; enum EMhwlibColorSpace InputColorSpace; enum cap_hdmi_mode hdmi_mode; RMbool AVI_InfoFrameDetected; RMbool Audio_InfoFrameDetected; RMbool SPD_InfoFrameDetected; RMbool MPEG_InfoFrameDetected; RMbool ACP_InfoFrameDetected; RMbool ISRC1_InfoFrameDetected; RMbool ISRC2_InfoFrameDetected; RMbool FirstPacketSinceReset;};/* CEA 861-C/D subset of all EMhwlib video modes *//* translates VIC to enum EMhwlibTVStandard */extern const enum EMhwlibTVStandard cap_hdmi_cea861_modes[HDMI_CEA861_VIDEOMODES_N];RMstatus cap_AD9380_open( struct RUA *pRUA, struct cap_AD9380_instance **ppAD9380, RMuint32 I2CModuleID, struct EMhwlibI2CDeviceParameter *pI2CDevice){ struct cap_AD9380_instance *pAD9380; RMDBGLOG((FUNCNAME, "%s\n",__func__)); // Sanity checks if (ppAD9380 == NULL) return RM_FATALINVALIDPOINTER; *ppAD9380 = NULL; if (pRUA == NULL) return RM_FATALINVALIDPOINTER; if (pI2CDevice == NULL) return RM_FATALINVALIDPOINTER; // Allocate and clear local instance pAD9380 = (struct cap_AD9380_instance *)RMMalloc(sizeof(struct cap_AD9380_instance)); if (pAD9380 == NULL) { RMDBGLOG((ENABLE, "[AD9380] FATAL! Not enough memory for struct cap_AD9380_instance!\n")); return RM_FATALOUTOFMEMORY; } RMMemset(pAD9380, 0, sizeof(struct cap_AD9380_instance)); *ppAD9380 = pAD9380; // Set default and startup values pAD9380->pRUA = pRUA; pAD9380->I2CModuleID = I2CModuleID; pAD9380->I2CDevice = *pI2CDevice; pAD9380->BaseDevice = pI2CDevice->DevAddr; pAD9380->AVI_InfoFrameDetected = FALSE; pAD9380->Audio_InfoFrameDetected = FALSE; pAD9380->SPD_InfoFrameDetected = FALSE; pAD9380->MPEG_InfoFrameDetected = FALSE; pAD9380->ACP_InfoFrameDetected = FALSE; pAD9380->ISRC1_InfoFrameDetected = FALSE; pAD9380->ISRC2_InfoFrameDetected = FALSE; pAD9380->FirstPacketSinceReset = TRUE; return RM_OK;}RMstatus cap_AD9380_close( struct cap_AD9380_instance *pAD9380){ RMDBGLOG((FUNCNAME, "%s\n",__func__)); // Sanity checks if (pAD9380 == NULL) return RM_OK; // already closed // Free all ressources RMFree(pAD9380); return RM_OK;}/* tri-state all outputs and power down chip */RMstatus cap_AD9380_tristate( struct cap_AD9380_instance *pAD9380){ RMDBGLOG((FUNCNAME, "%s\n",__func__)); // Sanity checks if (pAD9380 == NULL) return RM_FATALINVALIDPOINTER; return RM_OK;}/*static RMstatus SetDigitalInputInterface(struct cap_AD9380_instance *pAD9380, RMbool isDigital){ RMuint32 reg_0x11 = 0; cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x11, ®_0x11); RMinsShiftBits(®_0x11, isDigital == TRUE, 1, 1); cap_i2c_write_dev(pAD9380, pAD9380->BaseDevice, 0x11, reg_0x11); return RM_OK;}*/static RMstatus cap_AD9380_detect_sync(struct cap_AD9380_instance *pAD9380){ RMuint8 reg_0x15, reg_0x16; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x15, ®_0x15); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x16, ®_0x16); RMDBGLOG((LOCALDBG, "sync detect reg0x15 0x%x\n", reg_0x15)); RMDBGLOG((LOCALDBG, "sync detect reg0x16 0x%x\n", reg_0x16)); return RM_OK;}static RMstatus cap_SA9380_reset_clock_termination(struct cap_AD9380_instance *pAD9380){ RMuint8 reg_0x59; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_write_dev(pAD9380, pAD9380->BaseDevice, 0x59, 0x06); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x59, ®_0x59); RMDBGLOG((LOCALDBG, "reg0x59 0x%x\n", reg_0x59)); return RM_OK;}static RMstatus cap_AD9380_detect_TMDS_sync(struct cap_AD9380_instance *pAD9380){ RMuint8 reg_0x2f; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x2f, ®_0x2f); RMDBGLOG((LOCALDBG, "TMDS sync ************* 0x%x \n", reg_0x2f)); return RM_OK; }static RMstatus cap_AD9380_power_up(struct cap_AD9380_instance *pAD9380){ RMuint8 reg_0x26; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x26, ®_0x26); RMDBGLOG((LOCALDBG, "before write reg 0x26 : 0x%x \n", reg_0x26)); reg_0x26 = 0x08; cap_i2c_write_dev(pAD9380, pAD9380->BaseDevice, 0x26, reg_0x26); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x26, ®_0x26); RMDBGLOG((LOCALDBG, "after write reg 0x26 : 0x%x \n", reg_0x26)); return RM_OK; }static RMstatus cap_AD9380_power_down(struct cap_AD9380_instance *pAD9380){ RMuint8 reg_0x26; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x26, ®_0x26); RMDBGLOG((LOCALDBG, "reg 0x26 : 0x%x \n", reg_0x26)); reg_0x26 |= 0x01; cap_i2c_write_dev(pAD9380, pAD9380->BaseDevice, 0x26, reg_0x26); return RM_OK; }static RMstatus cap_AD9380_enable_MCLK(struct cap_AD9380_instance *pAD9380){ RMuint8 reg; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x27, ®); RMDBGLOG((LOCALDBG, "reg 0x27 : 0x%x \n", reg)); reg |= 0x20; cap_i2c_write_dev(pAD9380, pAD9380->BaseDevice, 0x27, reg); return RM_OK; }RMstatus cap_AD9380_init_HDMI_capture(struct cap_AD9380_instance *pAD9380, RMuint32 input){ RMuint8 reg; RMuint8 cap_AD9380_HDMI_INIT[][2] = {#if 1 { 0x1 , 0x69 }, { 0x2 , 0xd0 }, { 0x1 , 0x0 }, { 0x2 , 0x0 }, { 0x3 , 0x48 }, // org { 0x3 , 0x88 }, // no change { 0x3 , 0xa4 }, // choi { 0x4 , 0x80 }, { 0xe , 0x20 },// { 0xf , 0x40 },// { 0x10 , 0x40 },// { 0x11 , 0x2 }, { 0x12 , 0xa9 }, // org { 0x12 , 0x40 }, // choi { 0x13 , 0x0 }, { 0x14 , 0x0 }, { 0x19 , 0x8 }, // org { 0x1a , 0x14 }, // org { 0x19 , 0x0 }, // choi { 0x1a , 0x0 }, // choi { 0x1b , 0x6 }, // org { 0x1b , 0xf8 }, // choi { 0x1c , 0x4e }, // org { 0x1c , 0x68 }, // choi { 0x1d , 0xff }, { 0x1e , 0x20 }, { 0x1f , 0x32 }, { 0x20 , 0x14 },// { 0x21 , 0xec },// { 0x21 , 0x7c }, // org { 0x21 , 0x0c }, // choi// { 0x21 , 0x0 },// { 0x24 , 0x0 }, { 0x22 , 0x8 }, // org { 0x22 , 0x0 }, // choi { 0x23 , 0x14 },// { 0x24 , 0x20 }, { 0x24 , 0x70 }, // org { 0x24 , 0x72 }, // choi { 0x25 , 0x52 }, // org { 0x25 , 0x52 }, // choi { 0x26 , 0x8 }, // org { 0x26 , 0x78 }, // choi { 0x27 , 0x80 }, // org { 0x27 , 0x88 }, // choi { 0x28 , 0x82 }, // org { 0x28 , 0x61 }, // choi { 0x29 , 0x0 }, { 0x2a , 0x5 }, { 0x2b , 0x0 }, { 0x2c , 0x2 }, { 0x2d , 0xd0 }, { 0x2e , 0x18 },// { 0x2e , 0x78 }, { 0x31 , 0x96 }, { 0x32 , 0xd }, { 0x33 , 0x95 }, { 0x34 , 0x84 }, // org { 0x34 , 0x80 }, // choi { 0x57 , 0x0 }, { 0x58 , 0x91 },// { 0x58 , 0x99 },// { 0x59 , 0x20 },// { 0x59 , 0x26 },// { 0x59 , 0x36 },#endif }; RMDBGLOG((FUNCNAME, "%s\n",__func__)); // power up the chip cap_AD9380_power_down(pAD9380); cap_AD9380_power_up(pAD9380); // print revision cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x00, ®); RMDBGLOG((LOCALDBG, "chip revision 0x%x\n", reg)); // color space conversion setting // initialize all others if(1) cap_i2c_init(pAD9380, pAD9380->BaseDevice, cap_AD9380_HDMI_INIT); // Input Port Setting if(1) cap_i2c_write_dev(pAD9380, pAD9380->BaseDevice, 0x11, 0x02); //interface select - digital interface // enable external MCLK if(1) cap_AD9380_enable_MCLK(pAD9380); if(0){ cap_SA9380_reset_clock_termination(pAD9380); cap_AD9380_detect_sync(pAD9380); } if(0) cap_AD9380_detect_TMDS_sync(pAD9380); return RM_OK;}/* initialize the audio clock and data outputs of the AD9380 */RMstatus cap_AD9380_init_audio_clock(struct cap_AD9380_instance *pAD9380, RMbool enable, RMuint32 mclk_f){ RMDBGLOG((FUNCNAME, "%s\n",__func__)); return RM_OK;}/* get current audio channel status from AD9380 */RMstatus cap_AD9380_get_audio_channel_status(struct cap_AD9380_instance *pAD9380, RMuint8 ch_stat[5]){ RMuint8 reg_0x5f, reg_0x60, reg_0x61; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x5f, ®_0x5f); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x60, ®_0x60); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x61, ®_0x61); RMDBGLOG((LOCALDBG, "audio channel status code 0x%x\n", reg_0x5f)); RMDBGLOG((LOCALDBG, "audio channel number 0x%x\n", reg_0x60)); RMDBGLOG((LOCALDBG, "audio channel accuracy & freqency code 0x%x\n", reg_0x61)); return RM_OK;}/* get current audio clock divider values N/CTS from AD9380 */RMstatus cap_AD9380_get_audio_n_cts(struct cap_AD9380_instance *pAD9380, RMuint32 *pN, RMuint32 *pCTS, RMuint32 *pApproxSamplingRate){ RMDBGLOG((FUNCNAME, "%s\n",__func__)); return RM_OK;}RMstatus cap_AD9380_detect_mode(struct cap_AD9380_instance *pAD9380, enum cap_hdmi_mode *pHDMIMode){ RMuint8 reg_0x5b = 0; RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x5b, ®_0x5b); *pHDMIMode = ((reg_0x5b & 0x8) ? cap_hdmi_mode_HDMI : cap_hdmi_mode_DVI); return RM_OK;}RMstatus cap_AD9380_set_mode(struct cap_AD9380_instance *pAD9380, enum cap_hdmi_mode hdmi_mode){ RMDBGLOG((FUNCNAME, "%s\n",__func__)); return RM_OK;}static RMstatus cap_AD9380_is_packet_detected_since_reset(struct cap_AD9380_instance *pAD9380, RMuint8 *pPacket){ RMuint8 reg_0x5a; //RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x5a, ®_0x5a); if(reg_0x5a && pAD9380->FirstPacketSinceReset){ RMDBGLOG((LOCALDBG, "packet since last reset 0x%x \n", reg_0x5a)); *pPacket = reg_0x5a; pAD9380->FirstPacketSinceReset = FALSE; } return RM_OK;}static RMstatus cap_AD9380_is_packet_detected(struct cap_AD9380_instance *pAD9380, RMuint8 *pPacket){ //RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_i2c_read_dev(pAD9380, pAD9380->BaseDevice, 0x87, pPacket); if(*pPacket){ RMDBGLOG((LOCALDBG, "*********packet********* 0x%x \n", *pPacket)); } return RM_OK;}/* Returns RM_OK if an interrupt is pending on the AD9380 */RMstatus cap_AD9380_check_int(struct cap_AD9380_instance *pAD9380){ RMuint8 packet = 0; //RMDBGLOG((FUNCNAME, "%s\n",__func__)); cap_AD9380_is_packet_detected_since_reset(pAD9380, &packet); if(0) cap_AD9380_is_packet_detected(pAD9380, &packet); pAD9380->AVI_InfoFrameDetected = ((packet & 0x1) == 0x1); pAD9380->Audio_InfoFrameDetected = ((packet & 0x2) == 0x2); pAD9380->SPD_InfoFrameDetected = ((packet & 0x4) == 0x4); pAD9380->MPEG_InfoFrameDetected = ((packet & 0x8) == 0x8); pAD9380->ACP_InfoFrameDetected = ((packet & 0x10) == 0x10); pAD9380->ISRC1_InfoFrameDetected = ((packet & 0x20) == 0x20); pAD9380->ISRC2_InfoFrameDetected = ((packet & 0x40) == 0x40); if(packet != 0){ RMDBGLOG((LOCALDBG, "packet 0x%x \n", packet)); return RM_OK; }else{ return RM_ERROR; }}RMstatus cap_AD9380_handle_int(struct cap_AD9380_instance *pAD9380, struct cap_update *pUpdate, struct cap_hdmi_update *pHDMIUpdate){ RMDBGLOG((FUNCNAME, "%s\n",__func__)); if(0) cap_AD9380_detect_TMDS_sync(pAD9380);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -