From: ? <uns...@us...> - 2002-06-09 20:47:28
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv13047 Modified Files: Config.in fbmem.c Added Files: vmonofb.c Log Message: First attempt at a driver for the VXT2000 monochrome framebuffer --- NEW FILE --- /* * A driver for the VXT2000's monochrome framebuffer. * * 2002 Uns Lider */ /* * The VMONO is believed to be a "dumb" monochrome framebuffer supporting 1bpp * and 2bpp modes, both of which are palletized. It appears to support * modification of the video timings to some degree, and may have hardware * cursor support. * * There is apparently no documentation available for the VMONO. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/fb.h> #include <video/fbcon.h> #include <asm/io.h> #define VMONO_FB_PHYS_ADDR 0x21000000 #define VMONO_FB_SIZE 0x80000 #define VMONO_REGS_PHYS_ADDR 0x200b0000 #define VMONO_REGS_SIZE 0x200 /* i think */ struct vmono_regs { u8 voodoo[0x50]; u8 bppthing; u8 morevoodo[0x12f]; u8 bt455_cmap_addr; u8 _padding1[3]; u8 bt455_cmap_data; u8 _padding2[3]; u8 bt455_clr; u8 _padding3[3]; u8 bt455_ovly; }; struct vmono_par { int bpp; }; struct vmono_fb_info { struct fb_info_gen gen; char *fbmem; volatile struct vmono_regs *regs; }; static struct vmono_fb_info the_fb_info; /* * */ /* par is the software's copy of the hardware state. var is the user-modifiable mode information fix is the non-user-modifiable state incurred by setting a mode */ /* par -> fix */ static int encode_fix(struct fb_fix_screeninfo *fix, const void *fb_par, struct fb_info_gen *fbinfo) { struct vmono_fb_info *info = (struct vmono_fb_info *)fbinfo; struct vmono_par *par = (struct vmono_par *)fb_par; strcpy(fix->id, info->gen.info.modename); fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; fix->visual = FB_VISUAL_PSEUDOCOLOR; fix->line_length = 1280 / 8; if(par->bpp == 2) fix->line_length *= 2; fix->smem_start = 0x21000000; fix->smem_len = fix->line_length * 1024; fix->xpanstep = fix->ypanstep = fix->ywrapstep = 0; fix->accel = FB_ACCEL_NONE; return 0; } /* var -> par */ static int decode_var(const struct fb_var_screeninfo *var, void *fb_par, struct fb_info_gen *info) { struct vmono_par *par = (struct vmono_par *)fb_par; if (var->xres_virtual != var->xres || var->yres_virtual != var->yres || var->nonstd) return -EINVAL; /* should also check vmode, etc */ if(var->xres != 1280 || var->yres != 1024) return -EINVAL; switch(var->bits_per_pixel) { case 1: case 2: par->bpp=var->bits_per_pixel; default: return -EINVAL; } return 0; } /* par -> var */ static int encode_var(struct fb_var_screeninfo *var, const void *fb_par, struct fb_info_gen *info) { struct vmono_par *par = (struct vmono_par *)fb_par; var->xres = 1280; var->yres = 1024; /* who knows what the other timing parameters are? */ var->xres_virtual = var->xres; var->yres_virtual = var->yres; var->xoffset = 0; var->yoffset = 0; var->red.offset = 0; var->green.offset = 0; var->blue.offset = 0; var->bits_per_pixel = par->bpp; var->grayscale = 1; /* uh. do we need to set red.length, green.length, blue.length? */ var->xoffset = 0; var->yoffset = 0; var->nonstd = 0; var->activate = 0; var->height = -1; var->width = -1; var->accel_flags = 0; return 0; } /* hardware -> par */ static void get_par(void *fb_par, struct fb_info_gen *info) { struct vmono_par *par = (struct vmono_par *)fb_par; /* don't know how to read from the hardware (if it can even be done) */ par->bpp = 1; } /* par -> hardware */ static void set_par(const void *fb_par, struct fb_info_gen *fbinfo) { struct vmono_fb_info *info = (struct vmono_fb_info *)fbinfo; struct vmono_par *par = (struct vmono_par *)fb_par; if(par->bpp == 1) { info->regs->bppthing = 1; } else { /* 2bpp */ info->regs->bppthing = 3; } } static int setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *fbinfo) { struct vmono_fb_info *info = (struct vmono_fb_info *)fbinfo; if(regno < 0 || regno > 3) return 1; info->regs->bt455_cmap_addr = regno; info->regs->bt455_cmap_data = 0; info->regs->bt455_cmap_data = green >> 12; return 0; } static int getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *transp, struct fb_info *fbinfo) { struct vmono_fb_info *info = (struct vmono_fb_info *)fbinfo; if(regno < 0 || regno > 3) return 1; info->regs->bt455_cmap_addr = regno; info->regs->bt455_cmap_data = 0; *red = 0; *green = (info->regs->bt455_cmap_data & 15) << 12; *blue = 0; return 0; } static int blank(int blank, struct fb_info_gen *info) { /* don't know how yet, so have fbgen blank with the palette */ return 1; } static void set_disp(const void *fb_par, struct display *disp, struct fb_info_gen *fbinfo) { struct vmono_fb_info *info = (struct vmono_fb_info *)fbinfo; disp->screen_base = (char *)info->fbmem; switch(fbinfo->info.var.bits_per_pixel) { #ifdef FBCON_HAS_MFB case 1: disp->dispsw = &fbcon_mfb; break; #endif #ifdef FBCON_HAS_CFB2 case 2: disp->dispsw = &fbcon_cfb2; break; #endif default: disp->dispsw = &fbcon_dummy; } disp->scrollmode = SCROLL_YREDRAW; } /* * Initialization code */ static struct fb_ops vmono_ops = { owner: THIS_MODULE, fb_open: NULL, fb_release: NULL, fb_get_fix: fbgen_get_fix, fb_get_var: fbgen_get_var, fb_set_var: fbgen_set_var, fb_get_cmap: fbgen_get_cmap, fb_set_cmap: fbgen_set_cmap, fb_pan_display: fbgen_pan_display, fb_ioctl: NULL, }; static struct fbgen_hwswitch vmono_hwswitch = { detect: NULL, encode_fix: encode_fix, decode_var: decode_var, encode_var: encode_var, get_par: get_par, set_par: set_par, getcolreg: getcolreg, setcolreg: setcolreg, pan_display: NULL, blank: blank, set_disp: set_disp }; static int __init vmonofb_probe(volatile unsigned char *vmono_fb_mem) { unsigned char a, b, c, d; a = vmono_fb_mem[0]; b = vmono_fb_mem[VMONO_FB_SIZE]; vmono_fb_mem[0] = a ^ 0xa5; c = vmono_fb_mem[0]; d = vmono_fb_mem[VMONO_FB_SIZE]; vmono_fb_mem[0] = a; if(c != (a ^ 0xa5)) { printk("vmonofb: No framebuffer seems to be installed!\n"); return 0; } if(a != b || c != d) { printk("vmonofb: This doesn't look like a VMONO. Using it anyway...\n"); } else { printk("vmonofb: Looks like a VMONO.\n"); } return 1; } static void __init vmonofb_reset(void) { /* erm.. dunno how yet */ } static void init_fb_info(struct fb_info *info) { static struct display disp; strcpy(info->modename, "VMONO"); info->node = -1; info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &vmono_ops; info->disp = &disp; info->changevar = NULL; info->switch_con = fbgen_switch; info->updatevar = fbgen_update_var; info->blank = fbgen_blank; fbgen_get_var(&disp.var, -1, &the_fb_info.gen.info); disp.var.activate = FB_ACTIVATE_NOW; fbgen_do_set_var(&disp.var, 1, &the_fb_info.gen); fbgen_set_disp(-1, &the_fb_info.gen); fbgen_install_cmap(0, &the_fb_info.gen); } static int __init map_fb(struct vmono_fb_info *info) { info->fbmem = ioremap(VMONO_FB_PHYS_ADDR, VMONO_FB_SIZE * 2); if(info->fbmem == NULL) return 1; info->regs = ioremap(VMONO_REGS_PHYS_ADDR, VMONO_REGS_SIZE); if(info->regs == NULL) { iounmap(info->fbmem); return 1; } return 0; } int __init vmonofb_init(void) { if(map_fb(&the_fb_info) != 0) { printk("vmonofb: Unable to map framebuffer!\n"); return -ENODEV; } if(vmonofb_probe(the_fb_info.fbmem) == 0) return -ENODEV; vmonofb_reset(); init_fb_info(&the_fb_info.gen.info); the_fb_info.gen.fbhw = &vmono_hwswitch; if(register_framebuffer(&the_fb_info.gen.info) < 0) { printk("vmonofb: unable to register framebuffer!\n"); return -ENODEV; } printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(the_fb_info.gen.info.node), the_fb_info.gen.info.modename); MOD_INC_USE_COUNT; return 0; } int __init vmonofb_setup(char *options) { return 0; } Index: Config.in =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/Config.in,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- Config.in 11 Apr 2002 13:26:51 -0000 1.2 +++ Config.in 9 Jun 2002 20:47:23 -0000 1.3 @@ -196,6 +196,9 @@ if [ "$CONFIG_NINO" = "y" ]; then bool ' TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912 fi + if [ "$ARCH" = "vax" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' VXT2000 monochrome framebuffer support (EXPERIMENTAL)' CONFIG_FB_VMONO + fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL fi @@ -399,6 +402,15 @@ if [ "$CONFIG_FB_VGA16" = "m" ]; then define_tristate CONFIG_FBCON_VGA_PLANES m fi + fi + if [ "$CONFIG_FB_VMONO" = "y" ]; then + define_tristate CONFIG_FBCON_MFB y + define_tristate CONFIG_FBCON_CFB2 y + else + if [ "$CONFIG_FB_VMONO" = "m" ]; then + define_tristate CONFIG_FBCON_MFB m + define_tristate CONFIG_FBCON_CFB2 m + fi fi if [ "$CONFIG_FB_HGA" = "y" ]; then define_tristate CONFIG_FBCON_HGA y Index: fbmem.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/fbmem.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- fbmem.c 11 Apr 2002 13:26:52 -0000 1.2 +++ fbmem.c 9 Jun 2002 20:47:23 -0000 1.3 @@ -126,6 +126,8 @@ extern int pvr2fb_setup(char*); extern int sstfb_init(void); extern int sstfb_setup(char*); +extern int vmonofb_init(void); +extern int vmonofb_setup(char*); static struct { const char *name; @@ -278,6 +280,9 @@ #endif #ifdef CONFIG_FB_VOODOO1 { "sst", sstfb_init, sstfb_setup }, +#endif +#ifdef CONFIG_FB_VMONO + { "vmono", vmonofb_init, vmonofb_setup }, #endif /* * Generic drivers that don't use resource management (yet) |