#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <video/vga.h>
* card parameters
*/
-static struct fb_info vga16fb;
-
-static struct vga16fb_par {
+struct vga16fb_par {
/* structure holding original VGA register settings when the
screen is blanked */
struct {
- unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
- unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
- unsigned char CrtMiscIO; /* Miscellaneous register */
- unsigned char HorizontalTotal; /* CRT-Controller:00h */
- unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
- unsigned char StartHorizRetrace; /* CRT-Controller:04h */
- unsigned char EndHorizRetrace; /* CRT-Controller:05h */
- unsigned char Overflow; /* CRT-Controller:07h */
- unsigned char StartVertRetrace; /* CRT-Controller:10h */
- unsigned char EndVertRetrace; /* CRT-Controller:11h */
- unsigned char ModeControl; /* CRT-Controller:17h */
- unsigned char ClockingMode; /* Seq-Controller:01h */
+ unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
+ unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
+ unsigned char CrtMiscIO; /* Miscellaneous register */
+ unsigned char HorizontalTotal; /* CRT-Controller:00h */
+ unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
+ unsigned char StartHorizRetrace;/* CRT-Controller:04h */
+ unsigned char EndHorizRetrace; /* CRT-Controller:05h */
+ unsigned char Overflow; /* CRT-Controller:07h */
+ unsigned char StartVertRetrace; /* CRT-Controller:10h */
+ unsigned char EndVertRetrace; /* CRT-Controller:11h */
+ unsigned char ModeControl; /* CRT-Controller:17h */
+ unsigned char ClockingMode; /* Seq-Controller:01h */
} vga_state;
struct vgastate state;
atomic_t ref_count;
int palette_blanked, vesa_blanked, mode, isVGA;
u8 misc, pel_msk, vss, clkdiv;
u8 crtc[VGA_CRT_C];
-} vga16_par;
+};
/* --------------------------------------------------------------------- */
-static struct fb_var_screeninfo vga16fb_defined = {
+static struct fb_var_screeninfo vga16fb_defined __initdata = {
.xres = 640,
.yres = 480,
.xres_virtual = 640,
.pixclock = 39721,
.left_margin = 48,
.right_margin = 16,
- .upper_margin = 39,
- .lower_margin = 8,
+ .upper_margin = 33,
+ .lower_margin = 10,
.hsync_len = 96,
.vsync_len = 2,
.vmode = FB_VMODE_NONINTERLACED,
suitable instruction is the x86 bitwise OR. The following
read-modify-write routine should optimize to one such bitwise
OR. */
-static inline void rmw(volatile char *p)
+static inline void rmw(volatile char __iomem *p)
{
readb(p);
writeb(1, p);
static void vga16fb_pan_var(struct fb_info *info,
struct fb_var_screeninfo *var)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
u32 xoffset, pos;
xoffset = var->xoffset;
static int vga16fb_open(struct fb_info *info, int user)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
int cnt = atomic_read(&par->ref_count);
if (!cnt) {
static int vga16fb_release(struct fb_info *info, int user)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
int cnt = atomic_read(&par->ref_count);
if (!cnt)
static int vga16fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
u32 xres, right, hslen, left, xtotal;
u32 yres, lower, vslen, upper, ytotal;
u32 vxres, xoffset, vyres, yoffset;
static int vga16fb_set_par(struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
u8 gdc[VGA_GFX_C];
u8 seq[VGA_SEQ_C];
u8 atc[VGA_ATT_C];
unsigned blue, unsigned transp,
struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
int gray;
/*
static int vga16fb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- if (var->xoffset + info->var.xres > info->var.xres_virtual ||
- var->yoffset + info->var.yres > info->var.yres_virtual)
- return -EINVAL;
-
vga16fb_pan_var(info, var);
-
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
- info->var.vmode &= ~FB_VMODE_YWRAP;
return 0;
}
* <Start of vertical Retrace> to maximum (incl. overflow)
* Result: turn off vertical sync (VSync) pulse.
*/
- if (mode & VESA_VSYNC_SUSPEND) {
+ if (mode & FB_BLANK_VSYNC_SUSPEND) {
outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */
outb_p(0xff,vga_video_port_val); /* maximum value */
outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */
outb_p(par->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
}
- if (mode & VESA_HSYNC_SUSPEND) {
+ if (mode & FB_BLANK_HSYNC_SUSPEND) {
/*
* Set <End of horizontal retrace> to minimum (0) and
* <Start of horizontal Retrace> to maximum
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
static int vga16fb_blank(int blank, struct fb_info *info)
{
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
+ struct vga16fb_par *par = info->par;
switch (blank) {
- case 0: /* Unblank */
+ case FB_BLANK_UNBLANK: /* Unblank */
if (par->vesa_blanked) {
vga_vesa_unblank(par);
par->vesa_blanked = 0;
}
if (par->palette_blanked) {
- //do_install_cmap(info->currcon, info);
par->palette_blanked = 0;
}
break;
- case 1: /* blank */
+ case FB_BLANK_NORMAL: /* blank */
vga_pal_blank();
par->palette_blanked = 1;
break;
default: /* VESA blanking */
- vga_vesa_blank(par, blank-1);
+ vga_vesa_blank(par, blank);
par->vesa_blanked = 1;
break;
}
return 0;
}
-void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+static void vga_8planes_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
u32 dx = rect->dx, width = rect->width;
char oldindex = getindex();
char oldmask = selectmask();
int line_ofs, height;
char oldop, oldsr;
- char *where;
+ char __iomem *where;
dx /= 4;
where = info->screen_base + dx + rect->dy * info->fix.line_length;
setindex(oldindex);
}
-void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+static void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
int x, x2, y2, vxres, vyres, width, height, line_ofs;
- char *dst;
+ char __iomem *dst;
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
}
}
-void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
char oldindex = getindex();
char oldmode = setmode(0x41);
char oldsr = setsr(0xf);
int height, line_ofs, x;
u32 sx, dx, width;
- char *dest, *src;
+ char __iomem *dest;
+ char __iomem *src;
height = area->height;
setindex(oldindex);
}
-void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
int x, x2, y2, old_dx, old_dy, vxres, vyres;
int height, width, line_ofs;
- char *dst = NULL, *src = NULL;
+ char __iomem *dst = NULL;
+ char __iomem *src = NULL;
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
#endif
#endif
-void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
+static void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
{
char oldindex = getindex();
char oldmode = setmode(0x40);
char oldmask = selectmask();
const char *cdat = image->data;
u32 dx = image->dx;
- char *where;
+ char __iomem *where;
int y;
dx /= 4;
setindex(oldindex);
}
-void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image)
+static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *image)
{
- char *where = info->screen_base + (image->dx/8) +
+ char __iomem *where = info->screen_base + (image->dx/8) +
image->dy * info->fix.line_length;
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
- char *cdat = (char *) image->data, *dst;
+ struct vga16fb_par *par = info->par;
+ char *cdat = (char *) image->data;
+ char __iomem *dst;
int x, y;
switch (info->fix.type) {
}
}
-void vga_imageblit_color(struct fb_info *info, const struct fb_image *image)
+static void vga_imageblit_color(struct fb_info *info, const struct fb_image *image)
{
/*
* Draw logo
*/
- struct vga16fb_par *par = (struct vga16fb_par *) info->par;
- char *where = info->screen_base + image->dy * info->fix.line_length +
+ struct vga16fb_par *par = info->par;
+ char __iomem *where =
+ info->screen_base + image->dy * info->fix.line_length +
image->dx/8;
- const char *cdat = image->data, *dst;
+ const char *cdat = image->data;
+ char __iomem *dst;
int x, y;
switch (info->fix.type) {
}
}
-void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image)
{
if (image->depth == 1)
vga_imageblit_expand(info, image);
- else if (image->depth <= info->var.bits_per_pixel)
+ else
vga_imageblit_color(info, image);
}
.fb_fillrect = vga16fb_fillrect,
.fb_copyarea = vga16fb_copyarea,
.fb_imageblit = vga16fb_imageblit,
- .fb_cursor = soft_cursor,
};
-int vga16fb_setup(char *options)
+#ifndef MODULE
+static int vga16fb_setup(char *options)
{
char *this_opt;
}
return 0;
}
+#endif
-int __init vga16fb_init(void)
+static int __init vga16fb_probe(struct device *device)
{
+ struct platform_device *dev = to_platform_device(device);
+ struct fb_info *info;
+ struct vga16fb_par *par;
int i;
- int ret;
-#ifndef MODULE
- char *option = NULL;
-
- if (fb_get_options("vga16fb", &option))
- return -ENODEV;
+ int ret = 0;
- vga16fb_setup(option);
-#endif
printk(KERN_DEBUG "vga16fb: initializing\n");
+ info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
+
+ if (!info) {
+ ret = -ENOMEM;
+ goto err_fb_alloc;
+ }
/* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
+ info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
- vga16fb.screen_base = (void *)VGA_MAP_MEM(VGA_FB_PHYS);
- if (!vga16fb.screen_base) {
+ if (!info->screen_base) {
printk(KERN_ERR "vga16fb: unable to map device\n");
ret = -ENOMEM;
goto err_ioremap;
}
- printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
- vga16_par.isVGA = ORIG_VIDEO_ISVGA;
- vga16_par.palette_blanked = 0;
- vga16_par.vesa_blanked = 0;
+ printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
+ par = info->par;
+
+ par->isVGA = ORIG_VIDEO_ISVGA;
+ par->palette_blanked = 0;
+ par->vesa_blanked = 0;
- i = vga16_par.isVGA? 6 : 2;
+ i = par->isVGA? 6 : 2;
vga16fb_defined.red.length = i;
vga16fb_defined.green.length = i;
vga16fb_defined.blue.length = i;
/* name should not depend on EGA/VGA */
- vga16fb.fbops = &vga16fb_ops;
- vga16fb.var = vga16fb_defined;
- vga16fb.fix = vga16fb_fix;
- vga16fb.par = &vga16_par;
- vga16fb.flags = FBINFO_FLAG_DEFAULT |
+ info->fbops = &vga16fb_ops;
+ info->var = vga16fb_defined;
+ info->fix = vga16fb_fix;
+ info->flags = FBINFO_FLAG_DEFAULT |
FBINFO_HWACCEL_YPAN;
- i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16;
- ret = fb_alloc_cmap(&vga16fb.cmap, i, 0);
+ i = (info->var.bits_per_pixel == 8) ? 256 : 16;
+ ret = fb_alloc_cmap(&info->cmap, i, 0);
if (ret) {
printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
ret = -ENOMEM;
goto err_alloc_cmap;
}
- if (vga16fb_check_var(&vga16fb.var, &vga16fb)) {
+ if (vga16fb_check_var(&info->var, info)) {
printk(KERN_ERR "vga16fb: unable to validate variable\n");
ret = -EINVAL;
goto err_check_var;
}
- vga16fb_update_fix(&vga16fb);
+ vga16fb_update_fix(info);
- if (register_framebuffer(&vga16fb) < 0) {
+ if (register_framebuffer(info) < 0) {
printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
ret = -EINVAL;
goto err_check_var;
}
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- vga16fb.node, vga16fb.fix.id);
+ info->node, info->fix.id);
+ dev_set_drvdata(device, info);
return 0;
err_check_var:
- fb_dealloc_cmap(&vga16fb.cmap);
+ fb_dealloc_cmap(&info->cmap);
err_alloc_cmap:
- iounmap(vga16fb.screen_base);
+ iounmap(info->screen_base);
err_ioremap:
+ framebuffer_release(info);
+ err_fb_alloc:
+ return ret;
+}
+
+static int vga16fb_remove(struct device *device)
+{
+ struct fb_info *info = dev_get_drvdata(device);
+
+ if (info) {
+ unregister_framebuffer(info);
+ iounmap(info->screen_base);
+ fb_dealloc_cmap(&info->cmap);
+ /* XXX unshare VGA regions */
+ framebuffer_release(info);
+ }
+
+ return 0;
+}
+
+static struct device_driver vga16fb_driver = {
+ .name = "vga16fb",
+ .bus = &platform_bus_type,
+ .probe = vga16fb_probe,
+ .remove = vga16fb_remove,
+};
+
+static struct platform_device vga16fb_device = {
+ .name = "vga16fb",
+};
+
+static int __init vga16fb_init(void)
+{
+ int ret;
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("vga16fb", &option))
+ return -ENODEV;
+
+ vga16fb_setup(option);
+#endif
+ ret = driver_register(&vga16fb_driver);
+
+ if (!ret) {
+ ret = platform_device_register(&vga16fb_device);
+ if (ret)
+ driver_unregister(&vga16fb_driver);
+ }
+
return ret;
}
static void __exit vga16fb_exit(void)
{
- unregister_framebuffer(&vga16fb);
- iounmap(vga16fb.screen_base);
- fb_dealloc_cmap(&vga16fb.cmap);
- /* XXX unshare VGA regions */
+ platform_device_unregister(&vga16fb_device);
+ driver_unregister(&vga16fb_driver);
}
-#ifdef MODULE
MODULE_LICENSE("GPL");
-#endif
module_init(vga16fb_init);
module_exit(vga16fb_exit);