diff options
Diffstat (limited to 'drivers/video/fbdev/vga16fb.c')
-rw-r--r-- | drivers/video/fbdev/vga16fb.c | 191 |
1 files changed, 73 insertions, 118 deletions
diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index d21f68f3ee44..35cf51ae3292 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -1,13 +1,13 @@ /* * linux/drivers/video/vga16.c -- VGA 16-color framebuffer driver - * + * * Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz> * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm * Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> * * This file is subject to the terms and conditions of the GNU General * Public License. See the file COPYING in the main directory of this - * archive for more details. + * archive for more details. */ #include <linux/module.h> @@ -25,9 +25,6 @@ #include <asm/io.h> #include <video/vga.h> -#define VGA_FB_PHYS 0xA0000 -#define VGA_FB_PHYS_LEN 65536 - #define MODE_SKIP4 1 #define MODE_8BPP 2 #define MODE_CFB 4 @@ -70,7 +67,7 @@ static struct fb_var_screeninfo vga16fb_defined = { .yres = 480, .xres_virtual = 640, .yres_virtual = 480, - .bits_per_pixel = 4, + .bits_per_pixel = 4, .activate = FB_ACTIVATE_TEST, .height = -1, .width = -1, @@ -87,8 +84,8 @@ static struct fb_var_screeninfo vga16fb_defined = { /* name should not depend on EGA/VGA */ static const struct fb_fix_screeninfo vga16fb_fix = { .id = "VGA16 VGA", - .smem_start = VGA_FB_PHYS, - .smem_len = VGA_FB_PHYS_LEN, + .smem_start = VGA_FB_PHYS_BASE, + .smem_len = VGA_FB_PHYS_SIZE, .type = FB_TYPE_VGA_PLANES, .type_aux = FB_AUX_VGA_PLANES_VGA4, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -120,7 +117,7 @@ static inline void rmw(volatile char __iomem *p) static inline int setmode(int mode) { int oldmode; - + oldmode = vga_io_rgfx(VGA_GFX_MODE); vga_io_w(VGA_GFX_D, mode); return oldmode; @@ -139,19 +136,19 @@ static inline void setmask(int mask) vga_io_w(VGA_GFX_D, mask); } -/* Set the Data Rotate Register and return its old value. +/* Set the Data Rotate Register and return its old value. Bits 0-2 are rotate count, bits 3-4 are logical operation (0=NOP, 1=AND, 2=OR, 3=XOR). */ static inline int setop(int op) { int oldop; - + oldop = vga_io_rgfx(VGA_GFX_DATA_ROTATE); vga_io_w(VGA_GFX_D, op); return oldop; } -/* Set the Enable Set/Reset Register and return its old value. +/* Set the Enable Set/Reset Register and return its old value. The code here always uses value 0xf for this register. */ static inline int setsr(int sr) { @@ -185,25 +182,25 @@ static inline void setindex(int index) } /* Check if the video mode is supported by the driver */ -static inline int check_mode_supported(void) +static inline int check_mode_supported(const struct screen_info *si) { /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ #if defined(CONFIG_X86) /* only EGA and VGA in 16 color graphic mode are supported */ - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EGAC && - screen_info.orig_video_isVGA != VIDEO_TYPE_VGAC) + if (si->orig_video_isVGA != VIDEO_TYPE_EGAC && + si->orig_video_isVGA != VIDEO_TYPE_VGAC) return -ENODEV; - if (screen_info.orig_video_mode != 0x0D && /* 320x200/4 (EGA) */ - screen_info.orig_video_mode != 0x0E && /* 640x200/4 (EGA) */ - screen_info.orig_video_mode != 0x10 && /* 640x350/4 (EGA) */ - screen_info.orig_video_mode != 0x12) /* 640x480/4 (VGA) */ + if (si->orig_video_mode != 0x0D && /* 320x200/4 (EGA) */ + si->orig_video_mode != 0x0E && /* 640x200/4 (EGA) */ + si->orig_video_mode != 0x10 && /* 640x350/4 (EGA) */ + si->orig_video_mode != 0x12) /* 640x480/4 (VGA) */ return -ENODEV; #endif return 0; } -static void vga16fb_pan_var(struct fb_info *info, +static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var) { struct vga16fb_par *par = info->par; @@ -296,7 +293,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par, par->clkdiv = best->seq_clock_mode; *pixclock = (best->pixclock * div) / mul; } - + #define FAIL(X) return -EINVAL static int vga16fb_open(struct fb_info *info, int user) @@ -511,7 +508,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var, par->misc &= ~0x40; if (var->sync & FB_SYNC_VERT_HIGH_ACT) par->misc &= ~0x80; - + par->mode = mode; if (mode & MODE_8BPP) @@ -520,8 +517,8 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var, else /* pixel clock == vga clock */ vga16fb_clock_chip(par, &var->pixclock, info, 1, 1); - - var->red.offset = var->green.offset = var->blue.offset = + + var->red.offset = var->green.offset = var->blue.offset = var->transp.offset = 0; var->red.length = var->green.length = var->blue.length = (par->isVGA) ? 6 : 2; @@ -588,10 +585,10 @@ static int vga16fb_set_par(struct fb_info *info) else atc[VGA_ATC_PEL] = info->var.xoffset & 7; atc[VGA_ATC_COLOR_PAGE] = 0x00; - + if (par->mode & MODE_TEXT) { - fh = 16; // FIXME !!! Fudge font height. - par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN] + fh = 16; // FIXME !!! Fudge font height. + par->crtc[VGA_CRTC_MAX_SCAN] = (par->crtc[VGA_CRTC_MAX_SCAN] & ~0x1F) | (fh - 1); } @@ -602,10 +599,10 @@ static int vga16fb_set_par(struct fb_info *info) vga_io_w(EGA_GFX_E0, 0x00); vga_io_w(EGA_GFX_E1, 0x01); } - + /* update misc output register */ vga_io_w(VGA_MIS_W, par->misc); - + /* synchronous reset on */ vga_io_wseq(0x00, 0x01); @@ -617,7 +614,7 @@ static int vga16fb_set_par(struct fb_info *info) for (i = 2; i < VGA_SEQ_C; i++) { vga_io_wseq(i, seq[i]); } - + /* synchronous reset off */ vga_io_wseq(0x00, 0x03); @@ -628,12 +625,12 @@ static int vga16fb_set_par(struct fb_info *info) for (i = 0; i < VGA_CRTC_REGS; i++) { vga_io_wcrt(i, par->crtc[i]); } - + /* write graphics controller registers */ for (i = 0; i < VGA_GFX_C; i++) { vga_io_wgfx(i, gdc[i]); } - + /* write attribute controller registers */ for (i = 0; i < VGA_ATT_C; i++) { vga_io_r(VGA_IS1_RC); /* reset flip-flop */ @@ -656,7 +653,7 @@ static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned b { static const unsigned char map[] = { 000, 001, 010, 011 }; int val; - + if (regno >= 16) return; val = map[red>>14] | ((map[green>>14]) << 1) | ((map[blue>>14]) << 2); @@ -687,17 +684,17 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, * (according to the entries in the `var' structure). Return * != 0 for invalid regno. */ - + if (regno >= 256) return 1; gray = info->var.grayscale; - + if (gray) { /* gray = 0.30*R + 0.59*G + 0.11*B */ red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; } - if (par->isVGA) + if (par->isVGA) vga16_setpalette(regno,red,green,blue); else ega16_setpalette(regno,red,green,blue); @@ -705,7 +702,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, } static int vga16fb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) + struct fb_info *info) { vga16fb_pan_var(info, var); return 0; @@ -720,7 +717,7 @@ static void vga_vesa_blank(struct vga16fb_par *par, int mode) { unsigned char SeqCtrlIndex = vga_io_r(VGA_SEQ_I); unsigned char CrtCtrlIndex = vga_io_r(VGA_CRT_IC); - + /* save original values of VGA controller registers */ if(!par->vesa_blanked) { par->vga_state.CrtMiscIO = vga_io_r(VGA_MIS_R); @@ -776,7 +773,7 @@ static void vga_vesa_unblank(struct vga16fb_par *par) { unsigned char SeqCtrlIndex = vga_io_r(VGA_SEQ_I); unsigned char CrtCtrlIndex = vga_io_r(VGA_CRT_IC); - + /* restore original values of VGA controller registers */ vga_io_w(VGA_MIS_W, par->vga_state.CrtMiscIO); @@ -962,7 +959,7 @@ static void vga16fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec } break; } - } else + } else vga_8planes_fillrect(info, rect); break; case FB_TYPE_PACKED_PIXELS: @@ -1029,7 +1026,7 @@ static void vga_8planes_copyarea(struct fb_info *info, const struct fb_copyarea 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; + 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 __iomem *dst = NULL; @@ -1094,9 +1091,9 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are dst += line_ofs; } } else { - dst = info->screen_base + (dx/8) + width + + dst = info->screen_base + (dx/8) + width + (dy + height - 1) * info->fix.line_length; - src = info->screen_base + (sx/8) + width + + src = info->screen_base + (sx/8) + width + (sy + height - 1) * info->fix.line_length; while (height--) { for (x = 0; x < width; x++) { @@ -1109,7 +1106,7 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are dst -= line_ofs; } } - } else + } else vga_8planes_copyarea(info, area); break; case FB_TYPE_PACKED_PIXELS: @@ -1182,7 +1179,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im setsr(0xf); setcolor(image->fg_color); selectmask(); - + setmask(0xff); writeb(image->bg_color, where); rmb(); @@ -1191,7 +1188,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im wmb(); for (y = 0; y < image->height; y++) { dst = where; - for (x = image->width/8; x--;) + for (x = image->width/8; x--;) writeb(*cdat++, dst++); where += info->fix.line_length; } @@ -1202,7 +1199,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im setsr(0xf); setcolor(image->bg_color); selectmask(); - + setmask(0xff); for (y = 0; y < image->height; y++) { dst = where; @@ -1218,7 +1215,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im where += info->fix.line_length; } } - } else + } else vga_8planes_imageblit(info, image); break; case FB_TYPE_PACKED_PIXELS: @@ -1231,7 +1228,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im static void vga_imageblit_color(struct fb_info *info, const struct fb_image *image) { /* - * Draw logo + * Draw logo */ struct vga16fb_par *par = info->par; char __iomem *where = @@ -1248,7 +1245,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima setsr(0xf); setop(0); setmode(0); - + for (y = 0; y < image->height; y++) { for (x = 0; x < image->width; x++) { dst = where + x/8; @@ -1272,7 +1269,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima break; } } - + static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image) { if (image->depth == 1) @@ -1304,28 +1301,22 @@ static const struct fb_ops vga16fb_ops = { .fb_imageblit = vga16fb_imageblit, }; -#ifndef MODULE -static int __init vga16fb_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) - return 0; - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) continue; - } - return 0; -} -#endif - static int vga16fb_probe(struct platform_device *dev) { + struct screen_info *si; struct fb_info *info; struct vga16fb_par *par; int i; int ret = 0; + si = dev_get_platdata(&dev->dev); + if (!si) + return -ENODEV; + + ret = check_mode_supported(si); + if (ret) + return ret; + printk(KERN_DEBUG "vga16fb: initializing\n"); info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev); @@ -1339,8 +1330,8 @@ static int vga16fb_probe(struct platform_device *dev) goto err_ioremap; } - /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ - info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0); + /* XXX share VGA_FB_PHYS_BASE and I/O region with vgacon and others */ + info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS_BASE, 0); if (!info->screen_base) { printk(KERN_ERR "vga16fb: unable to map device\n"); @@ -1352,19 +1343,19 @@ static int vga16fb_probe(struct platform_device *dev) par = info->par; #if defined(CONFIG_X86) - par->isVGA = screen_info.orig_video_isVGA == VIDEO_TYPE_VGAC; + par->isVGA = si->orig_video_isVGA == VIDEO_TYPE_VGAC; #else /* non-x86 architectures treat orig_video_isVGA as a boolean flag */ - par->isVGA = screen_info.orig_video_isVGA; + par->isVGA = si->orig_video_isVGA; #endif par->palette_blanked = 0; par->vesa_blanked = 0; i = par->isVGA? 6 : 2; - + vga16fb_defined.red.length = i; vga16fb_defined.green.length = i; - vga16fb_defined.blue.length = i; + vga16fb_defined.blue.length = i; /* name should not depend on EGA/VGA */ info->fbops = &vga16fb_ops; @@ -1391,8 +1382,8 @@ static int vga16fb_probe(struct platform_device *dev) vga16fb_update_fix(info); - info->apertures->ranges[0].base = VGA_FB_PHYS; - info->apertures->ranges[0].size = VGA_FB_PHYS_LEN; + info->apertures->ranges[0].base = VGA_FB_PHYS_BASE; + info->apertures->ranges[0].size = VGA_FB_PHYS_SIZE; if (register_framebuffer(info) < 0) { printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); @@ -1425,58 +1416,22 @@ static int vga16fb_remove(struct platform_device *dev) return 0; } +static const struct platform_device_id vga16fb_driver_id_table[] = { + {"ega-framebuffer", 0}, + {"vga-framebuffer", 0}, + { } +}; + static struct platform_driver vga16fb_driver = { .probe = vga16fb_probe, .remove = vga16fb_remove, .driver = { .name = "vga16fb", }, + .id_table = vga16fb_driver_id_table, }; -static struct platform_device *vga16fb_device; - -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 = check_mode_supported(); - if (ret) - return ret; - - ret = platform_driver_register(&vga16fb_driver); - - if (!ret) { - vga16fb_device = platform_device_alloc("vga16fb", 0); - - if (vga16fb_device) - ret = platform_device_add(vga16fb_device); - else - ret = -ENOMEM; - - if (ret) { - platform_device_put(vga16fb_device); - platform_driver_unregister(&vga16fb_driver); - } - } - - return ret; -} - -static void __exit vga16fb_exit(void) -{ - platform_device_unregister(vga16fb_device); - platform_driver_unregister(&vga16fb_driver); -} +module_platform_driver(vga16fb_driver); MODULE_DESCRIPTION("Legacy VGA framebuffer device driver"); MODULE_LICENSE("GPL"); -module_init(vga16fb_init); -module_exit(vga16fb_exit); |