Exemple #1
0
static int s5p_hdp_irq_eint(int irq)
{

	HPDIFPRINTK("\n");

	if (hpd_struct.read_gpio()) {
		HPDIFPRINTK("gpio is high\n");
		set_irq_type(hpd_struct.irq_n, IRQ_TYPE_LEVEL_LOW);
		if (atomic_read(&hpd_struct.state) == HPD_HI)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);
	} else {
		HPDIFPRINTK("gpio is low\n");
		set_irq_type(hpd_struct.irq_n, IRQ_TYPE_LEVEL_HIGH);
		if (atomic_read(&hpd_struct.state) == HPD_LO)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
		wake_up_interruptible(&hpd_struct.waitq);
	}
	schedule_work(&hpd_work);

	HPDIFPRINTK("%s\n", atomic_read(&hpd_struct.state) == HPD_HI ?
		"HPD HI" : "HPD LO");

	return IRQ_HANDLED;
}
irqreturn_t s5p_hpd_irq_handler(int irq)
{
	int ret = IRQ_HANDLED;
	unsigned long flags;

	spin_lock_irqsave(&hpd_struct.lock, flags);

	if (gpio_get_value(S5PV210_GPH1(5))) {

		if (irq_event == EVENT_FALLING) {
			mod_timer(&hpd_irq_check_timer, jiffies + HZ/20);
		}
		irq_event = EVENT_RISING;
	} else {
		irq_event =  EVENT_FALLING;
		del_timer(&hpd_irq_check_timer);
	}

	/* check HDMI status */
	if (atomic_read(&hdmi_status)) {
		/* HDMI on */
		ret = irq_hdmi(irq);
		HPDIFPRINTK("HDMI HPD interrupt\n");
	} else {
		/* HDMI off */
		ret = irq_eint(irq);
		HPDIFPRINTK("EINT HPD interrupt\n");
	}

	spin_unlock_irqrestore(&hpd_struct.lock, flags);

	return ret;
}
Exemple #3
0
static long s5p_hpd_ioctl(struct file *file,
			  unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case HPD_GET_STATE:
		{
			unsigned int *status = (unsigned int *)arg;
			*status = atomic_read(&hpd_struct.state);

			if (last_uevent_state == -1)
				last_uevent_state = *status;

			if (last_uevent_state != *status) {
				on_start_process = false;
				on_stop_process = false;
				HPDIFPRINTK("%s() on_start_process, "
					"on_stop_process = false" , __func__);
			}

			HPDIFPRINTK("HPD status is %s\n",
				    (*status) ? "plugged" : "unplugged");
			return 0;
		}
#ifdef	CONFIG_LSI_HDMI_AUDIO_CH_EVENT
	case AUDIO_CH_SET_STATE:
		{
			int supported_ch_num;
			if (copy_from_user(&supported_ch_num,
				(void __user *)arg, sizeof(supported_ch_num))) {
				printk(KERN_ERR	"%s() -copy_from_user error\n",
					__func__);
				return -EFAULT;
			}

			printk(KERN_INFO	"%s() - AUDIO_CH_SET_STATE = 0x%x\n",
				__func__, supported_ch_num);
			hdmi_send_audio_ch_num(supported_ch_num,
				&g_audio_ch_switch);
			return 0;
		}
#endif
	default:
		printk(KERN_ERR "(%d) unknown ioctl, HPD_GET_STATE(%d)\n",
		       (unsigned int)cmd, (unsigned int)HPD_GET_STATE);
		return -EFAULT;
	}

}
Exemple #4
0
int s5p_hpd_set_hdmiint(void)
{
	/* EINT -> HDMI */

	HPDIFPRINTK("\n");
	set_irq_type(hpd_struct.irq_n, IRQ_TYPE_NONE);

	if (last_hpd_state)
		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 0);
	else
		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 0);

	atomic_set(&hdmi_status, HDMI_ON);

	hpd_struct.int_src_hdmi_hpd();

	s5p_hdmi_reg_hpd_gen();

	if (s5p_hdmi_reg_get_hpd_status())
		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 1);
	else
		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 1);

	return 0;
}
Exemple #5
0
static int irq_eint(int irq)
{
	if (gpio_get_value(S5PV210_GPH1(5))) {
		if (g_last_hpd_state == HPD_HI)
			return IRQ_HANDLED;
		atomic_set(&g_hpd_struct.state, HPD_HI);
		atomic_set(&g_poll_state, 1);

		g_last_hpd_state = HPD_HI;
		wake_up_interruptible(&g_hpd_struct.waitq);
	} else {
		if (g_last_hpd_state == HPD_LO)
			return IRQ_HANDLED;
		atomic_set(&g_hpd_struct.state, HPD_LO);
		atomic_set(&g_poll_state, 1);

		g_last_hpd_state = HPD_LO;
		wake_up_interruptible(&g_hpd_struct.waitq);
	}

	schedule_work(&g_hpd_work);

	HPDIFPRINTK("%s\n", atomic_read(&g_hpd_struct.state) == HPD_HI ?
		"HPD HI" : "HPD LO");

	return IRQ_HANDLED;
}
int irq_eint(int irq)
{
	if (gpio_get_value(S5PV210_GPH1(5))) {
		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);
	} else {
		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
		wake_up_interruptible(&hpd_struct.waitq);
	}

	if (atomic_read(&hpd_struct.state))
		set_irq_type(IRQ_EINT13, IRQ_TYPE_EDGE_FALLING);
	else
		set_irq_type(IRQ_EINT13, IRQ_TYPE_EDGE_RISING);

	schedule_work(&hpd_work);

	HPDIFPRINTK("%s\n", atomic_read(&hpd_struct.state) == HPD_HI ?
		"HPD HI" : "HPD LO");

	return IRQ_HANDLED;

}
Exemple #7
0
static int s5p_hpd_ioctl(struct inode *inode, struct file *file,
		         unsigned int cmd, unsigned long arg)
{
	switch (cmd) {
	case HPD_GET_STATE:
		{
		unsigned int *status = (unsigned int *)arg;
#ifdef CONFIG_VIDEO_MHL_V1
		if (!gpio_get_value(GPIO_MHL_SEL))
			*status = HPD_LO;
		else
#endif
			*status = atomic_read(&hpd_struct.state);

		if (last_uevent_state == -1)
			last_uevent_state = *status;

		if (last_uevent_state != *status) {
			on_start_process = false;
			on_stop_process = false;
		}

		HPDIFPRINTK("HPD status is %s\n",
				(*status) ? "plugged" : "unplugged");
		return 0;
		}
	default:
		printk(KERN_ERR "(%d) unknown ioctl, HPD_GET_STATE(%d)\n", (unsigned int)cmd, (unsigned int)HPD_GET_STATE);
		return  -EFAULT;
	}

}
Exemple #8
0
static int s5p_hpd_irq_eint(int irq)
{

	HPDIFPRINTK("\n");

	if (hpd_struct.read_gpio()) {
		HPDIFPRINTK("gpio is high\n");
		irq_set_irq_type(hpd_struct.irq_n, IRQ_TYPE_LEVEL_LOW);
		if (atomic_read(&hpd_struct.state) == HPD_HI)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);
	} else {
		HPDIFPRINTK("gpio is low\n");
		irq_set_irq_type(hpd_struct.irq_n, IRQ_TYPE_LEVEL_HIGH);
		if (atomic_read(&hpd_struct.state) == HPD_LO)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
#ifdef	CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
		if (is_mhl_power_state_on != NULL)
			if (!is_mhl_power_state_on())
				mhl_hpd_handler(false);
#endif

#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
		schedule_delayed_work(&ext_ic_control_dwork ,
				msecs_to_jiffies(1000));
#endif
		wake_up_interruptible(&hpd_struct.waitq);
	}
	schedule_work(&hpd_work);

	HPDIFPRINTK("%s\n", atomic_read(&hpd_struct.state) == HPD_HI ?
		    "HPD HI" : "HPD LO");

	return IRQ_HANDLED;
}
Exemple #9
0
/*
 * HPD interrupt handler
 *
 * Handles interrupt requests from HPD hardware.
 * Handler changes value of internal variable and notifies waiting thread.
 */
static irqreturn_t s5p_hpd_irq_handler(int irq, void *dev_id)
{
	irqreturn_t ret = IRQ_HANDLED;

	HPDIFPRINTK("\n");
	/* check HDMI status */
	if (atomic_read(&hdmi_status)) {
		/* HDMI on */
		ret = s5p_hpd_irq_hdmi(irq);
		HPDIFPRINTK("HDMI HPD interrupt\n");
	} else {
		/* HDMI off */
		ret = s5p_hdp_irq_eint(irq);
		HPDIFPRINTK("EINT HPD interrupt\n");
	}

	return ret;
}
Exemple #10
0
/*
 * HPD interrupt handler
 *
 * Handles interrupt requests from HPD hardware.
 * Handler changes value of internal variable and notifies waiting thread.
 */
irqreturn_t s5p_hpd_irq_handler(int irq)
{
	int ret = IRQ_HANDLED;

	spin_lock_irq(&hpd_struct.lock);

	/* check HDMI status */
	if (atomic_read(&hdmi_status)) {
		/* HDMI on */
		ret = irq_hdmi(irq);
		HPDIFPRINTK("HDMI HPD interrupt\n");
	} else {
		/* HDMI off */
		ret = irq_eint(irq);
		HPDIFPRINTK("EINT HPD interrupt\n");
	}

	spin_unlock_irq(&hpd_struct.lock);

	return ret;
}
Exemple #11
0
static irqreturn_t s5p_hpd_irq_default_handler(int irq, void *dev_id)
{
	u8 flag;

	flag = s5p_hdmi_reg_intc_status();

	if (s5p_hdmi_reg_get_hpd_status())
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_PLUG);
	else
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_UNPLUG);

	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 0);
	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 0);

	if (flag & (1 << HDMI_IRQ_HPD_PLUG))
		HPDIFPRINTK("HPD_HI\n");
	else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG))
		HPDIFPRINTK("HPD_LO\n");
	else
		HPDIFPRINTK("UNKNOWN EVENT\n");

	return IRQ_HANDLED;
}
Exemple #12
0
int s5p_hpd_set_eint(void)
{
	HPDIFPRINTK("\n");
	/* HDMI -> EINT */
	atomic_set(&hdmi_status, HDMI_OFF);

	s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_PLUG);
	s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_UNPLUG);

	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 0);
	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 0);

	hpd_struct.int_src_ext_hpd();

	return 0;
}
Exemple #13
0
int irq_eint(int irq)
{
// by pjlee : Interrupt Signal Change
#ifdef CONFIG_MACH_MANGO210_EVT0
	if (!gpio_get_value(S5PV210_GPH1(5))) {
#else
	if (gpio_get_value(S5PV210_GPH1(5))) {
#endif
		if(last_hpd_state == HPD_HI)
			return;
		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);
	} else {
		if(last_hpd_state == HPD_LO)
			return;
		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
		wake_up_interruptible(&hpd_struct.waitq);
	}

	schedule_work(&hpd_work);

	HPDIFPRINTK("%s\n", atomic_read(&hpd_struct.state) == HPD_HI ?
		"HPD HI" : "HPD LO");

	return IRQ_HANDLED;

}

int irq_hdmi(int irq)
{
	u8 flag;
	int ret = IRQ_HANDLED;

	/* read flag register */
	flag = s5p_hdmi_get_interrupts();

#ifdef CONFIG_MACH_MANGO210_EVT0
	if (!s5p_hdmi_get_hpd_status())
#else
	if (s5p_hdmi_get_hpd_status())
#endif
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_PLUG);

	else
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_UNPLUG);

	s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG);
	s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG);


	/* is this our interrupt? */

	if (!(flag & (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG))) {
		ret = IRQ_NONE;
		goto out;
	}

	if (flag == (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG)) {

		HPDIFPRINTK("HPD_HI && HPD_LO\n");

#ifdef CONFIG_MACH_MANGO210_EVT0
		if (last_hpd_state == HPD_HI && !s5p_hdmi_get_hpd_status())
#else
		if (last_hpd_state == HPD_HI && s5p_hdmi_get_hpd_status())
#endif
			flag = 1 << HDMI_IRQ_HPD_UNPLUG;
		else
			flag = 1 << HDMI_IRQ_HPD_PLUG;
	}

	if (flag & (1 << HDMI_IRQ_HPD_PLUG)) {

		s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG);

		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);

		s5p_hdcp_encrypt_stop(true);

		HPDIFPRINTK("HPD_HI\n");

	} else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG)) {

		s5p_hdcp_encrypt_stop(false);

		s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG);

		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
		wake_up_interruptible(&hpd_struct.waitq);

		HPDIFPRINTK("HPD_LO\n");
	}

	schedule_work(&hpd_work);

out:
	return IRQ_HANDLED;
}
Exemple #14
0
/*
 * HPD interrupt handler
 *
 * Handles interrupt requests from HPD hardware.
 * Handler changes value of internal variable and notifies waiting thread.
 */
irqreturn_t s5p_hpd_irq_handler(int irq, void *pw)
{
#ifdef USEEXTINT
	spin_lock_irq(&hpd_struct.lock);

	if (gpio_get_value(S5PV210_GPH1(5))) {
		if (atomic_read(&hpd_struct.state) == HPD_HI)
			goto out;
		atomic_set(&hpd_struct.state, HPD_HI);
	} else {
		if (atomic_read(&hpd_struct.state) == HPD_LO)
			goto out;
		atomic_set(&hpd_struct.state, HPD_LO);
	}
	
	if(atomic_read(&hpd_struct.state)){
		set_irq_type(IRQ_EINT13, IRQ_TYPE_LEVEL_LOW);
	}else{
		set_irq_type(IRQ_EINT13, IRQ_TYPE_LEVEL_HIGH);
	}

	/* Send UEvent for HPD - added by jyg1004 */
	schedule_work(&hpd_work);

	spin_unlock_irq(&hpd_struct.lock);

	HPDIFPRINTK("hpd_status = %d\n", atomic_read(&hpd_struct.state));
	return IRQ_HANDLED;
out:
	spin_unlock_irq(&hpd_struct.lock);

	return IRQ_HANDLED;
#else
	u8 flag;
	int ret = IRQ_HANDLED;
	
	/* read flag register */
	flag = s5p_hdmi_get_interrupts();

	/* is this our interrupt? */

	if (!(flag & (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG))) {
		ret = IRQ_NONE;
		goto out;
	}

	/* workaround: ignore HPD IRQ caused by reseting HDCP engine */
	if (s5p_hdmi_get_swhpd_status()) {
		s5p_hdmi_swhpd_disable();
		/* clear pending bit */
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_UNPLUG);
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_PLUG);
		ret = IRQ_HANDLED;
		goto out;
	}

	if (flag == (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_HI && HPD_LO\n");

		if (last_hpd_state == HPD_HI && s5p_hdmi_get_hpd_status())
			//if ( last_hpd_state == HPD_HI )
			flag = 1 << HDMI_IRQ_HPD_UNPLUG;
		else
			flag = 1 << HDMI_IRQ_HPD_PLUG;
	}

	if (flag & (1 << HDMI_IRQ_HPD_PLUG)) {
		HPDIFPRINTK("HPD_HI\n");
		/* clear pending bit */
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_PLUG);
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_UNPLUG);
		atomic_set(&hpd_struct.state, HPD_HI);
		// workaround: enable HDMI_IRQ_HPD_UNPLUG interrupt
		s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_PLUG);
		s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_UNPLUG);		
		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);
	} else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_LO\n");
		/* clear pending bit */
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_PLUG);
		s5p_hdmi_clear_pending(HDMI_IRQ_HPD_UNPLUG);
		atomic_set(&hpd_struct.state, HPD_LO);
		// workaround: disable HDMI_IRQ_HPD_UNPLUG interrupt
		last_hpd_state = HPD_LO;
		s5p_hdmi_disable_interrupts(HDMI_IRQ_HPD_UNPLUG);
		s5p_hdmi_enable_interrupts(HDMI_IRQ_HPD_PLUG);
		wake_up_interruptible(&hpd_struct.waitq);
	}

out:
	return IRQ_HANDLED;

#endif
}
Exemple #15
0
static void s5p_hpd_kobject_uevent(void)
{
	char env_buf[120];
	char *envp[2];
	int env_offset = 0;
	int i = 0;
	int hpd_state = atomic_read(&hpd_struct.state);

	HPDIFPRINTK("++\n");

	if (hpd_tvout_kobj == NULL || hpd_video_kobj == NULL)
		return;

	memset(env_buf, 0, sizeof(env_buf));

	if (hpd_state)
	{
		while(on_stop_process && (i < RETRY_COUNT))
		{
			HPDIFPRINTK("on_stop_process\n");
			msleep(5);
			i++;
		};
	} else {
		while(on_start_process && (i < RETRY_COUNT))
		{
			HPDIFPRINTK("on_start_process\n");
			msleep(5);
			i++;
		};
	}

	if (i == RETRY_COUNT) {
		on_stop_process = false;
		on_start_process = false;
	}

	hpd_state = atomic_read(&hpd_struct.state);
	if (hpd_state) {
		if (last_uevent_state == -1 || last_uevent_state == HPD_LO) {
			sprintf(env_buf, "HDMI_STATE=online");
			envp[env_offset++] = env_buf;
			envp[env_offset] = NULL;
			HPDIFPRINTK("online event\n");
			kobject_uevent_env(hpd_tvout_kobj, KOBJ_CHANGE, envp);
			on_start_process = true;
		}
		last_uevent_state = HPD_HI;
	} else {
		if (last_uevent_state == -1 || last_uevent_state == HPD_HI) {
			sprintf(env_buf, "HDMI_STATE=offline");
			envp[env_offset++] = env_buf;
			envp[env_offset] = NULL;
			HPDIFPRINTK("offline event\n");
			kobject_uevent_env(hpd_tvout_kobj, KOBJ_CHANGE, envp);
			on_stop_process = true;
		}
		last_uevent_state = HPD_LO;
	}
	printk("[HDMI] s5p_hpd_kobject_uevent : hpd_state= %d\n",hpd_state);
}
Exemple #16
0
static int s5p_hpd_irq_hdmi(int irq)
{
	u8 flag;
	int ret = IRQ_HANDLED;
	HPDIFPRINTK("\n");

	/* read flag register */
	flag = s5p_hdmi_reg_intc_status();

	if (s5p_hdmi_reg_get_hpd_status())
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_PLUG);
	else
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_UNPLUG);

	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 0);
	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 0);

	/* is this our interrupt? */
	if (!(flag & (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG))) {
		ret = IRQ_NONE;

		goto out;
	}

	if (flag == (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_HI && HPD_LO\n");

		if (last_hpd_state == HPD_HI && s5p_hdmi_reg_get_hpd_status())
			flag = 1 << HDMI_IRQ_HPD_UNPLUG;
		else
			flag = 1 << HDMI_IRQ_HPD_PLUG;
	}

	if (flag & (1 << HDMI_IRQ_HPD_PLUG)) {
		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 1);
		if (atomic_read(&hpd_struct.state) == HPD_HI)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);

		//s5p_hdcp_encrypt_stop(true);

		HPDIFPRINTK("HPD_HI\n");

	} else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG)) {
		//s5p_hdcp_encrypt_stop(false);
		s5p_hdcp_stop();

		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 1);
		if (atomic_read(&hpd_struct.state) == HPD_LO)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
		wake_up_interruptible(&hpd_struct.waitq);

		HPDIFPRINTK("HPD_LO\n");
	}

	schedule_work(&hpd_work);

out:
	return IRQ_HANDLED;
}
Exemple #17
0
static void s5p_hpd_kobject_uevent(void)
{
	char env_buf[120];
#ifndef CONFIG_HDMI_SWITCH_HPD
	char *envp[2];
	int env_offset = 0;
#endif
	int i = 0;
	int hpd_state = atomic_read(&hpd_struct.state);

	HPDIFPRINTK("++\n");
	memset(env_buf, 0, sizeof(env_buf));

	if (hpd_state) {
		while (on_stop_process && (i < RETRY_COUNT)) {
			HPDIFPRINTK("waiting on_stop_process\n");
			usleep_range(5000, 5000);
			i++;
		};
	} else {
		while (on_start_process && (i < RETRY_COUNT)) {
			HPDIFPRINTK("waiting on_start_process\n");
			usleep_range(5000, 5000);
			i++;
		};
	}

	if (i == RETRY_COUNT) {
		on_stop_process = false;
		on_start_process = false;
		printk(KERN_ERR	"[ERROR] %s() %s fail !!\n", __func__,
			hpd_state ? "on_stop_process" : "on_start_process");
	}

	hpd_state = atomic_read(&hpd_struct.state);
	if (hpd_state) {
		if (last_uevent_state == -1 || last_uevent_state == HPD_LO) {
#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
			HPDPRINTK("ext_ic power ON\n");
			hpd_struct.ext_ic_control(true);
			msleep(20);
#endif
#ifdef CONFIG_HDMI_SWITCH_HPD
			hpd_struct.hpd_switch.state = 0;
			switch_set_state(&hpd_struct.hpd_switch, 1);
#else
			sprintf(env_buf, "HDMI_STATE=online");
			envp[env_offset++] = env_buf;
			envp[env_offset] = NULL;
			HPDIFPRINTK("online event\n");
			kobject_uevent_env(&(hpd_misc_device.this_device->kobj),
					   KOBJ_CHANGE, envp);
#endif
			HPDPRINTK("[HDMI] HPD event -connect!!!\n");
			if (atomic_read(&hdmi_status) == HDMI_OFF) {
				on_start_process = true;
			} else {
				on_start_process = false;
			}
			HPDIFPRINTK("%s() on_start_process(%d)\n",
					__func__, on_start_process);
		}
		last_uevent_state = HPD_HI;
	} else {
		if (last_uevent_state == -1 || last_uevent_state == HPD_HI) {
#ifdef CONFIG_LSI_HDMI_AUDIO_CH_EVENT
			switch_set_state(&g_audio_ch_switch, (int)-1);
#endif
#ifdef CONFIG_HDMI_SWITCH_HPD
			hpd_struct.hpd_switch.state = 1;
			switch_set_state(&hpd_struct.hpd_switch, 0);
#else
			sprintf(env_buf, "HDMI_STATE=offline");
			envp[env_offset++] = env_buf;
			envp[env_offset] = NULL;
			HPDIFPRINTK("offline event\n");
			kobject_uevent_env(&(hpd_misc_device.this_device->kobj),
					   KOBJ_CHANGE, envp);
#endif
			HPDPRINTK("[HDMI] HPD event -disconnet!!!\n");
			if (atomic_read(&hdmi_status) == HDMI_ON) {
				on_stop_process = true;
			} else {
				on_stop_process = false;
			}
			HPDIFPRINTK("%s() on_stop_process(%d)\n",
					__func__, on_stop_process);

		}
		last_uevent_state = HPD_LO;
	}
}
Exemple #18
0
static int s5p_hpd_irq_hdmi(int irq)
{
	u8 flag;
	int ret = IRQ_HANDLED;
	HPDIFPRINTK("\n");

	/* read flag register */
	flag = s5p_hdmi_reg_intc_status();

	if (s5p_hdmi_reg_get_hpd_status())
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_PLUG);
	else
		s5p_hdmi_reg_intc_clear_pending(HDMI_IRQ_HPD_UNPLUG);

	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 0);
	s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 0);

	/* is this our interrupt? */
	if (!(flag & (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG))) {
		printk(KERN_WARNING "%s() flag is wrong : 0x%x\n",
		       __func__, flag);
		ret = IRQ_NONE;

		goto out;
	}

	if (flag == (1 << HDMI_IRQ_HPD_PLUG | 1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_HI && HPD_LO\n");

		if (last_hpd_state == HPD_HI && s5p_hdmi_reg_get_hpd_status())
			flag = 1 << HDMI_IRQ_HPD_UNPLUG;
		else
			flag = 1 << HDMI_IRQ_HPD_PLUG;
	}

	if (flag & (1 << HDMI_IRQ_HPD_PLUG)) {
		HPDIFPRINTK("HPD_HI\n");

		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_UNPLUG, 1);
		if (atomic_read(&hpd_struct.state) == HPD_HI)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_HI);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_HI;
		wake_up_interruptible(&hpd_struct.waitq);

	} else if (flag & (1 << HDMI_IRQ_HPD_UNPLUG)) {
		HPDIFPRINTK("HPD_LO\n");

		s5p_hdcp_stop();

		s5p_hdmi_reg_intc_enable(HDMI_IRQ_HPD_PLUG, 1);
		if (atomic_read(&hpd_struct.state) == HPD_LO)
			return IRQ_HANDLED;

		atomic_set(&hpd_struct.state, HPD_LO);
		atomic_set(&poll_state, 1);

		last_hpd_state = HPD_LO;
#ifdef	CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
		if (is_mhl_power_state_on != NULL)
			if (!is_mhl_power_state_on())
				mhl_hpd_handler(false);
#endif
#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
		schedule_delayed_work(&ext_ic_control_dwork ,
				msecs_to_jiffies(1000));
#endif

		wake_up_interruptible(&hpd_struct.waitq);
	}

	schedule_work(&hpd_work);

 out:
	return IRQ_HANDLED;
}