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

📄 davincifb.c

📁 这是我自已改的适合RGB888的视频驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (is_win(id, VID0)) {		dispc_reg_out(OSD_VIDWIN0ADR, addr);		dispc_reg_out(OSD_VIDWIN0OFST, line_length);//		printk("Address Calculated =0x%p\n", OSD_VIDWIN0ADR);//		printk("Value written =0x%p\n", addr);//		printk("****Video Window 0 Address =0x%p\n", dispc_reg_in(OSD_VIDWIN0ADR));//		printk("Video Window 0 Line Offset  =0x%p\n", line_length);	}	else if (is_win(id, VID1)) {		dispc_reg_out(OSD_VIDWIN1ADR, addr);		dispc_reg_out(OSD_VIDWIN1OFST, line_length);		printk("Video Window 1 Address =0x%p\n", addr);		printk("Video Window 1 Line Offset  =0x%p\n", line_length);	}	else if (is_win(id, OSD0)) {		dispc_reg_out(OSD_OSDWIN0ADR, addr);		dispc_reg_out(OSD_OSDWIN0OFST, line_length);//		printk("OSD Window 0 Address =0x%p\n", addr);//		printk("OSD Window 0 Line Offset  =0x%p\n", line_length);	}	else if (is_win(id, OSD1)) {		dispc_reg_out(OSD_OSDWIN1ADR, addr);		dispc_reg_out(OSD_OSDWIN1OFST, line_length);//		printk("OSD Window 1 Address =0x%p\n", addr);//		printk("OSD Window 1 Line Offset  =0x%p\n", line_length);	}	DBGEXIT;}static void set_win_enable(char *id, unsigned int on)		//启动指定的窗口{	on = (on == 0) ? 0 : ~0;		DBGENTER;	if (is_win(id, VID0))	/* Turning off VID0 use due to field inversion issue */		dispc_reg_merge(OSD_VIDWINMD, 0, OSD_VIDWINMD_ACT0);	else if (is_win(id, VID1)) 		dispc_reg_merge(OSD_VIDWINMD, on, OSD_VIDWINMD_ACT1);	else if (is_win(id, OSD0))		dispc_reg_merge(OSD_OSDWIN0MD, on, OSD_OSDWIN0MD_OACT0);	else if (is_win(id, OSD1)) {		/* The OACT1 bit is applicable only if OSD1 is not used as 		 * the attribute window		 */		if (!(dispc_reg_in(OSD_OSDWIN1MD) & OSD_OSDWIN1MD_OASW))			dispc_reg_merge(OSD_OSDWIN1MD, on, OSD_OSDWIN1MD_OACT1);	}			DBGEXIT;}static void set_win_mode(char *id)		//设定窗口的显示属性,根据的是每象素的位数值和窗口{	DBGENTER;	if (is_win(id, VID0))		;	else if (is_win(id, VID1)) {		if (dm.vid1->info.var.bits_per_pixel == 32)     ////////////////////////////////////			dispc_reg_merge(OSD_MISCCT, ~0,				OSD_MISCCT_RGBWIN | OSD_MISCCT_RGBEN);	}				else if (is_win(id, OSD0))		/* Set RGB565 mode */		dispc_reg_merge(OSD_OSDWIN0MD, OSD_OSDWIN0MD_RGB0E, 			OSD_OSDWIN0MD_RGB0E);	else if (is_win(id, OSD1)) {		/* Set as attribute window */		dispc_reg_merge(OSD_OSDWIN1MD, OSD_OSDWIN1MD_OASW, 			OSD_OSDWIN1MD_OASW);	}	DBGEXIT;}/** *      dm64xxfb_set_par - Optional function. Alters the hardware state. *      @info: frame buffer structure that represents a single frame buffer * *	Using the fb_var_screeninfo in fb_info we set the resolution of the *	this particular framebuffer. This function alters the par AND the *	fb_fix_screeninfo stored in fb_info. It doesn't not alter var in  *	fb_info since we are using that data. This means we depend on the *	data in var inside fb_info to be supported by the hardware.  *	dm64xxfb_check_var is always called before dmfb_set_par to ensure this. *	Again if you can't can't the resolution you don't need this function. * */static int dm64xxfb_set_par(struct fb_info *info) //利用了fb_info中的var来设置fix以及窗口的一些属性,在注册fb时使用{	struct dm_win_info *w = (struct dm_win_info *) info->par;	struct fb_var_screeninfo *v = &info->var;	u32 start = 0, offset = 0;		DBGENTER;//	printk(" set_par for %s \n", info->fix.id);	info->fix.line_length = v->xres_virtual * v->bits_per_pixel / 8;		offset = v->yoffset * info->fix.line_length + 		 v->xoffset * v->bits_per_pixel / 8;	start = (u32) w->fb_base_phys + offset;	set_sdram_params(info->fix.id, start, info->fix.line_length); //设置fb存储区寄存器	set_interlaced(info->fix.id, 0);	set_win_position(info->fix.id, 			 x_pos(w), y_pos(w), v->xres, v->yres );	set_win_mode(info->fix.id);    //如果fix.id="VID1"且bit-per-pixel=32,则此窗口设为RGB888	set_win_enable(info->fix.id, 1);		RETURN(0);	}/** *	dm64xxfb_ioctl - handler for private ioctls. */static intdm64xxfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,   //自定义的一些ioctl
	unsigned long arg, struct fb_info *info)
{
	struct dm_win_info *w = (struct dm_win_info *) info->par;
	void __user *argp = (void __user *)arg;
	struct fb_fillrect rect;
	struct Zoom_Params Zoom;
	long   std=0;
	
	DBGENTER;
		
	switch (cmd) {
		case FBIO_WAITFORVSYNC:
			/* This ioctl accepts an integer argument to specify a			 * display.  We only support one display, so we will			 * simply ignore the argument.			 */			RETURN(dm64xxfb_wait_for_vsync(w));			break;		case FBIO_SETATTRIBUTE:						//设置属性			if (copy_from_user(&rect, argp, sizeof(rect)))				return -EFAULT;			RETURN(dm64xxfb_set_attr_blend(&rect));			break;		case FBIO_SETPOSX:			if (arg >= 0 && arg <= DISP_XRES) {				w->x = arg;				dm64xxfb_check_var(&w->info.var, &w->info);				dm64xxfb_set_par(&w->info);				return 0;			}			else 				return -EINVAL;				break;		case FBIO_SETPOSY:			if (arg >= 0 && arg <= DISP_YRES) {
				w->y = arg;
				dm64xxfb_check_var(&w->info.var, &w->info);
				dm64xxfb_set_par(&w->info);
				return 0;			}			else 				return -EINVAL;				break;		case FBIO_SETZOOM:			if(copy_from_user(&Zoom, argp, sizeof(Zoom)))				return -EFAULT;			printk("win: %d, hfactor:%d, vfactor: %d\n", Zoom.WindowID,Zoom.Zoom_H, Zoom.Zoom_V );			if((Zoom.Zoom_H == 2) || (Zoom.Zoom_H == 0) || (Zoom.Zoom_H == 1) ||			   (Zoom.Zoom_V == 2) || (Zoom.Zoom_V == 0) || (Zoom.Zoom_V == 1))			{				set_zoom(Zoom.WindowID, Zoom.Zoom_H, Zoom.Zoom_V);				return 0;			}			else{				return -EINVAL;				}			break;		case FBIO_GETSTD:			std = ((dmparams.output << 16 ) |(dmparams.format));//(NTSC <<16) | (COPOSITE);			copy_to_user(argp, &std , sizeof(u_int32_t));			return 0;			break;	}	RETURN(-EINVAL);}/** *  	dm64xxfb_setcolreg - Optional function. Sets a color register. *      @regno: Which register in the CLUT we are programming  *      @red: The red value which can be up to 16 bits wide  *	@green: The green value which can be up to 16 bits wide  *	@blue:  The blue value which can be up to 16 bits wide. *	@transp: If supported the alpha value which can be up to 16 bits wide.	 *      @info: frame buffer info structure *  *  	Set a single color register. The values supplied have a 16 bit *  	magnitude which needs to be scaled in this function for the hardware.  *	Things to take into consideration are how many color registers, if *	any, are supported with the current color visual. With truecolor mode *	no color palettes are supported. Here a psuedo palette is created  *	which we store the value in pseudo_palette in struct fb_info. For *	pseudocolor mode we have a limited color palette. To deal with this *	we can program what color is displayed for a particular pixel value. *	DirectColor is similar in that we can program each color field. If *	we have a static colormap we don't need to implement this function.  *  *	Returns negative errno on error, or zero on success. */static int dm64xxfb_setcolreg(unsigned regno, unsigned red, unsigned green,			      unsigned blue, unsigned transp,			      struct fb_info *info)							//设定每个调色板中寄存器的值{	DBGENTER;	/* only pseudo-palette (16 bpp) allowed */	if (regno >= 16)  /* maximum number of palette entries */		RETURN(1);	if (info->var.grayscale) {		/* grayscale = 0.30*R + 0.59*G + 0.11*B */		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;	}	/* Truecolor has hardware-independent 16-entry pseudo-palette */  //真彩色模式	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {		u32 v;		if (regno >= 16)			RETURN(1);		red >>= (16 - info->var.red.length);		green >>= (16 - info->var.green.length);		blue >>= (16 - info->var.blue.length);		v = (red << info->var.red.offset) |		    (green << info->var.green.offset) |		    (blue << info->var.blue.offset);		switch (info->var.bits_per_pixel) {			case 16:		   		((u16*)(info->pseudo_palette))[regno] = v;				break;			default:				RETURN(1);		}		RETURN(0);	}	RETURN(0);}/** *      dm64xxfb_pan_display - NOT a required function. Pans the display. *      @var: frame buffer variable screen structure *      @info: frame buffer structure that represents a single frame buffer * *	Pan (or wrap, depending on the `vmode' field) the display using the *  	`xoffset' and `yoffset' fields of the `var' structure. *  	If the values don't fit, return -EINVAL. * *      Returns negative errno on error, or zero on success. */static int dm64xxfb_pan_display(struct fb_var_screeninfo *var,    //检查var的合法性,然后根据var的值设置ram映射
				struct fb_info *info)
{
	struct dm_win_info *w = (struct dm_win_info *) info->par;
	u32 start = 0, offset = 0;
	
	DBGENTER;
	if (var->xoffset > var->xres_virtual - var->xres)
		RETURN(-EINVAL);
	if (var->yoffset > var->yres_virtual - var->yres)
		RETURN(-EINVAL);
	if((var->xres_virtual * var->bits_per_pixel/8) % 32)	
		RETURN(-EINVAL);
		
	offset = var->yoffset * info->fix.line_length + 
		 var->xoffset * var->bits_per_pixel / 8;
	start = (u32) w->fb_base_phys + offset;
	set_sdram_params(info->fix.id, start, info->fix.line_length);

	RETURN(0);}/** *      dm64xxfb_blank - NOT a required function. Blanks the display. *      @blank_mode: the blank mode we want.  *      @info: frame buffer structure that represents a single frame buffer * *      Blank the screen if blank_mode != 0, else unblank. Return 0 if *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a  *      video mode which doesn't support it. Implements VESA suspend *      and powerdown modes on hardware that supports disabling hsync/vsync: *      blank_mode == 2: suspend vsync *      blank_mode == 3: suspend hsync *      blank_mode == 4: powerdown * *      Returns negative errno on error, or zero on success. * */static int dm64xxfb_blank(int blank_mode, struct fb_info *info){	DBGENTER;	/* ... */	RETURN(0);}		static int parse_win_params(char *wp,			      int *xres, int *yres, int *xpos, int *ypos){	char *s;		if ((s = strsep(&wp, "x")) == NULL)		return -EINVAL;	*xres = simple_strtoul(s, NULL, 0);	if ((s = strsep(&wp, "@")) == NULL)		return -EINVAL;	*yres = simple_strtoul(s, NULL, 0);	if ((s = strsep(&wp, ",")) == NULL)		return -EINVAL;	*xpos = simple_strtoul(s, NULL, 0);	if ((s = strsep(&wp, ":")) == NULL)		return -EINVAL;	*ypos = simple_strtoul(s, NULL, 0);	return 0;}/*  * Pass boot-time options by adding the following string to the boot params: * 	video=dm64xxfb:[option[:option]] * Valid options: * 	output=[lcd|ntsc|pal] * 	format=[composite|s-video|component|rgb] * 	vid0=[off|MxN@X,Y] * 	vid1=[off|MxN@X,Y] * 	osd0=[off|MxN@X,Y] * 	osd1=[off|MxN@X,Y] * 		MxN specify the window resolution (displayed size) * 		X,Y specify the window position * 		M, N, X, Y are integers * 		M, X should be multiples of 16 */#ifndef MODULEint __init dm64xxfb_setup(char *options){	char *this_opt;	u32 xres, yres, xpos, ypos;	int format_yres = 480;	DBGENTER;	printk("dm64xxfb: Options \"%s\"\n", options);	if (!options || !*options)		return 0;	while((this_opt = strsep(&options, ":")) != NULL) {		if (!*this_opt)	continue;		if (!strncmp(this_opt, "output=", 7)) {			if (!strncmp(this_opt + 7, "lcd", 3)) {				dmparams.output = LCD;				dmparams.format = 0;			}			else if (!strncmp(this_opt + 7, "ntsc", 4))				dmparams.output = NTSC;			else if (!strncmp(this_opt + 7, "pal", 3))				dmparams.output = PAL;		}		else if (!strncmp(this_opt, "format=", 7)) {			if (dmparams.output == LCD)				continue;			if (!strncmp(this_opt + 7, "composite", 9))				dmparams.format = COMPOSITE;			else if (!strncmp(this_opt + 7, "s-video", 7))				dmparams.format = SVIDEO;			else if (!strncmp(this_opt + 7, "component", 9))				dmparams.format = COMPONENT;			else if (!strncmp(this_opt + 7, "rgb", 3))				dmparams.format = RGB;		}		else if (!strncmp(this_opt, "vid0=", 5)) {			if (!strncmp(this_opt + 5, "off", 3))				dmparams.windows &= ~(1 << VID0);			else if (!parse_win_params(this_opt + 5, 						&xres, &yres, &xpos, &ypos)) {				dmparams.vid0_xres = xres;	      				dmparams.vid0_yres = yres;				dmparams.vid0_xpos = xpos;				dmparams.vid0_ypos = ypos;			}		}		else if (!strncmp(this_opt, "vid1=", 5)) {			if (!strncmp(this_opt + 5, "off", 3))				dmparams.windows &= ~(1 << VID1);			else if (!parse_win_params(this_opt + 5, 					      &xres, &yres, &xpos, &ypos)) {				dmparams.vid1_xres = xres;	      				dmparams.vid1_yres = yres;				dmparams.vid1_xpos = xpos;				dmparams.vid1_ypos = ypos;			}		}		else if (!strncmp(this_opt, "osd0=", 5)) { 			if (!strncmp(this_opt + 5, "off", 3))				dmparams.windows &= ~(1 << OSD0);			else if (!parse_win_params(this_opt + 5, 					      &xres, &yres, &xpos, &ypos)) {				dmparams.osd0_xres = xres;	      				dmparams.osd0_yres = yres;				dmparams.osd0_xpos = xpos;				dmparams.osd0_ypos = ypos;			}		}		else if (!strncmp(this_opt, "osd1=", 5)) {			if (!strncmp(this_opt + 5, "off", 3))				dmparams.windows &= ~(1 << OSD1);			else if (!parse_win_params(this_opt + 5, 					      &xres, &yres, &xpos, &ypos)) {				dmparams.osd1_xres = xres;	      				dmparams.osd1_yres = yres;				dmparams.osd1_xpos = xpos;				dmparams.osd1_ypos = ypos;			}		}	}	printk(KERN_INFO "DM64XX: " 		"Output on %s%s, Enabled windows: %s %s %s %s\n",		(dmparams.output == LCD) ? "LCD" :		(dmparams.output == NTSC) ? "NTSC" :		(dmparams.output == PAL) ? "PAL" : "unknown device!",

⌨️ 快捷键说明

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