⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sis_main.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return 0;}static voidsisfb_set_disp(int con, struct fb_var_screeninfo *var, struct fb_info *info){	struct sis_video_info    *ivideo = (struct sis_video_info *)info->par;	struct display           *display;	struct display_switch    *sw;	struct fb_fix_screeninfo fix;	long   flags;	display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;	sisfb_get_fix(&fix, con, info);	display->var = *var;	display->screen_base = (char *)ivideo->video_vbase;	display->visual = fix.visual;	display->type = fix.type;	display->type_aux = fix.type_aux;	display->ypanstep = fix.ypanstep;	display->ywrapstep = fix.ywrapstep;	display->line_length = fix.line_length;	display->can_soft_blank = 1;	display->inverse = ivideo->sisfb_inverse;	display->next_line = fix.line_length;	save_flags(flags);	switch(ivideo->video_bpp) {#ifdef FBCON_HAS_CFB8	case 8:		sw = ivideo->accel ? &fbcon_sis8 : &fbcon_cfb8;		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		sw = ivideo->accel ? &fbcon_sis16 : &fbcon_cfb16;		display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb16;		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		sw = ivideo->accel ? &fbcon_sis32 : &fbcon_cfb32;		display->dispsw_data = &ivideo->sis_fbcon_cmap.cfb32;		break;#endif	default:		sw = &fbcon_dummy;		break;	}	memcpy(&ivideo->sisfb_sw, sw, sizeof(*sw));	display->dispsw = &ivideo->sisfb_sw;		restore_flags(flags);        if(ivideo->sisfb_ypan) {  	    /* display->scrollmode = 0;  */	} else {	    display->scrollmode = SCROLL_YREDRAW;	    ivideo->sisfb_sw.bmove = fbcon_redraw_bmove;	}}static voidsisfb_do_install_cmap(int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	        if(con != ivideo->currcon) return;        if(fb_display[con].cmap.len) {		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);        } else {		int size = sisfb_get_cmap_len(&fb_display[con].var);		fb_set_cmap(fb_default_cmap(size), 1, sisfb_setcolreg, info);	}}static intsisfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;		if(con == -1) {		memcpy(var, &ivideo->default_var, sizeof(struct fb_var_screeninfo));	} else {		*var = fb_display[con].var;	}	if(ivideo->sisfb_fstn) {	   	if(var->xres == 320 && var->yres == 480) var->yres = 240;        }	return 0;}static intsisfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	unsigned int cols, rows;	int err;	fb_display[con].var.activate = FB_ACTIVATE_NOW;	        if(sisfb_do_set_var(var, con == ivideo->currcon, info)) {		sisfb_crtc_to_var(ivideo, var);		return -EINVAL;	}	sisfb_crtc_to_var(ivideo, var);	sisfb_set_disp(con, var, info);	if(info->changevar) {		(*info->changevar)(con);	}	if((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) {		return err;	}	sisfb_do_install_cmap(con, info);	cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;	rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;	#if 0	/* Why was this called here? */ 	vc_resize_con(rows, cols, fb_display[con].conp->vc_num); #endif		return 0;}static intsisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	struct display *display;		display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;	        if(con == ivideo->currcon) {			return fb_get_cmap(cmap, kspc, sis_getcolreg, info);			} else if(display->cmap.len) {			fb_copy_cmap(&display->cmap, cmap, kspc ? 0 : 2);			} else {			int size = sisfb_get_cmap_len(&display->var);		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);			}	return 0;}static intsisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	struct display *display;	int err, size;		display = (con >= 0) ? &fb_display[con] : &ivideo->sis_disp;		size = sisfb_get_cmap_len(&display->var);	if(display->cmap.len != size) {		err = fb_alloc_cmap(&display->cmap, size, 0);		if(err)	return err;	}        	if(con == ivideo->currcon) {		return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);	} else {		fb_copy_cmap(cmap, &display->cmap, kspc ? 0 : 1);	}	return 0;}static intsisfb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info* info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	int err;	if(var->vmode & FB_VMODE_YWRAP) {		if((var->yoffset < 0) || 		   (var->yoffset >= fb_display[con].var.yres_virtual) || 		   (var->xoffset)) {			return -EINVAL;		}	} else {		if((var->xoffset+fb_display[con].var.xres > fb_display[con].var.xres_virtual) ||		   (var->yoffset+fb_display[con].var.yres > fb_display[con].var.yres_virtual)) {			return -EINVAL;		}	}        if(con == ivideo->currcon) {	   	if((err = sisfb_pan_var(ivideo, var)) < 0) return err;	}	fb_display[con].var.xoffset = var->xoffset;	fb_display[con].var.yoffset = var->yoffset;	if(var->vmode & FB_VMODE_YWRAP) {		fb_display[con].var.vmode |= FB_VMODE_YWRAP;	} else {		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;	}	return 0;}static intsisfb_update_var(int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	        return(sisfb_pan_var(ivideo, &fb_display[con].var));}static intsisfb_switch(int con, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	int cols, rows;        if(fb_display[ivideo->currcon].cmap.len) {		fb_get_cmap(&fb_display[ivideo->currcon].cmap, 1, sis_getcolreg, info);	}	fb_display[con].var.activate = FB_ACTIVATE_NOW;	if(!memcmp(&fb_display[con].var, &fb_display[ivideo->currcon].var,	                           	sizeof(struct fb_var_screeninfo))) {		ivideo->currcon = con;		return 1;	}	ivideo->currcon = con;	sisfb_do_set_var(&fb_display[con].var, 1, info);	sisfb_set_disp(con, &fb_display[con].var, info);	sisfb_do_install_cmap(con, info);	cols = sisbios_mode[ivideo->sisfb_mode_idx].cols;	rows = sisbios_mode[ivideo->sisfb_mode_idx].rows;	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);	sisfb_update_var(con, info);	return 1;}static voidsisfb_blank(int blank, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;		sisfb_myblank(ivideo, blank);}#endif/* ------------ FBDev related routines for 2.6 series ----------- */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)static intsisfb_open(struct fb_info *info, int user){    	return 0;}static intsisfb_release(struct fb_info *info, int user){    	return 0;}static intsisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,		unsigned transp, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;		if(regno >= sisfb_get_cmap_len(&info->var)) return 1;	switch(info->var.bits_per_pixel) {	case 8:	        outSISREG(SISDACA, regno);		outSISREG(SISDACD, (red >> 10));		outSISREG(SISDACD, (green >> 10));		outSISREG(SISDACD, (blue >> 10));		if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {		        outSISREG(SISDAC2A, regno);			outSISREG(SISDAC2D, (red >> 8));			outSISREG(SISDAC2D, (green >> 8));			outSISREG(SISDAC2D, (blue >> 8));		}		break;	case 16:		((u32 *)(info->pseudo_palette))[regno] =		    ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);		break;	case 32:		red >>= 8;		green >>= 8;		blue >>= 8;		((u32 *)(info->pseudo_palette))[regno] =				(red << 16) | (green << 8) | (blue);		break;	}	return 0;}static intsisfb_set_par(struct fb_info *info){	int err;        if((err = sisfb_do_set_var(&info->var, 1, info))) {		return err;	}	sisfb_get_fix(&info->fix, info->currcon, info);	return 0;}static intsisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	unsigned int htotal = 0, vtotal = 0, myrateindex = 0;	unsigned int drate = 0, hrate = 0, maxyres;	int found_mode = 0;	int refresh_rate, search_idx;	BOOLEAN recalc_clock = FALSE;	u32 pixclock;	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;	pixclock = var->pixclock;	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {		vtotal += var->yres;		vtotal <<= 1;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {		vtotal += var->yres;		vtotal <<= 2;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {		vtotal += var->yres;		vtotal <<= 1;	} else 	vtotal += var->yres;	if(!(htotal) || !(vtotal)) {		SISFAIL("sisfb: no valid timing data");	}	search_idx = 0;	while( (sisbios_mode[search_idx].mode_no[0] != 0) &&	       (sisbios_mode[search_idx].xres <= var->xres) ) {		if( (sisbios_mode[search_idx].xres == var->xres) &&		    (sisbios_mode[search_idx].yres == var->yres) &&		    (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {		        if(sisfb_validate_mode(ivideo, search_idx, ivideo->currentvbflags) > 0) {			   found_mode = 1;			   break;			}		}		search_idx++;	}	if(!found_mode) {                search_idx = 0;		while(sisbios_mode[search_idx].mode_no[0] != 0) {		   if( (var->xres <= sisbios_mode[search_idx].xres) &&		       (var->yres <= sisbios_mode[search_idx].yres) &&		       (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {		          if(sisfb_validate_mode(ivideo,search_idx, ivideo->currentvbflags) > 0) {			     found_mode = 1;			     break;			  }		   }		   search_idx++;	        }		if(found_mode) {			printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",		   		var->xres, var->yres, var->bits_per_pixel,				sisbios_mode[search_idx].xres,				sisbios_mode[search_idx].yres,				var->bits_per_pixel);			var->xres = sisbios_mode[search_idx].xres;		      	var->yres = sisbios_mode[search_idx].yres;		} else {		   	printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",				var->xres, var->yres, var->bits_per_pixel);		   	return -EINVAL;		}	}	if( ((ivideo->vbflags & VB_LVDS) ||			/* Slave modes on LVDS and 301B-DH */	     ((ivideo->vbflags & VB_30xBDH) && (ivideo->currentvbflags & CRT2_LCD))) &&	    (var->bits_per_pixel == 8) ) {	    	refresh_rate = 60;		recalc_clock = TRUE;	} else if( (ivideo->current_htotal == htotal) &&	/* x=x & y=y & c=c -> assume depth change */	    	   (ivideo->current_vtotal == vtotal) &&	    	   (ivideo->current_pixclock == pixclock) ) {		drate = 1000000000 / pixclock;	        hrate = (drate * 1000) / htotal;	        refresh_rate = (unsigned int) (hrate * 2 / vtotal);	} else if( ( (ivideo->current_htotal != htotal) ||	/* x!=x | y!=y & c=c -> invalid pixclock */	    	     (ivideo->current_vtotal != vtotal) ) &&	    	   (ivideo->current_pixclock == var->pixclock) ) {		if(ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]]) {			refresh_rate = ivideo->sisfb_lastrates[sisbios_mode[search_idx].mode_no[ivideo->mni]];		} else if(ivideo->sisfb_parm_rate != -1) {			/* Sic, sisfb_parm_rate - want to know originally desired rate here */			refresh_rate = ivideo->sisfb_parm_rate;		} else {			refresh_rate = 60;		}		recalc_clock = TRUE;	} else if((pixclock) && (htotal) && (vtotal)) {		drate = 1000000000 / pixclock;	   	hrate = (drate * 1000) / htotal;	   	refresh_rate = (unsigned int) (hrate * 2 / vtotal);	} else if(ivideo->current_refresh_rate) {		refresh_rate = ivideo->current_refresh_rate;		recalc_clock = TRUE;	} else {		refresh_rate = 60;		recalc_clock = TRUE;	}	myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);	/* Eventually recalculate timing and clock */	if(recalc_clock) {	   if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;	   var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&ivideo->SiS_Pr, 	   					&ivideo->sishw_ext, 						sisbios_mode[search_idx].mode_no[ivideo->mni], 						myrateindex));	   sisfb_mode_rate_to_ddata(&ivideo->SiS_Pr, &ivideo->sishw_ext,		 		    sisbios_mode[search_idx].mode_no[ivideo->mni], myrateindex,	var);	   if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {	      var->pixclock <<= 1;	   }	}	if(ivideo->sisfb_thismonitor.datavalid) {	   if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, search_idx,	                         myrateindex, refresh_rate)) {	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");	   }	}	/* Adapt RGB settings */	sisfb_bpp_to_var(ivideo, var);		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -