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_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; }
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_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; }
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; }
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; }