Exemple #1
0
char *vout_get_edid(int no)
{
	vout_t *vo;
	int ret;

	DBG_DETAIL("(%d)\n",no);

	if( (vo = vout_get_entry(no)) == 0 ){
		return 0;
	}

	if( vo->status & VPP_VOUT_STS_EDID ){
		DBG_MSG("edid exist\n");
		return vo->edid;
	}

	vout_change_status(vo,VPP_VOUT_STS_EDID,0);
#ifdef CONFIG_VOUT_EDID_ALLOC
	if( vo->edid == 0 ){
//		DBG_MSG("edid buf alloc\n");
		vo->edid = (char *) kmalloc(128*EDID_BLOCK_MAX,GFP_KERNEL);
		if( !vo->edid ){
			DBG_ERR("edid buf alloc\n");
			return 0;
		}
	}
#endif

	ret = 1;	
	if( vo->dev && vo->dev->get_edid ){
		ret = vo->dev->get_edid(vo->edid);
	}
	else {
		if( vo->inf->get_edid ){
			ret = vo->inf->get_edid(vo,(int)vo->edid);
		}
	}
	
	if( ret == 0 ){
		vout_info_t *info;
		
		DBG_DETAIL("edid read\n");
		vout_change_status(vo,VPP_VOUT_STS_EDID,1);
		if( (info = vout_get_info_entry((g_vpp.virtual_display)?1:no)) ){
			info->force_config = 1;
		}
		return vo->edid;
	}
	else {
		DBG_ERR("read edid fail\n");
	}

#ifdef CONFIG_VOUT_EDID_ALLOC
	if( vo->edid ){
		kfree(vo->edid);
		vo->edid = 0;
	}
#endif
	return 0;
}
Exemple #2
0
int vout_chkplug(int no)
{
	vout_t *vo;
	vout_inf_t *inf;
	int ret = 0;

	DBG_DETAIL("(%d)\n",no);

	if( (vo = vout_get_entry(no)) == 0 ){
		return 0;
	}

	if( vo->inf == 0 ){
		return 0;
	}

	if( (inf = vout_inf_get_entry(vo->inf->mode)) == 0 ){
		return 0;
	}

	if( vo->dev && vo->dev->check_plugin ){
		ret = vo->dev->check_plugin(0);
	}
	else {
		ret = inf->chkplug(vo,0);
	}
	vout_change_status(vo,VPP_VOUT_STS_PLUGIN,ret);
	return ret; 
}
Exemple #3
0
int vout_set_mode(int no,vout_inf_mode_t mode)
{
	vout_t *vo;

	DBG_DETAIL("(%d,%d)\n",no,mode);

	if( vout_query_inf_support(no,mode)==0 ){
		DBG_ERR("not support this interface(%d,%d)\n",no,mode);
		return -1;
	}

	vo = vout_get_entry(no);
	if( vo->inf ){
		if( vo->inf->mode == mode )
			return 0;
		vo->inf->uninit(vo,0);
		vout_change_status(vo,VPP_VOUT_STS_ACTIVE,0);
		if( vo->dev )
			vo->dev->set_power_down(1);
	}
	
	vo->inf = vout_inf_get_entry(mode);
	vo->dev = ( vo->ext_dev && (vo->ext_dev->mode == mode) )? vo->ext_dev:0;
	vo->inf->init(vo,0);
	vout_change_status(vo,VPP_VOUT_STS_ACTIVE,1);
	return 0;
}
Exemple #4
0
static void vo_do_plug
(
    void *ptr		/*!<; // work input data */
)
#endif
{
    vout_t *vo;
    int plugin;

    if( vo_plug_func == 0 )
        return;

    vo = vout_get_entry(vo_plug_vout);
    govrh_set_dvo_enable(vo->govr,1);
    plugin = vo_plug_func(1);
    govrh_set_dvo_enable(vo->govr,plugin);
    vout_change_status(vo,VPP_VOUT_STS_PLUGIN,plugin);
    vo_plug_flag = 0;
    DBG_DETAIL("vo_do_plug %d\n",plugin);
    vppif_reg32_write(GPIO_BASE_ADDR+0x300+VPP_VOINT_NO,0x80,7,1);	// GPIO irq enable
    vppif_reg32_write(GPIO_BASE_ADDR+0x80,0x1<<VPP_VOINT_NO,VPP_VOINT_NO,0x0);	// GPIO input mode
#ifdef __KERNEL__
    vpp_netlink_notify(USER_PID,DEVICE_PLUG_IN,plugin);
    vpp_netlink_notify(WP_PID,DEVICE_PLUG_IN,plugin);
#endif
    return;
}
Exemple #5
0
int vout_set_blank(unsigned int mask,vout_blank_t arg)
{
	int i;
	vout_t *vo;

	DBG_DETAIL("(0x%x,%d)\n",mask,arg);

	if( mask == 0 )
		return 0;

	for(i=0;i<VPP_VOUT_NUM;i++){
		if( (mask & (0x1 << i)) == 0 )
			continue;

		if( (vo = vout_get_entry(i)) ){
			if( vo->inf ){
				vout_change_status(vo,VPP_VOUT_STS_BLANK,arg);
				vo->inf->blank(vo,arg);
				if( vo->dev && vo->dev->set_power_down ){
					vo->dev->set_power_down((arg==VOUT_BLANK_POWERDOWN)?1:0);
				}
			}
		}
	}

	if(1){
		int govr_enable_mask,govr_mask;
		govrh_mod_t *govr;
		
		govr_enable_mask = 0;
		for(i=0;i<VPP_VOUT_NUM;i++){
			if( (vo = vout_get_entry(i)) ){
				if( vo->govr ){
					govr_mask = (vo->govr->mod == VPP_MOD_GOVRH)? 0x1:0x2;
					govr_enable_mask |= (vo->status & VPP_VOUT_STS_BLANK)? 0:govr_mask;
				}
			}
		}
		for(i=0;i<VPP_VOUT_INFO_NUM;i++){
			govr = (i==0)? p_govrh:p_govrh2;
			govr_mask = 0x1 << i;
			govrh_set_MIF_enable(govr,(govr_enable_mask & govr_mask)? 1:0);
		}
	}
	return 0;
}
Exemple #6
0
int vout_config(unsigned int mask,vout_info_t *info)
{
	vout_t *vo;
	vpp_timing_t *p_timing;
	int no = VPP_VOUT_NUM;
	int i;
	unsigned int govr_mask = 0;

	DBG_DETAIL("(0x%x)\n",mask);

	if( mask == 0 )
		return 0;

	for(i=0;i<VPP_VOUT_NUM;i++){
		if( (mask & (0x1 << i)) == 0 )
			continue;

		if( no == VPP_VOUT_NUM ){
			no = i;		// get first vo
		}
		
		if( vout_chkplug(i) ){
			no = i;
			break;
		}
	}

	if( (p_timing = vout_find_video_mode(no,info)) == 0 ){
		return -1;
	}
	
	info->option = p_timing->option;
	for(i=0;i<VPP_VOUT_NUM;i++){
		if( (mask & (0x1 << i)) == 0 )
			continue;

		if( (vo = vout_get_entry(i)) == 0 )
			continue;

		if( vo->govr == 0 )
			continue;

		if( (govr_mask & (0x1 << vo->govr->mod)) == 0 ){
			govrh_set_timing(vo->govr,p_timing);
			govr_mask |= (0x1 << vo->govr->mod);
		}

		if( vo->inf ){
			vo->inf->config(vo,(int)info);
			if( vo->dev )
				vo->dev->config(info);
		}
	}
	return 0;
}
Exemple #7
0
int vout_query_inf_support(int no,vout_inf_mode_t mode)
{
	vout_t *vo;

	if( no >= VPP_VOUT_NUM )
		return 0;

	if( mode >= VOUT_INF_MODE_MAX ){
		return 0;
	}

	vo = vout_get_entry(no);
	return (vo->fix_cap & BIT(mode))? 1:0;
}
Exemple #8
0
int vout_inf_chkplug(int no,vout_inf_mode_t mode)
{
	vout_t *vo;
	vout_inf_t *inf;
	int plugin = 0;

	DBG_MSG("(%d,%d)\n",no,mode);
	if( vout_query_inf_support(no,mode) == 0 )
		return 0;

	vo = vout_get_entry(no);
	if( (inf = vout_inf_get_entry(mode)) ){
		if( inf->chkplug ){
			plugin = inf->chkplug(vo,0);
		}
	}
	return plugin;
}
Exemple #9
0
void vout_set_tg_enable(unsigned int mask,int enable)
{
	int i;
	vout_t *vo;

	if( mask == 0 )
		return;

	for(i=0;i<VPP_VOUT_NUM;i++){
		if( (mask & (0x1 << i)) == 0 )
			continue;
		if( (vo = vout_get_entry(i)) ){
			if( vo->govr ){
				govrh_set_tg_enable(vo->govr,enable);
			}
		}
	}
}
Exemple #10
0
/*----------------------- vout control API --------------------------------------*/
void vout_set_framebuffer(unsigned int mask,vdo_framebuf_t *fb)
{
	int i;
	vout_t *vo;

	if( mask == 0 )
		return;

	for(i=0;i<VPP_VOUT_NUM;i++){
		if( (mask & (0x1 << i)) == 0 )
			continue;
		if( (vo = vout_get_entry(i)) ){
			if( vo->govr ){
				vo->govr->fb_p->set_framebuf(fb);
			}
		}
	}
}
Exemple #11
0
int vout_get_edid_option(int no)
{
	vout_t *vo;

	DBG_DETAIL("(%d)\n",no);

	if( (vo = vout_get_entry(no)) == 0 ){
		return 0;
	}

	if( vo->edid_info.option ){
		return vo->edid_info.option;
	}

	if( vout_get_edid(no) == 0 ){
		return 0;
	}

	edid_parse(vo->edid,&vo->edid_info);
	return vo->edid_info.option;
}
Exemple #12
0
vout_t *vout_get_entry_adapter(vout_mode_t mode)
{
	int no;

	switch(mode){
		case VOUT_SD_DIGITAL:
		case VOUT_DVI:
		case VOUT_LCD:
		case VOUT_DVO2HDMI:
		case VOUT_SD_ANALOG:
		case VOUT_VGA:
			no = VPP_VOUT_NUM_DVI;
			break;
		case VOUT_HDMI:
		case VOUT_LVDS:
			no = VPP_VOUT_NUM_HDMI;
			break;
		default:
			no = VPP_VOUT_NUM;
			break;
	}
	return vout_get_entry(no);
}
Exemple #13
0
vpp_timing_t *vout_find_video_mode(int no,vout_info_t *info)
{
	vout_t *vo;
	char *edid = 0;
	unsigned int vo_option;
	vpp_timing_t *p_timing = 0;
	unsigned int opt = 0;
	int index = 0;
	vpp_timing_t *edid_timing = 0;

	if( (vo = vout_get_entry(no)) == 0 )
		return 0;

//	if( vo->num != VPP_VOUT_NUM_HDMI )	// wm3445 simulate dual display
	{
	if( info->fixed_timing ){
		p_timing = info->fixed_timing;
		DBG_MSG("%d(fixed timer)\n",no);
		goto find_video_mode;
	}
	}

	vo_option = vo->option[1];
	DBG_MSG("(%d,%dx%d@%d,%d),%s\n",no,info->resx,info->resy,info->pixclk,info->fps,(vo_option & VOUT_OPT_INTERLACE)?"i":"p");
	if( vo->status & VPP_VOUT_STS_PLUGIN ){
		if( (edid = vout_get_edid(no)) ){
			if( edid_parse(edid,&vo->edid_info) == 0 ){
				edid = 0;
			}
			else {
				opt = info->fps | ((vo_option & VOUT_OPT_INTERLACE)? EDID_TMR_INTERLACE:0);
				if( edid_find_support(&vo->edid_info,info->resx,info->resy,opt,&edid_timing) ){
					if( edid_timing ){
						p_timing = edid_timing;
						DBG_MSG("Use EDID detail timing\n");
						goto find_video_mode;
					}
				}
			}
		}
	}

	do {
		p_timing = vpp_get_video_mode(info->resx,info->resy,info->pixclk,&index);
		DBG_MSG("find(%dx%d@%d) -> %dx%d\n",info->resx,info->resy,info->pixclk,p_timing->hpixel,p_timing->vpixel);
		info->resx = p_timing->hpixel;
		info->resy = p_timing->vpixel;
		if( p_timing->option & VPP_OPT_INTERLACE ){
			info->resy *= 2;
		}
		info->fps = VPP_GET_OPT_FPS(p_timing->option);
		opt = info->fps | ((vo_option & VOUT_OPT_INTERLACE)? EDID_TMR_INTERLACE:0);
		if( edid == 0 )
			break;

		DBG_MSG("find edid %dx%d@%d%s\n",info->resx,info->resy,info->fps,(opt & EDID_TMR_INTERLACE)?"i":"p");
		if( edid_find_support(&vo->edid_info,info->resx,info->resy,opt,&edid_timing) ){
			break;
		}

		opt = info->fps | ((vo_option & VOUT_OPT_INTERLACE)? 0:EDID_TMR_INTERLACE);
		DBG_MSG("find edid %dx%d@%d%s\n",info->resx,info->resy,info->fps,(opt & EDID_TMR_INTERLACE)?"i":"p");
		if( edid_find_support(&vo->edid_info,info->resx,info->resy,opt,&edid_timing) ){
			break;
		}

		if( (info->resx <= vpp_video_mode_table[0].hpixel) || (index <=1) ){
			info->resx = vpp_video_mode_table[0].hpixel;
			info->resy = vpp_video_mode_table[0].vpixel;
			break;
		}
		
		do {
			index--;
			p_timing = (vpp_timing_t *) &vpp_video_mode_table[index];
			if( info->resx == p_timing->hpixel ){
				int vpixel;

				vpixel = p_timing->vpixel;
				if( p_timing->option & VPP_OPT_INTERLACE ){
					vpixel *= 2;
					index--;
				}
				if( info->resy == vpixel ){
					continue;
				}
			}
			break;
		} while(1);
		info->resx = vpp_video_mode_table[index].hpixel;
		info->resy = vpp_video_mode_table[index].vpixel;
		if(vpp_video_mode_table[index].option & VPP_OPT_INTERLACE){
			info->resy *= 2;
		}
	} while(1);

	if( edid_timing ){
		p_timing = edid_timing;
		DBG_MSG("Use EDID detail timing\n");
	}
	else {
		if( opt & EDID_TMR_INTERLACE )
			vo_option |= VOUT_OPT_INTERLACE;
		else 
			vo_option &= ~VOUT_OPT_INTERLACE;
		
		p_timing = vpp_get_video_mode_ext(info->resx,info->resy,info->fps,vo_option);
	}
find_video_mode:
	{
		int hpixel,vpixel;
		
		info->resx = p_timing->hpixel;
		info->resy = p_timing->vpixel;
		hpixel = p_timing->hpixel + p_timing->hsync + p_timing->hfp + p_timing->hbp;
		vpixel = p_timing->vpixel + p_timing->vsync + p_timing->vfp + p_timing->vbp;
		if( p_timing->option & VPP_OPT_INTERLACE ) {
			info->resy *= 2;
//			vpixel *= 2;
		}
		info->pixclk = p_timing->pixel_clock;
		info->fps = info->pixclk / (hpixel * vpixel);
		info->resx_virtual = vpp_calc_fb_width(g_vpp.mb_colfmt,info->resx);
		info->resy_virtual = info->resy;
	}
	DBG_MSG("Leave (%dx%d@%d,%d)\n",p_timing->hpixel,p_timing->vpixel,p_timing->pixel_clock,info->fps);
	return p_timing;
}