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

📄 pvr2fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			display->inverse = pvr2fb_inverse;			switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB16			    case 16:				display->dispsw = &fbcon_cfb16;				display->dispsw_data = fbcon_cmap.cfb16;				break;#endif#ifdef FBCON_HAS_CFB24			    case 24:				display->dispsw = &fbcon_cfb24;				display->dispsw_data = fbcon_cmap.cfb24;				break;#endif#ifdef FBCON_HAS_CFB32			    case 32:				display->dispsw = &fbcon_cfb32;				display->dispsw_data = fbcon_cmap.cfb32;				break;#endif			    default:				display->dispsw = &fbcon_dummy;				break;			}			if (fb_info.changevar)				(*fb_info.changevar)(con);		}		if (oldbpp != var->bits_per_pixel) {			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))				return err;			do_install_cmap(con, info);		}		if (con == currcon)			pvr2_set_var(&display->var);	}	return 0;}/* * Pan or wrap the display. * This call looks only at xoffset, yoffset and the FB_VMODE_YRAP flag */static int pvr2fb_pan_display(struct fb_var_screeninfo *var, int con,                                struct fb_info *info){	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)		pvr2_pan_var(var);	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;}/* Get the colormap */static int pvr2fb_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, pvr2_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(1<<fb_display[con].var.bits_per_pixel),		             cmap, kspc ? 0 : 2);	return 0;}/* Set the colormap */static int pvr2fb_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? */		if ((err = fb_alloc_cmap(&fb_display[con].cmap,		                         1<<fb_display[con].var.bits_per_pixel,					 0)))			 return err;	}	if (con == currcon)                     /* current console? */		return fb_set_cmap(cmap, kspc, pvr2_setcolreg, info);	else		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	return 0;}static int pvr2fbcon_switch(int con, struct fb_info *info){	/* Do we have to save the colormap? */	if (fb_display[currcon].cmap.len)		fb_get_cmap(&fb_display[currcon].cmap, 1, pvr2_getcolreg, info);	currcon = con;	pvr2_set_var(&fb_display[con].var);	/* Install new colormap */	do_install_cmap(con, info);	return 0;}static int pvr2fbcon_updatevar(int con, struct fb_info *info){	pvr2_pan_var(&fb_display[con].var);	return 0;}static void pvr2fbcon_blank(int blank, struct fb_info *info){	do_blank = blank ? blank : -1;}/* Setup the colormap */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, pvr2_setcolreg, info);	else		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),                            1, pvr2_setcolreg, info);}static inline u_long get_line_length(int xres_virtual, int bpp){	return (u_long)((((xres_virtual*bpp)+31)&~31) >> 3);}static void set_color_bitfields(struct fb_var_screeninfo *var){	switch (var->bits_per_pixel) {	    case 16:        /* RGB 565 */		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 24:        /* RGB 888 */		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 = 0;  var->transp.length = 0;		break;	    case 32:        /* ARGB 8888 */		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 int pvr2_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,                            u_int *transp, struct fb_info *info){	if (regno > 255)	    return 1;		*red = palette[regno].red;	*green = palette[regno].green;	*blue = palette[regno].blue;	*transp = 0;	return 0;}	static int pvr2_setcolreg(u_int regno, u_int red, u_int green, u_int blue,                            u_int transp, struct fb_info *info){	if (regno > 255)		return 1;	palette[regno].red = red;	palette[regno].green = green;	palette[regno].blue = blue;	if (regno < 16) {		switch (currbpp) {#ifdef FBCON_HAS_CFB16		    case 16: /* RGB 565 */			fbcon_cmap.cfb16[regno] = (red & 0xf800) |			                          ((green & 0xfc00) >> 5) |						  ((blue & 0xf800) >> 11);			break;#endif#ifdef FBCON_HAS_CFB24		    case 24: /* RGB 888 */			red >>= 8; green >>= 8; blue >>= 8;			fbcon_cmap.cfb24[regno] = (red << 16) | (green << 8) | blue;			break;#endif#ifdef FBCON_HAS_CFB32		    case 32: /* ARGB 8888 */			red >>= 8; green >>= 8; blue >>= 8;			fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | blue;			break;#endif		    default:			DPRINTK("Invalid bit depth %d?!?\n", currbpp);			return 1;		}	}	return 0;}static int pvr2_encode_fix(struct fb_fix_screeninfo *fix,                             struct pvr2fb_par *par){	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, pvr2fb_name);	fix->smem_start = videomemory;	fix->smem_len = videomemorysize;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;	fix->visual = FB_VISUAL_TRUECOLOR;	if (par->vmode & FB_VMODE_YWRAP) {		fix->ywrapstep = 1;		fix->xpanstep = fix->ypanstep = 0;	} else {		fix->ywrapstep = 0;		fix->xpanstep = 1;		fix->ypanstep = 1;	}	fix->line_length = par->next_line;	return 0;}/* * Create a hardware video mode using the framebuffer values.  If a value needs * to be clipped or constrained it's done here.  This routine needs a bit more * work to make sure we're doing the right tests at the right time. */static int pvr2_decode_var(struct fb_var_screeninfo *var,                             struct pvr2fb_par *par){	u_long line_length;	u_short vtotal;	if (var->pixclock != TV_CLK && var->pixclock != VGA_CLK) {		DPRINTK("Invalid pixclock value %d\n", var->pixclock);		return -EINVAL;	}	par->pixclock = var->pixclock;		if ((par->xres = var->xres) < 320)		par->xres = 320;	if ((par->yres = var->yres) < 240)		par->yres = 240;	if ((par->vxres = var->xres_virtual) < par->xres)		par->vxres = par->xres;	if ((par->vyres = var->yres_virtual) < par->yres)		par->vyres = par->yres;	if ((par->bpp = var->bits_per_pixel) <= 16)		par->bpp = 16;	else if ((par->bpp = var->bits_per_pixel) <= 24)		par->bpp = 24;	else if ((par->bpp = var->bits_per_pixel) <= 32)		par->bpp = 32;	currbpp = par->bpp;	/*	 * XXX: It's possible that a user could use a VGA box, change the cable	 * type in hardware (i.e. switch from VGA<->composite), then change modes	 * (i.e. switching to another VT).  If that happens we should automagically	 * change the output format to cope, but currently I don't have a VGA box	 * to make sure this works properly.	 */	cable_type = pvr2_init_cable();	if (cable_type == CT_VGA && video_output != VO_VGA)		video_output = VO_VGA;	par->vmode = var->vmode & FB_VMODE_MASK;	if (par->vmode & FB_VMODE_INTERLACED && video_output != VO_VGA)		par->is_interlaced = 1;	/* 	 * XXX: Need to be more creative with this (i.e. allow doublecan for	 * PAL/NTSC output).	 */	par->is_doublescan = (par->yres < 480 && video_output == VO_VGA);		par->hsync_total = var->left_margin + var->xres + var->right_margin +	                   var->hsync_len;	par->vsync_total = var->upper_margin + var->yres + var->lower_margin +	                   var->vsync_len;	if (var->sync & FB_SYNC_BROADCAST) {		vtotal = par->vsync_total;		if (par->is_interlaced)			vtotal /= 2;		if (vtotal > (PAL_VTOTAL + NTSC_VTOTAL)/2) {			/* PAL video output */			/* XXX: Should be using a range here ... ? */			if (par->hsync_total != PAL_HTOTAL) {				DPRINTK("invalid hsync total for PAL\n");				return -EINVAL;			}			/* XXX: Check for start values here... */			/* XXX: Check hardware for PAL-compatibility */			par->borderstart_h = 116;			par->borderstart_v = 44;		} else {			/* NTSC video output */			if (par->hsync_total != NTSC_HTOTAL) {				DPRINTK("invalid hsync total for NTSC\n");				return -EINVAL;			}			par->borderstart_h = 126;			par->borderstart_v = 18;		}	} else {		/* VGA mode */		/* XXX: What else needs to be checked? */		/* 		 * XXX: We have a little freedom in VGA modes, what ranges should		 * be here (i.e. hsync/vsync totals, etc.)?		 */		par->borderstart_h = 126;		par->borderstart_v = 40;	}	/* Calculate the remainding offsets */	par->borderstop_h = par->borderstart_h + par->hsync_total -	                    var->hsync_len;	par->borderstop_v = par->borderstart_v + par->vsync_total -	                    var->vsync_len;	par->diwstart_h = par->borderstart_h + var->left_margin;	par->diwstart_v = par->borderstart_v + var->upper_margin;	if (!par->is_interlaced)		par->borderstop_v /= 2;	if (par->xres < 640)		par->is_lowres = 1;	/* XXX: Needs testing. */	if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {		par->xoffset = var->xoffset;		par->yoffset = var->yoffset;		if (par->vmode & FB_VMODE_YWRAP) {			if (par->xoffset || par->yoffset < 0 || par->yoffset >=			    par->vyres)				par->xoffset = par->yoffset = 0;		} else {			if (par->xoffset < 0 || par->xoffset > par->vxres-par->xres ||			    par->yoffset < 0 || par->yoffset > par->vyres-par->yres)				par->xoffset = par->yoffset = 0;		}	} else		par->xoffset = par->yoffset = 0;	/* Check memory sizes */	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);	if (line_length * var->yres_virtual > videomemorysize)		return -ENOMEM;	par->disp_start = videomemory + (get_line_length(par->vxres, par->bpp) *	                  par->yoffset) * get_line_length(par->xoffset, par->bpp);	par->next_line = line_length;		return 0;}static int pvr2_encode_var(struct fb_var_screeninfo *var,                             struct pvr2fb_par *par){	memset(var, 0, sizeof(struct fb_var_screeninfo));	var->xres = par->xres;	var->yres = par->yres;

⌨️ 快捷键说明

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