Exemplo n.º 1
0
static ssize_t hdcp_enable_write(struct device *device,
			   struct device_attribute *attr, const char *buf, size_t count)
{
	int enable;

	if(hdcp == NULL)
		return -EINVAL;
	
	sscanf(buf, "%d", &enable);
	if(hdcp->enable != enable)
	{
		/* Post event to workqueue */
		if(enable) {
			if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0)
				return -EFAULT;
		}
		else {
			hdcp_cancel_work(&hdcp->pending_start);
			hdcp_cancel_work(&hdcp->pending_wq_event);
		
			/* Post event to workqueue */
			if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0)
				return -EFAULT;
		}
		hdcp->enable = 	enable;
	}
	return count;
}
Exemplo n.º 2
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_irq_cb
 *-----------------------------------------------------------------------------
 */
static void hdcp_irq_cb(int status)
{
	DBG("hdcp_irq_cb() status=%x", status);

	if (!hdcp.hdcp_keys_loaded) {
		DBG("%s: hdcp_keys not loaded = %d",
		    __func__, hdcp.hdcp_keys_loaded);
		return;
	}

	/* Disable auto Ri/BCAPS immediately */
	if (((status & HDMI_RI_ERR) ||
	    (status & HDMI_BCAP) ||
	    (status & HDMI_HPD_LOW)) &&
	    (hdcp.hdcp_state != HDCP_ENABLE_PENDING)) {
		hdcp_lib_auto_ri_check(false);
		hdcp_lib_auto_bcaps_rdy_check(false);
	}

	/* Work queue execution not required if HDCP is disabled */
	/* TODO: ignore interrupts if they are masked (cannnot access UMASK
	 * here so should use global variable
	 */
	if ((hdcp.hdcp_state != HDCP_DISABLED) &&
	    (hdcp.hdcp_state != HDCP_ENABLE_PENDING)) {
		if (status & HDMI_HPD_LOW) {
			hdcp_lib_set_encryption(HDCP_ENC_OFF);
			hdcp_ddc_abort();
		}

		if (status & HDMI_RI_ERR) {
			hdcp_lib_set_av_mute(AV_MUTE_SET);
			hdcp_lib_set_encryption(HDCP_ENC_OFF);
			hdcp_submit_work(HDCP_RI_FAIL_EVENT, 0);
		}
		/* RI error takes precedence over BCAP */
		else if (status & HDMI_BCAP)
			hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0);
	}

	if (status & HDMI_HPD_LOW) {
		hdcp.pending_disable = 1;	/* Used to exit on-going HDCP
						 * work */
		hdcp.hpd_low = 0;		/* Used to cancel HDCP works */
		hdcp_lib_disable();
		/* In case of HDCP_STOP_FRAME_EVENT, HDCP stop
		 * frame callback is blocked and waiting for
		 * HDCP driver to finish accessing the HW
		 * before returning
		 * Reason is to avoid HDMI driver to shutdown
		 * DSS/HDMI power before HDCP work is finished
		 */
		hdcp.hdmi_state = HDMI_STOPPED;
		hdcp.hdcp_state = HDCP_ENABLE_PENDING;
		hdcp.auth_state = HDCP_STATE_DISABLED;
	}
}
Exemplo n.º 3
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_enable_ctl
 *-----------------------------------------------------------------------------
 */
static long hdcp_enable_ctl(void __user *argp)
{
	DBG("hdcp_ioctl() - ENABLE %u", jiffies_to_msecs(jiffies));

	if (hdcp.en_ctrl == 0) {
		hdcp.en_ctrl =
			kmalloc(sizeof(struct hdcp_enable_control),
							GFP_KERNEL);

		if (hdcp.en_ctrl == 0) {
			printk(KERN_WARNING
				"HDCP: Cannot allocate memory for HDCP"
				" enable control struct\n");
			return -EFAULT;
		}
	}

	if (copy_from_user(hdcp.en_ctrl, argp,
			   sizeof(struct hdcp_enable_control))) {
		printk(KERN_WARNING "HDCP: Error copying from user space "
				    "- enable ioctl\n");
		return -EFAULT;
	}

	hdcp.hdcp_keys_loaded = true;

	/* Post event to workqueue */
	if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0)
		return -EFAULT;

	return 0;
}
Exemplo n.º 4
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_start_authentication
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_start_authentication(void)
{
	int status = HDCP_OK;

	hdcp.hdcp_state = HDCP_AUTHENTICATION_START;

	printk(KERN_INFO "HDCP: authentication start\n");

	/* Step 1 part 1 (until R0 calc delay) */
	status = hdcp_lib_step1_start();

	if (status == -HDCP_AKSV_ERROR) {
		hdcp_wq_authentication_failure();
	} else if (status == -HDCP_CANCELLED_AUTH) {
		DBG("Authentication step 1 cancelled.");
		return;
	} else if (status != HDCP_OK) {
		hdcp_wq_authentication_failure();
	} else {
		hdcp.hdcp_state = HDCP_WAIT_R0_DELAY;
		hdcp.auth_state = HDCP_STATE_AUTH_1ST_STEP;
		hdcp.pending_wq_event = hdcp_submit_work(HDCP_R0_EXP_EVENT,
							 HDCP_R0_DELAY);
	}
}
Exemplo n.º 5
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_authentication_failure
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_authentication_failure(void)
{
	if (hdcp->hdmi_state == HDMI_STOPPED) {
		return;
	}

	rk30_hdcp_disable(hdcp);
	rk30_hdmi_control_output(hdcp->hdmi, HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE);
	
	hdcp_cancel_work(&hdcp->pending_wq_event);

	if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) {
		if (hdcp->retry_cnt < HDCP_INFINITE_REAUTH) {
			hdcp->retry_cnt--;
			printk(KERN_INFO "HDCP: authentication failed - "
					 "retrying, attempts=%d\n",
							hdcp->retry_cnt);
		} else
			printk(KERN_INFO "HDCP: authentication failed - "
					 "retrying\n");

		hdcp->hdcp_state = HDCP_AUTHENTICATION_START;

		hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT,
							 HDCP_REAUTH_DELAY);
	} else {
		printk(KERN_INFO "HDCP: authentication failed - "
				 "HDCP disabled\n");
		hdcp->hdcp_state = HDCP_ENABLE_PENDING;
	}

}
Exemplo n.º 6
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_start_frame_cb
 *-----------------------------------------------------------------------------
 */
static void hdcp_start_frame_cb(void)
{
	DBG("hdcp_start_frame_cb()");

	/* Cancel any pending work */
	if (hdcp->pending_start)
		hdcp_cancel_work(&hdcp->pending_start);
	if (hdcp->pending_wq_event)
		hdcp_cancel_work(&hdcp->pending_wq_event);

	hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT,
							HDCP_ENABLE_DELAY);
}
Exemplo n.º 7
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_disable_ctl
 *-----------------------------------------------------------------------------
 */
static long hdcp_disable_ctl(void)
{
	DBG("hdcp_ioctl() - DISABLE %u", jiffies_to_msecs(jiffies));

	hdcp_cancel_work(&hdcp.pending_start);
	hdcp_cancel_work(&hdcp.pending_wq_event);

	hdcp.pending_disable = 1;
	/* Post event to workqueue */
	if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0)
		return -EFAULT;

	return 0;
}
Exemplo n.º 8
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_power_off_cb
 *-----------------------------------------------------------------------------
 */
static void hdcp_power_off_cb(void)
{
	DBG("%s", __FUNCTION__);
	if(!hdcp->enable)
		return;
	
	hdcp_cancel_work(&hdcp->pending_start);
	hdcp_cancel_work(&hdcp->pending_wq_event);
	init_completion(&hdcp->complete);
	/* Post event to workqueue */
	if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0))	
		wait_for_completion_interruptible_timeout(&hdcp->complete,
							msecs_to_jiffies(2000));
}
Exemplo n.º 9
0
/*-----------------------------------------------------------------------------
 * 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);
}
Exemplo n.º 10
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_authentication_failure
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_authentication_failure(void)
{
	if (hdcp.hdmi_state == HDMI_STOPPED) {
		hdcp.auth_state = HDCP_STATE_AUTH_FAILURE;
		return;
	}

	hdcp_lib_auto_ri_check(false);
	hdcp_lib_auto_bcaps_rdy_check(false);
	hdcp_lib_set_av_mute(AV_MUTE_SET);
	hdcp_lib_set_encryption(HDCP_ENC_OFF);

	hdcp_cancel_work(&hdcp.pending_wq_event);

	hdcp_lib_disable();
	hdcp.pending_disable = 0;

	if (hdcp.retry_cnt && (hdcp.hdmi_state != HDMI_STOPPED)) {
		if (hdcp.retry_cnt < HDCP_INFINITE_REAUTH) {
			hdcp.retry_cnt--;
			printk(KERN_INFO "HDCP: authentication failed - "
					 "retrying, attempts=%d\n",
							hdcp.retry_cnt);
		} else
			printk(KERN_INFO "HDCP: authentication failed - "
					 "retrying\n");

		hdcp.hdcp_state = HDCP_AUTHENTICATION_START;
		hdcp.auth_state = HDCP_STATE_AUTH_FAIL_RESTARTING;

		hdcp.pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT,
							 HDCP_REAUTH_DELAY);
	} else {
		printk(KERN_INFO "HDCP: authentication failed - "
				 "HDCP disabled\n");
		hdcp.hdcp_state = HDCP_ENABLE_PENDING;
		hdcp.auth_state = HDCP_STATE_AUTH_FAILURE;
	}

}
Exemplo n.º 11
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_start_frame_cb
 *-----------------------------------------------------------------------------
 */
static void hdcp_start_frame_cb(void)
{
	DBG("hdcp_start_frame_cb() %u", jiffies_to_msecs(jiffies));

	if (!hdcp.hdcp_keys_loaded) {
		DBG("%s: hdcp_keys not loaded = %d",
		    __func__, hdcp.hdcp_keys_loaded);
		return;
	}

	/* Cancel any pending work */
	if (hdcp.pending_start)
		hdcp_cancel_work(&hdcp.pending_start);
	if (hdcp.pending_wq_event)
		hdcp_cancel_work(&hdcp.pending_wq_event);

	hdcp.hpd_low = 0;
	hdcp.pending_disable = 0;
	hdcp.retry_cnt = HDCP_INFINITE_REAUTH;
	hdcp.pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT,
							HDCP_ENABLE_DELAY);
}
Exemplo n.º 12
0
/*-----------------------------------------------------------------------------
 * Function: hdcp_wq_check_r0
 *-----------------------------------------------------------------------------
 */
static void hdcp_wq_check_r0(void)
{
	int status = hdcp_lib_step1_r0_check();

	if (status == -HDCP_CANCELLED_AUTH) {
		DBG("Authentication step 1/R0 cancelled.");
		return;
	} else if (status < 0)
		hdcp_wq_authentication_failure();
	else {
		if (hdcp_lib_check_repeater_bit_in_tx()) {
			/* Repeater */
			printk(KERN_INFO "HDCP: authentication step 1 "
					 "successful - Repeater\n");

			hdcp.hdcp_state = HDCP_WAIT_KSV_LIST;
			hdcp.auth_state = HDCP_STATE_AUTH_2ND_STEP;

			hdcp.pending_wq_event =
				hdcp_submit_work(HDCP_KSV_TIMEOUT_EVENT,
						 HDCP_KSV_TIMEOUT_DELAY);
		} else {
			/* Receiver */
			printk(KERN_INFO "HDCP: authentication step 1 "
					 "successful - Receiver\n");

			hdcp.hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
			hdcp.auth_state = HDCP_STATE_AUTH_3RD_STEP;

			/* Restore retry counter */
			if (hdcp.en_ctrl->nb_retry == 0)
				hdcp.retry_cnt = HDCP_INFINITE_REAUTH;
			else
				hdcp.retry_cnt = hdcp.en_ctrl->nb_retry;
		}
	}
}