⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvi_hdmi.c.070605.msg

📁 linux下面的hdmi驱动
💻 MSG
📖 第 1 页 / 共 5 页
字号:
	
	return DH_i2c_read_data(pRUA, pi2c_dev, sub_address, data, data_size);
}

static RMstatus DH_i2c_write_data(struct RUA *pRUA, struct DH_I2C *pi2c_dev, RMuint8 sub_address, RMuint8 *data, RMuint32 data_size)
{
	struct I2C_WriteData_type i2c_write;
	RMstatus err;
	RMuint32 r;
	
	if (data == NULL) {
		return RM_FATALINVALIDPOINTER;
	}
	
	RMDBGLOG((DISABLE, "==== I2C Wr 0x%02X:0x%02X-0x%02X ====\n", pi2c_dev->dev.WrAddr, sub_address, sub_address + data_size - 1));
	r = MAX_I2C_ATTEMPTS;
	do {
		if (RMFAILED(err = DH_update_i2c(pRUA, pi2c_dev))) continue;
		i2c_write.UseSubAddr = TRUE;
		i2c_write.SubAddr = sub_address;
		i2c_write.DataSize = data_size;
		RMMemcpy(i2c_write.Data, data, data_size);
#if DISABLE_I2C_BURST_WRITE
		{
			RMuint32 i;
			struct I2C_WriteRMuint8_type i2c_write;
			RMstatus e;
			for (i = 0; i < data_size; i++) {
				i2c_write.SubAddr = sub_address + i;
				i2c_write.Data = data[i];
				e = RUASetProperty(pRUA, pi2c_dev->I2C, RMI2CPropertyID_WriteRMuint8, &i2c_write, sizeof(i2c_write), 0);
				if (RMFAILED(e)) err = e;
			}
		}
#else
		err = RUASetProperty(pRUA, pi2c_dev->I2C, RMI2CPropertyID_WriteData, &i2c_write, sizeof(i2c_write), 0);
#endif
		i2c_usage--;  // decrease usage counter for this I2C configuration
	} while (--r && RMFAILED(err));
	if (RMFAILED(err)) {
		RMDBGLOG((LOCALDBG, "Error setting RMI2CPropertyID_WriteData(0x%02X:0x%02X, 0x%02X) on I2C 0x%08lX GPIO %lu/%lu! %s\n", 
			pi2c_dev->dev.WrAddr, i2c_write.SubAddr, i2c_write.DataSize, 
			pi2c_dev->I2C, pi2c_dev->dev.PioClock, pi2c_dev->dev.PioData, 
			RMstatusToString(err)));
	}
#if DH_I2C_VERIFY_WRITE
	{
		RMuint32 i;
		DH_i2c_read_data(pRUA, pi2c_dev, sub_address, i2c_write.Data, i2c_write.DataSize);
		for (i = 0; i < data_size; i++) {
			if (i2c_write.Data[i] != data[i]) {
				RMDBGLOG((LOCALDBG, "Error verifying 0x%02lX:0x%02lX, is 0x%02X instead of 0x%02X!\n", 
					pi2c_dev->dev.WrAddr, i2c_write.SubAddr + i, i2c_write.Data[i], data[i]));
			}
		}
	}
#endif  // DH_I2C_VERIFY_WRITE	
	return err;
}

static RMstatus DH_i2c_write_data_segment(
	struct RUA *pRUA, 
	struct DH_I2C *pi2c_dev, 
	RMuint8 sub_address, 
	RMuint8 *data, 
	RMuint32 data_size, 
	RMuint8 segment_ptr, 
	RMuint8 segment)
{
	struct I2C_SelectSegment_type i2c_segment;
	RMstatus err;
	RMuint32 r, index;
	
	if (data == NULL) {
		return RM_FATALINVALIDPOINTER;
	}
	
	r = MAX_I2C_ATTEMPTS;
	do {
		if (RMFAILED(err = DH_update_i2c(pRUA, pi2c_dev))) continue;
		i2c_segment.SegmentPtr = segment_ptr;
		i2c_segment.Segment = segment;
		err = RUASetProperty(pRUA, pi2c_dev->I2C, RMI2CPropertyID_SelectSegment, &i2c_segment, sizeof(i2c_segment), 0);
		i2c_usage--;  // decrease usage counter for this I2C configuration
	} while (--r && RMFAILED(err));
	if (RMFAILED(err)) {
		RMDBGLOG((LOCALDBG, "%s: failed to set RMI2CPropertyID_SelectSegment(0x%02X:0x%02X, 0x%02X) on I2C 0x%08lX GPIO %lu/%lu! %s\n", 
			(segment > 0) ? "Error" : "Warning", 
			pi2c_dev->dev.WrAddr, i2c_segment.SegmentPtr, i2c_segment.Segment, 
			pi2c_dev->I2C, pi2c_dev->dev.PioClock, pi2c_dev->dev.PioData, 
			RMstatusToString(err)));
		if (segment > 0) return err;
	}
	
	//return DH_i2c_write_data(pRUA, pi2c_dev, sub_address, data, data_size);
	for (index = 0; index < data_size; index++) {
		RMuint8 v;
		r = 10;
		do {
			err = DH_i2c_write(pRUA, pi2c_dev, sub_address + index, data[index]);
			if (RMFAILED(err)) {
				RMDBGLOG((LOCALDBG, "Error writing 0x%02X to %02X! %s\n", data[index], sub_address + index, RMstatusToString(err)));
			}
			RMMicroSecondSleep(100000);  // Delay for EEPROM
			err = DH_i2c_read(pRUA, pi2c_dev, sub_address + index, &v);
			if (RMSUCCEEDED(err) && (v == data[index])) break;
		} while (--r);
		if (RMFAILED(err) || (v != data[index])) {
			RMDBGLOG((LOCALDBG, "Error writing 0x%02X to %02X! Read back 0x%02X instead.\n", data[index], sub_address + index, v));
		}
	}
	return err;
}

static RMstatus DHSetTMDSResistor(struct DH_control *pDH)
{
	RMstatus err = RM_OK;
	struct SystemBlock_GPIO_type gpio;
	
	if (pDH->TMDS_Threshold) {
		gpio.Bit = pDH->TMDS_GPIO;
		gpio.Data = (pDH->VideoPixelClock >= pDH->TMDS_Threshold) ? 1 : 0;
		if (RMFAILED(err = RUASetProperty(pDH->pRUA, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0))) {
			RMDBGLOG((LOCALDBG, "Error setting GPIO %u to set external swing resistor of HDMI TMDS: %s\n", pDH->TMDS_GPIO, RMstatusToString(err)));
			return err;
		}
	}
	return err;
}

RMstatus DHSetTMDSMode(struct DH_control *pDH, 
	enum GPIOId_type GPIO, 
	RMuint32 PixelClockThreshold)
{
	CHECK_pDH("DHSetTMDSMode");
	pDH->TMDS_Threshold = PixelClockThreshold;
	pDH->TMDS_GPIO = GPIO;
	return RM_OK;
}

static RMstatus DHReset_siI164(struct DH_control *pDH)
{
	RMstatus err = RM_OK;
	struct SystemBlock_GPIO_type gpio;
	
	// Set GPIO direction and Reset SiI170
	if (! manutest) fprintf(stderr, "[HDMI] Resetting DVI transmitter with GPIO pin %u.\n", pDH->gpio_reset);
	gpio.Bit = pDH->gpio_reset;
	gpio.Data = 0;
	if (RMFAILED(err = RUASetProperty(pDH->pRUA, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0))) {
		RMDBGLOG((LOCALDBG, "Error setting GPIO to reset SiI170!!! %s\n", RMstatusToString(err)));
		return err;
	}
	
	// Assert 50 uSec low time
	RMMicroSecondSleep(50);
	
	// Unreset SiI170
	gpio.Bit = pDH->gpio_reset;
	gpio.Data = 1;
	if (RMFAILED(err = RUASetProperty(pDH->pRUA, SystemBlock, RMSystemBlockPropertyID_GPIO, &gpio, sizeof(gpio), 0))) {
		RMDBGLOG((LOCALDBG, "Error setting GPIO to unreset SiI170!!! %s\n", RMstatusToString(err)));
		return err;
	}
	
	if (pDH->part == DH_siI170) {
		RMuint8 reg;
		err = DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), HDCP_CTRL_ADDR, &reg);
		if (RMFAILED(err)) return err;
		RMDBGLOG((LOCALDBG, "Read status from transmitter: %02X\n", reg));
		if (reg & 0x01) {
			if (! manutest) fprintf(stderr, "[HDMI] FATAL! Reset of DVI transmitter failed, encryption still enabled!\n");
		}
	}
	
	RMMicroSecondSleep(10*1000);
	
	return err;
}

// The following functions should work with all Sigma Reference Designs

#ifdef RMFEATURE_HAS_HDMI
static RMstatus DHResetHDMICore(struct RUA *pRUA)
{
	RMstatus err = RM_OK;
	
	enum DisplayBlock_HDMIState_type hs;
	
	if (RMFAILED(err = RUAGetProperty(pRUA, 
		DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
		&hs, sizeof(hs)))) {
		RMDBGLOG((LOCALDBG, "Error getting internal HDMI state! %s\n", RMstatusToString(err)));
		return err;
	}
	if (hs == DisplayBlock_HDMIState_Running) {
		if (! manutest) fprintf(stderr, "[HDMI] Resetting internal HDMI core!\n");
		hs = DisplayBlock_HDMIState_ResetHDMI;
		if (RMFAILED(err = RUASetProperty(pRUA, 
			DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
			&hs, sizeof(hs), 0))) {
			RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to ResetHDMI! %s\n", RMstatusToString(err)));
			return err;
		}
		RMMicroSecondSleep(5*1000);
		hs = DisplayBlock_HDMIState_Running;
		if (RMFAILED(err = RUASetProperty(pRUA, 
			DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
			&hs, sizeof(hs), 0))) {
			RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to Running! %s\n", RMstatusToString(err)));
			return err;
		}
		RMMicroSecondSleep(5*1000);
	}
	
	return err;
}

// Reset: if TRUE, assure that a ResetHDMI to Running transition is performed
static RMstatus DHUnresetHDMICore(struct RUA *pRUA, RMbool Reset)
{
	RMstatus err = RM_OK;
	
	enum DisplayBlock_HDMIState_type hs;
	
	if (RMFAILED(err = RUAGetProperty(pRUA, 
		DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
		&hs, sizeof(hs)))) {
		RMDBGLOG((LOCALDBG, "Error getting internal HDMI state! %s\n", RMstatusToString(err)));
		return err;
	}
	
	if (Reset && (hs == DisplayBlock_HDMIState_Running)) {
		return DHResetHDMICore(pRUA);
	}
	
	if (hs == DisplayBlock_HDMIState_ResetConfig) {
		hs = DisplayBlock_HDMIState_ResetKeymemI2C;
		if (RMFAILED(err = RUASetProperty(pRUA, 
			DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
			&hs, sizeof(hs), 0))) {
			RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to ResetKeymemI2C! %s\n", RMstatusToString(err)));
			return err;
		}
		RMMicroSecondSleep(5*1000);  // wait 5 ms
	}
	if (hs == DisplayBlock_HDMIState_ResetKeymemI2C) {
		hs = DisplayBlock_HDMIState_ResetHDMI;
		if (RMFAILED(err = RUASetProperty(pRUA, 
			DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
			&hs, sizeof(hs), 0))) {
			RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to ResetHDMI! %s\n", RMstatusToString(err)));
			return err;
		}
		RMMicroSecondSleep(5*1000);  // wait 5 ms
	}
	if (hs == DisplayBlock_HDMIState_ResetHDMI) {
		hs = DisplayBlock_HDMIState_Running;
		if (RMFAILED(err = RUASetProperty(pRUA, 
			DisplayBlock, RMDisplayBlockPropertyID_HDMIState, 
			&hs, sizeof(hs), 0))) {
			RMDBGLOG((LOCALDBG, "Error setting internal HDMI state to Running! %s\n", RMstatusToString(err)));
			return err;
		}
	}
	
	return err;
}
#endif

RMstatus DHCheckHDCPKeyMem(struct DH_control *pDH)
{
	RMstatus err;
	RMuint8 bist;
	RMuint64 t0, t1;
	
	CHECK_pDH("DHCheckHDCPKeyMem");
	
	if (pDH->part == DH_cat6611)
	{
	    return RM_OK ;
	}
	
	if ((pDH->part != DH_siI9030) && (pDH->part != DH_siI170)) {
		RMDBGLOG((LOCALDBG, "Call to DHCheckHDCPKeyMem: Error, only siI9030 supports this function\n"));
		return RM_ERROR;
	}
	
	err = DH_i2c_write(pDH->pRUA, &(pDH->i2c_tx), 0xFA, 0x03);
	t0 = RMGetTimeInMicroSeconds();
	do {
		err = DH_i2c_read(pDH->pRUA, &(pDH->i2c_tx), 0xF9, &bist);
		t1 = RMGetTimeInMicroSeconds();
		if (RMCyclesElapsed64(t0, t1) > 200000) err = RM_TIMEOUT;  // 0.2 sec
	} while (RMSUCCEEDED(err) && ((bist & 0x01) == 0));
	if (err == RM_TIMEOUT) {
		if (! manutest) fprintf(stderr, "[HDMI] HDCP BIST Timeout!\n");
	} else {
		if (! manutest) fprintf(stderr, "[HDMI] HDCP BIST took %llu mSec.\n", RMCyclesElapsed64(t0, t1) / 1000);
	}
	if (bist & 0x02) {
		if (! manutest) fprintf(stderr, "[HDMI] HDCP BIST failed! 0x%02X\n", bist);
		err = RM_ERROR;
	}
	return err;
}

static RMstatus DHCreate(struct RUA *pRUA, struct DH_control **ppDH)
{
	if (! manutest) fprintf(stderr, "[HDMI] ========================== creating pDH ==========================\n");
#ifdef HDCP_USE_FACSIMILE_KEY
	if (! manutest) fprintf(stderr, "[HDMI] ===  COMPILED WITH HDCP FACSIMILE KEYS -- Not for production!  ===\n");
	if (! manutest) fprintf(stderr, "[HDMI] ==================================================================\n");
#endif
	*ppDH = (struct DH_control *)RMMalloc(sizeof(struct DH_control));
	if (*ppDH == NULL) {
		if (! manutest) fprintf(stderr, "[HDMI] FATAL! Not enough memory for struct DH_control!\n");
		return RM_FATALOUTOFMEMORY;
	}
	
	RMMemset(*ppDH, 0, sizeof(struct DH_control));
	
	(*ppDH)->pRUA = pRUA;
	(*ppDH)->SRM_dss.y = bignum_from_bytes((RMuint8 *)SRM_y, 128);
	(*ppDH)->SRM_dss.p = bignum_from_bytes((RMuint8 *)SRM_p, 128);
	(*ppDH)->SRM_dss.q = bignum_from_bytes((RMuint8 *)SRM_q, 20);
	(*ppDH)->SRM_dss.g = bignum_from_bytes((RMuint8 *)SRM_g, 128);
	
	return RM_OK;
}

RMstatus DHInitWithAutoDetectReset(struct RUA *pRUA, 
	RMuint8 pio_clock_transmitter, RMuint8 pio_data_transmitter, RMuint32 i2c_module, 
	RMuint8 gpio_reset, struct DH_control **ppDH, RMbool Reset)
{
	RMstatus err = RM_OK;
	RMuint8 vendor_id[4];
	RMuint8 part_num, index;
	RMbool found_part;
	
	if (pRUA == NULL) {
		if (! manutest) fprintf(stderr, "[HDMI] Call to DHInitWithAutoDetect with invalid RUA structure!\n");
		return RM_FATALINVALIDPOINTER;
	}
	CHECK_PTR("DHInitWithAutoDetect", ppDH);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -