Beispiel #1
0
static int s5ptvfb_open(struct fb_info *fb, int user)
{
	struct s5ptvfb_window *win = fb->par;
	int ret = 0;

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

	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_RGB;

	s5p_tv_if_set_disp();

#ifndef CONFIG_USER_ALLOC_TVOUT
	s5ptvfb_display_on(&g_s5ptv_status);
	s5ptvfb_enable_window(0);
#endif

	mutex_lock(&g_s5ptv_status.fb_lock);

	if (atomic_read(&win->in_use)) {
		dev_dbg(g_s5ptv_status.dev_fb,
		"do not allow multiple open "
		"for window\n");
		ret = -EBUSY;

	} else
		atomic_inc(&win->in_use);

	mutex_unlock(&g_s5ptv_status.fb_lock);

	return ret;

}
static int __devinit s5p_tv_probe(struct platform_device *pdev)
{
	int	irq_num;
	int	ret = 0;
	int	i;

	g_s5ptv_status.dev_fb = &pdev->dev;
	g_clks_enabled = 0;

	ret = s5p_sdout_probe(pdev, 0);
	if (ret != 0) {
		pr_err("%s::s5p_sdout_probe() fail\n", __func__);
		goto err_s5p_sdout_probe;
	}

	ret = s5p_vp_probe(pdev, 1);
	if (ret != 0) {
		pr_err("%s::s5p_vmixer_probe() fail\n", __func__);
		goto err_s5p_vp_probe;
	}

	ret = s5p_vmixer_probe(pdev, 2);
	if (ret != 0) {
		pr_err("%s::s5p_vmixer_probe() fail\n", __func__);
		goto err_s5p_vmixer_probe;
	}

	tv_clk_get(pdev, &g_s5ptv_status);
	s5p_tv_base_clk_gate(true);

	ret = s5p_hdmi_probe(pdev, 3, 4);
	if (ret != 0) {
		pr_err("%s::s5p_hdmi_probe() fail\n", __func__);
		goto err_s5p_hdmi_probe;
	}

	s5p_hdcp_init();

#ifdef CONFIG_HDMI_HPD
	g_s5ptv_status.hpd_status = s5p_hpd_get_state();
#else
	g_s5ptv_status.hpd_status = 0;
#endif
	dev_info(&pdev->dev, "hpd status is cable %s\n",
			g_s5ptv_status.hpd_status ? "inserted" : "removed");

	/* interrupt */
	TVOUT_IRQ_INIT(irq_num, ret, pdev, 0, err_vm_irq,    s5p_vmixer_irq, "mixer");
	TVOUT_IRQ_INIT(irq_num, ret, pdev, 1, err_hdmi_irq,  s5p_hdmi_irq , "hdmi");
	TVOUT_IRQ_INIT(irq_num, ret, pdev, 2, err_tvenc_irq, s5p_tvenc_irq, "tvenc");

	/* v4l2 video device registration */
	for (i = 0; i < S5P_TVMAX_CTRLS; i++) {
		g_s5ptv_status.video_dev[i] = &s5p_tvout[i];

		if (video_register_device(g_s5ptv_status.video_dev[i],
					VFL_TYPE_GRABBER, s5p_tvout[i].minor) != 0) {

			dev_err(&pdev->dev,
					"Couldn't register tvout driver.\n");

			ret = -EBUSY;
			goto err_video_register_device;
		}
	}

#ifdef CONFIG_TV_FB
	mutex_init(&g_s5ptv_status.fb_lock);

	/* for default start up */
	s5p_tv_if_init_param();

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

#ifndef CONFIG_USER_ALLOC_TVOUT
	s5p_tv_base_clk_gate(true);
	s5p_tv_base_phy_power(true);
	s5p_tv_if_set_disp();
#endif

	s5ptvfb_set_lcd_info(&g_s5ptv_status);

	/* prepare memory */
	if (s5ptvfb_alloc_framebuffer()) {
		ret = -ENOMEM;
		goto err_alloc_fb;
	}

	if (s5ptvfb_register_framebuffer()) {
		ret = -EBUSY;
		goto err_register_fb;
	}

#ifndef CONFIG_USER_ALLOC_TVOUT
	s5ptvfb_display_on(&g_s5ptv_status);
#endif
#endif
	g_mutex_for_fo = kmalloc(sizeof(struct mutex),
			GFP_KERNEL);

	if (g_mutex_for_fo == NULL) {
		dev_err(&pdev->dev,
			"failed to create mutex handle\n");
		ret = -ENOMEM;
		goto err_mutex_alloc;
	}

	mutex_init(g_mutex_for_fo);

	/* added for phy cut off when boot up */
	clk_enable(g_s5ptv_status.i2c_phy_clk);
	s5p_hdmi_phy_power(false);
	clk_disable(g_s5ptv_status.i2c_phy_clk);
	s5p_tv_base_clk_gate(false);

	return 0;

err_mutex_alloc:
#ifdef CONFIG_TV_FB
err_register_fb:
	s5ptvfb_free_framebuffer();
err_alloc_fb:
#endif
err_video_register_device:
	free_irq(IRQ_TVENC, pdev);

err_tvenc_irq:
	free_irq(IRQ_HDMI, pdev);

err_hdmi_irq:
	free_irq(IRQ_MIXER, pdev);

err_vm_irq:
	s5p_hdmi_release(pdev);

err_s5p_hdmi_probe:
	s5p_vmixer_release(pdev);

err_s5p_vmixer_probe:
	s5p_vp_release(pdev);

err_s5p_vp_probe:
	s5p_sdout_release(pdev);

err_s5p_sdout_probe:
	pr_err("%s::not found (%d).\n", __func__, ret);

	return ret;
}
Beispiel #3
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;
}