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

📄 retz3fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static void do_install_cmap(int con, struct fb_info *info){	struct retz3_fb_info *zinfo = retz3info(info);	if (con != zinfo->currcon)		return;	if (fb_display[con].cmap.len)		fb_set_cmap(&fb_display[con].cmap, 1, retz3_setcolreg, info);	else		fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),					    1, retz3_setcolreg, info);}/* *    Get the Fixed Part of the Display */static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,			   struct fb_info *info){	struct retz3fb_par par;	int error = 0;	if (con == -1)		retz3fb_get_par(info, &par);	else		error = retz3_decode_var(&fb_display[con].var, &par);	return(error ? error : retz3_encode_fix(info, fix, &par));}/* *    Get the User Defined Part of the Display */static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,			   struct fb_info *info){	struct retz3fb_par par;	int error = 0;	if (con == -1) {		retz3fb_get_par(info, &par);		error = retz3_encode_var(var, &par);	} else		*var = fb_display[con].var;	return error;}static void retz3fb_set_disp(int con, struct fb_info *info){	struct fb_fix_screeninfo fix;	struct display *display;	struct retz3_fb_info *zinfo = retz3info(info);	if (con >= 0)		display = &fb_display[con];	else		display = &zinfo->disp;	/* used during initialization */	retz3fb_get_fix(&fix, con, info);	if (con == -1)		con = 0;	display->screen_base = zinfo->fbmem;	display->visual = fix.visual;	display->type = fix.type;	display->type_aux = fix.type_aux;	display->ypanstep = fix.ypanstep;	display->ywrapstep = fix.ywrapstep;	display->can_soft_blank = 1;	display->inverse = z3fb_inverse;	/*	 * This seems to be about 20% faster.	 */	display->scrollmode = SCROLL_YREDRAW;	switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 8:		if (display->var.accel_flags & FB_ACCELF_TEXT) {		    display->dispsw = &fbcon_retz3_8;		    retz3_set_video(info, &display->var, &zinfo->current_par);		} else		    display->dispsw = &fbcon_cfb8;		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		display->dispsw = &fbcon_cfb16;		break;#endif	default:		display->dispsw = &fbcon_dummy;		break;	}}/* *    Set the User Defined Part of the Display */static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,			   struct fb_info *info){	int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;	struct display *display;	struct retz3_fb_info *zinfo = retz3info(info);	if (con >= 0)		display = &fb_display[con];	else		display = &zinfo->disp;	/* used during initialization */	if ((err = do_fb_set_var(info, var, con == zinfo->currcon)))		return err;	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {		oldxres = display->var.xres;		oldyres = display->var.yres;		oldvxres = display->var.xres_virtual;		oldvyres = display->var.yres_virtual;		oldbpp = display->var.bits_per_pixel;		oldaccel = display->var.accel_flags;		display->var = *var;		if (oldxres != var->xres || oldyres != var->yres ||		    oldvxres != var->xres_virtual ||		    oldvyres != var->yres_virtual ||		    oldbpp != var->bits_per_pixel ||		    oldaccel != var->accel_flags) {			struct fb_fix_screeninfo fix;			retz3fb_get_fix(&fix, con, info);			display->screen_base = zinfo->fbmem;			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->can_soft_blank = 1;			display->inverse = z3fb_inverse;			switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8			case 8:				if (var->accel_flags & FB_ACCELF_TEXT) {					display->dispsw = &fbcon_retz3_8;				} else					display->dispsw = &fbcon_cfb8;				break;#endif#ifdef FBCON_HAS_CFB16			case 16:				display->dispsw = &fbcon_cfb16;				break;#endif			default:				display->dispsw = &fbcon_dummy;				break;			}			/*			 * We still need to find a way to tell the X			 * server that the video mem has been fiddled with			 * so it redraws the entire screen when switching			 * between X and a text console.			 */			retz3_set_video(info, var, &zinfo->current_par);			if (info->changevar)				(*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);		}	}	return 0;}/* *    Get the Colormap */static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			    struct fb_info *info){	struct retz3_fb_info *zinfo = retz3info(info);	if (con == zinfo->currcon) /* current console? */		return(fb_get_cmap(cmap, kspc, retz3_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 retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			    struct fb_info *info){	int err;	struct retz3_fb_info *zinfo = retz3info(info);	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 == zinfo->currcon)              /* current console? */		return(fb_set_cmap(cmap, kspc, retz3_setcolreg, info));	else		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	return 0;}static struct fb_ops retz3fb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	retz3fb_get_fix,	fb_get_var:	retz3fb_get_var,	fb_set_var:	retz3fb_set_var,	fb_get_cmap:	retz3fb_get_cmap,	fb_set_cmap:	retz3fb_set_cmap,};int __init retz3fb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt)			continue;		if (!strcmp(this_opt, "inverse")) {			z3fb_inverse = 1;			fb_invert_cmaps();		} else if (!strncmp(this_opt, "font:", 5)) {			strncpy(fontname, this_opt+5, 39);			fontname[39] = '\0';		} else			z3fb_mode = get_video_mode(this_opt);	}	return 0;}/* *    Initialization */int __init retz3fb_init(void){	unsigned long board_addr, board_size;	struct zorro_dev *z = NULL;	volatile unsigned char *regs;	struct retz3fb_par par;	struct retz3_fb_info *zinfo;	struct fb_info *fb_info;	short i;	int res = -ENXIO;	while ((z = zorro_find_device(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, z))) {		board_addr = z->resource.start;		board_size = z->resource.end-z->resource.start+1;		if (!request_mem_region(board_addr, 0x0c00000,			    		"ncr77c32blt")) {			continue;		if (!request_mem_region(board_addr+VIDEO_MEM_OFFSET,			    		0x00400000, "RAM"))			release_mem_region(board_addr, 0x00c00000);			continue;		}		if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info),				      GFP_KERNEL)))			return -ENOMEM;		memset(zinfo, 0, sizeof(struct retz3_fb_info));		zinfo->base = ioremap(board_addr, board_size);		zinfo->regs = zinfo->base;		zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;		/* Get memory size - for now we asume its a 4MB board */		zinfo->fbsize = 0x00400000; /* 4 MB */		zinfo->physregs = board_addr;		zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET;		fb_info = fbinfo(zinfo);		for (i = 0; i < 256; i++){			for (i = 0; i < 256; i++){				zinfo->color_table[i][0] = i;				zinfo->color_table[i][1] = i;				zinfo->color_table[i][2] = i;			}		}		regs = zinfo->regs;		/* Disable hardware cursor */		seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00);		retz3_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info);		retz3_setcolreg (254, 0, 0, 0, 0, fb_info);		strcpy(fb_info->modename, retz3fb_name);		fb_info->changevar = NULL;		fb_info->node = -1;		fb_info->fbops = &retz3fb_ops;		fb_info->disp = &zinfo->disp;		fb_info->switch_con = &z3fb_switch;		fb_info->updatevar = &z3fb_updatevar;		fb_info->blank = &z3fb_blank;		fb_info->flags = FBINFO_FLAG_DEFAULT;		strncpy(fb_info->fontname, fontname, 40);		if (z3fb_mode == -1)			retz3fb_default = retz3fb_predefined[0].var;		retz3_decode_var(&retz3fb_default, &par);		retz3_encode_var(&retz3fb_default, &par);		do_fb_set_var(fb_info, &retz3fb_default, 0);		retz3fb_get_var(&zinfo->disp.var, -1, fb_info);		retz3fb_set_disp(-1, fb_info);		do_install_cmap(0, fb_info);		if (register_framebuffer(fb_info) < 0)			return -EINVAL;		printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "		       "video memory\n", GET_FB_IDX(fb_info->node),		       fb_info->modename, zinfo->fbsize>>10);		/* FIXME: This driver cannot be unloaded yet */		MOD_INC_USE_COUNT;		res = 0;	}	return res;}static int z3fb_switch(int con, struct fb_info *info){	struct retz3_fb_info *zinfo = retz3info(info);	/* Do we have to save the colormap? */	if (fb_display[zinfo->currcon].cmap.len)		fb_get_cmap(&fb_display[zinfo->currcon].cmap, 1,			    retz3_getcolreg, info);	do_fb_set_var(info, &fb_display[con].var, 1);	zinfo->currcon = con;	/* Install new colormap */	do_install_cmap(con, info);	return 0;}/* *    Update the `var' structure (called by fbcon.c) * *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. *    Since it's called by a kernel driver, no range checking is done. */static int z3fb_updatevar(int con, struct fb_info *info){	return 0;}/* *    Blank the display. */static void z3fb_blank(int blank, struct fb_info *info){	struct retz3_fb_info *zinfo = retz3info(info);	volatile unsigned char *regs = retz3info(info)->regs;	short i;	if (blank)		for (i = 0; i < 256; i++){			reg_w(regs, VDAC_ADDRESS_W, i);			reg_w(regs, VDAC_DATA, 0);			reg_w(regs, VDAC_DATA, 0);			reg_w(regs, VDAC_DATA, 0);		}	else		for (i = 0; i < 256; i++){			reg_w(regs, VDAC_ADDRESS_W, i);			reg_w(regs, VDAC_DATA, zinfo->color_table[i][0]);			reg_w(regs, VDAC_DATA, zinfo->color_table[i][1]);			reg_w(regs, VDAC_DATA, zinfo->color_table[i][2]);		}}/* *    Get a Video Mode */static int __init get_video_mode(const char *name){	short i;	for (i = 0; i < NUM_TOTAL_MODES; i++)		if (!strcmp(name, retz3fb_predefined[i].name)){			retz3fb_default = retz3fb_predefined[i].var;			return i;		}	return -1;}#ifdef MODULEMODULE_LICENSE("GPL");int init_module(void){	return retz3fb_init();}void cleanup_module(void){	/*	 * Not reached because the usecount will never	 * be decremented to zero	 *	 * FIXME: clean up ... *	 */}#endif/* *  Text console acceleration */#ifdef FBCON_HAS_CFB8static void retz3_8_bmove(struct display *p, int sy, int sx,			  int dy, int dx, int height, int width){	int fontwidth = fontwidth(p);	sx *= fontwidth;	dx *= fontwidth;	width *= fontwidth;	retz3_bitblt(p,		     (unsigned short)sx,		     (unsigned short)(sy*fontheight(p)),		     (unsigned short)dx,		     (unsigned short)(dy*fontheight(p)),		     (unsigned short)width,		     (unsigned short)(height*fontheight(p)),		     Z3BLTcopy,		     0xffff);}static void retz3_8_clear(struct vc_data *conp, struct display *p,			  int sy, int sx, int height, int width){	unsigned short col;	int fontwidth = fontwidth(p);	sx *= fontwidth;	width *= fontwidth;	col = attr_bgcol_ec(p, conp);	col &= 0xff;	col |= (col << 8);	retz3_bitblt(p,		     (unsigned short)sx,		     (unsigned short)(sy*fontheight(p)),		     (unsigned short)sx,		     (unsigned short)(sy*fontheight(p)),		     (unsigned short)width,		     (unsigned short)(height*fontheight(p)),		     Z3BLTset,		     col);}static void retz3_putc(struct vc_data *conp, struct display *p, int c,		       int yy, int xx){	retz3_busy(p);	fbcon_cfb8_putc(conp, p, c, yy, xx);}static void retz3_putcs(struct vc_data *conp, struct display *p,			const unsigned short *s, int count,			int yy, int xx){	retz3_busy(p);	fbcon_cfb8_putcs(conp, p, s, count, yy, xx);}static void retz3_revc(struct display *p, int xx, int yy){	retz3_busy(p);	fbcon_cfb8_revc(p, xx, yy);}static void retz3_clear_margins(struct vc_data* conp, struct display* p,				int bottom_only){	retz3_busy(p);	fbcon_cfb8_clear_margins(conp, p, bottom_only);}static struct display_switch fbcon_retz3_8 = {    setup:		fbcon_cfb8_setup,    bmove:		retz3_8_bmove,    clear:		retz3_8_clear,    putc:		retz3_putc,    putcs:		retz3_putcs,    revc:		retz3_revc,    clear_margins:	retz3_clear_margins,    fontwidthmask:	FONTWIDTH(8)};#endif

⌨️ 快捷键说明

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