示例#1
0
int rk610_hdmi_sys_init(struct hdmi *hdmi)
{
	// System power power off
	HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH);
	
	//Synchronize analog module.
//	HDMIWrReg(PHY_SYNC, 0x00);
//	HDMIWrReg(PHY_SYNC, 0x01);
	
	// set hdmi phy parameters
	// driver mode
	HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0));
//	HDMIWrReg(PHY_PRE_EMPHASIS, 0x04);
	HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1));	//Driver power down	
	// pll mode
	HDMIWrReg(0xe8, 0x10);
	HDMIWrReg(0xe6, 0x2c);
#if 0
	HDMIWrReg(PHY_PLL_CTRL, 0);
#else
	HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1));
	HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1));
	HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN);
#endif

	// Enable Hotplug interrupt
	HDMIWrReg(INTERRUPT_MASK1, m_INT_HOTPLUG);
	return HDMI_ERROR_SUCESS;
}
示例#2
0
static void rk2928_hdmi_config_avi(unsigned char vic, unsigned char output_color)
{
	int i;
	char info[SIZE_AVI_INFOFRAME];
	
	memset(info, 0, SIZE_AVI_INFOFRAME);
	HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
	info[0] = 0x82;
	info[1] = 0x02;
	info[2] = 0x0D;	
	info[3] = info[0] + info[1] + info[2];
	info[4] = (AVI_COLOR_MODE_RGB << 5);
	info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME;
	info[6] = 0;
	info[7] = vic;
	info[8] = 0;

	// Calculate AVI InfoFrame ChecKsum
	for (i = 4; i < SIZE_AVI_INFOFRAME; i++)
	{
    	info[3] += info[i];
	}
	info[3] = 0x100 - info[3];
	
	for(i = 0; i < SIZE_AVI_INFOFRAME; i++)
		HDMIWrReg(CONTROL_PACKET_ADDR + i, info[i]);
}
示例#3
0
static void rk30_hdmi_config_avi(unsigned char vic, unsigned char output_color)
{
	int i, clolorimetry, aspect_ratio;
	char info[SIZE_AVI_INFOFRAME];
	
	memset(info, 0, SIZE_AVI_INFOFRAME);
	HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
	info[0] = 0x82;
	info[1] = 0x02;
	info[2] = 0x0D;	
	info[3] = info[0] + info[1] + info[2];

	if(output_color == VIDEO_OUTPUT_YCBCR444)	
		info[4] = (AVI_COLOR_MODE_YCBCR444 << 5);
	else if(output_color == VIDEO_OUTPUT_YCBCR422)
		info[4] = (AVI_COLOR_MODE_YCBCR422 << 5);
	else
		info[4] = (AVI_COLOR_MODE_RGB << 5);
	info[4] |= (1 << 4);	//Enable active format data bits is present in info[2]
	
	switch(vic)
	{
		case HDMI_720x480i_60Hz_4_3:
		case HDMI_720x576i_50Hz_4_3:
		case HDMI_720x480p_60Hz_4_3:
		case HDMI_720x576p_50Hz_4_3:				
			aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3;
			clolorimetry = AVI_COLORIMETRY_SMPTE_170M;
			break;
		case HDMI_720x480i_60Hz_16_9:
		case HDMI_720x576i_50Hz_16_9:
		case HDMI_720x480p_60Hz_16_9:
		case HDMI_720x576p_50Hz_16_9:
			aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
			clolorimetry = AVI_COLORIMETRY_SMPTE_170M;
			break;
		default:
			aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
			clolorimetry = AVI_COLORIMETRY_ITU709;
	}

	if(output_color == VIDEO_OUTPUT_RGB444)
		clolorimetry = AVI_COLORIMETRY_NO_DATA;
	
	info[5] = (clolorimetry << 6) | (aspect_ratio << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME;
	info[6] = 0;
	info[7] = vic;
	info[8] = 0;

	// Calculate AVI InfoFrame ChecKsum
	for (i = 4; i < SIZE_AVI_INFOFRAME; i++)
	{
    	info[3] += info[i];
	}
	info[3] = 0x100 - info[3];
	
	for(i = 0; i < SIZE_AVI_INFOFRAME; i++)
		HDMIWrReg(CONTROL_PACKET_HB0 + i*4, info[i]);
}
示例#4
0
static inline void rk30_hdmi_config_phy_reg(int reg, int value)
{
	HDMIWrReg(reg, value);
	HDMIWrReg(SYS_CTRL, 0x2C);
	delay100us();
	HDMIWrReg(SYS_CTRL, 0x20);
	msleep(1);
}
示例#5
0
int rk610_hdmi_sys_insert(struct hdmi *hdmi)
{
	//Bring up analog module.
	HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_UP);	//BG power on 
	HDMIWrReg(PHY_PLL_LDO_PWR, 0x00);		//PLL power on
	msleep(1);
	HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(0));	//Analog reset
	return 0;
}
int rk610_hdmi_sys_insert(void)
{
	hdmi_dbg(hdmi->dev, "%s \n", __FUNCTION__);
	//Bring up analog module.
	HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_UP);	//BG power on 
	HDMIWrReg(PHY_PLL_LDO_PWR, 0x00);		//PLL power on
	msleep(1);
	HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(0));	//Analog reset
	return 0;
}
示例#7
0
int rk610_hdmi_sys_remove(struct hdmi *hdmi)
{
	if(rk610_hdmi->hdcp_power_off_cb)
		rk610_hdmi->hdcp_power_off_cb();
	HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0));
	HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1));	//Driver power down	
	HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1));
	HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1));
	HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN);
	return 0;
}
int rk610_hdmi_sys_remove(void)
{
	hdmi_dbg(hdmi->dev, "%s \n", __FUNCTION__);
	if(hdmi->hdcp_power_off_cb)
		hdmi->hdcp_power_off_cb();
	HDMIWrReg(PHY_DRIVER, v_MAIN_DRIVER(8)| v_PRE_DRIVER(0) | v_TX_ENABLE(0));
	HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(1));	//Driver power down	
	HDMIWrReg(PHY_PLL_CTRL, v_PLL_DISABLE(1) | v_PLL_RESET(1) | v_TMDS_RESET(1));
	HDMIWrReg(PHY_PLL_LDO_PWR, v_LDO_PWR_DOWN(1));
	HDMIWrReg(PHY_BANDGAP_PWR, v_BANDGAP_PWR_DOWN);
	return 0;
}
示例#9
0
irqreturn_t hdmi_irq(int irq, void *priv)
{		
	char interrupt1 = 0, interrupt2 = 0, interrupt3 = 0, interrupt4 = 0;
	
	if(hdmi->pwr_mode == PWR_SAVE_MODE_A)
	{
		HDMIWrReg(SYS_CTRL, 0x20);
		hdmi->pwr_mode = PWR_SAVE_MODE_B;
		
		hdmi_dbg(hdmi->dev, "hdmi irq wake up\n");
		// HDMI was inserted when system is sleeping, irq was triggered only once
		// when wake up. So we need to check hotplug status.
		if(HDMIRdReg(HPD_MENS_STA) & (m_HOTPLUG_STATUS | m_MSEN_STATUS)) {			
			queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));
		}
	}
	else
	{
		interrupt1 = HDMIRdReg(INTR_STATUS1);
		interrupt2 = HDMIRdReg(INTR_STATUS2);
		interrupt3 = HDMIRdReg(INTR_STATUS3);
		interrupt4 = HDMIRdReg(INTR_STATUS4);
		HDMIWrReg(INTR_STATUS1, interrupt1);
//		HDMIWrReg(INTR_STATUS2, interrupt2);
//		HDMIWrReg(INTR_STATUS3, interrupt3);
//		HDMIWrReg(INTR_STATUS4, interrupt4);
#if 0
		hdmi_dbg(hdmi->dev, "[%s] interrupt1 %02x interrupt2 %02x interrupt3 %02x interrupt4 %02x\n",\
			 __FUNCTION__, interrupt1, interrupt2, interrupt3, interrupt4);
#endif
		if(interrupt1 & (m_INT_HOTPLUG | m_INT_MSENS))
		{
			if(hdmi->state == HDMI_SLEEP)
				hdmi->state = WAIT_HOTPLUG;
			interrupt1 &= ~(m_INT_HOTPLUG | m_INT_MSENS);
			queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));	
		}
		else if(interrupt1 & (m_INT_EDID_READY | m_INT_EDID_ERR)) {
			spin_lock(&hdmi->irq_lock);
			edid_result = interrupt1;
			spin_unlock(&hdmi->irq_lock);
		}
//		else if(hdmi->state == HDMI_SLEEP) {
//			RK30DBG( "hdmi return to sleep mode\n");
//			HDMIWrReg(SYS_CTRL, 0x10);
//			rk30_hdmi->pwr_mode = PWR_SAVE_MODE_A;
//		}
		if(hdmi->hdcp_irq_cb)
			hdmi->hdcp_irq_cb(interrupt2);
	}
	return IRQ_HANDLED;
}
示例#10
0
irqreturn_t hdmi_irq(int irq, void *priv)
{		
	char interrupt1 = 0;
	unsigned long flags;
	spin_lock_irqsave(&hdmi->irq_lock,flags);
	interrupt1 = HDMIRdReg(INTERRUPT_STATUS1);
	HDMIWrReg(INTERRUPT_STATUS1, interrupt1);
#if 1
		hdmi_dbg(hdmi->dev, "[%s] interrupt1 %02x  \n",\
			 __FUNCTION__, interrupt1);
#endif
	if(interrupt1 & m_INT_HOTPLUG ){
		if(hdmi->state == HDMI_SLEEP)
			hdmi->state = WAIT_HOTPLUG;
		if(hdmi->pwr_mode == LOWER_PWR)
			rk2928_hdmi_set_pwr_mode(NORMAL);
		queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));	
	}else if(interrupt1 & m_INT_EDID_READY) {
		edid_result = interrupt1;
	}else if(hdmi->state == HDMI_SLEEP) {
		hdmi_dbg(hdmi->dev, "hdmi return to sleep mode\n");
		rk2928_hdmi_set_pwr_mode(LOWER_PWR);
	}
#if 0
	if(hdmi->hdcp_irq_cb)
		hdmi->hdcp_irq_cb(interrupt2);
#endif
	spin_unlock_irqrestore(&hdmi->irq_lock,flags);
	return IRQ_HANDLED;
}
示例#11
0
static void rk30_hdmi_config_csc(struct hdmi_video_para *vpara)
{
	int i, mode;
	char *coeff = NULL;
		
	if( ((vpara->input_color == VIDEO_INPUT_COLOR_RGB) && (vpara->output_color == VIDEO_OUTPUT_RGB444)) ||
		((vpara->input_color == VIDEO_INPUT_COLOR_YCBCR) && (vpara->output_color != VIDEO_OUTPUT_RGB444) ))
	{
		return;
	}
	switch(vpara->vic)
	{
		case HDMI_720x480i_60Hz_4_3:
		case HDMI_720x576i_50Hz_4_3:
		case HDMI_720x480p_60Hz_4_3:
		case HDMI_720x576p_50Hz_4_3:
		case HDMI_720x480i_60Hz_16_9:
		case HDMI_720x576i_50Hz_16_9:
		case HDMI_720x480p_60Hz_16_9:
		case HDMI_720x576p_50Hz_16_9:
			if(vpara->input_color == VIDEO_INPUT_COLOR_RGB)
				mode = CSC_RGB_0_255_TO_ITU601_16_235;
			else if(vpara->output_mode == OUTPUT_HDMI)
				mode = CSC_ITU601_16_235_TO_RGB_16_235;
			else
				mode = CSC_ITU601_16_235_TO_RGB_0_255;
			break;
		default:
			if(vpara->input_color == VIDEO_INPUT_COLOR_RGB)
				mode = CSC_RGB_0_255_TO_ITU709_16_235;
			else if(vpara->output_mode == OUTPUT_HDMI)
				mode = CSC_ITU709_16_235_TO_RGB_16_235;
			else
				mode = CSC_ITU709_16_235_TO_RGB_0_255;
			break;
	}
	
	coeff = coeff_csc[mode];
	
	HDMIWrReg(CSC_CONFIG1, v_CSC_MODE(CSC_MODE_MANUAL) | v_CSC_BRSWAP_DIABLE(1));
	
	for(i = 0; i < 24; i++)
		HDMIWrReg(CSC_PARA_C0_H + i*4, coeff[i]);
		
	HDMIWrReg(AV_CTRL2, v_CSC_ENABLE(1));
}
示例#12
0
int rk30_hdmi_removed(void)
{
	if(hdmi->pwr_mode == PWR_SAVE_MODE_E)
	{
		HDMIWrReg(VIDEO_SETTING2, 0x00);
		rk30_hdmi_audio_reset();
		rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D);
	}
	if(hdmi->pwr_mode == PWR_SAVE_MODE_D)
		rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B);
	if(hdmi->pwr_mode == PWR_SAVE_MODE_B && hdmi->state == HDMI_SLEEP)
	{
		HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS);
		HDMIWrReg(INTR_MASK2, 0);
		HDMIWrReg(INTR_MASK3, 0);
		HDMIWrReg(INTR_MASK4, 0);
		// Disable color space convertion
		HDMIWrReg(AV_CTRL2, v_CSC_ENABLE(0));
		HDMIWrReg(CSC_CONFIG1, v_CSC_MODE(CSC_MODE_AUTO) | v_CSC_BRSWAP_DIABLE(1));
		if(hdmi->hdcp_power_off_cb)
			hdmi->hdcp_power_off_cb();
		rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_A);
	}
	dev_printk(KERN_INFO , hdmi->dev , "Removed.\n");
	return HDMI_ERROR_SUCESS;
}
示例#13
0
void rk610_hdmi_interrupt()
{
	char interrupt = 0;
	
	if(rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &interrupt))
		return;
		
	HDMIWrReg(INTERRUPT_STATUS1, interrupt);
	hdmi_dbg(rk610_hdmi->hdmi->dev, "%s interrupt %02x\n", __FUNCTION__, interrupt);
	
	if(interrupt)
		HDMIWrReg(INTERRUPT_STATUS1, interrupt);
	
	if(interrupt & m_INT_HOTPLUG)
		hdmi_changed(rk610_hdmi->hdmi, 0);
		
	if(interrupt & m_INT_EDID_READY)
		edid_ready = 1;
}
示例#14
0
void rk30_hdmi_control_output(int enable)
{
	hdmi_dbg(hdmi->dev, "[%s] %d\n", __FUNCTION__, enable);
	if(enable == 0) {
		HDMIWrReg(VIDEO_SETTING2, 0x03);
	}
	else {
		if(hdmi->pwr_mode == PWR_SAVE_MODE_B) {
			//  Switch to power save mode_d
			rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_D);
		}
		if(hdmi->pwr_mode == PWR_SAVE_MODE_D) {
			//  Switch to power save mode_e
			rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_E);
		}
		HDMIWrReg(VIDEO_SETTING2, 0x00);
		rk30_hdmi_audio_reset();
	}
}
void rk610_hdmi_sys_enalbe_output(int enable)
{
	char mutestatus = 0;
	
	if(enable) {
		rk610_hdmi_i2c_read_reg(AV_MUTE, &mutestatus);
		if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
			HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
			HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH);
			HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_OFF | v_INT_POL_HIGH);
			HDMIWrReg(SYS_CTRL, v_REG_CLK_SOURCE_IIS | v_PWR_ON | v_INT_POL_HIGH);
			if(hdmi->hdcp_cb)
				hdmi->hdcp_cb();
		}
	}
	else {
		HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));		
	}
}
int rk30_hdmi_initial(void)
{
	int rc = HDMI_ERROR_SUCESS;
	// internal hclk = hdmi_hclk/20
	HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV);
	
	if(hdmi->hdcp_power_on_cb)
		rc = hdmi->hdcp_power_on_cb();

	return rc;
}
示例#17
0
static void rk30_hdmi_config_phy(unsigned char vic)
{
	HDMIWrReg(DEEP_COLOR_MODE, 0x22);	// tmds frequency same as input dlck
	rk30_hdmi_set_pwr_mode(PWR_SAVE_MODE_B);
	switch(vic)
	{
		case HDMI_1920x1080p_60Hz:
		case HDMI_1920x1080p_50Hz:
			rk30_hdmi_config_phy_reg(0x158, 0x0E);
			rk30_hdmi_config_phy_reg(0x15c, 0x00);
			rk30_hdmi_config_phy_reg(0x160, 0x60);
			rk30_hdmi_config_phy_reg(0x164, 0x00);
			rk30_hdmi_config_phy_reg(0x168, 0xDA);
			rk30_hdmi_config_phy_reg(0x16c, 0xA1);
			rk30_hdmi_config_phy_reg(0x170, 0x0e);
			rk30_hdmi_config_phy_reg(0x174, 0x22);
			rk30_hdmi_config_phy_reg(0x178, 0x00);
			break;
			
		case HDMI_1920x1080i_60Hz:
		case HDMI_1920x1080i_50Hz:
		case HDMI_1280x720p_60Hz:
		case HDMI_1280x720p_50Hz:
			rk30_hdmi_config_phy_reg(0x158, 0x06);
			rk30_hdmi_config_phy_reg(0x15c, 0x00);
			rk30_hdmi_config_phy_reg(0x160, 0x60);
			rk30_hdmi_config_phy_reg(0x164, 0x00);
			rk30_hdmi_config_phy_reg(0x168, 0xCA);
			rk30_hdmi_config_phy_reg(0x16c, 0xA3);
			rk30_hdmi_config_phy_reg(0x170, 0x0e);
			rk30_hdmi_config_phy_reg(0x174, 0x20);
			rk30_hdmi_config_phy_reg(0x178, 0x00);
			break;
			
		case HDMI_720x576p_50Hz_4_3:
		case HDMI_720x576p_50Hz_16_9:
		case HDMI_720x480p_60Hz_4_3:
		case HDMI_720x480p_60Hz_16_9:
			rk30_hdmi_config_phy_reg(0x158, 0x02);
			rk30_hdmi_config_phy_reg(0x15c, 0x00);
			rk30_hdmi_config_phy_reg(0x160, 0x60);
			rk30_hdmi_config_phy_reg(0x164, 0x00);
			rk30_hdmi_config_phy_reg(0x168, 0xC2);
			rk30_hdmi_config_phy_reg(0x16c, 0xA2);
			rk30_hdmi_config_phy_reg(0x170, 0x0e);
			rk30_hdmi_config_phy_reg(0x174, 0x20);
			rk30_hdmi_config_phy_reg(0x178, 0x00);
			break;
		default:
			hdmi_err(hdmi->dev, "not support such vic %d\n", vic);
			break;
	}
}
示例#18
0
static void rk30_hdmi_config_aai(void)
{
	int i;
	char info[SIZE_AUDIO_INFOFRAME];
	
	memset(info, 0, SIZE_AUDIO_INFOFRAME);
	
	info[0] = 0x84;
	info[1] = 0x01;
	info[2] = 0x0A;
	
	info[3] = info[0] + info[1] + info[2];	
	for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++)
    	info[3] += info[i];
    	
	info[3] = 0x100 - info[3];
	
	HDMIWrReg(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI);
	for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++)
		HDMIWrReg(CONTROL_PACKET_HB0 + i*4, info[i]);
}
示例#19
0
static void rk30_hdmi_set_pwr_mode(int mode)
{
	if(hdmi->pwr_mode == mode)
		return;
	hdmi_dbg(hdmi->dev, "[%s] mode %d\n", __FUNCTION__, mode);	
	switch(mode)
	{
		case PWR_SAVE_MODE_A:
			HDMIWrReg(SYS_CTRL, 0x10);
			break;
		case PWR_SAVE_MODE_B:
			HDMIWrReg(SYS_CTRL, 0x20);
			break;
		case PWR_SAVE_MODE_D:
			// reset PLL A&B
			HDMIWrReg(SYS_CTRL, 0x4C);
			delay100us();
			// release PLL A reset
			HDMIWrReg(SYS_CTRL, 0x48);
			delay100us();
			// release PLL B reset
			HDMIWrReg(SYS_CTRL, 0x40);
			break;
		case PWR_SAVE_MODE_E:
			HDMIWrReg(SYS_CTRL, 0x80);
			break;
	}
	hdmi->pwr_mode = mode;
	if(mode != PWR_SAVE_MODE_A)
		msleep(10);
	hdmi_dbg(hdmi->dev, "[%s] curmode %02x\n", __FUNCTION__, HDMIRdReg(SYS_CTRL));
}
void rk610_hdmi_interrupt()
{
	char interrupt = 0;
	
	if(rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &interrupt))
		return;
		
	HDMIWrReg(INTERRUPT_STATUS1, interrupt);
	
	if(interrupt)
		HDMIWrReg(INTERRUPT_STATUS1, interrupt);
	
	if(interrupt & m_INT_HOTPLUG) {
		hdmi_dbg(hdmi->dev, "%s interrupt %02x\n", __FUNCTION__, interrupt);
		if(hdmi->state == HDMI_SLEEP)
			hdmi->state = WAIT_HOTPLUG;
		queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));	
	}
	else if(interrupt & m_INT_EDID_READY) {
		atomic_set(&edid_ready, 1);
	}
}
示例#21
0
void rk2928_hdmi_control_output(int enable)
{
	char mutestatus = 0;
	
	if(enable) {
		mutestatus = HDMIRdReg(AV_MUTE);
		if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
			HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
    		rk2928_hdmi_sys_power_up();
    		rk2928_hdmi_sys_power_down();
     		rk2928_hdmi_sys_power_up();
			if(analog_sync){
				HDMIWrReg(0xce, 0x00);
				delay100us();
				HDMIWrReg(0xce, 0x01);
				analog_sync = 0;
			}
		}
	}
	else {
		HDMIWrReg(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
	}
}
示例#22
0
int rk610_hdmi_sys_read_edid(struct hdmi *hdmi, int block, unsigned char *buff)
{
	char value;
	int count, rc = HDMI_ERROR_EDID;
	
	// Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)
	// when reg00 select reg_clk equal to sys_clk which is equal
	// to i2s clk, it gernerally is 11.2896MHz.
	
	count = SYSCLK/(DDC_CLK*4);
	HDMIWrReg(DDC_CLK_L, count & 0xFF);
	HDMIWrReg(DDC_CLK_H, (count >> 8) & 0xFF);
	
	// Enable EDID Interrupt
	edid_ready = 0;
	value = 0;
	rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value);
	value |= m_INT_EDID_READY;
	HDMIWrReg(INTERRUPT_MASK1, value);
	
	// Reset FIFO offset
	HDMIWrReg(EDID_FIFO_OFFSET, 0);
	// Set EDID read addr.
	HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80);
	HDMIWrReg(EDID_SEGMENT_POINTER, block/2);
	
	count = 0;
	while(count++ < 100)
	{
		value = 0;
		rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &value);
		#ifdef HDMI_USE_IRQ
		value = edid_ready;
		#else
		HDMIWrReg(INTERRUPT_STATUS1, value);
		#endif
		if(value | m_INT_EDID_READY)
		{
			for(count = 0; count < 128; count++)
				rk610_hdmi_i2c_read_reg(EDID_FIFO_ADDR, buff + count);
			rc = HDMI_ERROR_SUCESS;
			break;
		}		
	}
	// Disable EDID interrupt.
	value = 0;
	rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value);
	value &= ~m_INT_EDID_READY;
	HDMIWrReg(INTERRUPT_MASK1, value);
	return rc;
}
static int CecReadFrame(CEC_FrameData_t *Frame)
{
	int i, length;
	char *data = Frame;
	if(Frame == NULL)
		return -1;
	length = HDMIRdReg(CEC_RX_LENGTH);
	HDMIWrReg(CEC_RX_OFFSET, 0);
	printk("%s length is %d\n", __FUNCTION__, length);
	for(i = 0; i < length; i++) {
		data[i] =  HDMIRdReg(CEC_DATA);
		printk("%02x\n", data[i]);
	}
	return 0;
}
示例#24
0
static inline void hdmi_io_remap(void)
{
	unsigned int value;
	
	// Remap HDMI IO Pin
	rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA);
	rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL);
	rk30_mux_api_set(GPIO0A0_HDMIHOTPLUGIN_NAME, GPIO0A_HDMI_HOT_PLUG_IN);
		
	// Select LCDC0 as video source and enabled.
	value = (HDMI_SOURCE_DEFAULT << 14) | (1 << 30);
	writel(value, GRF_SOC_CON0 + RK30_GRF_BASE);
	
	// internal hclk = hdmi_hclk/20
	HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV);
}
示例#25
0
int rk610_hdmi_sys_detect_hpd(void)
{
	char hdmi_status = 0;

	#ifdef HDMI_USE_IRQ
	rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status);
	HDMIWrReg(INTERRUPT_STATUS1, hdmi_status);
	#endif
	hdmi_status = 0;
	rk610_hdmi_i2c_read_reg(HDMI_STATUS, &hdmi_status);
//	printk("%s value is %02x\n", __FUNCTION__, hdmi_status);	
	if(hdmi_status)
		return HDMI_HPD_ACTIVED;
	else
		return HDMI_HPD_REMOVED;
}
示例#26
0
int rk610_hdmi_sys_detect_hpd(struct hdmi *hdmi, int *hpdstatus)
{
	char hdmi_status = 0;

	#ifdef HDMI_USE_IRQ
	rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status);
	HDMIWrReg(INTERRUPT_STATUS1, hdmi_status);
	#endif
	hdmi_status = 0;
	rk610_hdmi_i2c_read_reg(HDMI_STATUS, &hdmi_status);
//	printk("%s value is %02x\n", __FUNCTION__, hdmi_status);	
	if(hdmi_status)
		*hpdstatus = HDMI_RECEIVER_ACTIVE;
	else
		*hpdstatus = HDMI_RECEIVER_REMOVE;
	return HDMI_ERROR_SUCESS;
}
示例#27
0
int rk610_hdmi_sys_read_edid(int block, unsigned char *buff)
{
	char value;
	int count, rc = HDMI_ERROR_EDID;
	int trytime = 2;
	
	// Config DDC bus clock: ddc_clk = reg_clk/4*(reg 0x4c 0x4b)
	// when reg00 select reg_clk equal to sys_clk which is equal
	// to i2s clk, it gernerally is 11.2896MHz.
	
	count = SYSCLK/(DDC_CLK*4);
	HDMIWrReg(DDC_CLK_L, count & 0xFF);
	HDMIWrReg(DDC_CLK_H, (count >> 8) & 0xFF);
	
	// Enable EDID Interrupt
//	edid_ready = 0;
	atomic_set(&edid_ready, 0);
	value = 0;
	rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value);
	value |= m_INT_EDID_READY;
	HDMIWrReg(INTERRUPT_MASK1, value);
	
	
	while(trytime--) {
		// Reset FIFO offset
		HDMIWrReg(EDID_FIFO_OFFSET, 0);
		// Set EDID read addr.
		HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80);
		HDMIWrReg(EDID_SEGMENT_POINTER, block/2);
		
		count = 0;
		while(count++ < 10)
		{	
			value = atomic_read(&edid_ready);
			if(value)
			{
				for(count = 0; count < 128; count++)
					rk610_hdmi_i2c_read_reg(EDID_FIFO_ADDR, buff + count);
				rc = HDMI_ERROR_SUCESS;
				break;
			}
			msleep(100);
		}
	}
	// Disable EDID interrupt.
	value = 0;
	rk610_hdmi_i2c_read_reg(INTERRUPT_MASK1, &value);
	value &= ~m_INT_EDID_READY;
	HDMIWrReg(INTERRUPT_MASK1, value);
	return rc;
}
示例#28
0
static void rk30_hdmi_early_resume(struct early_suspend *h)
{
	struct rk30_hdmi *rk30_hdmi = container_of(h, struct rk30_hdmi, early_suspend);
	struct hdmi *hdmi = rk30_hdmi->hdmi;
	
	RK30DBG("hdmi exit early resume\n");

	rk30_mux_api_set(GPIO0A2_HDMII2CSDA_NAME, GPIO0A_HDMI_I2C_SDA);
	rk30_mux_api_set(GPIO0A1_HDMII2CSCL_NAME, GPIO0A_HDMI_I2C_SCL);
	
	clk_enable(rk30_hdmi->hclk);
	// internal hclk = hdmi_hclk/20
	HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV);
	if(hdmi->ops->hdcp_power_on_cb)
		hdmi->ops->hdcp_power_on_cb();		
	hdmi_submit_work(hdmi, HDMI_RESUME_CTL, 0, NULL);
	
	return;
}
示例#29
0
int rk30_hdmi_initial(void)
{
	int rc = HDMI_ERROR_SUCESS;

	hdmi->pwr_mode = PWR_SAVE_MODE_A;
	hdmi->remove = rk30_hdmi_removed ;
	hdmi->control_output = rk30_hdmi_control_output;
	hdmi->config_video = rk30_hdmi_config_video;
	hdmi->config_audio = rk30_hdmi_config_audio;
	hdmi->detect_hotplug = rk30_hdmi_detect_hotplug;
	hdmi->read_edid = rk30_hdmi_read_edid;
	// internal hclk = hdmi_hclk/20
	HDMIWrReg(0x800, HDMI_INTERANL_CLK_DIV);
	
	if(hdmi->hdcp_power_on_cb)
		rc = hdmi->hdcp_power_on_cb();

	return rc;
}
static int CecSendFrame(CEC_FrameData_t *Frame)
{
	int i;
	
	CECDBG("TX srcDestAddr %02x opcode %02x ",
		 Frame->srcDestAddr, Frame->opcode);
	if(Frame->argCount) {
		CECDBG("args:");
		for(i = 0; i < Frame->argCount; i++) {
			CECDBG("%02x ", Frame->args[i]);
		}
	}
	CECDBG("\n");
	
	HDMIWrReg(CEC_TX_OFFSET, 0);
	HDMIWrReg(CEC_DATA, Frame->srcDestAddr);
	HDMIWrReg(CEC_DATA, Frame->opcode);
	for(i = 0; i < Frame->argCount; i++)
		HDMIWrReg(CEC_DATA, Frame->args[i]);
	HDMIWrReg(CEC_TX_LENGTH, Frame->argCount + 2);
	
	//Wait for bus free
	Cec.busfree = 1;
	HDMIWrReg(CEC_CTRL, m_BUSFREETIME_ENABLE);
	if(wait_event_interruptible_timeout(Cec.wait, Cec.busfree == 0, msecs_to_jiffies(17))) {
		return -1;
	}
	//Start TX
	Cec.tx_done = 0;
	HDMIWrReg(CEC_CTRL, m_BUSFREETIME_ENABLE|m_START_TX);
	if(wait_event_interruptible_timeout(Cec.wait, Cec.tx_done != 0, msecs_to_jiffies(100)))
	HDMIWrReg(CEC_CTRL, 0);
	if(Cec.tx_done == 1) {
		return 0;
	}
	else
		return -1;
}