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

📄 sis_main.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* 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 = (double) ivideo.refresh_rate * (double) VT / 2;	drate = hrate * HT;	var->pixclock = (u32) (1E12 / drate);	if(sisfb_ypan) {	    var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));	    if(var->yres_virtual <= var->yres) {	        var->yres_virtual = var->yres;	    }	} else	    var->yres_virtual = var->yres;}static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,			 unsigned *transp, struct fb_info *fb_info){	if (regno >= ivideo.video_cmap_len)		return 1;	*red = sis_palette[regno].red;	*green = sis_palette[regno].green;	*blue = sis_palette[regno].blue;	*transp = 0;	return 0;}static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,                           unsigned transp, struct fb_info *fb_info){	if (regno >= ivideo.video_cmap_len)		return 1;	sis_palette[regno].red = red;	sis_palette[regno].green = green;	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:		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;		sis_fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);		break;#endif	}	return 0;}static void sisfb_set_disp(int con, struct fb_var_screeninfo *var,                           struct fb_info *info){	struct fb_fix_screeninfo fix;	long   flags;	struct display *display;	struct display_switch *sw;	if(con >= 0)		display = &fb_display[con];	else		display = &sis_disp;	sisfb_get_fix(&fix, con, 0);	display->screen_base = 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->next_line = fix.line_length;	display->can_soft_blank = 0;	display->inverse = sisfb_inverse;	display->var = *var;	save_flags(flags);	switch (ivideo.video_bpp) {#ifdef FBCON_HAS_CFB8	   case 8:#ifdef SISFBACCEL		sw = ivideo.accel ? &fbcon_sis8 : &fbcon_cfb8;#else		sw = &fbcon_cfb8;#endif		break;#endif#ifdef FBCON_HAS_CFB16	   case 16:#ifdef SISFBACCEL		sw = ivideo.accel ? &fbcon_sis16 : &fbcon_cfb16;#else		sw = &fbcon_cfb16;#endif		display->dispsw_data = sis_fbcon_cmap.cfb16;		break;#endif#ifdef FBCON_HAS_CFB32	   case 32:#ifdef SISFBACCEL		sw = ivideo.accel ? &fbcon_sis32 : &fbcon_cfb32;#else		sw = &fbcon_cfb32;#endif		display->dispsw_data = sis_fbcon_cmap.cfb32;		break;#endif	   default:		sw = &fbcon_dummy;		return;	}	memcpy(&sisfb_sw, sw, sizeof(*sw));	display->dispsw = &sisfb_sw;	restore_flags(flags);        if(sisfb_ypan) {  	    /* display->scrollmode = 0;  */	} else {	    display->scrollmode = SCROLL_YREDRAW;	    sisfb_sw.bmove = fbcon_redraw_bmove;	}}static void sisfb_do_install_cmap(int con, struct fb_info *info){        if (con != currcon)		return;        if (fb_display[con].cmap.len)		fb_set_cmap(&fb_display[con].cmap, 1, sisfb_setcolreg, info);        else		fb_set_cmap(fb_default_cmap(ivideo.video_cmap_len), 1,			    sisfb_setcolreg, info);}static int sisfb_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	if(con == -1)		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));	else		*var = fb_display[con].var; 	/* For FSTN, DSTN */	if (var->xres == 320 && var->yres == 480)		var->yres = 240;	return 0;}static int sisfb_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	int err;	unsigned int cols, rows;	fb_display[con].var.activate = FB_ACTIVATE_NOW;        if(sisfb_do_set_var(var, con == currcon, info)) {		sisfb_crtc_to_var(var);		return -EINVAL;	}	sisfb_crtc_to_var(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[sisfb_mode_idx].cols;	rows = sisbios_mode[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 int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info){        if (con == currcon)		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);	else if (fb_display[con].cmap.len)		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);	return 0;}static int sisfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info){	int err;	if (!fb_display[con].cmap.len) {		err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);		if (err)			return err;	}        	if (con == currcon)		return fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);	else		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	return 0;}static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,			     struct fb_info* info){	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 == currcon) {	   if((err = sisfb_pan_var(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 int sisfb_mmap(struct fb_info *info, struct file *file,		      struct vm_area_struct *vma){	struct fb_var_screeninfo var;	unsigned long start;	unsigned long off;	u32 len, mmio_off;	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;	off = vma->vm_pgoff << PAGE_SHIFT;	start = (unsigned long) ivideo.video_base;	len = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.video_size);#if 0	if (off >= len) {		off -= len;#endif	/* By Jake Page: Treat mmap request with offset beyond heapstart	 *               as request for mapping the mmio area 	 */	mmio_off = PAGE_ALIGN((start & ~PAGE_MASK) + ivideo.heapstart);	if(off >= mmio_off) {		off -= mmio_off;				sisfb_get_var(&var, currcon, info);		if(var.accel_flags) return -EINVAL;		start = (unsigned long) ivideo.mmio_base;		len = PAGE_ALIGN((start & ~PAGE_MASK) + sisfb_mmio_size);	}	start &= PAGE_MASK;	if((vma->vm_end - vma->vm_start + off) > len)	return -EINVAL;	off += start;	vma->vm_pgoff = off >> PAGE_SHIFT;	vma->vm_flags |= VM_IO;   /* by Jake Page; is that really needed? */#if defined(__i386__) || defined(__x86_64__)	if (boot_cpu_data.x86 > 3)		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;#endif	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,				vma->vm_page_prot))		return -EAGAIN;	return 0;}static void sis_get_glyph(struct fb_info *info, SIS_GLYINFO *gly){	struct display *p = &fb_display[currcon];	u16 c;	u8 *cdat;	int widthb;	u8 *gbuf = gly->gmask;	int size;	gly->fontheight = fontheight(p);	gly->fontwidth = fontwidth(p);	widthb = (fontwidth(p) + 7) / 8;	c = gly->ch & p->charmask;	if (fontwidth(p) <= 8)		cdat = p->fontdata + c * fontheight(p);	else		cdat = p->fontdata + (c * fontheight(p) << 1);	size = fontheight(p) * widthb;	memcpy(gbuf, cdat, size);	gly->ngmask = size;}static int sisfb_update_var(int con, struct fb_info *info){        return(sisfb_pan_var(&fb_display[con].var));}static int sisfb_switch(int con, struct fb_info *info){	int cols, rows;        if(fb_display[currcon].cmap.len)		fb_get_cmap(&fb_display[currcon].cmap, 1, sis_getcolreg, info);	fb_display[con].var.activate = FB_ACTIVATE_NOW;	if(!memcmp(&fb_display[con].var, &fb_display[currcon].var,	                           sizeof(struct fb_var_screeninfo))) {		currcon = con;		return 1;	}	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[sisfb_mode_idx].cols;	rows = sisbios_mode[sisfb_mode_idx].rows;	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);	sisfb_update_var(con, info);	return 1;}static void sisfb_blank(int blank, struct fb_info *info){	u8 reg;	if(sisfb_bridgeisslave()) return;	inSISIDXREG(SISCR, 0x17, reg);	if(blank > 0)		reg &= 0x7f;	else		reg |= 0x80;        outSISIDXREG(SISCR, 0x17, reg);	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */}#endif/* ------------ FBDev related routines for 2.5 series ----------- */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)static int sisfb_open(struct fb_info *info, int user){    return 0;}static int sisfb_release(struct fb_info *info, int user){    return 0;}static int sisfb_get_cmap_len(const struct fb_var_screeninfo *var){	int rc = 16;			switch(var->bits_per_pixel) {	case 8:		rc = 256;			break;	case 16:		rc = 16;			break;			case 32:		rc = 16;		break;		}	return rc;}static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,                           unsigned transp, struct fb_info *info){	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 int sisfb_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 int sisfb_check_var(struct fb_var_screeninfo *var,                           struct fb_info *info)

⌨️ 快捷键说明

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