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

📄 jzlcd.c

📁 jzlcd linux参考代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static int jzfb_set_par(struct fb_info *info){	print_dbg("jzfb_set_par");	return 0;}/* * (Un)Blank the display. * Fix me: should we use VESA value? */static int jzfb_blank(int blank_mode, struct fb_info *info){	dprintk("fb_blank %d %p", blank_mode, info);	switch (blank_mode) {	case FB_BLANK_UNBLANK:		//case FB_BLANK_NORMAL:			/* Turn on panel */		__lcd_set_ena();		__lcd_display_on();		break;	case FB_BLANK_NORMAL:	case FB_BLANK_VSYNC_SUSPEND:	case FB_BLANK_HSYNC_SUSPEND:	case FB_BLANK_POWERDOWN:#if 0			/* Turn off panel */		__lcd_set_dis();		__lcd_display_off();#endif		break;	default:		break;	}	return 0;}/*  * pan display */static int jzfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info){	struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;	int dy;	if (!var || !cfb) {		return -EINVAL;	}	if (var->xoffset - cfb->fb.var.xoffset) {		/* No support for X panning for now! */		return -EINVAL;	}	dy = var->yoffset - cfb->fb.var.yoffset;	print_dbg("var.yoffset: %d", dy);	if (dy) {		print_dbg("Panning screen of %d lines", dy);		lcd_frame_desc0->databuf += (cfb->fb.fix.line_length * dy);		/* TODO: Wait for current frame to finished */	}	return 0;}/* use default function cfb_fillrect, cfb_copyarea, cfb_imageblit */static struct fb_ops jzfb_ops = {	.owner			= THIS_MODULE,	.fb_setcolreg		= jzfb_setcolreg,	.fb_check_var 		= jzfb_check_var,	.fb_set_par 		= jzfb_set_par,	.fb_blank		= jzfb_blank,	.fb_pan_display		= jzfb_pan_display,	.fb_fillrect		= cfb_fillrect,	.fb_copyarea		= cfb_copyarea,	.fb_imageblit		= cfb_imageblit,	.fb_mmap		= jzfb_mmap,	.fb_ioctl		= jzfb_ioctl,#if defined(CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT)	.fb_rotate		= jzfb_fb_rotate,#endif};static int jzfb_set_var(struct fb_var_screeninfo *var, int con,			struct fb_info *info){	struct lcd_cfb_info *cfb = (struct lcd_cfb_info *)info;	int chgvar = 0;	var->height	            = jzfb.h ;	var->width	            = jzfb.w ;	var->bits_per_pixel	    = jzfb.bpp;	var->vmode                  = FB_VMODE_NONINTERLACED;	var->activate               = cfb->fb.var.activate;	var->xres                   = var->width;	var->yres                   = var->height;	var->xres_virtual           = var->width;	var->yres_virtual           = var->height;	var->xoffset                = 0;	var->yoffset                = 0;	var->pixclock               = 0;	var->left_margin            = 0;	var->right_margin           = 0;	var->upper_margin           = 0;	var->lower_margin           = 0;	var->hsync_len              = 0;	var->vsync_len              = 0;	var->sync                   = 0;	var->activate              &= ~FB_ACTIVATE_TEST;    	/*	 * CONUPDATE and SMOOTH_XPAN are equal.  However,	 * SMOOTH_XPAN is only used internally by fbcon.	 */	if (var->vmode & FB_VMODE_CONUPDATE) {		var->vmode |= FB_VMODE_YWRAP;		var->xoffset = cfb->fb.var.xoffset;		var->yoffset = cfb->fb.var.yoffset;	}	if (var->activate & FB_ACTIVATE_TEST)		return 0;	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)		return -EINVAL;	if (cfb->fb.var.xres != var->xres)		chgvar = 1;	if (cfb->fb.var.yres != var->yres)		chgvar = 1;	if (cfb->fb.var.xres_virtual != var->xres_virtual)		chgvar = 1;	if (cfb->fb.var.yres_virtual != var->yres_virtual)		chgvar = 1;	if (cfb->fb.var.bits_per_pixel != var->bits_per_pixel)		chgvar = 1;	var->red.msb_right	= 0;	var->green.msb_right	= 0;	var->blue.msb_right	= 0;	switch(var->bits_per_pixel){	case 1:	/* Mono */		cfb->fb.fix.visual	= FB_VISUAL_MONO01;		cfb->fb.fix.line_length	= (var->xres * var->bits_per_pixel) / 8;		break;	case 2:	/* Mono */		var->red.offset		= 0;		var->red.length		= 2;		var->green.offset	= 0;		var->green.length	= 2;		var->blue.offset	= 0;		var->blue.length	= 2;		cfb->fb.fix.visual	= FB_VISUAL_PSEUDOCOLOR;		cfb->fb.fix.line_length	= (var->xres * var->bits_per_pixel) / 8;		break;	case 4:	/* PSEUDOCOLOUR*/		var->red.offset		= 0;		var->red.length		= 4;		var->green.offset	= 0;		var->green.length	= 4;		var->blue.offset	= 0;		var->blue.length	= 4;		cfb->fb.fix.visual	= FB_VISUAL_PSEUDOCOLOR;		cfb->fb.fix.line_length	= var->xres / 2;		break;	case 8:	/* PSEUDOCOLOUR, 256 */		var->red.offset		= 0;		var->red.length		= 8;		var->green.offset	= 0;		var->green.length	= 8;		var->blue.offset	= 0;		var->blue.length	= 8;		cfb->fb.fix.visual	= FB_VISUAL_PSEUDOCOLOR;		cfb->fb.fix.line_length	= var->xres ;		break;	case 15: /* DIRECTCOLOUR, 32k */		var->bits_per_pixel	= 15;		var->red.offset		= 10;		var->red.length		= 5;		var->green.offset	= 5;		var->green.length	= 5;		var->blue.offset	= 0;		var->blue.length	= 5;		cfb->fb.fix.visual	= FB_VISUAL_DIRECTCOLOR;		cfb->fb.fix.line_length	= var->xres_virtual * 2;		break;	case 16: /* DIRECTCOLOUR, 64k */		var->bits_per_pixel	= 16;		var->red.offset		= 11;		var->red.length		= 5;		var->green.offset	= 5;		var->green.length	= 6;		var->blue.offset	= 0;		var->blue.length	= 5;		cfb->fb.fix.visual	= FB_VISUAL_TRUECOLOR;		cfb->fb.fix.line_length	= var->xres_virtual * 2;		break;	case 18:	case 24:	case 32:		/* DIRECTCOLOUR, 16M */		var->bits_per_pixel	= 32;		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;		cfb->fb.fix.visual	= FB_VISUAL_TRUECOLOR;		cfb->fb.fix.line_length	= var->xres_virtual * 4;		break;	default: /* in theory this should never happen */		printk(KERN_WARNING "%s: don't support for %dbpp\n",		       cfb->fb.fix.id, var->bits_per_pixel);		break;	}	cfb->fb.var = *var;	cfb->fb.var.activate &= ~FB_ACTIVATE_ALL;	/*	 * Update the old var.  The fbcon drivers still use this.	 * Once they are using cfb->fb.var, this can be dropped.	 *					--rmk	 */	//display->var = cfb->fb.var;	/*	 * If we are setting all the virtual consoles, also set the	 * defaults used to create new consoles.	 */	fb_set_cmap(&cfb->fb.cmap, &cfb->fb);	dprintk("jzfb_set_var: after fb_set_cmap...\n");	return 0;}static struct lcd_cfb_info * jzfb_alloc_fb_info(void){ 	struct lcd_cfb_info *cfb;	cfb = kmalloc(sizeof(struct lcd_cfb_info) + sizeof(u32) * 16, GFP_KERNEL);	if (!cfb)		return NULL;	jzlcd_info = cfb;	memset(cfb, 0, sizeof(struct lcd_cfb_info) );	cfb->currcon		= -1;	strcpy(cfb->fb.fix.id, "jz-lcd");	cfb->fb.fix.type	= FB_TYPE_PACKED_PIXELS;	cfb->fb.fix.type_aux	= 0;	cfb->fb.fix.xpanstep	= 1;	cfb->fb.fix.ypanstep	= 1;	cfb->fb.fix.ywrapstep	= 0;	cfb->fb.fix.accel	= FB_ACCEL_NONE;	cfb->fb.var.nonstd	= 0;	cfb->fb.var.activate	= FB_ACTIVATE_NOW;	cfb->fb.var.height	= -1;	cfb->fb.var.width	= -1;	cfb->fb.var.accel_flags	= FB_ACCELF_TEXT;	cfb->fb.fbops		= &jzfb_ops;	cfb->fb.flags		= FBINFO_FLAG_DEFAULT;	cfb->fb.pseudo_palette	= (void *)(cfb + 1);	switch (jzfb.bpp) {	case 1:		fb_alloc_cmap(&cfb->fb.cmap, 4, 0);		break;	case 2:		fb_alloc_cmap(&cfb->fb.cmap, 8, 0);		break;	case 4:		fb_alloc_cmap(&cfb->fb.cmap, 32, 0);		break;	case 8:	default:		fb_alloc_cmap(&cfb->fb.cmap, 256, 0);		break;	}	dprintk("fb_alloc_cmap,fb.cmap.len:%d....\n", cfb->fb.cmap.len);	return cfb;}/* * Map screen memory */static int jzfb_map_smem(struct lcd_cfb_info *cfb){	struct page * map = NULL;	unsigned char *tmp;	unsigned int page_shift, needroom, t;#if defined(CONFIG_SOC_JZ4740)	if (jzfb.bpp == 18 || jzfb.bpp == 24)		t = 32;	else		t = jzfb.bpp;#else	if (jzfb.bpp == 15)		t = 16;	else		t = jzfb.bpp;#endif	needroom = ((jzfb.w * t + 7) >> 3) * jzfb.h;	for (page_shift = 0; page_shift < 12; page_shift++)		if ((PAGE_SIZE << page_shift) >= needroom)			break;	/* lcd_palette room total 4KB:	 * 0 -- 512: lcd palette	 * 1024 -- [1024+16*3]: lcd descripters	 * [1024+16*3] -- 4096: reserved	 */	lcd_palette = (unsigned char *)__get_free_pages(GFP_KERNEL, 0);	if ((!lcd_palette))		return -ENOMEM;	memset((void *)lcd_palette, 0, PAGE_SIZE);	map = virt_to_page(lcd_palette);	set_bit(PG_reserved, &map->flags);	lcd_desc_base  = (struct lcd_desc *)(lcd_palette + 1024);	jz_lcd_buffer_addrs.fb_num = CONFIG_JZLCD_FRAMEBUFFER_MAX;	printk("jzlcd use %d framebuffer:\n", CONFIG_JZLCD_FRAMEBUFFER_MAX);	/* alloc frame buffer space */	for ( t = 0; t < CONFIG_JZLCD_FRAMEBUFFER_MAX; t++ ) {		lcd_frame[t] = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);		if ((!lcd_frame[t])) {			printk("no mem for fb[%d]\n", t);			return -ENOMEM;		}//		memset((void *)lcd_frame[t], 0, PAGE_SIZE << page_shift);		for (tmp=(unsigned char *)lcd_frame[t];		     tmp < lcd_frame[t] + (PAGE_SIZE << page_shift);		     tmp += PAGE_SIZE) {			map = virt_to_page(tmp);			set_bit(PG_reserved, &map->flags);		}		jz_lcd_buffer_addrs.fb_phys_addr[t] = virt_to_phys((void *)lcd_frame[t]);		printk("jzlcd fb[%d] phys addr =0x%08x\n", 		       t, jz_lcd_buffer_addrs.fb_phys_addr[t]);	}#if !defined(CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT)	cfb->fb.fix.smem_start = virt_to_phys((void *)lcd_frame[0]);	cfb->fb.fix.smem_len = (PAGE_SIZE << page_shift);	cfb->fb.screen_base =		(unsigned char *)(((unsigned int)lcd_frame[0] & 0x1fffffff) | 0xa0000000);#else  /* Framebuffer rotate */	lcd_frame_user_fb = (unsigned char *)__get_free_pages(GFP_KERNEL, page_shift);	if ((!lcd_frame_user_fb)) {		printk("no mem for fb[%d]\n", t);		return -ENOMEM;	}	memset((void *)lcd_frame_user_fb, 0, PAGE_SIZE << page_shift);	for (tmp=(unsigned char *)lcd_frame_user_fb;	     tmp < lcd_frame_user_fb + (PAGE_SIZE << page_shift);	     tmp += PAGE_SIZE) {		map = virt_to_page(tmp);		set_bit(PG_reserved, &map->flags);	}	printk("Rotate userfb phys addr =0x%08x\n", 	       (unsigned int)virt_to_phys((void *)lcd_frame_user_fb));	cfb->fb.fix.smem_start = virt_to_phys((void *)lcd_frame_user_fb);	cfb->fb.fix.smem_len = (PAGE_SIZE << page_shift);	cfb->fb.screen_base = (unsigned char *)(((unsigned int)lcd_frame_user_fb & 0x1fffffff) | 0xa0000000);#endif	/* #if defined(CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT) */	if (!cfb->fb.screen_base) {		printk("%s: unable to map screen memory\n", cfb->fb.fix.id);		return -ENOMEM;	}	return 0;}static void jzfb_free_fb_info(struct lcd_cfb_info *cfb){	if (cfb) {		fb_alloc_cmap(&cfb->fb.cmap, 0, 0);		kfree(cfb);	}}static void jzfb_unmap_smem(struct lcd_cfb_info *cfb){	struct page * map = NULL;	unsigned char *tmp;	unsigned int page_shift, needroom, t;#if defined(CONFIG_SOC_JZ4740)	if (jzfb.bpp == 18 || jzfb.bpp == 24)		t = 32;	else		t = jzfb.bpp;#else	if (jzfb.bpp == 15)		t = 16;	else		t = jzfb.bpp;#endif	needroom = ((jzfb.w * t + 7) >> 3) * jzfb.h;	for (page_shift = 0; page_shift < 12; page_shift++)		if ((PAGE_SIZE << page_shift) >= needroom)			break;	if (cfb && cfb->fb.screen_base) {		iounmap(cfb->fb.screen_base);		cfb->fb.screen_base = NULL;		release_mem_region(cfb->fb.fix.smem_start,				   cfb->fb.fix.smem_len);	}	if (lcd_palette) {		map = virt_to_page(lcd_palette);		clear_bit(PG_reserved, &map->flags);		free_pages((int)lcd_palette, 0);	}	for ( t=0; t < CONFIG_JZLCD_FRAMEBUFFER_MAX; t++ ) {		if (lcd_frame[t]) {			for (tmp=(unsigned char *)lcd_frame[t]; 			     tmp < lcd_frame[t] + (PAGE_SIZE << page_shift); 			     tmp += PAGE_SIZE) {				map = virt_to_page(tmp);				clear_bit(PG_reserved, &map->flags);			}			free_pages((int)lcd_frame[t], page_shift);		}	}#if defined(CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT)	if (lcd_frame_user_fb) {		for (tmp=(unsigned char *)lcd_frame_user_fb; 		     tmp < lcd_frame_user_fb + (PAGE_SIZE << page_shift); 		     tmp += PAGE_SIZE) {			map = virt_to_page(tmp);			clear_bit(PG_reserved, &map->flags);		}		free_pages((int)lcd_frame_user_fb, page_shift);	}	#endif}static void lcd_descriptor_init(void){	int i;	unsigned int pal_size;	unsigned int frm_size, ln_size;	unsigned char dual_panel = 0;	i = jzfb.bpp;#if defined(CONFIG_SOC_JZ4740)	if (i == 18 || i == 24)		i = 32;#else	if (i == 15)		i = 16;#endif	frm_size = (jzfb.w*jzfb.h*i)>>3;	ln_size = (jzfb.w*i)>>3;	if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL)) {		dual_panel = 1;		frm_size >>= 1;	}	frm_size = frm_size / 4;	ln_size = ln_size / 4;	switch (jzfb.bpp) {	case 1:		pal_size = 4;		break;	case 2:		pal_size = 8;		break;	case 4:		pal_size = 32;		break;	case 8:	default:		pal_size = 512;	}	pal_size /= 4;	lcd_frame_desc0  = lcd_desc_base + 0;	lcd_frame_desc1  = lcd_desc_base + 1;	lcd_palette_desc = lcd_desc_base + 2;	jz_lcd_buffer_addrs.lcd_desc_phys_addr = (unsigned int)virt_to_phys(lcd_frame_desc0);	/* Palette Descriptor */	lcd_palette_desc->next_desc = (int)virt_to_phys(lcd_frame_desc0);

⌨️ 快捷键说明

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