示例#1
0
int s5p_tv_v_release(struct file *filp)
{
#if defined(CONFIG_PM)
	if ((g_s5ptv_status.hpd_status) && !(g_s5ptv_status.suspend_status)) {
#endif
		if (g_s5ptv_status.vp_layer_enable)
			s5p_vlayer_stop();
		if (g_s5ptv_status.tvout_output_enable)
			s5p_tv_if_stop();
#if defined(CONFIG_PM)
	} else
		g_s5ptv_status.vp_layer_enable = false;
#endif

	g_s5ptv_status.hdcp_en = false;

	g_s5ptv_status.tvout_output_enable = false;

	/*
	 * drv. release
	 *        - just check drv. state reg. or not.
	 */

#ifdef CONFIG_PM
	if ((g_s5ptv_status.hpd_status) && !(g_s5ptv_status.suspend_status)) {
#endif
		s5p_tv_base_clk_gate(false);
		s5p_tv_base_phy_power(false);
#ifdef CONFIG_PM
	}
#endif

	return 0;
}
示例#2
0
static int s5p_tv_vid_release(struct file *file)
{
	g_s5ptv_status.vp_layer_enable = false;

	s5p_vlayer_stop();

	return 0;
}
static int s5p_tv_v4l2_streamoff(struct file *file, void *fh,
	enum v4l2_buf_type i)
{
	struct s5p_tv_vo *layer = (struct s5p_tv_vo *)fh;

	V4L2PRINTK("(0x%08x)++\n", i);

	/* tv driver is on suspend mode or hdmi cable is not inserted
	* Each layer was disabled on suspend function already.
	* Just set the status variable on this function
	* Each layer will be enabled or disabled on resume or
	* handle_cable function according to this status variable
	*/
	if (g_s5ptv_status.suspend_status == true || !(g_s5ptv_status.hpd_status)) {
		switch (i) {
		/* Vlayer */
		case V4L2_BUF_TYPE_VIDEO_OUTPUT:
			g_s5ptv_status.vp_layer_enable = false;
			break;
		/* GRP0/1 */
		case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
			g_s5ptv_status.grp_layer_enable[layer->index] = false;
			break;
		default:
			break;
		}
		V4L2PRINTK("()it's on suspend mode or hdmi cable is not inserted--\n");
		return 0;

	}

	switch (i) {
	/* Vlayer */
	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
		s5p_vlayer_stop();
		break;
	/* GRP0/1 */
	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
		s5p_grp_stop(layer->index);
		break;
	default:
		break;
	}

	V4L2PRINTK("()--\n");

	return 0;
}
示例#4
0
void s5p_tv_early_suspend(struct early_suspend *h)
{
	BASEPRINTK("(hpd_status = %d)++\n", g_s5ptv_status.hpd_status);

	mutex_lock(g_mutex_for_fo);
	g_s5ptv_status.suspend_status = true;

	if (g_s5ptv_status.hpd_status == true) {
		/* video layer stop */
		if (g_s5ptv_status.vp_layer_enable) {
			s5p_vlayer_stop();
			g_s5ptv_status.vp_layer_enable = true;
		}

		/* grp0 layer stop */
		if (g_s5ptv_status.grp_layer_enable[VM_GPR0_LAYER]) {
			s5p_grp_stop(VM_GPR0_LAYER);
			g_s5ptv_status.grp_layer_enable[VM_GPR0_LAYER] = true;
		}

		/* grp1 layer stop */
		if (g_s5ptv_status.grp_layer_enable[VM_GPR1_LAYER]) {
			s5p_grp_stop(VM_GPR1_LAYER);
			g_s5ptv_status.grp_layer_enable[VM_GPR1_LAYER] = true;
		}

		/* tv off */
		if (g_s5ptv_status.tvout_output_enable) {
			s5p_tv_if_stop();
			g_s5ptv_status.tvout_output_enable = true;
			g_s5ptv_status.tvout_param_available = true;
		}

		/* clk & power off */
		s5p_tv_base_clk_gate(false);
		if (g_s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI ||
		    g_s5ptv_status.tvout_param.out_mode == TVOUT_OUTPUT_HDMI_RGB)
			s5p_tv_base_phy_power(false);
	}

	mutex_unlock(g_mutex_for_fo);
	BASEPRINTK("()--\n");
	return;
}
示例#5
0
static int s5ptvfb_release(struct fb_info *fb, int user)
{
	int ret;
	struct s5ptvfb_window *win = fb->par;

	s5ptvfb_release_window(fb);

/*
 * Following block is deleted for enabling multiple open of TV frame buffer
 *
 *	mutex_lock(&g_s5ptv_status.fb_lock);
 *	atomic_dec(&win->in_use);
 *	mutex_unlock(&g_s5ptv_status.fb_lock);
 */

	s5p_vlayer_stop();
	s5p_tv_if_stop();

	g_s5ptv_status.hdcp_en = false;

	g_s5ptv_status.tvout_output_enable = false;

	/*
	* drv. release
	*        - just check drv. state reg. or not.
	*/

	ret = s5p_tv_base_clk_gate(false);
	if (ret < 0) {
		pr_err("%s::s5p_tv_base_clk_gate(false) fail\n",
			__func__);
		return -1;
	}
	s5p_tv_base_phy_power(false);

	mutex_lock(&g_s5ptv_status.fb_lock);
	atomic_dec(&win->in_use);
	mutex_unlock(&g_s5ptv_status.fb_lock);

	return 0;
}
示例#6
0
void s5p_tv_base_handle_cable(void)
{
	char env_buf[120];
	char *envp[2];
	int env_offset = 0;
	bool previous_hpd_status = g_s5ptv_status.hpd_status;

#ifdef CONFIG_HDMI_HPD
#else
	return;
#endif

	switch (g_s5ptv_status.tvout_param.out_mode) {
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_DVI:
		break;
	default:
		return;
	}

	g_s5ptv_status.hpd_status = s5p_hpd_get_state();

	if (previous_hpd_status == g_s5ptv_status.hpd_status) {
		pr_err("same hpd_status value: %d\n", previous_hpd_status);
		return;
	}

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

	if (g_s5ptv_status.hpd_status == true) {
		BASEPRINTK("\n hdmi cable is connected\n");
		sprintf(env_buf, "HDMI_STATE=online");
		envp[env_offset++] = env_buf;
		envp[env_offset] = NULL;

		s5p_set_qos();

		if (g_s5ptv_status.suspend_status) {
			kobject_uevent_env(&(s5p_tvout[0].dev.kobj), KOBJ_CHANGE, envp);
			return;
		}

#ifdef CONFIG_PM
		s5p_tv_base_clk_gate(true);
		s5p_tv_base_phy_power(true);
#endif
		/* tv on */
		if (g_s5ptv_status.tvout_output_enable)
			s5p_tv_if_start();

		/* video layer start */
		if (g_s5ptv_status.vp_layer_enable)
			s5p_vlayer_start();

		/* grp0 layer start */
		if (g_s5ptv_status.grp_layer_enable[VM_GPR0_LAYER])
			s5p_grp_start(VM_GPR0_LAYER);

		/* grp1 layer start */
		if (g_s5ptv_status.grp_layer_enable[VM_GPR1_LAYER])
			s5p_grp_start(VM_GPR1_LAYER);

	} else {
		BASEPRINTK("\n hdmi cable is disconnected\n");
		sprintf(env_buf, "HDMI_STATE=offline");
		envp[env_offset++] = env_buf;
		envp[env_offset] = NULL;

		s5p_restore_qos();

		if (g_s5ptv_status.suspend_status) {
			kobject_uevent_env(&(s5p_tvout[0].dev.kobj), KOBJ_CHANGE, envp);
			return;
		}

		if (g_s5ptv_status.vp_layer_enable) {
			s5p_vlayer_stop();
			g_s5ptv_status.vp_layer_enable = true;
		}

		/* grp0 layer stop */
		if (g_s5ptv_status.grp_layer_enable[VM_GPR0_LAYER]) {
			s5p_grp_stop(VM_GPR0_LAYER);
			g_s5ptv_status.grp_layer_enable[VM_GPR0_LAYER] = true;
		}

		/* grp1 layer stop */
		if (g_s5ptv_status.grp_layer_enable[VM_GPR1_LAYER]) {
			s5p_grp_stop(VM_GPR1_LAYER);
			g_s5ptv_status.grp_layer_enable[VM_GPR1_LAYER] = true;
		}

		/* tv off */
		if (g_s5ptv_status.tvout_output_enable) {
			s5p_tv_if_stop();
			g_s5ptv_status.tvout_output_enable = true;
			g_s5ptv_status.tvout_param_available = true;
		}

#ifdef CONFIG_PM
		/* clk & power off */
		s5p_tv_base_clk_gate(false);
		s5p_tv_base_phy_power(false);
#endif
	}
	kobject_uevent_env(&(s5p_tvout[0].dev.kobj), KOBJ_CHANGE, envp);
}
示例#7
0
int s5ptvfb_direct_ioctl(int id, unsigned int cmd, unsigned long arg)
{
	struct fb_info *fb = g_s5ptv_status.fb;
	struct fb_fix_screeninfo *fix = &fb->fix;
	struct s5ptvfb_window *win = fb->par;
	void *argp = (void *) arg;
	int ret = 0;

	switch (cmd) {
	case FBIO_ALLOC:
		win->path = (enum s5ptvfb_data_path_t) argp;
		break;
	case FBIOGET_FSCREENINFO:
		ret = memcpy(argp, &fb->fix, sizeof(fb->fix)) ? 0 : -EFAULT;
		break;
	case FBIOGET_VSCREENINFO:
		ret = memcpy(argp, &fb->var, sizeof(fb->var)) ? 0 : -EFAULT;
		break;
	case FBIOPUT_VSCREENINFO:
		ret = s5ptvfb_check_var((struct fb_var_screeninfo *) argp, fb);
		if (ret) {
			dev_err(g_s5ptv_status.dev_fb, "invalid vscreeninfo\n");
			break;
		}

		ret = memcpy(&fb->var, (struct fb_var_screeninfo *) argp,
				sizeof(fb->var)) ? 0 : -EFAULT;
		if (ret) {
			dev_err(g_s5ptv_status.dev_fb,
			       "failed to put new vscreeninfo\n");
			break;
		}

		ret = s5ptvfb_set_par(fb);
		break;
	case S5PTVFB_SET_WIN_ON:
#ifdef CONFIG_USER_ALLOC_TVOUT
		s5ptvfb_display_on(&g_s5ptv_status);
		s5ptvfb_enable_window(0);
#endif
		break;
	case S5PTVFB_SET_WIN_OFF:
#ifdef CONFIG_USER_ALLOC_TVOUT
		s5ptvfb_display_off(&g_s5ptv_status);
		s5ptvfb_disable_window(0);
#endif
		break;
	case S5PTVFB_POWER_ON:
		s5p_tv_base_clk_gate(true);
		s5p_tv_base_phy_power(true);

		s5p_tv_if_init_param();

		s5p_tv_v4l2_init_param();

		/* g_s5ptv_status.tvout_param.disp_mode = TVOUT_720P_60; */
		g_s5ptv_status.tvout_param.out_mode  = TVOUT_OUTPUT_HDMI;

		s5p_tv_if_set_disp();

		break;
	case S5PTVFB_POWER_OFF:
		s5p_vlayer_stop();
		s5p_tv_if_stop();

		s5p_tv_base_clk_gate(false);
		s5p_tv_base_phy_power(false);
		break;
	case S5PTVFB_WIN_SET_ADDR:
		fix->smem_start = (unsigned long)argp;
		s5ptvfb_set_buffer_address(&g_s5ptv_status, win->id);
		break;
	default:
		ret = s5ptvfb_ioctl(fb, cmd, arg);
		break;
	}

	return ret;
}
bool s5p_tv_if_start(void)
{
	struct s5p_tv_status *st = &g_s5ptv_status;

	enum s5p_tv_o_mode out_mode = st->tvout_param.out_mode;

	s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, false);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER,  false);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER,  false);

	s5p_tv_if_stop();

	if (st->vp_layer_enable) {
		s5p_vlayer_stop();
		/* In order to start video layer on the s5p_tv_resume()
		 * or handle_calbe() function
		 */
		st->vp_layer_enable = true;
	}

	/* Clear All Interrupt Pending */
	s5p_vm_clear_pend_all();

	/*
	* have not to call
	* another request function simultaneously
	*/
	switch (out_mode) {
	case TVOUT_OUTPUT_COMPOSITE:
	case TVOUT_OUTPUT_SVIDEO:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		clk_set_parent(st->sclk_mixer, st->sclk_dac);
		break;
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
	case TVOUT_OUTPUT_DVI:
		clk_set_parent(st->sclk_mixer, st->sclk_hdmi);
		clk_set_parent(st->sclk_hdmi, st->sclk_hdmiphy);
		break;
	default:
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, st->tvout_param.out_mode);

		s5p_tv_if_stop();

		st->tvout_param_available = false;
		return false;
		break;
	}

	if (!s5p_tv_if_init_vm_reg()) {
		pr_err("%s::s5p_tv_if_init_vm_reg() fail\n", __func__);
		return false;
	}

	switch (out_mode) {
	case TVOUT_OUTPUT_COMPOSITE:
	case TVOUT_OUTPUT_SVIDEO:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_INERLACED:
	case TVOUT_OUTPUT_COMPONENT_YPBPR_PROGRESSIVE:
	case TVOUT_OUTPUT_COMPONENT_RGB_PROGRESSIVE:
		if (!s5p_tv_if_init_sd_reg()) {
			pr_err("%s::s5p_tv_if_init_sd_reg() fail\n",
				__func__);
			return false;
		}
		break;
	case TVOUT_OUTPUT_DVI:
		st->hdmi_audio_type = HDMI_AUDIO_NO;
	case TVOUT_OUTPUT_HDMI:
	case TVOUT_OUTPUT_HDMI_RGB:
		if (!s5p_tv_if_init_hd_reg()) {
			pr_err("%s::s5p_tv_if_init_hd_reg() fail\n",
				__func__);
			return false;
		}
		if (g_s5ptv_status.hdcp_en)
			s5p_start_hdcp();
		break;
	default:
		s5p_tv_if_stop();
		pr_err("%s::invalid out_mode parameter(%d)\n",
			__func__, out_mode);
		return false;
		break;
	}

	st->tvout_output_enable = true;

	s5p_vm_set_underflow_interrupt_enable(VM_VIDEO_LAYER, true);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR0_LAYER,  true);
	s5p_vm_set_underflow_interrupt_enable(VM_GPR1_LAYER,  true);

	/* Clear All Interrupt Pending */
	s5p_vm_clear_pend_all();

	TVOUTIFPRINTK("()\n");

	return true;
}