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

📄 vesafb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * framebuffer driver for VBE 2.0 compliant graphic boards * * switching to graphics mode happens at boot time (while * running in real mode, see arch/i386/boot/video.S). * * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> * */#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/fb.h>#include <linux/console.h>#include <linux/selection.h>#include <linux/ioport.h>#include <linux/init.h>#include <asm/io.h>#include <asm/mtrr.h>#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/fbcon-cfb24.h>#include <video/fbcon-cfb32.h>#include <video/fbcon-mac.h>#define dac_reg	(0x3c8)#define dac_val	(0x3c9)/* --------------------------------------------------------------------- *//* * card parameters *//* card */unsigned long video_base; /* physical addr */int   video_size;char *video_vbase;        /* mapped *//* mode */static int  video_bpp;static int  video_width;static int  video_height;static int  video_height_virtual;static int  video_type = FB_TYPE_PACKED_PIXELS;static int  video_visual;static int  video_linelength;static int  video_cmap_len;/* --------------------------------------------------------------------- */static struct fb_var_screeninfo vesafb_defined = {	0,0,0,0,	/* W,H, W, H (virtual) load xres,xres_virtual*/	0,0,		/* virtual -> visible no offset */	8,		/* depth -> load bits_per_pixel */	0,		/* greyscale ? */	{0,0,0},	/* R */	{0,0,0},	/* G */	{0,0,0},	/* B */	{0,0,0},	/* transparency */	0,		/* standard pixel format */	FB_ACTIVATE_NOW,	-1,-1,	0,	0L,0L,0L,0L,0L,	0L,0L,0,	/* No sync info */	FB_VMODE_NONINTERLACED,	{0,0,0,0,0,0}};static struct display disp;static struct fb_info fb_info;static struct { u_short blue, green, red, pad; } palette[256];static union {#ifdef FBCON_HAS_CFB16    u16 cfb16[16];#endif#ifdef FBCON_HAS_CFB24    u32 cfb24[16];#endif#ifdef FBCON_HAS_CFB32    u32 cfb32[16];#endif} fbcon_cmap;static int             inverse   = 0;#ifdef __x86_64__static int             mtrr      = 1;#elsestatic int             mtrr      = 0;#endifstatic int	 vram __initdata = 0;	/* needed for vram boot option */static int             currcon   = 0;static int             pmi_setpal = 0;	/* pmi for palette changes ??? */static int             ypan       = 0;  /* 0..nothing, 1..ypan, 2..ywrap */static unsigned short  *pmi_base  = 0;static void            (*pmi_start)(void);static void            (*pmi_pal)(void);static struct display_switch vesafb_sw;/* --------------------------------------------------------------------- */static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,                              struct fb_info *info){#ifdef __i386__	int offset;	if (!ypan)		return -EINVAL;	if (var->xoffset)		return -EINVAL;	if (var->yoffset > var->yres_virtual)		return -EINVAL;	if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual)		return -EINVAL;	offset = (var->yoffset * video_linelength + var->xoffset) / 4;        __asm__ __volatile__(                "call *(%%edi)"                : /* no return value */                : "a" (0x4f07),         /* EAX */                  "b" (0),              /* EBX */                  "c" (offset),         /* ECX */                  "d" (offset >> 16),   /* EDX */                  "D" (&pmi_start));    /* EDI */#endif	return 0;}static int vesafb_update_var(int con, struct fb_info *info){	if (con == currcon && ypan) {		struct fb_var_screeninfo *var = &fb_display[currcon].var;		return vesafb_pan_display(var,con,info);	}	return 0;}static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info){	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id,"VESA VGA");	fix->smem_start=video_base;	fix->smem_len=video_size;	fix->type = video_type;	fix->visual = video_visual;	fix->xpanstep  = 0;	fix->ypanstep  = ypan     ? 1 : 0;	fix->ywrapstep = (ypan>1) ? 1 : 0;	fix->line_length=video_linelength;	return 0;}static int vesafb_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	if(con==-1)		memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));	else		*var=fb_display[con].var;	return 0;}static void vesafb_set_disp(int con){	struct fb_fix_screeninfo fix;	struct display *display;	struct display_switch *sw;		if (con >= 0)		display = &fb_display[con];	else		display = &disp;	/* used during initialization */	vesafb_get_fix(&fix, con, 0);	memset(display, 0, sizeof(struct display));	display->screen_base = 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 = inverse;	vesafb_get_var(&display->var, -1, &fb_info);	switch (video_bpp) {#ifdef FBCON_HAS_CFB8	case 8:		sw = &fbcon_cfb8;		break;#endif#ifdef FBCON_HAS_CFB16	case 15:	case 16:		sw = &fbcon_cfb16;		display->dispsw_data = fbcon_cmap.cfb16;		break;#endif#ifdef FBCON_HAS_CFB24	case 24:		sw = &fbcon_cfb24;		display->dispsw_data = fbcon_cmap.cfb24;		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		sw = &fbcon_cfb32;		display->dispsw_data = fbcon_cmap.cfb32;		break;#endif	default:#ifdef FBCON_HAS_MAC		sw = &fbcon_mac;		break;#else		sw = &fbcon_dummy;		return;#endif	}	memcpy(&vesafb_sw, sw, sizeof(*sw));	display->dispsw = &vesafb_sw;	if (!ypan) {		display->scrollmode = SCROLL_YREDRAW;		vesafb_sw.bmove = fbcon_redraw_bmove;	}}static int vesafb_set_var(struct fb_var_screeninfo *var, int con,			  struct fb_info *info){	static int first = 1;	if (var->xres           != vesafb_defined.xres           ||	    var->yres           != vesafb_defined.yres           ||	    var->xres_virtual   != vesafb_defined.xres_virtual   ||	    var->yres_virtual   >  video_height_virtual          ||	    var->yres_virtual   <  video_height                  ||	    var->xoffset                                         ||	    var->bits_per_pixel != vesafb_defined.bits_per_pixel ||	    var->nonstd) {		if (first) {			printk(KERN_ERR "Vesafb does not support changing the video mode\n");			first = 0;		}		return -EINVAL;	}	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)		return 0;	if (ypan) {		if (vesafb_defined.yres_virtual != var->yres_virtual) {			vesafb_defined.yres_virtual = var->yres_virtual;			if (con != -1) {				fb_display[con].var = vesafb_defined;				info->changevar(con);			}		}		if (var->yoffset != vesafb_defined.yoffset)			return vesafb_pan_display(var,con,info);		return 0;	}	if (var->yoffset)		return -EINVAL;	return 0;}static int vesa_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 >= video_cmap_len)		return 1;	*red   = palette[regno].red;	*green = palette[regno].green;	*blue  = palette[regno].blue;	*transp = 0;	return 0;}#ifdef FBCON_HAS_CFB8static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue){#ifdef i386	struct { u_char blue, green, red, pad; } entry;	if (pmi_setpal) {		entry.red   = red   >> 10;		entry.green = green >> 10;		entry.blue  = blue  >> 10;		entry.pad   = 0;	        __asm__ __volatile__(                "call *(%%esi)"                : /* no return value */                : "a" (0x4f09),         /* EAX */                  "b" (0),              /* EBX */                  "c" (1),              /* ECX */                  "d" (regno),          /* EDX */                  "D" (&entry),         /* EDI */                  "S" (&pmi_pal));      /* ESI */	} else {		/* without protected mode interface, try VGA registers... */		outb_p(regno,       dac_reg);		outb_p(red   >> 10, dac_val);		outb_p(green >> 10, dac_val);		outb_p(blue  >> 10, dac_val);	}#endif}#endifstatic int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,			  unsigned blue, unsigned transp,			  struct fb_info *fb_info){	/*	 *  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 >= video_cmap_len)		return 1;

⌨️ 快捷键说明

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