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

📄 au1200fb.c

📁 为AU1200芯片linux系统所设计的LCD液晶显示驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
winbpp (unsigned int winctrl1){	/* how many bytes of memory are needed for each pixel format */	switch (winctrl1 & LCD_WINCTRL1_FRM)	{		case LCD_WINCTRL1_FRM_1BPP: return 1; break;		case LCD_WINCTRL1_FRM_2BPP: return 2; break;		case LCD_WINCTRL1_FRM_4BPP: return 4; break;		case LCD_WINCTRL1_FRM_8BPP: return 8; break;		case LCD_WINCTRL1_FRM_12BPP: return 16; break;		case LCD_WINCTRL1_FRM_16BPP655: return 16; break;		case LCD_WINCTRL1_FRM_16BPP565: return 16; break;		case LCD_WINCTRL1_FRM_16BPP556: return 16; break;		case LCD_WINCTRL1_FRM_16BPPI1555: return 16; break;		case LCD_WINCTRL1_FRM_16BPPI5551: return 16; break;		case LCD_WINCTRL1_FRM_16BPPA1555: return 16; break;		case LCD_WINCTRL1_FRM_16BPPA5551: return 16; break;		case LCD_WINCTRL1_FRM_24BPP: return 32; break;		case LCD_WINCTRL1_FRM_32BPP: return 32; break;		default: return 0; break;	}}static intfbinfo2index (struct fb_info *fb_info){	int i;	for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i)	{		if (fb_info == (struct fb_info *)(&fb_infos[i]))			return i;	}	printk("au1200fb: ERROR: fbinfo2index failed!\n");	return -1;}static void au1200_detect(void){	/*	 *  This function should detect the current video mode settings 	 *  and store it as the default video mode	 * Yeh, well, we're not going to change any settings so we're	 * always stuck with the default ...	 */}static int au1200_encode_fix(struct fb_fix_screeninfo *fix, 		const void *_par, struct fb_info_gen *_info){    struct au1200fb_info *info = (struct au1200fb_info *) _info;    struct au1200fb_par *par = (struct au1200fb_par *) _par;	//struct fb_var_screeninfo *var = &par->var;	int plane;	plane = fbinfo2index(info);	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	fix->smem_start = info->fb_phys;	fix->smem_len = info->fb_size;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;        fix->visual = (par->var.bits_per_pixel == 8) ?	       	FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;	fix->ywrapstep = 0;	fix->xpanstep = 1;	fix->ypanstep = 1;// FIX!!!! why doesn't par->line_length work???? it does for au1100	fix->line_length = fb_pars[plane].line_length; //par->line_length;//printk("par -> lline _ length %d\n", par->line_length);	return 0;}static void set_color_bitfields(struct fb_var_screeninfo *var, int plane){	if (var->bits_per_pixel == 8)	{		var->red.offset = 0;		var->red.length = 8;		var->green.offset = 0;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.offset = 0;		var->transp.length = 0;	}	else		if (var->bits_per_pixel == 16)	{		/* FIX!!! How does CCO affect this ? */		/* FIX!!! Not exactly sure how many of these work with FB */		switch (win->w[plane].mode_winctrl1 & LCD_WINCTRL1_FRM)		{			case LCD_WINCTRL1_FRM_16BPP655:				var->red.offset = 10;				var->red.length = 6;				var->green.offset = 5;				var->green.length = 5;				var->blue.offset = 0;				var->blue.length = 5;				var->transp.offset = 0;				var->transp.length = 0;				break;			case LCD_WINCTRL1_FRM_16BPP565:				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 LCD_WINCTRL1_FRM_16BPP556:				var->red.offset = 11;				var->red.length = 5;				var->green.offset = 6;				var->green.length = 5;				var->blue.offset = 0;				var->blue.length = 6;				var->transp.offset = 0;				var->transp.length = 0;				break;			case LCD_WINCTRL1_FRM_16BPPI1555:				var->red.offset = 10;				var->red.length = 5;				var->green.offset = 5;				var->green.length = 5;				var->blue.offset = 0;				var->blue.length = 5;				var->transp.offset = 0;				var->transp.length = 0;				break;			case LCD_WINCTRL1_FRM_16BPPI5551:				var->red.offset = 11;				var->red.length = 5;				var->green.offset = 6;				var->green.length = 5;				var->blue.offset = 1;				var->blue.length = 5;				var->transp.offset = 0;				var->transp.length = 0;				break;			case LCD_WINCTRL1_FRM_16BPPA1555:				var->red.offset = 10;				var->red.length = 5;				var->green.offset = 5;				var->green.length = 5;				var->blue.offset = 0;				var->blue.length = 5;				var->transp.offset = 15;				var->transp.length = 1;				break;			case LCD_WINCTRL1_FRM_16BPPA5551:				var->red.offset = 11;				var->red.length = 5;				var->green.offset = 6;				var->green.length = 5;				var->blue.offset = 1;				var->blue.length = 5;				var->transp.offset = 0;				var->transp.length = 1;				break;			default:				printk("ERROR: Invalid PIXEL FORMAT!!!\n"); break;		}	}	else	if (var->bits_per_pixel == 32)	{		switch (win->w[plane].mode_winctrl1 & LCD_WINCTRL1_FRM)		{		case LCD_WINCTRL1_FRM_24BPP:			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 LCD_WINCTRL1_FRM_32BPP:			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;		}	}	var->red.msb_right = 0;	var->green.msb_right = 0;	var->blue.msb_right = 0;	var->transp.msb_right = 0;#if 0printk("set_color_bitfields(a=%d, r=%d..%d, g=%d..%d, b=%d..%d)\n",	var->transp.offset,	var->red.offset+var->red.length-1, var->red.offset,	var->green.offset+var->green.length-1, var->green.offset,	var->blue.offset+var->blue.length-1, var->blue.offset);#endif}static int au1200_decode_var(const struct fb_var_screeninfo *var, 		void *_par, struct fb_info_gen *_info){	struct au1200fb_par *par = (struct au1200fb_par *)_par;	int plane, bpp;	plane = fbinfo2index((struct fb_info *)_info);//printk("au1200_decode_var on plane %d\n", plane);	/*	 * Don't allow setting any of these yet: xres and yres don't	 * make sense for LCD panels.	 */	if (var->xres != win->w[plane].xres ||	    var->yres != win->w[plane].yres ||	    var->xres != win->w[plane].xres ||	    var->yres != win->w[plane].yres) {		return -EINVAL;	}	bpp = winbpp(win->w[plane].mode_winctrl1);	if(var->bits_per_pixel != bpp) {		//return -EINVAL; on au1200, pixel format is independent of panel pixel		printk("WARNING: bits_per_pizel != panel->bpp\n");	}	memset(par, 0, sizeof(struct au1200fb_par));	par->var = *var;		/* FIXME */	switch (var->bits_per_pixel) {		case 8:			par->var.bits_per_pixel = 8;			break;		case 16:			par->var.bits_per_pixel = 16;			break;		case 24:		case 32:			par->var.bits_per_pixel = 32;			break;		default:			printk("color depth %d bpp not supported\n",					var->bits_per_pixel);			return -EINVAL;	}	set_color_bitfields(&par->var, plane);	/* FIX!!! what is this for 24/32bpp? */	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;	return 0;}static int au1200_encode_var(struct fb_var_screeninfo *var, 		const void *par, struct fb_info_gen *_info){	*var = ((struct au1200fb_par *)par)->var;	return 0;}static void au1200_get_par(void *_par, struct fb_info_gen *_info){	int index;	index = fbinfo2index((struct fb_info *)_info);	*(struct au1200fb_par *)_par = fb_pars[index]; //current_par;}static void au1200_set_par(const void *par, struct fb_info_gen *info){	/* nothing to do: we don't change any settings */}static int au1200_getcolreg(unsigned regno, unsigned *red, unsigned *green,			 unsigned *blue, unsigned *transp,			 struct fb_info *info){	struct au1200fb_info* i = (struct au1200fb_info*)info;//	printk("au1200_getcolreg...%d what does this actually do for >=16bpp\n", regno);	if (regno > 255)		return 1;   	*red    = i->palette[regno].red; 	*green  = i->palette[regno].green; 	*blue   = i->palette[regno].blue; 	*transp = 0;	return 0;}static int au1200_setcolreg(unsigned regno, unsigned red, unsigned green,			 unsigned blue, unsigned transp,			 struct fb_info *info){	struct au1200fb_info* i = (struct au1200fb_info *)info;	u32 rgbcol;	int plane, bpp;	plane = fbinfo2index((struct fb_info *)info);	bpp = winbpp(win->w[plane].mode_winctrl1);//	printk("au1200_setcolreg...%d what does this actually do for >=16bpp\n", regno);	if (regno > 255)		return 1;	i->palette[regno].red    = red;	i->palette[regno].green  = green;	i->palette[regno].blue   = blue;   	switch(bpp) {#ifdef FBCON_HAS_CFB8	case 8:		red >>= 10;		green >>= 10;		blue >>= 10;		panel_reg->lcd_pallettebase[regno] = (blue&0x1f) | 			((green&0x3f)<<5) | ((red&0x1f)<<11);		break;#endif#ifdef FBCON_HAS_CFB16/* FIX!!!! depends upon pixel format */	case 16:		i->fbcon_cmap16[regno] =			((red & 0xf800) >> 0) |			((green & 0xfc00) >> 5) |			((blue & 0xf800) >> 11);		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		i->fbcon_cmap32[regno] =            (((u32 )transp & 0xff00) << 16) |            (((u32 )red & 0xff00) << 8) |            (((u32 )green & 0xff00)) |            (((u32 )blue & 0xff00) >> 8);		break;#endif	default:	printk("unsupported au1200_setcolreg(%d)\n", bpp);		break;	}	return 0;}static int  au1200_blank(int blank_mode, struct fb_info_gen *_info){	struct au1200fb_info *fb_info = (struct au1200fb_info *)_info;	int plane;	/* Short-circuit screen blanking */	if (fb_info->noblanking)		return 0;	plane = fbinfo2index((struct fb_info *)_info);	switch (blank_mode) {	case VESA_NO_BLANKING:		/* turn on panel *///		printk("turn on panel\n");		if (panel->device_init) panel->device_init();        lcd->screen |= LCD_SCREEN_SEN;		break;	case VESA_VSYNC_SUSPEND:	case VESA_HSYNC_SUSPEND:	case VESA_POWERDOWN:		/* turn off panel *///		printk("turn off panel\n");		if (panel->device_shutdown) panel->device_shutdown();        lcd->screen &= ~LCD_SCREEN_SEN;		while ((lcd->intstatus & LCD_INT_SD) == 0)			;		lcd->intstatus = LCD_INT_SD;        break;	default: 		break;	}	return 0;}static void au1200_set_disp(const void *unused, struct display *disp,			 struct fb_info_gen *info){	struct au1200fb_info *fb_info;	int plane;	fb_info = (struct au1200fb_info *)info;	disp->screen_base = (char *)fb_info->fb_virt_start;	switch (disp->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 8:		disp->dispsw = &fbcon_cfb8;		if (fb_info->nohwcursor)			fbcon_cfb8.cursor = au1200_nocursor;		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		disp->dispsw = &fbcon_cfb16;		disp->dispsw_data = fb_info->fbcon_cmap16;		if (fb_info->nohwcursor)			fbcon_cfb16.cursor = au1200_nocursor;		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		disp->dispsw = &fbcon_cfb32;		disp->dispsw_data = fb_info->fbcon_cmap32;		if (fb_info->nohwcursor)			fbcon_cfb32.cursor = au1200_nocursor;		break;#endif	default:		disp->dispsw = &fbcon_dummy;		disp->dispsw_data = NULL;		break;	}}static intau1200fb_mmap(struct fb_info *_fb,	     struct file *file,	     struct vm_area_struct *vma){	unsigned int len;	unsigned long start=0, off;	struct au1200fb_info *fb_info = (struct au1200fb_info *)_fb;	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {		return -EINVAL;	}    	start = fb_info->fb_phys & PAGE_MASK;	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info->fb_size);	off = vma->vm_pgoff << PAGE_SHIFT;	if ((vma->vm_end - vma->vm_start + off) > len) {		return -EINVAL;	}	off += start;	vma->vm_pgoff = off >> PAGE_SHIFT;	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;	/* This is an IO map - tell maydump to skip this VMA */	vma->vm_flags |= VM_IO;    	if (io_remap_page_range(vma->vm_start, off,				vma->vm_end - vma->vm_start,				vma->vm_page_prot)) {		return -EAGAIN;	}	fb_info->mmaped = 1;	return 0;}int au1200_pan_display(const struct fb_var_screeninfo *var,		       struct fb_info_gen *info){	return 0;}static int au1200fb_ioctl(struct inode *inode, struct file *file, u_int cmd,			  u_long arg, int con, struct fb_info *info){	int plane;	plane = fbinfo2index(info);//	printk("au1200fb: ioctl %d on plane %d\n", cmd, plane);	if (cmd == 0x46FF)	{		au1200_lcd_getset_t iodata;		if (copy_from_user(&iodata, (void *) arg, sizeof(au1200_lcd_getset_t)))			return -EFAULT;		switch (iodata.subcmd)		{			case AU1200_LCD_GET_WINENABLE:				iodata.winenable.enable = (lcd->winenable & (1<<plane)) ? 1 : 0;				break;			case AU1200_LCD_SET_WINENABLE:				{				u32 winenable;				winenable = lcd->winenable;				winenable &= ~(1<<plane);				winenable |= (iodata.winenable.enable) ? (1<<plane) : 0;				lcd->winenable = winenable;				}				break;			case AU1200_LCD_GET_WINLOCATION:				iodata.winlocation.x =					(lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;				iodata.winlocation.y =					(lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;				break;			case AU1200_LCD_SET_WINLOCATION:				au1200_setlocation(plane, iodata.winlocation.x, iodata.winlocation.y);				break;			case AU1200_LCD_GET_WINSIZE:

⌨️ 快捷键说明

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