📄 davincifb.c
字号:
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 + -