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

📄 vga16fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/* Wait for screen to stabilize. */	mdelay(50);	outb(0x01, VGA_SEQ_I);	outb(par->seq[1], VGA_SEQ_D);	inb(VGA_IS1_RC);	outb(0x20, VGA_ATT_IW);		return 0;}static int vga16fb_set_var(struct fb_var_screeninfo *var, int con,			  struct fb_info *fb){	struct vga16fb_info *info = (struct vga16fb_info*)fb;	struct vga16fb_par par;	struct display *display;	int err;	if (con < 0)		display = fb->disp;	else		display = fb_display + con;	if ((err = vga16fb_decode_var(var, &par, info)) != 0)		return err;	vga16fb_encode_var(var, &par, info);		if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)		return 0;	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {		u32 oldxres, oldyres, oldvxres, oldvyres, oldbpp;		oldxres = display->var.xres;		oldyres = display->var.yres;		oldvxres = display->var.xres_virtual;		oldvyres = display->var.yres_virtual;		oldbpp = display->var.bits_per_pixel;		display->var = *var;		if (oldxres != var->xres || oldyres != var->yres ||		    oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||		    oldbpp != var->bits_per_pixel) {			vga16fb_set_disp(con, info);			if (info->fb_info.changevar)				info->fb_info.changevar(con);		}		if (con == currcon)			vga16fb_set_par(&par, info);	}	return 0;}static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned blue){	static unsigned char map[] = { 000, 001, 010, 011 };	int val;		val = map[red>>14] | ((map[green>>14]) << 1) | ((map[blue>>14]) << 2);	inb_p(0x3DA);   /* ! 0x3BA */	outb_p(regno, 0x3C0);	outb_p(val, 0x3C0);	inb_p(0x3DA);   /* some clones need it */	outb_p(0x20, 0x3C0); /* unblank screen */}static int vga16_getcolreg(unsigned regno, unsigned *red, unsigned *green,			  unsigned *blue, unsigned *transp,			  struct fb_info *fb_info){	/*	 *  Read a single color register and split it into colors/transparent.	 *  Return != 0 for invalid regno.	 */	if (regno >= 16)		return 1;	*red   = palette[regno].red;	*green = palette[regno].green;	*blue  = palette[regno].blue;	*transp = 0;	return 0;}static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue){	outb(regno,       dac_reg);	outb(red   >> 10, dac_val);	outb(green >> 10, dac_val);	outb(blue  >> 10, dac_val);}static int vga16_setcolreg(unsigned regno, unsigned red, unsigned green,			  unsigned blue, unsigned transp,			  struct fb_info *fb_info){	int gray;	/*	 *  Set a single color register. The values supplied are	 *  already rounded down to the hardware's capabilities	 *  (according to the entries in the `var' structure). Return	 *  != 0 for invalid regno.	 */		if (regno >= 16)		return 1;	palette[regno].red   = red;	palette[regno].green = green;	palette[regno].blue  = blue;		if (currcon < 0)		gray = disp.var.grayscale;	else		gray = fb_display[currcon].var.grayscale;	if (gray) {		/* gray = 0.30*R + 0.59*G + 0.11*B */		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;	}	if (((struct vga16fb_info *) fb_info)->isVGA) 		vga16_setpalette(regno,red,green,blue);	else		ega16_setpalette(regno,red,green,blue);		return 0;}static void 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, vga16_setcolreg, info);	else		fb_set_cmap(fb_default_cmap(16), 1, vga16_setcolreg,			    info);}static int vga16fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			   struct fb_info *info){	if (con == currcon) /* current console? */		return fb_get_cmap(cmap, kspc, vga16_getcolreg, info);	else if (fb_display[con].cmap.len) /* non default colormap? */		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap(16),		     cmap, kspc ? 0 : 2);	return 0;}static int vga16fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			   struct fb_info *info){	int err;	if (!fb_display[con].cmap.len) {	/* no colormap allocated? */		err = fb_alloc_cmap(&fb_display[con].cmap,16,0);		if (err)			return err;	}	if (con == currcon)			/* current console? */		return fb_set_cmap(cmap, kspc, vga16_setcolreg, info);	else		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	return 0;}static int vga16fb_pan_display(struct fb_var_screeninfo *var, int con,			       struct fb_info *info) {	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)		vga16fb_pan_var(info, var);	fb_display[con].var.xoffset = var->xoffset;	fb_display[con].var.yoffset = var->yoffset;	fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;	return 0;}static struct fb_ops vga16fb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	vga16fb_get_fix,	fb_get_var:	vga16fb_get_var,	fb_set_var:	vga16fb_set_var,	fb_get_cmap:	vga16fb_get_cmap,	fb_set_cmap:	vga16fb_set_cmap,	fb_pan_display:	vga16fb_pan_display,};int vga16fb_setup(char *options){	char *this_opt;		vga16fb.fb_info.fontname[0] = '\0';		if (!options || !*options)		return 0;		while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt) continue;				if (!strncmp(this_opt, "font:", 5))			strcpy(vga16fb.fb_info.fontname, this_opt+5);	}	return 0;}static int vga16fb_switch(int con, struct fb_info *fb){	struct vga16fb_par par;	struct vga16fb_info *info = (struct vga16fb_info*)fb;	/* Do we have to save the colormap? */	if (fb_display[currcon].cmap.len)		fb_get_cmap(&fb_display[currcon].cmap, 1, vga16_getcolreg,			    fb);		currcon = con;	vga16fb_decode_var(&fb_display[con].var, &par, info);	vga16fb_set_par(&par, info);	vga16fb_set_disp(con, info);	/* Install new colormap */	do_install_cmap(con, fb);/*	vga16fb_update_var(con, fb); */	return 1;}/* The following VESA blanking code is taken from vgacon.c.  The VGA   blanking code was originally by Huang shi chao, and modified by   Christoph Rimek (chrimek@toppoint.de) and todd j. derr   (tjd@barefoot.org) for Linux. */#define attrib_port	0x3c0#define seq_port_reg	0x3c4#define seq_port_val	0x3c5#define gr_port_reg	0x3ce#define gr_port_val	0x3cf#define video_misc_rd	0x3cc#define video_misc_wr	0x3c2#define vga_video_port_reg	0x3d4#define vga_video_port_val	0x3d5static void vga_vesa_blank(struct vga16fb_info *info, int mode){	unsigned char SeqCtrlIndex;	unsigned char CrtCtrlIndex;		cli();	SeqCtrlIndex = inb_p(seq_port_reg);	CrtCtrlIndex = inb_p(vga_video_port_reg);	/* save original values of VGA controller registers */	if(!info->vesa_blanked) {		info->vga_state.CrtMiscIO = inb_p(video_misc_rd);		sti();		outb_p(0x00,vga_video_port_reg);	/* HorizontalTotal */		info->vga_state.HorizontalTotal = inb_p(vga_video_port_val);		outb_p(0x01,vga_video_port_reg);	/* HorizDisplayEnd */		info->vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */		info->vga_state.StartHorizRetrace = inb_p(vga_video_port_val);		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */		info->vga_state.EndHorizRetrace = inb_p(vga_video_port_val);		outb_p(0x07,vga_video_port_reg);	/* Overflow */		info->vga_state.Overflow = inb_p(vga_video_port_val);		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */		info->vga_state.StartVertRetrace = inb_p(vga_video_port_val);		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */		info->vga_state.EndVertRetrace = inb_p(vga_video_port_val);		outb_p(0x17,vga_video_port_reg);	/* ModeControl */		info->vga_state.ModeControl = inb_p(vga_video_port_val);		outb_p(0x01,seq_port_reg);		/* ClockingMode */		info->vga_state.ClockingMode = inb_p(seq_port_val);	}	/* assure that video is enabled */	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */	cli();	outb_p(0x01,seq_port_reg);	outb_p(info->vga_state.ClockingMode | 0x20,seq_port_val);	/* test for vertical retrace in process.... */	if ((info->vga_state.CrtMiscIO & 0x80) == 0x80)		outb_p(info->vga_state.CrtMiscIO & 0xef,video_misc_wr);	/*	 * Set <End of vertical retrace> to minimum (0) and	 * <Start of vertical Retrace> to maximum (incl. overflow)	 * Result: turn off vertical sync (VSync) pulse.	 */	if (mode & VESA_VSYNC_SUSPEND) {		outb_p(0x10,vga_video_port_reg);	/* StartVertRetrace */		outb_p(0xff,vga_video_port_val); 	/* maximum value */		outb_p(0x11,vga_video_port_reg);	/* EndVertRetrace */		outb_p(0x40,vga_video_port_val);	/* minimum (bits 0..3)  */		outb_p(0x07,vga_video_port_reg);	/* Overflow */		outb_p(info->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */	}	if (mode & VESA_HSYNC_SUSPEND) {		/*		 * Set <End of horizontal retrace> to minimum (0) and		 *  <Start of horizontal Retrace> to maximum		 * Result: turn off horizontal sync (HSync) pulse.		 */		outb_p(0x04,vga_video_port_reg);	/* StartHorizRetrace */		outb_p(0xff,vga_video_port_val);	/* maximum */		outb_p(0x05,vga_video_port_reg);	/* EndHorizRetrace */		outb_p(0x00,vga_video_port_val);	/* minimum (0) */	}	/* restore both index registers */	outb_p(SeqCtrlIndex,seq_port_reg);	outb_p(CrtCtrlIndex,vga_video_port_reg);	sti();}static void vga_vesa_unblank(struct vga16fb_info *info){	unsigned char SeqCtrlIndex;	unsigned char CrtCtrlIndex;		cli();	SeqCtrlIndex = inb_p(seq_port_reg);	CrtCtrlIndex = inb_p(vga_video_port_reg);	/* restore original values of VGA controller registers */	outb_p(info->vga_state.CrtMiscIO,video_misc_wr);	outb_p(0x00,vga_video_port_reg);		/* HorizontalTotal */	outb_p(info->vga_state.HorizontalTotal,vga_video_port_val);	outb_p(0x01,vga_video_port_reg);		/* HorizDisplayEnd */	outb_p(info->vga_state.HorizDisplayEnd,vga_video_port_val);	outb_p(0x04,vga_video_port_reg);		/* StartHorizRetrace */	outb_p(info->vga_state.StartHorizRetrace,vga_video_port_val);	outb_p(0x05,vga_video_port_reg);		/* EndHorizRetrace */	outb_p(info->vga_state.EndHorizRetrace,vga_video_port_val);	outb_p(0x07,vga_video_port_reg);		/* Overflow */	outb_p(info->vga_state.Overflow,vga_video_port_val);	outb_p(0x10,vga_video_port_reg);		/* StartVertRetrace */	outb_p(info->vga_state.StartVertRetrace,vga_video_port_val);	outb_p(0x11,vga_video_port_reg);		/* EndVertRetrace */	outb_p(info->vga_state.EndVertRetrace,vga_video_port_val);	outb_p(0x17,vga_video_port_reg);		/* ModeControl */	outb_p(info->vga_state.ModeControl,vga_video_port_val);	outb_p(0x01,seq_port_reg);		/* ClockingMode */	outb_p(info->vga_state.ClockingMode,seq_port_val);	/* restore index/control registers */	outb_p(SeqCtrlIndex,seq_port_reg);	outb_p(CrtCtrlIndex,vga_video_port_reg);	sti();}static void vga_pal_blank(void){	int i;	for (i=0; i<16; i++) {		outb_p (i, dac_reg) ;		outb_p (0, dac_val) ;		outb_p (0, dac_val) ;		outb_p (0, dac_val) ;	}}/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */static void vga16fb_blank(int blank, struct fb_info *fb_info){	struct vga16fb_info *info = (struct vga16fb_info*)fb_info;	switch (blank) {	case 0:				/* Unblank */		if (info->vesa_blanked) {			vga_vesa_unblank(info);			info->vesa_blanked = 0;		}		if (info->palette_blanked) {			do_install_cmap(currcon, fb_info);			info->palette_blanked = 0;		}		break;	case 1:				/* blank */		vga_pal_blank();		info->palette_blanked = 1;		break;	default:			/* VESA blanking */		vga_vesa_blank(info, blank-1);		info->vesa_blanked = 1;		break;	}}int __init vga16fb_init(void){	int i,j;	printk(KERN_DEBUG "vga16fb: initializing\n");	/* XXX share VGA_FB_PHYS region with vgacon */        vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);	if (!vga16fb.video_vbase) {		printk(KERN_ERR "vga16fb: unable to map device\n");		return -ENOMEM;	}	printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);	vga16fb.isVGA = ORIG_VIDEO_ISVGA;	vga16fb.palette_blanked = 0;	vga16fb.vesa_blanked = 0;	i = vga16fb.isVGA? 6 : 2;		vga16fb_defined.red.length   = i;	vga16fb_defined.green.length = i;	vga16fb_defined.blue.length  = i;		for(i = 0; i < 16; i++) {		j = color_table[i];		palette[i].red   = default_red[j];		palette[i].green = default_grn[j];		palette[i].blue  = default_blu[j];	}	/* XXX share VGA I/O region with vgacon and others */	disp.var = vga16fb_defined;	/* name should not depend on EGA/VGA */	strcpy(vga16fb.fb_info.modename, "VGA16 VGA");	vga16fb.fb_info.changevar = NULL;	vga16fb.fb_info.node = -1;	vga16fb.fb_info.fbops = &vga16fb_ops;	vga16fb.fb_info.disp=&disp;	vga16fb.fb_info.switch_con=&vga16fb_switch;	vga16fb.fb_info.updatevar=&vga16fb_update_var;	vga16fb.fb_info.blank=&vga16fb_blank;	vga16fb.fb_info.flags=FBINFO_FLAG_DEFAULT;	vga16fb_set_disp(-1, &vga16fb);	if (register_framebuffer(&vga16fb.fb_info)<0) {		iounmap(vga16fb.video_vbase);		return -EINVAL;	}	printk(KERN_INFO "fb%d: %s frame buffer device\n",	       GET_FB_IDX(vga16fb.fb_info.node), vga16fb.fb_info.modename);	return 0;}static void __exit vga16fb_exit(void){    unregister_framebuffer(&vga16fb.fb_info);    iounmap(vga16fb.video_vbase);    /* XXX unshare VGA regions */}#ifdef MODULEMODULE_LICENSE("GPL");module_init(vga16fb_init);#endifmodule_exit(vga16fb_exit);/* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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