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

📄 sis_main.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	         var->yres_virtual = maxyres;	      }	   }	   if(var->yres_virtual <= var->yres) {	      var->yres_virtual = var->yres;	   }	} else {	   var->yres_virtual = var->yres;	}}static intsis_getcolreg(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 >= ivideo->video_cmap_len) return 1;	*red   = ivideo->sis_palette[regno].red;	*green = ivideo->sis_palette[regno].green;	*blue  = ivideo->sis_palette[regno].blue;	*transp = 0;	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 >= ivideo->video_cmap_len) return 1;	ivideo->sis_palette[regno].red   = red;	ivideo->sis_palette[regno].green = green;	ivideo->sis_palette[regno].blue  = blue;	switch(ivideo->video_bpp) {#ifdef FBCON_HAS_CFB8	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;#endif#ifdef FBCON_HAS_CFB16	case 16:		ivideo->sis_fbcon_cmap.cfb16[regno] =		    ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		red   >>= 8;		green >>= 8;		blue  >>= 8;		ivideo->sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);		break;#endif	}	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, sisfb_setcolreg, info);        } else {		int size = sisfb_get_cmap_len(&fb_display[con].var);		fb_set_cmap(fb_default_cmap(size), 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;	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);#if 0	/* Why was this called here? */	unsigned int cols, rows;	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);#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) return -EINVAL;	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;	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) ) {

⌨️ 快捷键说明

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