예제 #1
0
int packets_SourceProductInfoFrame(u16 baseAddr, const u8 * vName, u8 vLength,
		const u8 * pName, u8 pLength, u8 code, u8 autoSend)
{
	const unsigned short pSize = 8;
	const unsigned short vSize = 16;

	LOG_TRACE();
	halFrameComposerPackets_AutoSend(baseAddr + FC_BASE_ADDR, 0, SPD_TX); /* prevent sending half the info. */
	if (vName == 0)
	{
		error_Set(ERR_INVALID_PARAM_VENDOR_NAME);
		LOG_WARNING("invalid parameter");
		return FALSE;
	}
	if (vLength > vSize)
	{
		vLength = vSize;
		LOG_WARNING("vendor name truncated");
	}
	if (pName == 0)
	{
		error_Set(ERR_INVALID_PARAM_PRODUCT_NAME);
		LOG_WARNING("invalid parameter");
		return FALSE;
	}
	if (pLength > pSize)
	{
		pLength = pSize;
		LOG_WARNING("product name truncated");
	}
	halFrameComposerSpd_VendorName(baseAddr + FC_BASE_ADDR, vName, vLength);
	halFrameComposerSpd_ProductName(baseAddr + FC_BASE_ADDR, pName, pLength);

	halFrameComposerSpd_SourceDeviceInfo(baseAddr + FC_BASE_ADDR, code);
	if (autoSend)
	{
		halFrameComposerPackets_AutoSend(baseAddr + FC_BASE_ADDR, autoSend, SPD_TX);
	}
	else
	{
		halFrameComposerPackets_ManualSend(baseAddr + FC_BASE_ADDR, SPD_TX);
	}
	return TRUE;
}
예제 #2
0
int dtd_SetPixelRepetitionInput(dtd_t *dtd, u16 value)
{
	LOG_TRACE();

	switch (dtd->mCode)
	{
	case (u8)-1:
	case 10:
	case 11:
	case 12:
	case 13:
	case 25:
	case 26:
	case 27:
	case 28:
		if (value < 10)
		{
			dtd->mPixelRepetitionInput = value;
			return TRUE;
		}
		break;
	case 14:
	case 15:
	case 29:
	case 30:
		if (value < 2)
		{
			dtd->mPixelRepetitionInput = value;
			return TRUE;
		}
		break;
	case 35:
	case 36:
	case 37:
	case 38:
		if (value < 2 || value == 3)
		{
			dtd->mPixelRepetitionInput = value;
			return TRUE;
		}
		break;
	default:
		if (value == dtd->mPixelRepetitionInput)
		{
			return TRUE;
		}
		break;
	}
	error_Set(ERR_PIXEL_REPETITION_FOR_VIDEO_MODE);
	LOG_ERROR3("Invalid pixel repetition input for video mode", value, dtd->mCode);
	return FALSE;
}
예제 #3
0
int api_Reinitialize(u16 address, u8 dataEnablePolarity, u16 sfrClock, u8 force) //cmd:auto argument: 0, 1, 2500, 0
{
	dataEnablePolarity = 1;

	api_mDataEnablePolarity = dataEnablePolarity;
	api_mHpd = FALSE;
	api_mSendGamutOk = FALSE; //?????????????????
	api_mSfrClock = sfrClock; // sfrClock,that are required for setting the low time of the SCL clock in each speed mode

	LOG_NOTICE("dwc_hdmi_tx_software_api_2.12");
	LOG_NOTICE(__DATE__);
	LOG_TRACE1(dataEnablePolarity);
	/* reset error */
	error_Set(NO_ERROR);

	api_mBaseAddress = address;
	if (!api_mutex_inited)
	{
		mutex_Initialize(&api_mMutex);
		api_mutex_inited = 1;
	}

	if ((api_mCurrentState < API_HPD) || (api_mCurrentState > API_EDID_READ))
	{
		/* if EDID read do not re-read, if HPDetected, keep in same state
		 * otherwise, set to INIT */
		api_mCurrentState = API_INIT;
	}

	if (system_InterruptHandlerRegister(TX_INT, api_EventHandler, NULL) == TRUE)
	{
		printk("==>enable TX_INT in %s:%d\n", __func__, __LINE__);
		//return system_InterruptEnable(TX_INT);
		printk("enter %s, %d\n", __func__, __LINE__);
		return TRUE;
	}
	return FALSE;
}
예제 #4
0
int api_Initialize(u16 address, u8 dataEnablePolarity, u16 sfrClock, u8 force) //cmd:auto argument: 0, 1, 2500, 0
{
	dtd_t dtd;
	videoParams_t params;
	dataEnablePolarity = 1;

	api_mDataEnablePolarity = dataEnablePolarity;
	api_mHpd = FALSE;
	api_mSendGamutOk = FALSE; //?????????????????
	api_mSfrClock = sfrClock; // sfrClock,that are required for setting the low time of the SCL clock in each speed mode

	LOG_NOTICE("dwc_hdmi_tx_software_api_2.12");
	LOG_NOTICE(__DATE__);
	LOG_TRACE1(dataEnablePolarity);
	/* reset error */
	error_Set(NO_ERROR);

	api_mBaseAddress = address;
	if (!api_mutex_inited)
	{
		mutex_Initialize(&api_mMutex);
		api_mutex_inited = 1;
	}
	control_InterruptMute(api_mBaseAddress, ~0); /* disable all interrupts */
	if ((api_mCurrentState < API_HPD) || (api_mCurrentState > API_EDID_READ))
	{
		/* if EDID read do not re-read, if HPDetected, keep in same state
		 * otherwise, NOT INIT */
		api_mCurrentState = API_NOT_INIT;
	}
	/* VGA must be supported by all sinks
	 * so use it as default configuration
	 */
	dtd_Fill(&dtd, 4, 60000); 
	videoParams_Reset(&params);
	videoParams_SetHdmi(&params, TRUE);
	videoParams_SetDtd(&params, &dtd); /* params->mDtd = dtd; */
	pixelClock = videoParams_GetPixelClock(&params); /* dtd_GetPixelClock(&(params->mDtd)); */

        /* reset HAPS51 DEMO BOARD, by default mask all interrupts */
	if (board_Initialize(api_mBaseAddress, pixelClock, 8) != TRUE) 
	{
		return FALSE;
	}

	/* get Product Identification Register 0 */
	LOG_NOTICE2("Product Line", control_ProductLine(api_mBaseAddress));
	/* get Product Identification Register 1*/
	LOG_NOTICE2("Product Type", control_ProductType(api_mBaseAddress));
        /* if ((ProductLine == 0xA0) && ((ProductType == 0x01 || ProductType == 0xC1))) */
	if (control_SupportsCore(api_mBaseAddress) != TRUE)
	{
		error_Set(ERR_HW_NOT_SUPPORTED);
		LOG_ERROR("Unknown device: aborting...");
		return FALSE;
	}

	/* get Design Identification Register */
	LOG_NOTICE2("HDMI TX Controller Design", control_Design(api_mBaseAddress));
	/* get Revision Identification Register */
	LOG_NOTICE2("HDMI TX Controller Revision", control_Revision(api_mBaseAddress));
	/* if(ProductLine == 0xA0 && ProductType == 0xC1)*/
	if (control_SupportsHdcp(api_mBaseAddress) == TRUE)
	{
		LOG_NOTICE("HDMI TX controller supports HDCP");
	}

	/* print api_mDataEnablePolarity value ,always return TRUE */
	if (video_Initialize(api_mBaseAddress, &params, api_mDataEnablePolarity)
			!= TRUE)
	{
		return FALSE;
	}
	if (audio_Initialize(api_mBaseAddress) != TRUE)
	{
		return FALSE;
	}
	if (packets_Initialize(api_mBaseAddress) != TRUE)
	{
		return FALSE;
	}
	if (hdcp_Initialize(api_mBaseAddress, api_mDataEnablePolarity)
			!= TRUE)
	{
		return FALSE;
	}

	/*  clock gate == 1 => turn off all modules */
	if (control_Initialize(api_mBaseAddress, api_mDataEnablePolarity,
			pixelClock) != TRUE)
	{
		return FALSE;
	}
#ifdef CONFIG_HMDI_JZ4780_DEBUG
	printk("jz4780 hdmi %s  %d  phy init\n",__func__,__LINE__);
#endif

	control_InterruptClearAll(api_mBaseAddress);

	if (board_PixelClock(api_mBaseAddress, pixelClock, videoParams_GetColorResolution(&params))!= TRUE)
	{
		return FALSE;
	}
#ifdef CONFIG_HMDI_JZ4780_DEBUG
	printk("jz4780 hdmi %s  %d  video configured\n",__func__,__LINE_);
#endif
	if (video_Configure(api_mBaseAddress, &params, api_mDataEnablePolarity, FALSE) != TRUE)
	{
		return FALSE;
	}
	if ((api_mCurrentState < API_HPD) || (api_mCurrentState > API_EDID_READ))
	{
		/* if EDID read do not re-read, if HPDetected, keep in same state
		 * otherwise, set to INIT */
		api_mCurrentState = API_INIT;
	}
	/*
	 * By default no pixel repetition and color resolution is 8
	 */
#ifdef CONFIG_HMDI_JZ4780_DEBUG
	printk("jz4780 hdmi %s  %d  control configured\n",__func__,__LINE_);
#endif
	if (control_Configure(api_mBaseAddress, pixelClock, 0, 8, 0, 0, 0, 0) != TRUE)
	{
		return FALSE;
	}
	/* send AVMUTE SET (optional) */
#ifdef CONFIG_HMDI_JZ4780_DEBUG
	printk("jz4780 hdmi %s  %d phy configured\n",__func__,__LINE_);
#endif

#if 0
	/* enable interrupts */
	access_CoreWriteByte(0x0, 0x10D2);
	access_CoreWriteByte(0x0, 0x10D6);
	access_CoreWriteByte(0x0, 0x10DA);
	access_CoreWriteByte(0x0, 0x0180);
#endif
#if 0
	access_CoreWriteByte(~0x4, 0x10D2);  //audio packets
	access_CoreWriteByte(0x0, 0x0180);   //intc mute
#endif

	api_phy_enable(PHY_ENABLE_HPD); 

	control_InterruptMute(api_mBaseAddress, 0);
	if (system_InterruptHandlerRegister(TX_INT, api_EventHandler, NULL) == TRUE)
	{
		printk("=====>enable TX_INT in %s:%d\n", __func__, __LINE__);
		//return system_InterruptEnable(TX_INT);
		return TRUE;
	}
	return FALSE;
}
예제 #5
0
int api_Configure(videoParams_t * video, audioParams_t * audio,
		productParams_t * product, hdcpParams_t * hdcp)
{
	hdmivsdb_t vsdb;
//	int audioOn = 0;  //lltang audio on
	int audioOn = 1;
	int success = TRUE;
	int hdcpOn = (hdcp != 0 && (control_SupportsHdcp(api_mBaseAddress) == TRUE)) ? TRUE : FALSE;
	LOG_TRACE();

	if (video == NULL)
	{
		error_Set(ERR_HPD_LOST);
		LOG_ERROR("video params invalid");
		return FALSE;
	}
	audioOn = (audio != 0 && videoParams_GetHdmi(video));

	if (api_mCurrentState < API_HPD)
	{
		error_Set(ERR_HPD_LOST);
		LOG_ERROR("cable not connected");
		return FALSE;
	}
	else if (api_mCurrentState == API_HPD)
	{
		printk("E-EDID not read. Media may not be supported by sink\n");
	}
	else if (api_mCurrentState == API_EDID_READ)
	{
		api_CheckParamsVideo(video);
		if (api_EdidHdmivsdb(&vsdb))
		{
			if (!hdmivsdb_GetDeepColor30(&vsdb) && !hdmivsdb_GetDeepColor36(&vsdb)
					&& !hdmivsdb_GetDeepColor48(&vsdb))
			{
				videoParams_SetColorResolution(video, 0);
			}
		}
	}
	control_InterruptMute(api_mBaseAddress, ~0); /* disable interrupts */
#ifdef CONFIG_HMDI_JZ4780_DEBUG
	printk("=====>disable TX_INT in %s:%d\n", __func__, __LINE__);
#endif
	system_InterruptDisable(TX_INT);
	do
	{
		if (video_Configure(api_mBaseAddress, video, api_mDataEnablePolarity,
				hdcpOn) != TRUE)
		{
			success = FALSE;
			break;
		}
		if (audioOn)
		{
			if (api_mCurrentState == API_EDID_READ)
			{
				api_CheckParamsAudio(audio);
			}
#if 0  //del by lltang
			if (board_AudioClock(api_mBaseAddress, audioParams_AudioClock(audio))
						!= TRUE)
			{
				success = FALSE;
				break;
			}
#endif
			if (audio_Configure(api_mBaseAddress, audio, videoParams_GetPixelClock(
					video), videoParams_GetRatioClock(video)) != TRUE)
			{
				success = FALSE;
				break;
			}
			packets_AudioInfoFrame(api_mBaseAddress, audio);
		}
		else if (audio != 0 && videoParams_GetHdmi(video) != TRUE)
		{
			printk("DVI mode selected: audio not configured\n");
		}
		else
		{
			printk("No audio parameters provided: not configured\n");
		}
		if (videoParams_GetHdmi(video) == TRUE)
		{
			if (packets_Configure(api_mBaseAddress, video, product) != TRUE)
			{
				success = FALSE;
				break;
			}
			api_mSendGamutOk = (videoParams_GetEncodingOut(video) == YCC444)
					|| (videoParams_GetEncodingOut(video) == YCC422);
			api_mSendGamutOk = api_mSendGamutOk && (videoParams_GetColorimetry(
					video) == EXTENDED_COLORIMETRY);
		}
		else
		{
			printk("DVI mode selected: packets not configured\n");
		}
		if (hdcpOn == TRUE)
		{	/* HDCP is PHY independent */
			if (hdcp_Configure(api_mBaseAddress, hdcp, videoParams_GetHdmi(video),
					dtd_GetHSyncPolarity(videoParams_GetDtd(video)),
					dtd_GetVSyncPolarity(videoParams_GetDtd(video))) == FALSE)
			{
				printk("HDCP not configured\n");
				hdcpOn = FALSE;
				success = FALSE;
				break;
			}
		}
		else if (hdcp != 0 && control_SupportsHdcp(api_mBaseAddress) != TRUE)
		{
			printk("HDCP is not supported by hardware\n");
		}
		else
		{
			printk("No HDCP parameters provided: not configured\n");
		}
		if (board_PixelClock(api_mBaseAddress, videoParams_GetPixelClock(video),
				videoParams_GetColorResolution(video)) != TRUE)
		{
			success = FALSE;
			break;
		}
		if (control_Configure(api_mBaseAddress, videoParams_GetPixelClock(video),
				videoParams_GetPixelRepetitionFactor(video),
				videoParams_GetColorResolution(video),
				videoParams_IsColorSpaceConversion(video), audioOn, FALSE, hdcpOn)
				!= TRUE)
		{
			success = FALSE;
			break;
		}
		if (phy_Configure(api_mBaseAddress, videoParams_GetPixelClock(video),
			videoParams_GetColorResolution(video),
			videoParams_GetPixelRepetitionFactor(video)) != TRUE)
		{
			success = FALSE;
			break;
		}
		/* disable blue screen transmission after turning on all necessary blocks (e.g. HDCP) */
		if (video_ForceOutput(api_mBaseAddress, FALSE) != TRUE)
		{
			success = FALSE;
			break;
		}
		/* reports HPD state to HDCP */
		if (hdcpOn)
		{
			hdcp_RxDetected(api_mBaseAddress, phy_HotPlugDetected(
					api_mBaseAddress));
		}
		/* send AVMUTE CLEAR (optional) */
		api_mCurrentState = API_CONFIGURED;
	}
	while(0);
	control_InterruptMute(api_mBaseAddress, 0); /* enable interrupts */
#ifdef CONFIG_HMDI_JZ4780_DEBUG
	printk("hdmi enable TX_INT in %s:%d\n", __func__, __LINE__);
#endif
	system_InterruptEnable(TX_INT);
	return success;
}
예제 #6
0
/**
 * Check Video parameters against allowed values and read EDID structure
 * to ensure compatibility with sink.
 * @param video video parameters
 */
static int api_CheckParamsVideo(videoParams_t * video)
{
	u8 errorCode = TRUE;
	hdmivsdb_t vsdb;
	dtd_t dtd;
	unsigned i = 0;
	shortVideoDesc_t svd;
	videoCapabilityDataBlock_t capability;
	int valid = FALSE;
	colorimetryDataBlock_t colorimetry;

	LOG_TRACE();
	colorimetryDataBlock_Reset(&colorimetry);
	shortVideoDesc_Reset(&svd);
	dtd_Fill(&dtd, 1, 60000);
	videoCapabilityDataBlock_Reset(&capability);

	if (videoParams_GetHdmi(video))
	{ /* HDMI mode */
		if (api_EdidHdmivsdb(&vsdb) == TRUE)
		{
			if (videoParams_GetColorResolution(video) == 10
					&& !hdmivsdb_GetDeepColor30(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_30BIT_DC);
				printk("Sink does NOT support 30bits/pixel deep colour mode");
				errorCode = FALSE;
			}
			else if (videoParams_GetColorResolution(video) == 12
					&& !hdmivsdb_GetDeepColor36(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_36BIT_DC);
				printk("Sink does NOT support 36bits/pixel deep colour mode");
				errorCode = FALSE;
			}
			else if (videoParams_GetColorResolution(video) == 16
					&& !hdmivsdb_GetDeepColor48(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_48BIT_DC);
				printk("Sink does NOT support 48bits/pixel deep colour mode");
				errorCode = FALSE;
			}
			if (videoParams_GetEncodingOut(video) == YCC444
					&& !hdmivsdb_GetDeepColorY444(&vsdb))
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC444_DC);
				printk("Sink does NOT support YCC444 in deep colour mode");
				errorCode = FALSE;
			}
			if (videoParams_GetTmdsClock(video) > 16500)
			{
				/*
				 * Sink must specify MaxTMDSClk when supports frequencies over 165MHz
				 * GetMaxTMDSClk() is TMDS clock / 5MHz and GetTmdsClock() returns [0.01MHz]
				 * so GetMaxTMDSClk() value must be multiplied by 500 in order to be compared
				 */
				if (videoParams_GetTmdsClock(video) > (hdmivsdb_GetMaxTmdsClk(
						&vsdb) * 500))
				{
					error_Set(ERR_SINK_DOES_NOT_SUPPORT_TMDS_CLOCK);
					LOG_WARNING2("Sink does not support TMDS clock", videoParams_GetTmdsClock(video));
					LOG_WARNING2("Maximum TMDS clock supported is", hdmivsdb_GetMaxTmdsClk(&vsdb) * 500);
					errorCode = FALSE;
				}
			}
		}
		else
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_HDMI);
			printk("Sink does not support HDMI");
			errorCode = FALSE;
		}
		/* video out encoding (YCC/RGB) */
		if (videoParams_GetEncodingOut(video) == YCC444
				&& !api_EdidSupportsYcc444())
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC444_ENCODING);
			printk("Sink does NOT support YCC444 encoding");
			errorCode = FALSE;
		}
		else if (videoParams_GetEncodingOut(video) == YCC422
				&& !api_EdidSupportsYcc422())
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_YCC422_ENCODING);
			printk("Sink does NOT support YCC422 encoding");
			errorCode = FALSE;
		}
		/* check extended colorimetry data and if supported by sink */
		if (videoParams_GetColorimetry(video) == EXTENDED_COLORIMETRY)
		{
			if (api_EdidColorimetryDataBlock(&colorimetry) == TRUE)
			{
				if (!colorimetryDataBlock_SupportsXvYcc601(&colorimetry)
						&& videoParams_GetExtColorimetry(video) == 0)
				{
					error_Set(ERR_SINK_DOES_NOT_SUPPORT_XVYCC601_COLORIMETRY);
					printk("Sink does NOT support xvYcc601 extended colorimetry");
					errorCode = FALSE;
				}
				else if (!colorimetryDataBlock_SupportsXvYcc709(&colorimetry)
						&& videoParams_GetExtColorimetry(video) == 1)
				{
					error_Set(ERR_SINK_DOES_NOT_SUPPORT_XVYCC709_COLORIMETRY);
					printk("Sink does NOT support xvYcc709 extended colorimetry");
					errorCode = FALSE;
				}
				else
				{
					error_Set(ERR_EXTENDED_COLORIMETRY_PARAMS_INVALID);
					printk("Invalid extended colorimetry parameters");
					errorCode = FALSE;
				}
			}
			else
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_EXTENDED_COLORIMETRY);
				errorCode = FALSE;
			}
		}
	}
	else
	{ /* DVI mode */
		if (videoParams_GetColorResolution(video) > 8)
		{
			error_Set(ERR_COLOR_DEPTH_NOT_SUPPORTED);
			printk("DVI - deep color not supported");
			errorCode = FALSE;
		}
		if (videoParams_GetEncodingOut(video) != RGB)
		{
			error_Set(ERR_DVI_MODE_WITH_YCC_ENCODING);
			printk("DVI mode does not support video encoding other than RGB");
			errorCode = FALSE;
		}
		if (videoParams_IsPixelRepetition(video))
		{
			error_Set(ERR_DVI_MODE_WITH_PIXEL_REPETITION);
			printk("DVI mode does not support pixel repetition");
			errorCode = FALSE;
		}
		if (videoParams_GetTmdsClock(video) > 16500)
		{
			printk("Sink must support DVI dual-link");
		}
		/* check colorimetry data */
		if ((videoParams_GetColorimetry(video) == EXTENDED_COLORIMETRY))
		{
			error_Set(ERR_DVI_MODE_WITH_EXTENDED_COLORIMETRY);
			printk("DVI does not support extended colorimetry");
			errorCode = FALSE;
		}
	}
	/*
	 * DTD check
	 * always checking VALID to minimise code execution (following probability)
	 * this video code is to be supported by all dtv's
	 */
	valid = (dtd_GetCode(videoParams_GetDtd(video)) == 1) ? TRUE : FALSE;
	if (!valid)
	{
		for (i = 0; i < api_EdidDtdCount(); i++)
		{
			api_EdidDtd(i, &dtd);
			if (dtd_GetCode(videoParams_GetDtd(video)) != (u8) (-1))
			{
				if (dtd_GetCode(videoParams_GetDtd(video)) == dtd_GetCode(&dtd))
				{
					valid = TRUE;
					break;
				}
			}
			else if (dtd_IsEqual(videoParams_GetDtd(video), &dtd))
			{
				valid = TRUE;
				break;
			}
		}
	}
	if (!valid)
	{
		if (dtd_GetCode(videoParams_GetDtd(video)) != (u8) (-1))
		{
			for (i = 0; i < api_EdidSvdCount(); i++)
			{
				api_EdidSvd(i, &svd);
				if ((unsigned) (dtd_GetCode(videoParams_GetDtd(video)))
						== shortVideoDesc_GetCode(&svd))
				{
					valid = TRUE;
					break;
				}
			}
		}
	}
	if (!valid)
	{
		error_Set(ERR_SINK_DOES_NOT_SUPPORT_SELECTED_DTD);
		printk("Sink does NOT indicate support for selected DTD");
		errorCode = FALSE;
	}
	/* check quantization range */
	if (api_EdidVideoCapabilityDataBlock(&capability) == TRUE)
	{
		if (!videoCapabilityDataBlock_GetQuantizationRangeSelectable(
				&capability) && videoParams_GetRgbQuantizationRange(video) > 1)
		{
			printk("Sink does NOT indicate support for selected quantization range");
		}
	}
	return errorCode;
}
예제 #7
0
/**
 * Check audio parameters against read EDID structure to ensure
 * compatibility with sink.
 * @param audio audio parameters data structure
 */
static int api_CheckParamsAudio(audioParams_t * audio)
{
	unsigned i = 0;
	int bitSupport = -1;
	shortAudioDesc_t sad;
	speakerAllocationDataBlock_t allocation;
	u8 errorCode = TRUE;
	int valid = FALSE;
	/* array to translate from AudioInfoFrame code to EDID Speaker Allocation data block bits */
	const u8 sadb[] =
	{ 1, 3, 5, 7, 17, 19, 21, 23, 9, 11, 13, 15, 25, 27, 29, 31, 73, 75, 77,
			79, 33, 35, 37, 39, 49, 51, 53, 55, 41, 43, 45, 47 };

	LOG_TRACE();
	if (!api_EdidSupportsBasicAudio())
	{
		error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO);
		printk("Sink does NOT support audio");
		return FALSE;
	}
	/* check if audio type supported */
	for (i = 0; i < api_EdidSadCount(); i++)
	{
		api_EdidSad(i, &sad);
		if (audioParams_GetCodingType(audio) == shortAudioDesc_GetFormatCode(
				&sad))
		{
			bitSupport = i;
			break;
		}
	}
	if (bitSupport >= 0)
	{
		api_EdidSad(bitSupport, &sad);
		/* 192 kHz| 176.4 kHz| 96 kHz| 88.2 kHz| 48 kHz| 44.1 kHz| 32 kHz */
		switch (audioParams_GetSamplingFrequency(audio))
		{
		case 32000:
			valid = shortAudioDesc_Support32k(&sad);
			break;
		case 44100:
			valid = shortAudioDesc_Support44k1(&sad);
			break;
		case 48000:
			valid = shortAudioDesc_Support48k(&sad);
			break;
		case 88200:
			valid = shortAudioDesc_Support88k2(&sad);
			break;
		case 96000:
			valid = shortAudioDesc_Support96k(&sad);
			break;
		case 176400:
			valid = shortAudioDesc_Support176k4(&sad);
			break;
		case 192000:
			valid = shortAudioDesc_Support192k(&sad);
			break;
		default:
			valid = FALSE;
			break;
		}
		if (!valid)
		{
			error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO_SAMPLING_FREQ);
			LOG_WARNING2("Sink does NOT support audio sampling frequency", audioParams_GetSamplingFrequency(audio));
			errorCode = FALSE;
		}
		if (audioParams_GetCodingType(audio) == PCM)
		{
			/* 24 bit| 20 bit| 16 bit */
			switch (audioParams_GetSampleSize(audio))
			{
			case 16:
				valid = shortAudioDesc_Support16bit(&sad);
				break;
			case 20:
				valid = shortAudioDesc_Support20bit(&sad);
				break;
			case 24:
				valid = shortAudioDesc_Support24bit(&sad);
				break;
			default:
				valid = FALSE;
				break;
			}
			if (!valid)
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO_SAMPLE_SIZE);
				LOG_WARNING2("Sink does NOT support audio sample size", audioParams_GetSampleSize(audio));
				errorCode = FALSE;
			}
		}
		/* check Speaker Allocation */
		if (api_EdidSpeakerAllocationDataBlock(&allocation) == TRUE)
		{
			LOG_DEBUG2("Audio channel allocation sent", sadb[audioParams_GetChannelAllocation(audio)]);
			LOG_DEBUG2("Audio channel allocation accepted", speakerAllocationDataBlock_GetSpeakerAllocationByte(&allocation));
			valid = (sadb[audioParams_GetChannelAllocation(audio)]
					& speakerAllocationDataBlock_GetSpeakerAllocationByte(
							&allocation))
					== sadb[audioParams_GetChannelAllocation(audio)];
			if (!valid)
			{
				error_Set(ERR_SINK_DOES_NOT_SUPPORT_ATTRIBUTED_CHANNELS);
				printk("Sink does NOT have attributed speakers");
				errorCode = FALSE;
			}
		}
	}
	else
	{
		error_Set(ERR_SINK_DOES_NOT_SUPPORT_AUDIO_TYPE);
		printk("Sink does NOT support audio type");
		errorCode = FALSE;
	}
	return errorCode;
}
예제 #8
0
int packets_Configure(u16 baseAddr, videoParams_t * video,
		productParams_t * prod)
{
	u8 send3d = FALSE;
	LOG_TRACE();
	if (videoParams_GetHdmiVideoFormat(video) == 2)
	{
		if (videoParams_Get3dStructure(video) == 6
				|| videoParams_Get3dStructure(video) == 8)
		{
			u8 data[3];
			data[0] = videoParams_GetHdmiVideoFormat(video) << 5;
			data[1] = videoParams_Get3dStructure(video) << 4;
			data[2] = videoParams_Get3dExtData(video) << 4;
			packets_VendorSpecificInfoFrame(baseAddr, 0x000C03,
					data, sizeof(data), 1); /* HDMI Licensing, LLC */
			send3d = TRUE;
		}
		else
		{
			LOG_ERROR2("3D structure not supported",
					videoParams_Get3dStructure(video));
			error_Set(ERR_3D_STRUCT_NOT_SUPPORTED);
			return FALSE;
		}
	}
	if (prod != 0)
	{
		if (productParams_IsSourceProductValid(prod))
		{
			packets_SourceProductInfoFrame(baseAddr,
					productParams_GetVendorName(prod),
					productParams_GetVendorNameLength(prod),
					productParams_GetProductName(prod),
					productParams_GetProductNameLength(prod),
					productParams_GetSourceType(prod), 1);
		}
		if (productParams_IsVendorSpecificValid(prod))
		{
			if (send3d)
			{
				LOG_WARNING("forcing Vendor Specific InfoFrame, 3D configuration will be ignored");
				error_Set(ERR_FORCING_VSD_3D_IGNORED);
			}
			packets_VendorSpecificInfoFrame(baseAddr,
					productParams_GetOUI(prod), productParams_GetVendorPayload(
							prod), productParams_GetVendorPayloadLength(prod),
					1);
		}
	}
	else
	{
		LOG_WARNING("No product info provided: not configured");
	}
	/* set values that shall not change */
	halFrameComposerPackets_MetadataFrameInterpolation(baseAddr + FC_BASE_ADDR,
			1);
	halFrameComposerPackets_MetadataFramesPerPacket(baseAddr + FC_BASE_ADDR, 1);
	halFrameComposerPackets_MetadataLineSpacing(baseAddr + FC_BASE_ADDR, 1);
	halFrameComposerGcp_DefaultPhase(baseAddr + FC_BASE_ADDR,
			videoParams_GetPixelPackingDefaultPhase(video) == 1); /* default phase 1 = true */
	halFrameComposerGamut_Profile(baseAddr + FC_BASE_ADDR + 0x100, 0x0); /* P0 */
	halFrameComposerGamut_PacketsPerFrame(baseAddr + FC_BASE_ADDR + 0x100, 0x1); /* P0 */
	halFrameComposerGamut_PacketLineSpacing(baseAddr + FC_BASE_ADDR + 0x100,
			0x1);
	packets_AuxiliaryVideoInfoFrame(baseAddr, video);
	return TRUE;
}
예제 #9
0
u8 edid_ParseDataBlock(u16 baseAddr, u8 * data)
{
	u8 tag = bitOperation_BitField(data[0], 5, 3);
	u8 length = bitOperation_BitField(data[0], 0, 5);
	u8 c = 0;
	shortAudioDesc_t tmpSad;
	shortVideoDesc_t tmpSvd;
	LOG_TRACE3("TAG", tag, length);
	switch (tag)
	{
	case 0x1: /* Audio Data Block */
		for (c = 1; c < (length + 1); c += 3)
		{
			shortAudioDesc_Parse(&tmpSad, data + c);
			if (edid_mSadIndex < (sizeof(edid_mSad) / sizeof(shortAudioDesc_t)))
			{
				edid_mSad[edid_mSadIndex++] = tmpSad;
			}
			else
			{
				error_Set(ERR_SHORT_AUDIO_DESC_BUFFER_FULL);
				LOG_WARNING("buffer full - SAD ignored");
			}
		}
		break;
	case 0x2: /* Video Data Block */
		for (c = 1; c < (length + 1); c++)
		{
			shortVideoDesc_Parse(&tmpSvd, data[c]);
			if (edid_mSvdIndex < (sizeof(edid_mSvd) / sizeof(shortVideoDesc_t)))
			{
				edid_mSvd[edid_mSvdIndex++] = tmpSvd;
			}
			else
			{
				error_Set(ERR_SHORT_VIDEO_DESC_BUFFER_FULL);
				LOG_WARNING("buffer full - SVD ignored");
			}
		}
		break;
	case 0x3: /* Vendor Specific Data Block */
	{
		u32 ieeeId = bitOperation_Bytes2Dword(0x00, data[3], data[2], data[1]);
		if (ieeeId == 0x000C03)
		{ /* HDMI */
			if (hdmivsdb_Parse(&edid_mHdmivsdb, data) != TRUE)
			{
				LOG_WARNING("HDMI Vendor Specific Data Block corrupt");
			}
		}
		else
		{
			LOG_WARNING2("Vendor Specific Data Block not parsed", ieeeId);
		}
		break;
	}
	case 0x4: /* Speaker Allocation Data Block */
		if (speakerAllocationDataBlock_Parse(&edid_mSpeakerAllocationDataBlock,
				data) != TRUE)
		{
			LOG_WARNING("Speaker Allocation Data Block corrupt");
		}
		break;
	case 0x7:
	{
		u8 extendedTag = data[1];
		switch (extendedTag)
		{
		case 0x00: /* Video Capability Data Block */
			if (videoCapabilityDataBlock_Parse(&edid_mVideoCapabilityDataBlock,
					data) != TRUE)
			{
				LOG_WARNING("Video Capability Data Block corrupt");
			}
			break;
		case 0x05: /* Colorimetry Data Block */
			if (colorimetryDataBlock_Parse(&edid_mColorimetryDataBlock, data)
					!= TRUE)
			{
				LOG_WARNING("Colorimetry Data Block corrupt");
			}
			break;
		case 0x04: /* HDMI Video Data Block */
		case 0x12: /* HDMI Audio Data Block */
			break;
		default:
			LOG_WARNING2("Extended Data Block not parsed", extendedTag);
			break;
		}
		break;
	}
	default:
		LOG_WARNING2("Data Block not parsed", tag);
		break;
	}
	return length + 1;
}
예제 #10
0
int edid_ParseBlock(u16 baseAddr, u8 * buffer)
{
	const unsigned DTD_SIZE = 0x12;
	const unsigned TIMING_MODES = 0x36;
	dtd_t tmpDtd;
	unsigned c = 0;
	unsigned i = 0;
	LOG_TRACE();
	if (edid_mCurrBlockNo == 0)
	{
		if (buffer[0] == 0x00)
		{ /* parse block zero */
			edid_mBlocksNo = buffer[126] + 1;
			/* parse DTD's */
			for (i = TIMING_MODES; i < (TIMING_MODES + (DTD_SIZE * 4)); i
					+= DTD_SIZE)
			{
				if (bitOperation_Bytes2Word(buffer[i + 1], buffer[i + 0]) > 0)
				{
					if (dtd_Parse(&tmpDtd, buffer + i) == TRUE)
					{
						if (edid_mDtdIndex < (sizeof(edid_mDtd)
								/ sizeof(dtd_t)))
						{
							edid_mDtd[edid_mDtdIndex++] = tmpDtd;
						}
						else
						{
							error_Set(ERR_DTD_BUFFER_FULL);
							LOG_WARNING("buffer full - DTD ignored");
						}
					}
					else
					{
						LOG_WARNING("DTD corrupt");
					}
				}
				else if ((buffer[i + 2] == 0) && (buffer[i + 4] == 0))
				{
					/* it is a Display-monitor Descriptor */
					if (buffer[i + 3] == 0xFC)
					{ /* Monitor Name */
						for (c = 0; c < 13; c++)
						{
							edid_mMonitorName[c] = buffer[i + c + 5];
						}
					}
					else if (buffer[i + 3] == 0xFD)
					{ /* Monitor Range Limits */
						if (monitorRangeLimits_Parse(&edid_mMonitorRangeLimits,
								buffer + i) != TRUE)
						{
							LOG_WARNING2("Monitor Range Limits corrupt", i);
						}
					}
				}
			}
		}
	}
	else if (buffer[0] == 0xF0)
	{ /* Block Map Extension */
		/* last is checksum */
		for (i = 1; i < (sizeof(edid_mBuffer) - 1); i++)
		{
			if (buffer[i] == 0x00)
			{
				break;
			}
		}
		if (edid_mBlocksNo < 128)
		{
			if (i > edid_mBlocksNo)
			{ /* N (no of extensions) does NOT include Block maps */
				edid_mBlocksNo += 2;
			}
			else if (i == edid_mBlocksNo)
			{
				edid_mBlocksNo += 1;
			}
		}
		else
		{
			i += 127;
			if (i > edid_mBlocksNo)
			{ /* N (no of extensions) does NOT include Block maps */
				edid_mBlocksNo += 3;
			}
			else if (i == edid_mBlocksNo)
			{
				edid_mBlocksNo += 1;
			}
		}
	}
	else if (buffer[0] == 0x02)
	{ /* CEA Extension block */
		if (buffer[1] == 0x03)
		{ /* revision number (only rev3 is allowed by HDMI spec) */
			u8 offset = buffer[2];
			edid_mYcc422Support = bitOperation_BitField(buffer[3], 4, 1) == 1;
			edid_mYcc444Support = bitOperation_BitField(buffer[3], 5, 1) == 1;
			edid_mBasicAudioSupport = bitOperation_BitField(buffer[3], 6, 1)
					== 1;
			edid_mUnderscanSupport = bitOperation_BitField(buffer[3], 7, 1)
					== 1;
			if (offset != 4)
			{
				for (i = 4; i < offset; i += edid_ParseDataBlock(baseAddr,
						buffer + i))
					;
			}
			/* last is checksum */
			for (i = offset, c = 0; i < (sizeof(edid_mBuffer) - 1) && c < 6; i
					+= DTD_SIZE, c++)
			{
				if (dtd_Parse(&tmpDtd, buffer + i) == TRUE)
				{
					if (edid_mDtdIndex < (sizeof(edid_mDtd) / sizeof(dtd_t)))
					{
						edid_mDtd[edid_mDtdIndex++] = tmpDtd;
					}
					else
					{
						error_Set(ERR_DTD_BUFFER_FULL);
						LOG_WARNING("buffer full - DTD ignored");
					}
				}
			}
		}
	}
	return TRUE;
}
예제 #11
0
u8 edid_EventHandler(u16 baseAddr, int hpd, u8 state)
{
	LOG_TRACE2(hpd, state);
	if (edid_mStatus != EDID_READING)
	{
		return EDID_IDLE;
	}
	else if (!hpd)
	{ /* hot plug detected without cable disconnection */
		error_Set(ERR_HPD_LOST);
		LOG_WARNING("hpd");
		edid_mStatus = EDID_ERROR;
	}
	else if ((state & BIT(0)) != 0) /* error */
	{ 
		LOG_WARNING("error");
		edid_mStatus = EDID_ERROR;
	}
	else if ((state & BIT(1)) != 0) /* done */
	{ 
		if (edid_mCurrAddress >= sizeof(edid_mBuffer))
		{
			error_Set(ERR_OVERFLOW);
			LOG_WARNING("overflow");
			edid_mStatus = EDID_ERROR;
		}
		else
		{
			edid_mBuffer[edid_mCurrAddress] = halEdid_ReadData(baseAddr
					+ I2CM_BASE_ADDR);
			edid_mBlockSum += edid_mBuffer[edid_mCurrAddress++];
			if (edid_mCurrAddress >= sizeof(edid_mBuffer))
			{
				/*check if checksum is correct (CEA-861 D Spec p108) */
				if (edid_mBlockSum % 0x100 == 0)
				{
					LOG_NOTICE("block checksum correct");
					edid_ParseBlock(baseAddr, edid_mBuffer);
					edid_mCurrAddress = 0;
					edid_mCurrBlockNo++;
					edid_mBlockSum = 0;
					if (edid_mCurrBlockNo >= edid_mBlocksNo)
					{
						edid_mStatus = EDID_DONE; 
					}
				}
				else
				{
					error_Set(ERR_BLOCK_CHECKSUM_INVALID);
					LOG_WARNING("block checksum invalid");
					edid_mStatus = EDID_ERROR; 
				}
			}
		}
	}
	if (edid_mStatus == EDID_READING)
	{
		edid_ReadRequest(baseAddr, edid_mCurrAddress, edid_mCurrBlockNo);
	}
	else if (edid_mStatus == EDID_DONE)
	{
		edid_mBlocksNo = 1;
		edid_mCurrBlockNo = 0;
		edid_mCurrAddress = 0;
		edid_mBlockSum = 0;
	}
	return edid_mStatus;
}
예제 #12
0
int dtd_Fill(dtd_t *dtd, u8 code, u32 refreshRate)
{
	LOG_TRACE();
	dtd->mCode = code;
	dtd->mHBorder = 0;
	dtd->mVBorder = 0;
	dtd->mPixelRepetitionInput = 0;
	dtd->mHImageSize = 16;
	dtd->mVImageSize = 9;
#ifdef	HDMI_JZ4780_DEBUG
	printk("jz4780  hmdi video code:%d\n",code);
#endif
	switch (code)
	{
		case 1: /* 640x480p @ 59.94/60Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
			dtd->mHActive = 640;
			dtd->mVActive = 480;
			dtd->mHBlanking = 160;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 16;
			dtd->mVSyncOffset = 10;
			dtd->mHSyncPulseWidth = 96;
			dtd->mVSyncPulseWidth = 2;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0; /* not(progressive_nI) */
			dtd->mPixelClock = (refreshRate == 59940) ? 2517 : 2520;
			break;
		case 2: /* 720x480p @ 59.94/60Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 3: /* 720x480p @ 59.94/60Hz 16:9 */
			dtd->mHActive = 720;
			dtd->mVActive = 480;
			dtd->mHBlanking = 138;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 16;
			dtd->mVSyncOffset = 9;
			dtd->mHSyncPulseWidth = 62;
			dtd->mVSyncPulseWidth = 6;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			//dtd->mPixelClock = (refreshRate == 59940) ? 2700 : 2702;
			dtd->mPixelClock = (refreshRate == 59940) ? 2700 : 2700;
			break;
		case 4: /* 1280x720p @ 59.94/60Hz 16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 370;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 110;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 59940) ? 7417 : 7425;
			break;
		case 5: /* 1920x1080i @ 59.94/60Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 540;
			dtd->mHBlanking = 280;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 88;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = (refreshRate == 59940) ? 7417 : 7425;
			break;
		case 6: /* 720(1440)x480i @ 59.94/60Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 7: /* 720(1440)x480i @ 59.94/60Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 240;
			dtd->mHBlanking = 276;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 38;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 124;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = (refreshRate == 59940) ? 2700 : 2702;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 8: /* 720(1440)x240p @ 59.826/60.054/59.886/60.115Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 9: /* 720(1440)x240p @ 59.826/60.054/59.886/60.115Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 240;
			dtd->mHBlanking = 276;
			dtd->mVBlanking = (refreshRate > 60000) ? 22 : 23;
			dtd->mHSyncOffset = 38;
			dtd->mVSyncOffset = (refreshRate > 60000) ? 4 : 5;
			dtd->mHSyncPulseWidth = 124;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock
					= ((refreshRate == 60054) || refreshRate == 59826) ? 2700
							: 2702; /*  else 60.115/59.886 Hz */
			dtd->mPixelRepetitionInput = 1;
			break;
		case 10: /* 2880x480i @ 59.94/60Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 11: /* 2880x480i @ 59.94/60Hz 16:9 */
			dtd->mHActive = 2880;
			dtd->mVActive = 240;
			dtd->mHBlanking = 552;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 76;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 248;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = (refreshRate == 59940) ? 5400 : 5405;
			break;
		case 12: /* 2880x240p @ 59.826/60.054/59.886/60.115Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 13: /* 2880x240p @ 59.826/60.054/59.886/60.115Hz 16:9 */
			dtd->mHActive = 2880;
			dtd->mVActive = 240;
			dtd->mHBlanking = 552;
			dtd->mVBlanking = (refreshRate > 60000) ? 22 : 23;
			dtd->mHSyncOffset = 76;
			dtd->mVSyncOffset = (refreshRate > 60000) ? 4 : 5;
			dtd->mHSyncPulseWidth = 248;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock
					= ((refreshRate == 60054) || refreshRate == 59826) ? 5400
							: 5405; /*  else 60.115/59.886 Hz */
			break;
		case 14: /* 1440x480p @ 59.94/60Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 15: /* 1440x480p @ 59.94/60Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 480;
			dtd->mHBlanking = 276;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 32;
			dtd->mVSyncOffset = 9;
			dtd->mHSyncPulseWidth = 124;
			dtd->mVSyncPulseWidth = 6;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 59940) ? 5400 : 5405;
			break;
		case 16: /* 1920x1080p @ 59.94/60Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 280;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 88;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 59940) ? 14835 : 14850;
			break;
		case 17: /* 720x576p @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 18: /* 720x576p @ 50Hz 16:9 */
			dtd->mHActive = 720;
			dtd->mVActive = 576;
			dtd->mHBlanking = 144;
			dtd->mVBlanking = 49;
			dtd->mHSyncOffset = 12;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 64;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 2700;
			break;
		case 19: /* 1280x720p @ 50Hz 16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 700;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 440;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 7425;
			break;
		case 20: /* 1920x1080i @ 50Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 540;
			dtd->mHBlanking = 720;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 528;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 7425;
			break;
		case 21: /* 720(1440)x576i @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 22: /* 720(1440)x576i @ 50Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 288;
			dtd->mHBlanking = 288;
			dtd->mVBlanking = 24;
			dtd->mHSyncOffset = 24;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 126;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 2700;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 23: /* 720(1440)x288p @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 24: /* 720(1440)x288p @ 50Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 288;
			dtd->mHBlanking = 288;
			dtd->mVBlanking = (refreshRate == 50080) ? 24
					: ((refreshRate == 49920) ? 25 : 26);
			dtd->mHSyncOffset = 24;
			dtd->mVSyncOffset = (refreshRate == 50080) ? 2
					: ((refreshRate == 49920) ? 3 : 4);
			dtd->mHSyncPulseWidth = 126;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 2700;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 25: /* 2880x576i @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 26: /* 2880x576i @ 50Hz 16:9 */
			dtd->mHActive = 2880;
			dtd->mVActive = 288;
			dtd->mHBlanking = 576;
			dtd->mVBlanking = 24;
			dtd->mHSyncOffset = 48;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 252;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 5400;
			break;
		case 27: /* 2880x288p @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 28: /* 2880x288p @ 50Hz 16:9 */
			dtd->mHActive = 2880;
			dtd->mVActive = 288;
			dtd->mHBlanking = 576;
			dtd->mVBlanking = (refreshRate == 50080) ? 24
					: ((refreshRate == 49920) ? 25 : 26);
			dtd->mHSyncOffset = 48;
			dtd->mVSyncOffset = (refreshRate == 50080) ? 2
					: ((refreshRate == 49920) ? 3 : 4);
			dtd->mHSyncPulseWidth = 252;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 5400;
			break;
		case 29: /* 1440x576p @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 30: /* 1440x576p @ 50Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 576;
			dtd->mHBlanking = 288;
			dtd->mVBlanking = 49;
			dtd->mHSyncOffset = 24;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 128;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 5400;
			break;
		case 31: /* 1920x1080p @ 50Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 720;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 528;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 14850;
			break;
		case 32: /* 1920x1080p @ 23.976/24Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 830;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 638;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 23976) ? 7417 : 7425;
			break;
		case 33: /* 1920x1080p @ 25Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 720;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 528;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 7425;
			break;
		case 34: /* 1920x1080p @ 29.97/30Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 280;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 88;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 29970) ? 7417 : 7425;
			break;
		case 35: /* 2880x480p @ 60Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 36: /* 2880x480p @ 60Hz 16:9 */
			dtd->mHActive = 2880;
			dtd->mVActive = 480;
			dtd->mHBlanking = 552;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 64;
			dtd->mVSyncOffset = 9;
			dtd->mHSyncPulseWidth = 248;
			dtd->mVSyncPulseWidth = 6;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 59940) ? 10800 : 10810;
			break;
		case 37: /* 2880x576p @ 50Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 38: /* 2880x576p @ 50Hz 16:9 */
			dtd->mHActive = 2880;
			dtd->mVActive = 576;
			dtd->mHBlanking = 576;
			dtd->mVBlanking = 49;
			dtd->mHSyncOffset = 48;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 256;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 10800;
			break;
		case 39: /* 1920x1080i (1250 total) @ 50Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 540;
			dtd->mHBlanking = 384;
			dtd->mVBlanking = 85;
			dtd->mHSyncOffset = 32;
			dtd->mVSyncOffset = 23;
			dtd->mHSyncPulseWidth = 168;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 7200;
			break;
		case 40: /* 1920x1080i @ 100Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 540;
			dtd->mHBlanking = 720;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 528;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 14850;
			break;
		case 41: /* 1280x720p @ 100Hz 16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 700;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 440;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 14850;
			break;
		case 42: /* 720x576p @ 100Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 43: /* 720x576p @ 100Hz 16:9 */
			dtd->mHActive = 720;
			dtd->mVActive = 576;
			dtd->mHBlanking = 144;
			dtd->mVBlanking = 49;
			dtd->mHSyncOffset = 12;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 64;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 5400;
			break;
		case 44: /* 720(1440)x576i @ 100Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 45: /* 720(1440)x576i @ 100Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 288;
			dtd->mHBlanking = 288;
			dtd->mVBlanking = 24;
			dtd->mHSyncOffset = 24;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 126;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 5400;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 46: /* 1920x1080i @ 119.88/120Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 540;
			dtd->mHBlanking = 288;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 88;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = (refreshRate == 119880) ? 14835 : 14850;
			break;
		case 47: /* 1280x720p @ 119.88/120Hz 16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 370;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 110;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 119880) ? 14835 : 14850;
			break;
		case 48: /* 720x480p @ 119.88/120Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 49: /* 720x480p @ 119.88/120Hz 16:9 */
			dtd->mHActive = 720;
			dtd->mVActive = 480;
			dtd->mHBlanking = 138;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 16;
			dtd->mVSyncOffset = 9;
			dtd->mHSyncPulseWidth = 62;
			dtd->mVSyncPulseWidth = 6;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 119880) ? 5400 : 5405;
			break;
		case 50: /* 720(1440)x480i @ 119.88/120Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 51: /* 720(1440)x480i @ 119.88/120Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 240;
			dtd->mHBlanking = 276;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 38;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 124;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = (refreshRate == 119880) ? 5400 : 5405;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 52: /* 720X576p @ 200Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 53: /* 720X576p @ 200Hz 16:9 */
			dtd->mHActive = 720;
			dtd->mVActive = 576;
			dtd->mHBlanking = 144;
			dtd->mVBlanking = 49;
			dtd->mHSyncOffset = 12;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 64;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 10800;
			break;
		case 54: /* 720(1440)x576i @ 200Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 55: /* 720(1440)x576i @ 200Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 288;
			dtd->mHBlanking = 288;
			dtd->mVBlanking = 24;
			dtd->mHSyncOffset = 24;
			dtd->mVSyncOffset = 2;
			dtd->mHSyncPulseWidth = 126;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = 10800;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 56: /* 720x480p @ 239.76/240Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 57: /* 720x480p @ 239.76/240Hz 16:9 */
			dtd->mHActive = 720;
			dtd->mVActive = 480;
			dtd->mHBlanking = 138;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 16;
			dtd->mVSyncOffset = 9;
			dtd->mHSyncPulseWidth = 62;
			dtd->mVSyncPulseWidth = 6;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 239760) ? 10800 : 10810;
			break;
		case 58: /* 720(1440)x480i @ 239.76/240Hz 4:3 */
			dtd->mHImageSize = 4;
			dtd->mVImageSize = 3;
		case 59: /* 720(1440)x480i @ 239.76/240Hz 16:9 */
			dtd->mHActive = 1440;
			dtd->mVActive = 240;
			dtd->mHBlanking = 276;
			dtd->mVBlanking = 22;
			dtd->mHSyncOffset = 38;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 124;
			dtd->mVSyncPulseWidth = 3;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 0;
			dtd->mInterlaced = 1;
			dtd->mPixelClock = (refreshRate == 239760) ? 10800 : 10810;
			dtd->mPixelRepetitionInput = 1;
			break;
		case 60: /* 1280x720p @ 23.97/24Hz 16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 2020;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 1760;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 23970) ? 5934 : 5940;
			break;
		case 61: /* 1280x720p @ 25Hz 16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 2680;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 2420;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 7425;
			break;
		case 62: /* 1280x720p @ 29.97/30Hz  16:9 */
			dtd->mHActive = 1280;
			dtd->mVActive = 720;
			dtd->mHBlanking = 2020;
			dtd->mVBlanking = 30;
			dtd->mHSyncOffset = 1760;
			dtd->mVSyncOffset = 5;
			dtd->mHSyncPulseWidth = 40;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 29970) ? 7417: 7425;
			break;
		case 63: /* 1920x1080p @ 119.88/120Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 280;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 88;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = (refreshRate == 119880) ?  29670: 29700;
			break;
		case 64: /* 1920x1080p @ 100Hz 16:9 */
			dtd->mHActive = 1920;
			dtd->mVActive = 1080;
			dtd->mHBlanking = 720;
			dtd->mVBlanking = 45;
			dtd->mHSyncOffset = 528;
			dtd->mVSyncOffset = 4;
			dtd->mHSyncPulseWidth = 44;
			dtd->mVSyncPulseWidth = 5;
			dtd->mHSyncPolarity = dtd->mVSyncPolarity = 1;
			dtd->mInterlaced = 0;
			dtd->mPixelClock = 29700;
			break;
	default:
		dtd->mCode = -1;
		error_Set(ERR_DTD_INVALID_CODE);
		LOG_ERROR("invalid code");
		return FALSE;
	}
	return TRUE;
}