static int hdmi_process_command(struct hdmi *hdmi)
{
	int change, state = hdmi->state;

	change = hdmi->command;
	if (change != HDMI_CONFIG_NONE) {
		hdmi->command = HDMI_CONFIG_NONE;
		switch (change) {
		case HDMI_CONFIG_ENABLE:
			/* disable HDMI */
			mutex_lock(&hdmi->enable_mutex);
			if (!hdmi->enable || hdmi->suspend) {
				if (hdmi->hotplug != HDMI_HPD_REMOVED) {
					hdmi->hotplug = HDMI_HPD_REMOVED;
					hdmi->control_output(hdmi, HDMI_DISABLE);
					hdmi_sys_remove(hdmi);
				}
				hdmi->state = HDMI_SLEEP;
				hdmi->remove(hdmi);
				state = HDMI_SLEEP;
			}
			mutex_unlock(&hdmi->enable_mutex);
			if (hdmi->wait == 1) {
				complete(&hdmi->complete);
				hdmi->wait = 0;
			}
			break;
		case HDMI_CONFIG_COLOR:
			if (state > CONFIG_VIDEO)
				state = CONFIG_VIDEO;
			break;
		case HDMI_CONFIG_HDCP:
			break;
		case HDMI_CONFIG_DISPLAY:
			break;
		case HDMI_CONFIG_AUDIO:
			if (state > CONFIG_AUDIO)
				state = CONFIG_AUDIO;
			break;
		case HDMI_CONFIG_VIDEO:
		default:
			if (state > SYSTEM_CONFIG) {
				state = SYSTEM_CONFIG;
				hdmi->control_output(hdmi, HDMI_DISABLE);
				msleep(2000);
			} else {
				if (hdmi->wait == 1) {
					complete(&hdmi->complete);
					hdmi->wait = 0;
				}
			}
			break;
		}
	} else if (state == HDMI_SLEEP) {
		state = WAIT_HOTPLUG;
	}
	return state;
}
Ejemplo n.º 2
0
static int hdmi_process_command(void)
{
	int change, state = hdmi->state;
	
	change = hdmi->command;
	if(change != HDMI_CONFIG_NONE)	
	{		
		hdmi->command = HDMI_CONFIG_NONE;
		switch(change)
		{	
			case HDMI_CONFIG_ENABLE:
				/* disable HDMI */
				mutex_lock(&hdmi->enable_mutex);
				if(!hdmi->enable || hdmi->suspend)
				{
					if(hdmi->hotplug == HDMI_HPD_ACTIVED)
						hdmi_sys_remove();
					hdmi->state = HDMI_SLEEP;
					hdmi->hotplug = HDMI_HPD_REMOVED;
					rk30_hdmi_removed();
					state = HDMI_SLEEP;
				}
				mutex_unlock(&hdmi->enable_mutex);
				if(hdmi->wait == 1) {
					complete(&hdmi->complete);
					hdmi->wait = 0;	
				}
				break;	
			case HDMI_CONFIG_COLOR:
				if(state > CONFIG_VIDEO)
					state = CONFIG_VIDEO;	
				break;
			case HDMI_CONFIG_HDCP:
				break;
			case HDMI_CONFIG_DISPLAY:
				break;
			case HDMI_CONFIG_AUDIO:
				if(state > CONFIG_AUDIO)
					state = CONFIG_AUDIO;
				break;
			case HDMI_CONFIG_VIDEO:
			default:
				if(state > SYSTEM_CONFIG)
					state = SYSTEM_CONFIG;
				else
				{
					if(hdmi->wait == 1) {
						complete(&hdmi->complete);
						hdmi->wait = 0;	
					}					
				}
				break;
		}
	}
	else if(state == HDMI_SLEEP)
		state = WAIT_HOTPLUG;
	return state;
}
void hdmi_work(struct work_struct *work)
{
	int hotplug, state_last;
	int rc = HDMI_ERROR_SUCESS, trytimes = 0;
	struct hdmi_video_para video;
	struct delayed_work *delay_work =
	    container_of(work, struct delayed_work, work);
	struct hdmi *hdmi = container_of(delay_work, struct hdmi, delay_work);

	mutex_lock(&work_mutex);
	/* Process hdmi command */
	hdmi->state = hdmi_process_command(hdmi);

	if (!hdmi->enable || hdmi->suspend) {
		mutex_unlock(&work_mutex);
		return;
	}
	hotplug = hdmi->detect_hotplug(hdmi);
	hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __func__,
		 hotplug, hdmi->hotplug);

	if (hotplug != hdmi->hotplug) {
		if (hotplug == HDMI_HPD_ACTIVED) {
			if (hdmi->insert)
				hdmi->insert(hdmi);
			hdmi->state = READ_PARSE_EDID;
		} else if (hdmi->hotplug == HDMI_HPD_ACTIVED) {
			hdmi->hotplug = hotplug;
			hdmi_sys_remove(hdmi);
			if (hotplug == HDMI_HPD_REMOVED) {
				hdmi_sys_sleep(hdmi);
			} else {
				hdmi->state = WAIT_HOTPLUG;
				hdmi->remove(hdmi);
			}
			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);
		}
		hdmi->hotplug = hotplug;
	} else if (hotplug == HDMI_HPD_REMOVED) {
		hdmi_sys_sleep(hdmi);
	} else if (hotplug == HDMI_HPD_ACTIVED) {
		if (hdmi->uboot_logo) {
			if (hdmi->insert)
				hdmi->insert(hdmi);
			hdmi->state = READ_PARSE_EDID;
		}
        }

	do {
		hdmi_sys_show_state(hdmi);
		state_last = hdmi->state;
		switch (hdmi->state) {
		case READ_PARSE_EDID:
			rc = hdmi_sys_parse_edid(hdmi);
			if (rc == HDMI_ERROR_SUCESS) {
				if (hdmi->cec_set_device_pa)
					hdmi->cec_set_device_pa(hdmi->edid.cecaddress);
				if (hdmi->cec_enumerate)
					hdmi->cec_enumerate();
				hdmi->state = SYSTEM_CONFIG;
				kobject_uevent_env(&hdmi->ddev->dev->kobj,
						   KOBJ_ADD, envp);
				hdmi_dbg(hdmi->dev,
					 "[%s] base_audio_support =%d,sink_hdmi = %d\n",
					 __func__,
					 hdmi->edid.base_audio_support,
					 hdmi->edid.sink_hdmi);
#ifdef CONFIG_SWITCH
				if ((hdmi->edid.base_audio_support == 1 &&
				     hdmi->edid.sink_hdmi == 1) ||
				     (rk_fb_get_display_policy() ==
				      DISPLAY_POLICY_BOX))
					switch_set_state(&(hdmi->switch_hdmi),
							 1);
#endif
				rockchip_set_system_status(SYS_STATUS_HDMI);
			}

			break;
		case SYSTEM_CONFIG:
			if ((hdmi->remove) && !hdmi->uboot_logo)
				hdmi->remove(hdmi);

			if (hdmi->autoconfig)
				hdmi->vic = hdmi_find_best_mode(hdmi, 0);
			else
				hdmi->vic =
				    hdmi_find_best_mode(hdmi, hdmi->vic);
			rc = hdmi_switch_fb(hdmi, hdmi->vic);
			if (rc == HDMI_ERROR_SUCESS)
				hdmi->state = CONFIG_VIDEO;
			if (hdmi->uboot_logo) {
				hdmi->state = CONFIG_AUDIO;
			}
			break;
		case CONFIG_VIDEO:
			hdmi->display = HDMI_DISABLE;
			hdmi_init_video_para(hdmi, &video);
			rc = hdmi->config_video(hdmi, &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, &(hdmi->audio));

			if (rc == HDMI_ERROR_SUCESS)
				hdmi->state = PLAY_BACK;
			break;
		case PLAY_BACK:
			if (hdmi->display != HDMI_ENABLE) {
				hdmi->control_output(hdmi, 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(20);
		}
		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", __func__);
	mutex_unlock(&work_mutex);
}
Ejemplo n.º 4
0
void hdmi_work(struct work_struct *work)
{
	int hotplug, state_last;
	int rc = HDMI_ERROR_SUCESS, trytimes = 0;
	struct rk30_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 = rk30_hdmi_detect_hotplug();
	hdmi_dbg(hdmi->dev, "[%s] hotplug %02x curvalue %d\n", __FUNCTION__, hotplug, hdmi->hotplug);
	
	if(hotplug != hdmi->hotplug)
	{
		if(hotplug  == HDMI_HPD_ACTIVED){
			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;
				rk30_hdmi_removed();
			}
			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;
			rk30_hdmi_removed();
		}
		hdmi->hotplug  = hotplug;
	}
	else if(hotplug == HDMI_HPD_REMOVED)
		hdmi_sys_sleep();
	
	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;	
					hdmi_sys_send_uevent(KOBJ_ADD);
					#ifdef CONFIG_SWITCH
					switch_set_state(&(hdmi->switch_hdmi), 1);
					#endif
					#ifdef CONFIG_HDMI_RK30_CTL_CODEC
					codec_set_spk(0);
					#endif
				}
				break;
			case SYSTEM_CONFIG:
				if(hdmi->autoconfig)	
					hdmi->vic = hdmi_find_best_mode(hdmi, 0);
				else
					hdmi->vic = hdmi_find_best_mode(hdmi, hdmi->vic);
				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 = rk30_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 = rk30_hdmi_config_audio(&(hdmi->audio));
							
				if(rc == HDMI_ERROR_SUCESS)
					hdmi->state = PLAY_BACK;
				break;
			case PLAY_BACK:
				if(hdmi->display != HDMI_ENABLE) {
					rk30_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);
}
Ejemplo n.º 5
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);
}