|
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)
|