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

📄 sis_main.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		break;	default:		ivideo->video_cmap_len = 16;		printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo->video_bpp);		ivideo->accel = 0;		break;   	}}static voidsisfb_bpp_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	ivideo->video_cmap_len = sisfb_get_cmap_len(var);		switch(var->bits_per_pixel) {	case 8:		var->red.offset = var->green.offset = var->blue.offset = 0;		var->red.length = var->green.length = var->blue.length = 6;		break;	case 16:		var->red.offset = 11;		var->red.length = 5;		var->green.offset = 5;		var->green.length = 6;		var->blue.offset = 0;		var->blue.length = 5;		var->transp.offset = 0;		var->transp.length = 0;		break;	case 32:		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.offset = 24;		var->transp.length = 8;		break;	}}static intsisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,		      struct fb_info *info){	struct sis_video_info *ivideo = (struct sis_video_info *)info->par;	unsigned int htotal = 0, vtotal = 0; 	unsigned int drate = 0, hrate = 0;	int found_mode = 0;	int old_mode;	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)) {		DPRINTK("sisfb: Invalid 'var' information\n");		return -EINVAL;	}	if(pixclock && htotal && vtotal) {	   	drate = 1000000000 / pixclock;	   	hrate = (drate * 1000) / htotal;	   	ivideo->refresh_rate = (unsigned int) (hrate * 2 / vtotal);	} else {	   	ivideo->refresh_rate = 60;	}	old_mode = ivideo->sisfb_mode_idx;	ivideo->sisfb_mode_idx = 0;	while( (sisbios_mode[ivideo->sisfb_mode_idx].mode_no[0] != 0) &&	       (sisbios_mode[ivideo->sisfb_mode_idx].xres <= var->xres) ) {		if( (sisbios_mode[ivideo->sisfb_mode_idx].xres == var->xres) &&		    (sisbios_mode[ivideo->sisfb_mode_idx].yres == var->yres) &&		    (sisbios_mode[ivideo->sisfb_mode_idx].bpp == var->bits_per_pixel)) {			ivideo->mode_no = sisbios_mode[ivideo->sisfb_mode_idx].mode_no[ivideo->mni];			found_mode = 1;			break;		}		ivideo->sisfb_mode_idx++;	}	if(found_mode) {		ivideo->sisfb_mode_idx = sisfb_validate_mode(ivideo, 				ivideo->sisfb_mode_idx, ivideo->currentvbflags);	} else {		ivideo->sisfb_mode_idx = -1;	}       	if(ivideo->sisfb_mode_idx < 0) {		printk(KERN_ERR "sisfb: Mode %dx%dx%d not supported\n", var->xres,		       var->yres, var->bits_per_pixel);		ivideo->sisfb_mode_idx = old_mode;		return -EINVAL;	}	if(sisfb_search_refresh_rate(ivideo, ivideo->refresh_rate, ivideo->sisfb_mode_idx) == 0) {		ivideo->rate_idx = sisbios_mode[ivideo->sisfb_mode_idx].rate_idx;		ivideo->refresh_rate = 60;	}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	if(ivideo->sisfb_thismonitor.datavalid) {	   if(!sisfb_verify_rate(ivideo, &ivideo->sisfb_thismonitor, ivideo->sisfb_mode_idx,	                         ivideo->rate_idx, ivideo->refresh_rate)) {	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");	   }	}#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {#else	if(isactive) {#endif			sisfb_pre_setmode(ivideo);		if(SiSSetMode(&ivideo->SiS_Pr, &ivideo->sishw_ext, ivideo->mode_no) == 0) {			printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);			return -EINVAL;		}				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);				sisfb_post_setmode(ivideo);				ivideo->video_bpp = sisbios_mode[ivideo->sisfb_mode_idx].bpp;		ivideo->video_vwidth  = ivideo->video_width  = sisbios_mode[ivideo->sisfb_mode_idx].xres;		ivideo->video_vheight = ivideo->video_height = sisbios_mode[ivideo->sisfb_mode_idx].yres;		ivideo->video_linelength = ivideo->video_width * (ivideo->video_bpp >> 3);		ivideo->org_x = ivideo->org_y = 0;		ivideo->accel = 0;		if(ivideo->sisfb_accel) {		   ivideo->accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;		}		sisfb_set_vparms(ivideo);				ivideo->current_width = ivideo->video_width;		ivideo->current_height = ivideo->video_height;		ivideo->current_bpp = ivideo->video_bpp;		ivideo->current_htotal = htotal;		ivideo->current_vtotal = vtotal;		ivideo->current_pixclock = var->pixclock;		ivideo->current_refresh_rate = ivideo->refresh_rate;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)                ivideo->sisfb_lastrates[ivideo->mode_no] = ivideo->refresh_rate;#endif			}	return 0;}static intsisfb_pan_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	unsigned int base;	if(var->xoffset > (var->xres_virtual - var->xres)) {		return -EINVAL;	}	if(var->yoffset > (var->yres_virtual - var->yres)) {		return -EINVAL;	}				base = var->yoffset * var->xres_virtual + var->xoffset;		        /* calculate base bpp dep. */        switch(var->bits_per_pixel) {	case 32:            	break;        case 16:        	base >>= 1;        	break;	case 8:        default:        	base >>= 2;            	break;        }		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);        outSISIDXREG(SISCR, 0x0D, base & 0xFF);	outSISIDXREG(SISCR, 0x0C, (base >> 8) & 0xFF);	outSISIDXREG(SISSR, 0x0D, (base >> 16) & 0xFF);	if(ivideo->sisvga_engine == SIS_315_VGA) {		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);	}        if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {		orSISIDXREG(SISPART1, ivideo->CRT2_write_enable, 0x01);        	outSISIDXREG(SISPART1, 0x06, (base & 0xFF));        	outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));        	outSISIDXREG(SISPART1, 0x04, ((base >> 16) & 0xFF));		if(ivideo->sisvga_engine == SIS_315_VGA) {			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);		}        }	return 0;}/* ------------ FBDev related routines for 2.4 series ----------- */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)static voidsisfb_crtc_to_var(struct sis_video_info *ivideo, struct fb_var_screeninfo *var){	u16 VRE, VBE, VRS, VBS, VDE, VT;	u16 HRE, HBE, HRS, HBS, HDE, HT;	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;	int A, B, C, D, E, F, temp;	unsigned int hrate, drate, maxyres;	inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);	if(sr_data & SIS_INTERLACED_MODE)	   var->vmode = FB_VMODE_INTERLACED;	else	   var->vmode = FB_VMODE_NONINTERLACED;	switch((sr_data & 0x1C) >> 2) {	case SIS_8BPP_COLOR_MODE:		var->bits_per_pixel = 8;		break;	case SIS_16BPP_COLOR_MODE:		var->bits_per_pixel = 16;		break;	case SIS_32BPP_COLOR_MODE:		var->bits_per_pixel = 32;		break;	}	sisfb_bpp_to_var(ivideo, var);		inSISIDXREG(SISSR, 0x0A, sr_data);        inSISIDXREG(SISCR, 0x06, cr_data);        inSISIDXREG(SISCR, 0x07, cr_data2);	VT = (cr_data & 0xFF) | 	     ((u16) (cr_data2 & 0x01) << 8) |	     ((u16) (cr_data2 & 0x20) << 4) | 	     ((u16) (sr_data  & 0x01) << 10);	A = VT + 2;	inSISIDXREG(SISCR, 0x12, cr_data);	VDE = (cr_data & 0xff) | 	      ((u16) (cr_data2 & 0x02) << 7) |	      ((u16) (cr_data2 & 0x40) << 3) | 	      ((u16) (sr_data  & 0x02) << 9);	E = VDE + 1;	inSISIDXREG(SISCR, 0x10, cr_data);	VRS = (cr_data & 0xff) | 	      ((u16) (cr_data2 & 0x04) << 6) |	      ((u16) (cr_data2 & 0x80) << 2) | 	      ((u16) (sr_data  & 0x08) << 7);	F = VRS + 1 - E;	inSISIDXREG(SISCR, 0x15, cr_data);	inSISIDXREG(SISCR, 0x09, cr_data3);	if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;	VBS = (cr_data & 0xff) | 	      ((u16) (cr_data2 & 0x08) << 5) |	      ((u16) (cr_data3 & 0x20) << 4) | 	      ((u16) (sr_data & 0x04) << 8);	inSISIDXREG(SISCR, 0x16, cr_data);	VBE = (cr_data & 0xff) | ((u16) (sr_data & 0x10) << 4);	temp = VBE - ((E - 1) & 511);	B = (temp > 0) ? temp : (temp + 512);	inSISIDXREG(SISCR, 0x11, cr_data);	VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);	temp = VRE - ((E + F - 1) & 31);	C = (temp > 0) ? temp : (temp + 32);	D = B - F - C;        var->yres = E;	var->upper_margin = D;	var->lower_margin = F;	var->vsync_len = C;	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {	   var->yres <<= 1;	   var->upper_margin <<= 1;	   var->lower_margin <<= 1;	   var->vsync_len <<= 1;	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {	   var->yres >>= 1;	   var->upper_margin >>= 1;	   var->lower_margin >>= 1;	   var->vsync_len >>= 1;	}	inSISIDXREG(SISSR, 0x0b, sr_data);	inSISIDXREG(SISCR, 0x00, cr_data);	HT = (cr_data & 0xff) | ((u16) (sr_data & 0x03) << 8);	A = HT + 5;	inSISIDXREG(SISCR, 0x01, cr_data);	HDE = (cr_data & 0xff) | ((u16) (sr_data & 0x0C) << 6);	E = HDE + 1;	inSISIDXREG(SISCR, 0x04, cr_data);	HRS = (cr_data & 0xff) | ((u16) (sr_data & 0xC0) << 2);	F = HRS - E - 3;	inSISIDXREG(SISCR, 0x02, cr_data);	HBS = (cr_data & 0xff) | ((u16) (sr_data & 0x30) << 4);	inSISIDXREG(SISSR, 0x0c, sr_data);	inSISIDXREG(SISCR, 0x03, cr_data);	inSISIDXREG(SISCR, 0x05, cr_data2);	HBE = (cr_data & 0x1f) | 	      ((u16) (cr_data2 & 0x80) >> 2) |	      ((u16) (sr_data  & 0x03) << 6);	HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);	temp = HBE - ((E - 1) & 255);	B = (temp > 0) ? temp : (temp + 256);	temp = HRE - ((E + F + 3) & 63);	C = (temp > 0) ? temp : (temp + 64);	D = B - F - C;	var->xres = var->xres_virtual = E * 8;	if((var->xres == 320) &&	   (var->yres == 200 || var->yres == 240)) {		/* Terrible hack, but the correct CRTC data for	  	 * these modes only produces a black screen...	  	 */       		var->left_margin = (400 - 376);       		var->right_margin = (328 - 320);       		var->hsync_len = (376 - 328);	} else {	   	var->left_margin = D * 8;	   	var->right_margin = F * 8;	   	var->hsync_len = C * 8;	}	var->activate = FB_ACTIVATE_NOW;	var->sync = 0;	mr_data = inSISREG(SISMISCR);	if(mr_data & 0x80)	   var->sync &= ~FB_SYNC_VERT_HIGH_ACT;	else	   var->sync |= FB_SYNC_VERT_HIGH_ACT;	if(mr_data & 0x40)	   var->sync &= ~FB_SYNC_HOR_HIGH_ACT;	else	   var->sync |= FB_SYNC_HOR_HIGH_ACT;	VT += 2;	VT <<= 1;	HT = (HT + 5) * 8;	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {	   VT <<= 1;	}	hrate = ivideo->refresh_rate * VT / 2;	drate = (hrate * HT) / 1000;	var->pixclock = (u32) (1000000000 / drate);	if(ivideo->sisfb_ypan) {	   maxyres = ivideo->heapstart / (var->xres * (var->bits_per_pixel >> 3));	   if(maxyres > 32767) maxyres = 32767;	   if(ivideo->sisfb_max) {	      var->yres_virtual = maxyres;	   } else {	      if(var->yres_virtual > maxyres) {	         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	}	

⌨️ 快捷键说明

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