示例#1
0
static int hdmi_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
{
	struct hdmi *hdmi = device->priv_data;
	struct fb_videomode *vmode;
		
	vmode = (struct fb_videomode*) hdmi_vic_to_videomode(hdmi->vic);
	if(unlikely(vmode == NULL))
		return -1;
	*mode = *vmode;
	return 0;
}
static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv, struct hdmi_video_para *vpara)	//TODO Daisen wait to add support 3D
{
	int h_act = 0, v_act = 0;
	int h_syncdelay = 0, v_syncdelay = 0;
	int h_sync = 0, v_sync = 0;
	int h_blank = 0, v_blank = 0;
	int vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
	int hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
	int de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
	struct fb_videomode *mode = NULL;
	struct rk3288_hdmi_device *hdmi_dev = container_of(hdmi_drv, struct rk3288_hdmi_device, driver);

	mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
	if(mode == NULL) {
		hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
		return -ENOENT;
	}

	hdmi_drv->pixclock = mode->pixclock;
	switch(vpara->color_depth) {
	case HDMI_COLOR_DEPTH_8BIT:
		hdmi_drv->tmdsclk = mode->pixclock;
		break;
	case HDMI_COLOR_DEPTH_10BIT:
		hdmi_drv->tmdsclk = mode->pixclock * 10 / 8;
		break;
	case HDMI_COLOR_DEPTH_12BIT:
		hdmi_drv->tmdsclk = mode->pixclock * 12 / 8;
		break;
	case HDMI_COLOR_DEPTH_16BIT:
		hdmi_drv->tmdsclk = mode->pixclock * 2;
		break;
	default:
		hdmi_drv->tmdsclk = mode->pixclock;
		break;
	}
	rk3288_hdmi_config_phy(hdmi_drv, vpara->pixel_repet, vpara->color_depth);

	hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_ENCRYPT_BYPASS | m_HDMI_DVI,
		v_ENCRYPT_BYPASS(1) | v_HDMI_DVI(vpara->output_mode));	//cfg to bypass hdcp data encrypt
	hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL | m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
		v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) | v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->output_mode) | v_FC_INTERLACE_MODE(mode->vmode));
	hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VBLANK, v_FC_VBLANK(mode->vmode));

	h_act = mode->xres;
	hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(h_act >> 8));
	hdmi_writel(hdmi_dev, FC_INHACTIV0, (h_act & 0xff));

	v_act = mode->yres;
	hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(v_act >> 8));
	hdmi_writel(hdmi_dev, FC_INVACTIV0, (v_act & 0xff));

	h_blank = mode->hsync_len + mode->left_margin + mode->right_margin;
	hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(h_blank >> 8));
	hdmi_writel(hdmi_dev, FC_INHBLANK0, (h_blank & 0xff));

	v_blank = mode->vsync_len + mode->upper_margin + mode->lower_margin;
	hdmi_writel(hdmi_dev, FC_INVBLANK, (v_blank & 0xff));

	h_syncdelay = mode->right_margin;
	hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1, v_FC_HSYNCINDEAY1(h_syncdelay >> 8));
	hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (h_syncdelay & 0xff));

	v_syncdelay = mode->lower_margin;
	hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (v_syncdelay & 0xff));

	h_sync = mode->hsync_len;
	hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(h_sync >> 8));
	hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (h_sync & 0xff));

	v_sync = mode->vsync_len;
	hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (v_sync & 0xff));

	/*Set the control period minimum duration(min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)*/
	hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
	hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
#if 0
	if(hdmi_drv->tmdsclk > 340000000) {	//used for HDMI 2.0 TX	//TODO Daisen wait to modify HDCP KEEPOUT
		hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_HDCP_KEEPOUT, v_FC_HDCP_KEEPOUT(1));
		hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, m_FC_SCRAMBLE_EN, v_FC_SCRAMBLE_EN(1));
	}

	/* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
	 * worst case: tmdsClock == 25MHz => config <= 19
	 */
	hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1);

	/*Set PreambleFilter*/
	for (i = 0; i < 3; i++) {
		value = (i + 1) * 11;
		if (i == 0)		/*channel 0*/
			hdmi_writel(hdmi_dev, FC_CH0PREAM, value);
		else if (i == 1)	/*channel 1*/
			hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f);
		else if (i == 2)	/*channel 2*/
			hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f);
	}
#endif
	/*Set PixelRepetition:No pixel repetition*/
	hdmi_writel(hdmi_dev, FC_PRCONF, v_FC_PR_FACTOR(vpara->pixel_repet + 1));

	return 0;
}
示例#3
0
int rk30_hdmi_config_video(struct hdmi_video_para *vpara)
{
	int value;
	struct fb_videomode *mode;
	
	hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__);
	if(vpara == NULL) {
		hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__);
		return -1;
	}
	if(hdmi->pwr_mode == PWR_SAVE_MODE_E)
		rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D);
	if(hdmi->pwr_mode == PWR_SAVE_MODE_D || hdmi->pwr_mode == PWR_SAVE_MODE_A)
		rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B);
	
	if(hdmi->hdcp_power_off_cb)
		hdmi->hdcp_power_off_cb();
		
	// Input video mode is RGB24bit, Data enable signal from external
	HDMIMskReg(value, AV_CTRL1, m_INPUT_VIDEO_MODE | m_DE_SIGNAL_SELECT, \
		v_INPUT_VIDEO_MODE(vpara->input_mode) | EXTERNAL_DE)	
	HDMIMskReg(value, VIDEO_CTRL1, m_VIDEO_OUTPUT_MODE | m_VIDEO_INPUT_DEPTH | m_VIDEO_INPUT_COLOR_MODE, \
		v_VIDEO_OUTPUT_MODE(vpara->output_color) | v_VIDEO_INPUT_DEPTH(VIDEO_INPUT_DEPTH_8BIT) | vpara->input_color)
	HDMIWrReg(DEEP_COLOR_MODE, 0x20);
	// color space convert
	rk30_hdmi_config_csc(vpara);
	// Set HDMI Mode
	HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode));

	// Set ext video
	mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
	if(mode == NULL)
	{
		hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
		return -ENOENT;
	}
	hdmi->tmdsclk = mode->pixclock;

	if( (vpara->vic == HDMI_720x480p_60Hz_4_3) || (vpara->vic == HDMI_720x480p_60Hz_16_9) )
		value = v_VSYNC_OFFSET(6);
	else
		value = v_VSYNC_OFFSET(0);
	value |= v_EXT_VIDEO_ENABLE(1) | v_INTERLACE(mode->vmode);
	if(mode->sync & FB_SYNC_HOR_HIGH_ACT)
		value |= v_HSYNC_POLARITY(1);
	if(mode->sync & FB_SYNC_VERT_HIGH_ACT)
		value |= v_VSYNC_POLARITY(1);
	HDMIWrReg(EXT_VIDEO_PARA, value);
	value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len;
	HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_L, value & 0xFF);
	HDMIWrReg(EXT_VIDEO_PARA_HTOTAL_H, (value >> 8) & 0xFF);
	
	value = mode->left_margin + mode->right_margin + mode->hsync_len;
	HDMIWrReg(EXT_VIDEO_PARA_HBLANK_L, value & 0xFF);
	HDMIWrReg(EXT_VIDEO_PARA_HBLANK_H, (value >> 8) & 0xFF);
	
	value = mode->left_margin + mode->hsync_len;
	HDMIWrReg(EXT_VIDEO_PARA_HDELAY_L, value & 0xFF);
	HDMIWrReg(EXT_VIDEO_PARA_HDELAY_H, (value >> 8) & 0xFF);
	
	value = mode->hsync_len;
	HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_L, value & 0xFF);
	HDMIWrReg(EXT_VIDEO_PARA_HSYNCWIDTH_H, (value >> 8) & 0xFF);
	
	value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len;
	HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_L, value & 0xFF);
	HDMIWrReg(EXT_VIDEO_PARA_VTOTAL_H, (value >> 8) & 0xFF);
	
	value = mode->upper_margin + mode->vsync_len + mode->lower_margin;
	HDMIWrReg(EXT_VIDEO_PARA_VBLANK_L, value & 0xFF);
	
	if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9)
		value = 42;
	else
		value = mode->upper_margin + mode->vsync_len;

	HDMIWrReg(EXT_VIDEO_PARA_VDELAY, value & 0xFF);
	
	value = mode->vsync_len;
	HDMIWrReg(EXT_VIDEO_PARA_VSYNCWIDTH, value & 0xFF);
	
	if(vpara->output_mode == OUTPUT_HDMI) {
		rk30_hdmi_config_avi(vpara->vic, vpara->output_color);
		hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__);
	}
	else {
		hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__);	
	}
	
	rk30_hdmi_config_phy(vpara->vic);
	rk30_hdmi_control_output(0);
	return 0;
}
示例#4
0
static int rk2928_hdmi_config_video(struct hdmi_video_para *vpara)
{
	int value;
	struct fb_videomode *mode;
	
	hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__);
	if(vpara == NULL) {
		hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__);
		return -1;
	}
	
	if(hdmi->hdcp_power_off_cb)
		hdmi->hdcp_power_off_cb();
		// Diable video and audio output
	HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
	
	// Input video mode is SDR RGB24bit, Data enable signal from external
	HDMIWrReg(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL);
	HDMIWrReg(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | (vpara->output_color & 0xFF));

	// Set HDMI Mode
	HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode));

	// Enable or disalbe color space convert
	if(vpara->input_color != vpara->output_color) {
		value = v_SOF_DISABLE | v_CSC_ENABLE;
	}
	else
		value = v_SOF_DISABLE;
	HDMIWrReg(VIDEO_CONTRL3, value);

	// Set ext video
#if 1
	HDMIWrReg(VIDEO_TIMING_CTL, 0);
	mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
	if(mode == NULL)
	{
		hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
		return -ENOENT;
	}
	hdmi->tmdsclk = mode->pixclock;
#else
	value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode);
	if(mode->sync & FB_SYNC_HOR_HIGH_ACT)
		value |= v_HSYNC_POLARITY(1);
	if(mode->sync & FB_SYNC_VERT_HIGH_ACT)
		value |= v_VSYNC_POLARITY(1);
	HDMIWrReg(VIDEO_TIMING_CTL, value);
	
	value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len;
	HDMIWrReg(VIDEO_EXT_HTOTAL_L, value & 0xFF);
	HDMIWrReg(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
	
	value = mode->left_margin + mode->right_margin + mode->hsync_len;
	HDMIWrReg(VIDEO_EXT_HBLANK_L, value & 0xFF);
	HDMIWrReg(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
	
	value = mode->left_margin + mode->hsync_len;
	HDMIWrReg(VIDEO_EXT_HDELAY_L, value & 0xFF);
	HDMIWrReg(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
	
	value = mode->hsync_len;
	HDMIWrReg(VIDEO_EXT_HDURATION_L, value & 0xFF);
	HDMIWrReg(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
	
	value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len;
	HDMIWrReg(VIDEO_EXT_VTOTAL_L, value & 0xFF);
	HDMIWrReg(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
	
	value = mode->upper_margin + mode->vsync_len + mode->lower_margin;
	HDMIWrReg(VIDEO_EXT_VBLANK, value & 0xFF);

	if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9)
		value = 42;
	else
		value = mode->upper_margin + mode->vsync_len;

	HDMIWrReg(VIDEO_EXT_VDELAY, value & 0xFF);
	
	value = mode->vsync_len;
	HDMIWrReg(VIDEO_EXT_VDURATION, value & 0xFF);
#endif
	
	if(vpara->output_mode == OUTPUT_HDMI) {
		rk2928_hdmi_config_avi(vpara->vic, vpara->output_color);
		hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__);
	}
	else {
		hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__);	
	}

	return 0;
}
示例#5
0
int cat66121_hdmi_sys_config_video(struct hdmi_video_para *vpara)
{
	struct fb_videomode *mode;
	HDMI_Aspec aspec ;
	HDMI_Colorimetry Colorimetry ;
	VIDEOPCLKLEVEL level ;

	if(vpara == NULL) {
		hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__);
		return -1;
	}

	// output Color mode
	switch(vpara->output_color)
	{
		case HDMI_COLOR_YCbCr444:
			bOutputColorMode = F_MODE_YUV444 ;
			break ;
		case HDMI_COLOR_YCbCr422:
			bOutputColorMode = F_MODE_YUV422 ;
			break ;
		case HDMI_COLOR_RGB:
		default:
			bOutputColorMode = F_MODE_RGB444 ;
			break ;
	}
	// Set ext video
	mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
	if(mode == NULL)
	{
		hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
		return -ENOENT;
	}

	hdmi->tmdsclk = mode->pixclock;
	switch(vpara->vic)
	{
		case HDMI_640x480p60:
			pixelrep = 0 ;
			aspec = HDMI_4x3 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_480p60:
			pixelrep = 0 ;
			aspec = HDMI_4x3 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_480p60_16x9:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_720p60:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_1080i60:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_480i60:
			pixelrep = 1 ;
			aspec = HDMI_4x3 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_480i60_16x9:
			pixelrep = 1 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_1080p60:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_576p50:
			pixelrep = 0 ;
			aspec = HDMI_4x3 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_576p50_16x9:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_720p50:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_1080i50:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_576i50:
			pixelrep = 1 ;
			aspec = HDMI_4x3 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_576i50_16x9:
			pixelrep = 1 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU601 ;
			break ;
		case HDMI_1080p50:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_1080p24:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_1080p25:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;
		case HDMI_1080p30:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
			break ;

		case HDMI_720p30:
			pixelrep = 0 ;
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;		
		default:
			aspec = HDMI_16x9 ;
			Colorimetry = HDMI_ITU709 ;
	}
	if( Colorimetry == HDMI_ITU709 )
	{
		bInputColorMode |= F_VIDMODE_ITU709 ;
	}
	else
	{
		bInputColorMode &= ~F_VIDMODE_ITU709 ;
	}
	if( vpara->vic != HDMI_640x480p60)
	{
		bInputColorMode |= F_VIDMODE_16_235 ;
	}
	else
	{
		bInputColorMode &= ~F_VIDMODE_16_235 ;
	}
	
	if( (hdmi->tmdsclk*(pixelrep+1))>80000000L )
	{
		level = PCLK_HIGH ;
	}
	else if((hdmi->tmdsclk*(pixelrep+1))>20000000L)
	{
		level = PCLK_MEDIUM ;
	}
	else
	{
		level = PCLK_LOW ;
	}

	HDMITX_EnableVideoOutput(level,bInputColorMode,bOutputColorMode ,vpara->output_mode);

	if(vpara->output_mode == OUTPUT_HDMI) {
		cat66121_sys_config_avi(vpara->vic, bOutputColorMode, aspec, Colorimetry, pixelrep);
#ifdef OUTPUT_3D_MODE
		ConfigfHdmiVendorSpecificInfoFrame(OUTPUT_3D_MODE);
#endif

	}
	else {
		HDMITX_EnableAVIInfoFrame(FALSE ,NULL);
		HDMITX_EnableVSInfoFrame(FALSE,NULL);
	}
	setHDMITX_VideoSignalType(INPUT_SIGNAL_TYPE);
#ifdef SUPPORT_SYNCEMBEDDED
	if(INPUT_SIGNAL_TYPE & T_MODE_SYNCEMB)
	{
		setHDMITX_SyncEmbeddedByVIC(vpara->vic,INPUT_SIGNAL_TYPE);
	}
#endif

	return HDMI_ERROR_SUCESS;
}
示例#6
0
void hdmi_work(struct work_struct *work)
{
	int hotplug, state_last;
	int rc = HDMI_ERROR_SUCESS, trytimes = 0;
	struct hdmi_video_para video;

	mutex_lock(&work_mutex);
	/* Process hdmi command */
	hdmi->state = hdmi_process_command();
	
	if(!hdmi->enable || hdmi->suspend) {
		mutex_unlock(&work_mutex);
		return;
	}
	hotplug = hdmi->detect_hotplug();
	hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __FUNCTION__, hotplug, hdmi->hotplug);
#ifndef AUTO_VIDEO_MODE_HANDLING
	/* 
	   Omegamoon: HDMI 'black screen/No signal' fix
	   Use sysfs to change this behaviour as follows:
	   Enable autoconfig: 
	     echo "1">/sys/devices/virtual/display/display0.HDMI/autoconfig
	   Disable autoconfig (default): 
	     echo "0">/sys/devices/virtual/display/display0.HDMI/autoconfig
	*/
	if(hdmi->autoconfig == HDMI_ENABLE) {
		// This is the original HDMI handling
		if(hotplug != hdmi->hotplug)
		{
			if(hotplug  == HDMI_HPD_ACTIVED){
				if(hdmi->insert)
					hdmi->insert();
				hdmi->state = READ_PARSE_EDID;
			}
			else if(hdmi->hotplug == HDMI_HPD_ACTIVED) {
				hdmi_sys_remove();
				hdmi->hotplug = hotplug;
				if(hotplug == HDMI_HPD_REMOVED)
					hdmi_sys_sleep();
				else {
					hdmi->state = WAIT_HOTPLUG;
					hdmi->remove();
				}
				if(hdmi->wait == 1) {
					complete(&hdmi->complete);
					hdmi->wait = 0;	
				}
				mutex_unlock(&work_mutex);
				return;
			}
			else if(hotplug == HDMI_HPD_REMOVED) {
				hdmi->state = HDMI_SLEEP;
				hdmi->remove();
			}
			hdmi->hotplug  = hotplug;
		}
		else if(hotplug == HDMI_HPD_REMOVED)
			hdmi_sys_sleep();
	} else {
		/*
		  If autoconfig is disabled, the Hotplug feature is also disabled.
		  EDID is no longer read from the display, and a fixed resolution is set.
		*/
		if(hotplug != hdmi->hotplug) {
			hdmi->state = SYSTEM_CONFIG;
			hdmi->hotplug = HDMI_HPD_ACTIVED;
#ifdef FORCE_HDMI_VIDEO_MODE
			// Omegamoon: Fixed HDMI output
			dev_printk(KERN_INFO, hdmi->dev, "Omegamoon: Force HDMI output\n");
			hdmi->edid.sink_hdmi = OUTPUT_HDMI;
#endif
#ifdef FORCE_DVI_VIDEO_MODE
			// Omegamoon: Fixed DVI output
			dev_printk(KERN_INFO, hdmi->dev, "Omegamoon: Force DVI output\n");
			hdmi->edid.sink_hdmi = OUTPUT_DVI;
#endif			
			// Omegamoon: Apart from this fixed output, see rk30_hdmi.h for default resolution
		}
	}
	// <<< Omegamoon: HDMI Fix
#else // AUTO_VIDEO_MODE_HANDLING
	if(hotplug != hdmi->hotplug)
	{
		if(hotplug  == HDMI_HPD_ACTIVED){
			if(hdmi->insert)
				hdmi->insert();
			hdmi->state = READ_PARSE_EDID;
		}
		else if(hdmi->hotplug == HDMI_HPD_ACTIVED) {
			hdmi_sys_remove();
			hdmi->hotplug = hotplug;
			if(hotplug == HDMI_HPD_REMOVED)
				hdmi_sys_sleep();
			else {
				hdmi->state = WAIT_HOTPLUG;
				hdmi->remove();
			}
			if(hdmi->wait == 1) {
				complete(&hdmi->complete);
				hdmi->wait = 0;	
			}
			mutex_unlock(&work_mutex);
			return;
		}
		else if(hotplug == HDMI_HPD_REMOVED) {
			hdmi->state = HDMI_SLEEP;
			hdmi->remove();
		}
		hdmi->hotplug  = hotplug;
	}
	else if(hotplug == HDMI_HPD_REMOVED)
		hdmi_sys_sleep();
#endif		
	
	do {
		hdmi_sys_show_state(hdmi->state);
		state_last = hdmi->state;
		switch(hdmi->state)
		{
			case READ_PARSE_EDID:
				rc = hdmi_sys_parse_edid(hdmi);
				if(rc == HDMI_ERROR_SUCESS)
				{
					hdmi->state = SYSTEM_CONFIG;	
					kobject_uevent_env(&hdmi->dev->kobj, KOBJ_ADD, envp);
					hdmi_dbg(hdmi->dev,"[%s],base_audio_support =%d,sink_hdmi = %d\n",hdmi->edid.base_audio_support,hdmi->edid.sink_hdmi );
					#ifdef CONFIG_SWITCH
					if(hdmi->edid.base_audio_support == 1 &&  hdmi->edid.sink_hdmi == 1)
						switch_set_state(&(hdmi->switch_hdmi), 1);
					#endif
					#ifdef CONFIG_RK_HDMI_CTL_CODEC
					#ifdef CONFIG_MACH_RK_FAC
						#if defined(CONFIG_SND_RK29_SOC_ES8323)
							es8323_codec_set_spk(0);
						#endif
						#if defined (CONFIG_SND_RK29_SOC_RT5616)
							rt5616_codec_set_spk(0);
						#endif		
						#if defined (CONFIG_SND_RK_SOC_RK616)
							rk616_codec_set_spk(0);
						#endif	
					#else
						codec_set_spk(0);
					#endif
					#endif
				}
				break;
			case SYSTEM_CONFIG:
                                #ifdef CONFIG_HDMI_RK616
                                hdmi->remove();
                                #endif
				if(hdmi->autoconfig) {
					hdmi->vic = hdmi_find_best_mode(hdmi, 0);
				} else {
					// Omegamoon: autoconfig is disabled, so set a fixed resolution
					hdmi->vic = HDMI_VIDEO_DEFAULT_MODE;
					dev_printk(KERN_INFO, hdmi->dev, "Omegamoon: Forced resolution to %s\n", hdmi_vic_to_videomode(hdmi->vic)->name);
				}
				rc = hdmi_switch_fb(hdmi, hdmi->vic);
				if(rc == HDMI_ERROR_SUCESS)
					hdmi->state = CONFIG_VIDEO;
				break;
			case CONFIG_VIDEO:
				hdmi->display = HDMI_DISABLE;
				video.vic = hdmi->vic;
				video.input_mode = VIDEO_INPUT_RGB_YCBCR_444;
				video.input_color = VIDEO_INPUT_COLOR_RGB;//VIDEO_INPUT_COLOR_YCBCR
				video.output_mode = hdmi->edid.sink_hdmi;
				
				if(hdmi->edid.ycbcr444)
					video.output_color = VIDEO_OUTPUT_YCBCR444;
				else if(hdmi->edid.ycbcr422)
					video.output_color = VIDEO_OUTPUT_YCBCR422;
				else
					video.output_color = VIDEO_OUTPUT_RGB444;
				// For DVI, output RGB
				if(hdmi->edid.sink_hdmi == 0)
					video.output_color = VIDEO_OUTPUT_RGB444;
				
				rc = hdmi->config_video(&video);
				if(rc == HDMI_ERROR_SUCESS)
				{
					if(hdmi->edid.sink_hdmi)
						hdmi->state = CONFIG_AUDIO;
					else
						hdmi->state = PLAY_BACK;
				}
				break;
			case CONFIG_AUDIO:
				rc = hdmi->config_audio(&(hdmi->audio));
							
				if(rc == HDMI_ERROR_SUCESS)
					hdmi->state = PLAY_BACK;
				break;
			case PLAY_BACK:
				if(hdmi->display != HDMI_ENABLE) {
					hdmi->control_output(HDMI_ENABLE);
					hdmi->display = HDMI_ENABLE;
					if(hdmi->hdcp_cb) {
						hdmi->hdcp_cb();
					}
				}
				
				if(hdmi->wait == 1) {	
					complete(&hdmi->complete);
					hdmi->wait = 0;						
				}
				break;
			default:
				break;
		}
		if(rc != HDMI_ERROR_SUCESS)
		{
			trytimes++;
			msleep(10);
		}
		if(hdmi->state != state_last) 
			trytimes = 0;
	
	}while((hdmi->state != state_last || (rc != HDMI_ERROR_SUCESS) ) && trytimes < HDMI_MAX_TRY_TIMES);
	
	hdmi_dbg(hdmi->dev, "[%s] done\n", __FUNCTION__);
	mutex_unlock(&work_mutex);
}