コード例 #1
0
ファイル: rk30_hdmi_hw.c プロジェクト: banbandir/q98_source
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;
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: rk30_hdmi_hw.c プロジェクト: banbandir/q98_source
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));
}
コード例 #4
0
ファイル: rk2928_hdmi_hw.c プロジェクト: Galland/rk_kernel
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;
}
コード例 #5
0
ファイル: rk2928_hdmi_hw.c プロジェクト: Galland/rk_kernel
int rk2928_hdmi_detect_hotplug(void)
{
	int value =	HDMIRdReg(HDMI_STATUS);
	
	hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value);
	value &= m_HOTPLUG;
	if(value == m_HOTPLUG)
		return HDMI_HPD_ACTIVED;
	else if(value)
		return HDMI_HPD_INSERT;
	else
		return HDMI_HPD_REMOVED;
}
コード例 #6
0
int rk30_hdmi_detect_hotplug(void)
{
	int value =	HDMIRdReg(HPD_MENS_STA);
	
	hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value);
	value &= m_HOTPLUG_STATUS | m_MSEN_STATUS;
	if(value  == (m_HOTPLUG_STATUS | m_MSEN_STATUS) )
		return HDMI_HPD_ACTIVED;
	else if(value)
		return HDMI_HPD_INSERT;
	else
		return HDMI_HPD_REMOVED;
}
コード例 #7
0
ファイル: rk2928_hdmi_hw.c プロジェクト: Galland/rk_kernel
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));
	}
}
コード例 #8
0
ファイル: rk30_hdcp.c プロジェクト: dream1986/Linux3188
/*-----------------------------------------------------------------------------
 * Function: hdcp_irq_cb
 *-----------------------------------------------------------------------------
 */
static void hdcp_irq_cb(int interrupt)
{
	int value;
	struct rk30_hdmi *rk30_hdmi = hdcp->hdmi->property->priv;
	
	DBG("%s 0x%x", __FUNCTION__, interrupt);
	if(interrupt & m_INT_HDCP_ERR)
	{
		value = HDMIRdReg(HDCP_ERROR);
		HDMIWrReg(HDCP_ERROR, value);
		printk(KERN_INFO "HDCP: Error 0x%02x\n", value);
		
		if( (hdcp->hdcp_state != HDCP_DISABLED) &&
			(hdcp->hdcp_state != HDCP_ENABLE_PENDING) )
		{	
			hdcp_submit_work(HDCP_FAIL_EVENT, 0);
		}
	}
	else if(interrupt & (m_INT_BKSV_RPRDY | m_INT_BKSV_RCRDY))
		hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0);
	else if(interrupt & m_INT_AUTH_DONE)
		hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0);
}
コード例 #9
0
ファイル: rk30_hdmi_hw.c プロジェクト: banbandir/q98_source
int rk30_hdmi_detect_hotplug(void)
{
	int value =	HDMIRdReg(HPD_MENS_STA);
	
	hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value);
	#if 0
	// When HPD and TMDS_CLK was high, HDMI is actived.
	value &= m_HOTPLUG_STATUS | m_MSEN_STATUS;
	if(value  == (m_HOTPLUG_STATUS | m_MSEN_STATUS) )
		return HDMI_HPD_ACTIVED;
	else if(value)
		return HDMI_HPD_INSERT;
	else
		return HDMI_HPD_REMOVED;
	#else
	// When HPD was high, HDMI is actived.
	if(value & m_HOTPLUG_STATUS)
		return HDMI_HPD_ACTIVED;
	else if(value & m_MSEN_STATUS)
		return HDMI_HPD_INSERT;
	else
		return HDMI_HPD_REMOVED;
	#endif
}
コード例 #10
0
ファイル: rk30_hdmi_hw.c プロジェクト: banbandir/q98_source
int rk30_hdmi_read_edid(int block, unsigned char *buff)
{
	int value, ret = -1, ddc_bus_freq = 0;
	char interrupt = 0, trytime = 2;
	unsigned long flags;
	
	hdmi_dbg(hdmi->dev, "[%s] block %d\n", __FUNCTION__, block);
	spin_lock_irqsave(&hdmi->irq_lock, flags);
	edid_result = 0;
	spin_unlock_irqrestore(&hdmi->irq_lock, flags);
	//Before Phy parameter was set, DDC_CLK is equal to PLLA freq which is 30MHz.
	//Set DDC I2C CLK which devided from DDC_CLK to 100KHz.
	ddc_bus_freq = (30000000/HDMI_EDID_DDC_CLK)/4;
	HDMIWrReg(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
	HDMIWrReg(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
	
	// Enable edid interrupt
	HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS | m_INT_EDID_ERR | m_INT_EDID_READY);
	
	while(trytime--) {
		// Config EDID block and segment addr
		HDMIWrReg(EDID_WORD_ADDR, (block%2) * 0x80);
		HDMIWrReg(EDID_SEGMENT_POINTER, block/2);	
	
		value = 100;
		while(value--)
		{
			spin_lock_irqsave(&hdmi->irq_lock, flags);
			interrupt = edid_result;
			edid_result = 0;
			spin_unlock_irqrestore(&hdmi->irq_lock, flags);
			if(interrupt & (m_INT_EDID_ERR | m_INT_EDID_READY))
				break;
			msleep(10);
		}
		hdmi_dbg(hdmi->dev, "[%s] edid read value %d\n", __FUNCTION__, value);
		if(interrupt & m_INT_EDID_READY)
		{
			for(value = 0; value < HDMI_EDID_BLOCK_SIZE; value++) 
				buff[value] = HDMIRdReg(DDC_READ_FIFO_ADDR);
			ret = 0;
			
			hdmi_dbg(hdmi->dev, "[%s] edid read sucess\n", __FUNCTION__);
#ifdef HDMI_DEBUG
			for(value = 0; value < 128; value++) {
				printk("%02x ,", buff[value]);
				if( (value + 1) % 16 == 0)
					printk("\n");
			}
#endif
			break;
		}		
		if(interrupt & m_INT_EDID_ERR)
			hdmi_err(hdmi->dev, "[%s] edid read error\n", __FUNCTION__);
		
		hdmi_dbg(hdmi->dev, "[%s] edid try times %d\n", __FUNCTION__, trytime);
		msleep(100);
	}
	// Disable edid interrupt
	HDMIWrReg(INTR_MASK1, m_INT_HOTPLUG | m_INT_MSENS);
	return ret;
}