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; }
static int s5p_tv_v_open(struct file *file) { int ret = 0; mutex_lock(g_mutex_for_fo); if (g_s5ptv_status.tvout_output_enable) { pr_err("%s::tvout drv. already used !!\n", __func__); ret = -EBUSY; goto drv_used; } #ifdef CONFIG_PM if ((g_s5ptv_status.hpd_status) && !(g_s5ptv_status.suspend_status)) { BASEPRINTK("tv is turned on\n"); #endif s5p_set_qos(); s5p_tv_base_clk_gate(true); s5p_tv_base_phy_power(true); #ifdef CONFIG_PM } else BASEPRINTK("tv is off\n"); #endif s5p_tv_if_init_param(); s5p_tv_v4l2_init_param(); mutex_unlock(g_mutex_for_fo); return 0; drv_used: mutex_unlock(g_mutex_for_fo); return ret; }
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; }
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; }
void s5p_tv_late_resume(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 = false; if (g_s5ptv_status.hpd_status == true) { /* clk & power on */ s5p_tv_base_clk_gate(true); 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(true); /* 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); #ifdef CONFIG_TV_FB if (g_s5ptv_status.tvout_output_enable) { s5ptvfb_display_on(&g_s5ptv_status); s5ptvfb_set_par(g_s5ptv_status.fb); } #endif } mutex_unlock(g_mutex_for_fo); BASEPRINTK("()--\n"); return; }
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; }
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; }
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); }
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; }