Exemplo n.º 1
0
int rk610_hdmi_sys_read_edid(int block, unsigned char *buff)
{
	char value;
	int count, rc = HDMI_ERROR_EDID;
	char hdmi_status = 0;
	
	// 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);
	
	// 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)
	{	
#ifdef HDMI_USE_IRQ
	    value = atomic_read(&edid_ready);
#else 
	    msleep(10);
	    rk610_hdmi_i2c_read_reg(INTERRUPT_STATUS1, &hdmi_status);
	    value = (hdmi_status & m_INT_EDID_READY);
#endif
	    if(value)
	    {
		for(value = 0; value < 128; value++)
		    rk610_hdmi_i2c_read_reg(EDID_FIFO_ADDR, buff + value);
		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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
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));		
	}
}
Exemplo n.º 6
0
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);
	}
}
Exemplo n.º 7
0
int rk610_hdmi_sys_config_video(struct hdmi *hdmi, int vic, int input_color, int output_color)
{
	char value;
	struct fb_videomode *mode;
	
	// Diable HDCP
	if(rk610_hdmi->hdcp_power_off_cb)
		rk610_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) | (output_color & 0xFF));

	// Set HDMI Mode
	HDMIWrReg(HDCP_CTRL, v_HDMI_DVI(hdmi->edid.is_hdmi));
	
	// Enable or disalbe color space convert
	if(input_color != output_color) {
		value = v_SOF_DISABLE | v_CSC_ENABLE;
	}
	else
		value = v_SOF_DISABLE;
	HDMIWrReg(VIDEO_CONTRL3, value);
	
	#if 1
	HDMIWrReg(VIDEO_TIMING_CTL, 0);
	mode = (struct fb_videomode *)ext_hdmi_vic_to_videomode(vic);
	if(mode == NULL)
	{
		hdmi_dbg(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vic);
		return -ENOENT;
	}
	rk610_hdmi->frequency = mode->pixclock;
	
	#else
	// Set ext video
	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);
	
	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(hdmi->edid.is_hdmi) {
		rk610_hdmi_config_avi(vic, output_color);
		hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__);
	}
	else {
		hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__);	
	}

	// Power on TMDS
	HDMIWrReg(PHY_PRE_EMPHASIS, v_PRE_EMPHASIS(0) | v_TMDS_PWRDOWN(0)); // TMDS power on
	
	// Enable TMDS
	value = 0;
	rk610_hdmi_i2c_read_reg(PHY_DRIVER, &value);
	value |= v_TX_ENABLE(1);
	HDMIWrReg(PHY_DRIVER, value);
	
	return 0;
}