11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/drivers/video/hgafb.c -- Hercules graphics adaptor frame buffer device 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu) 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Based on skeletonfb.c by Geert Uytterhoeven and 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mdacon.c by Andrew Apted 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * History: 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.8 (23 Oct 2002): Ported to new framebuffer api. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.7 (23 Jan 2001): fix crash resulting from MDA only cards 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * being detected as Hercules. (Paul G.) 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.6 (17 Aug 2000): new style structs 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * documentation 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.5 (13 Mar 2000): spinlocks instead of saveflags();cli();etc 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * minor fixes 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.4 (24 Jan 2000): fixed a bug in hga_card_detect() for 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HGA-only systems 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.3 (22 Jan 2000): modified for the new fb_info structure 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * screen is cleared after rmmod 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * virtual resolutions 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * module parameter 'nologo={0|1}' 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the most important: boot logo :) 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - Revision 0.1.0 (6 Dec 1999): faster scrolling and minor fixes 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - First release (25 Nov 1999) 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License. See the file COPYING in the main directory of this archive 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details. 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/spinlock.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fb.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 431d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas#include <linux/platform_device.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/vga.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args) 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DPRINTK(args...) 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CHKINFO(ret) if (info != &fb_info) { printk(KERN_DEBUG __FILE__": This should never happen, line:%d \n", __LINE__); return ret; } 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CHKINFO(ret) 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Description of the hardware layout */ 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *hga_vram; /* Base of video memory */ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long hga_vram_len; /* Size of video memory */ 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_TXT 0 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_GFX 1 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 __iomem * rowaddr(struct fb_info *info, u_int row) 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return info->screen_base + HGA_ROWADDR(row); 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hga_mode = -1; /* 0 = txt, 1 = gfx mode */ 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic enum { TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } hga_type; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *hga_type_name; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_INDEX_PORT 0x3b4 /* Register select port */ 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_VALUE_PORT 0x3b5 /* Register value port */ 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_MODE_PORT 0x3b8 /* Mode control port */ 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_STATUS_PORT 0x3ba /* Status and Config port */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_GFX_PORT 0x3bf /* Graphics control port */ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* HGA register values */ 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_CURSOR_BLINKING 0x00 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_CURSOR_OFF 0x20 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_CURSOR_SLOWBLINK 0x60 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_MODE_GRAPHICS 0x02 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_MODE_VIDEO_EN 0x08 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_MODE_BLINK_EN 0x20 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_MODE_GFX_PAGE1 0x80 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_STATUS_HSYNC 0x01 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_STATUS_VSYNC 0x80 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_STATUS_VIDEO 0x08 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_CONFIG_COL132 0x08 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_GFX_MODE_EN 0x01 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HGA_GFX_PAGE_EN 0x02 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Global locks */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEFINE_SPINLOCK(hga_reg_lock); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Framebuffer driver structures */ 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10948c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic struct fb_var_screeninfo hga_default_var = { 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .xres = 720, 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .yres = 348, 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .xres_virtual = 720, 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .yres_virtual = 348, 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .bits_per_pixel = 1, 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .red = {0, 1, 0}, 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .green = {0, 1, 0}, 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .blue = {0, 1, 0}, 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .transp = {0, 0, 0}, 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .height = -1, 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .width = -1, 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12348c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic struct fb_fix_screeninfo hga_fix = { 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .id = "HGA", 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .visual = FB_VISUAL_MONO10, 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .xpanstep = 8, 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ypanstep = 8, 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .line_length = 90, 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .accel = FB_ACCEL_NONE 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Don't assume that tty1 will be the initial current console. */ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int release_io_port = 0; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int release_io_ports = 0; 13690ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool nologo = 0; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------------------- 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Low level hardware functions 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ------------------------------------------------------------------------- */ 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void write_hga_b(unsigned int val, unsigned char reg) 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(reg, HGA_INDEX_PORT); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(val, HGA_VALUE_PORT); 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void write_hga_w(unsigned int val, unsigned char reg) 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(reg, HGA_INDEX_PORT); outb_p(val >> 8, HGA_VALUE_PORT); 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(reg+1, HGA_INDEX_PORT); outb_p(val & 0xff, HGA_VALUE_PORT); 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int test_hga_b(unsigned char val, unsigned char reg) 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(reg, HGA_INDEX_PORT); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb (val, HGA_VALUE_PORT); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(20); val = (inb_p(HGA_VALUE_PORT) == val); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return val; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hga_clear_screen(void) 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char fillchar = 0xbf; /* magic */ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&hga_reg_lock, flags); 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hga_mode == HGA_TXT) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fillchar = ' '; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (hga_mode == HGA_GFX) 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fillchar = 0x00; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&hga_reg_lock, flags); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fillchar != 0xbf) 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset_io(hga_vram, fillchar, hga_vram_len); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hga_txt_mode(void) 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&hga_reg_lock, flags); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(HGA_MODE_VIDEO_EN | HGA_MODE_BLINK_EN, HGA_MODE_PORT); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(0x00, HGA_GFX_PORT); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(0x00, HGA_STATUS_PORT); 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x61, 0x00); /* horizontal total */ 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x50, 0x01); /* horizontal displayed */ 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x52, 0x02); /* horizontal sync pos */ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x0f, 0x03); /* horizontal sync width */ 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x19, 0x04); /* vertical total */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x06, 0x05); /* vertical total adjust */ 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x19, 0x06); /* vertical displayed */ 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x19, 0x07); /* vertical sync pos */ 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x02, 0x08); /* interlace mode */ 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x0d, 0x09); /* maximum scanline */ 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x0c, 0x0a); /* cursor start */ 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x0d, 0x0b); /* cursor end */ 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_w(0x0000, 0x0c); /* start address */ 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_w(0x0000, 0x0e); /* cursor location */ 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_mode = HGA_TXT; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&hga_reg_lock, flags); 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hga_gfx_mode(void) 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&hga_reg_lock, flags); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(0x00, HGA_STATUS_PORT); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(HGA_GFX_MODE_EN, HGA_GFX_PORT); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(HGA_MODE_VIDEO_EN | HGA_MODE_GRAPHICS, HGA_MODE_PORT); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x35, 0x00); /* horizontal total */ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x2d, 0x01); /* horizontal displayed */ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x2e, 0x02); /* horizontal sync pos */ 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x07, 0x03); /* horizontal sync width */ 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x5b, 0x04); /* vertical total */ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x02, 0x05); /* vertical total adjust */ 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x57, 0x06); /* vertical displayed */ 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x57, 0x07); /* vertical sync pos */ 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x02, 0x08); /* interlace mode */ 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x03, 0x09); /* maximum scanline */ 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x00, 0x0a); /* cursor start */ 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_b(0x00, 0x0b); /* cursor end */ 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_w(0x0000, 0x0c); /* start address */ 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_w(0x0000, 0x0e); /* cursor location */ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_mode = HGA_GFX; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&hga_reg_lock, flags); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hga_show_logo(struct fb_info *info) 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *dest = hga_vram; 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *logo = linux_logo_bw; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int x, y; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (y = 134; y < 134 + 80 ; y++) * this needs some cleanup * 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (x = 0; x < 10 ; x++) 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40)); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hga_pan(unsigned int xoffset, unsigned int yoffset) 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int base; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds base = (yoffset / 8) * 90 + xoffset; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&hga_reg_lock, flags); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_hga_w(base, 0x0c); /* start address */ 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&hga_reg_lock, flags); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("hga_pan: base:%d\n", base); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hga_blank(int blank_mode) 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&hga_reg_lock, flags); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (blank_mode) { 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(0x00, HGA_MODE_PORT); /* disable video */ 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(HGA_MODE_VIDEO_EN | HGA_MODE_GRAPHICS, HGA_MODE_PORT); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&hga_reg_lock, flags); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27948c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int hga_card_detect(void) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 281630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt int count = 0; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *p, *q; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned short p_save, q_save; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_vram_len = 0x08000; 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_vram = ioremap(0xb0000, hga_vram_len); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_region(0x3b0, 12, "hgafb")) 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_io_ports = 1; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_region(0x3bf, 1, "hgafb")) 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_io_port = 1; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* do a memory check */ 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = hga_vram; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds q = hga_vram + 0x01000; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_save = readw(p); q_save = readw(q); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0xaa55, p); if (readw(p) == 0xaa55) count++; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0x55aa, p); if (readw(p) == 0x55aa) count++; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(p_save, p); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 305630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt if (count != 2) 306630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt goto error; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Ok, there is definitely a card registering at the correct 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * memory location, so now we do an I/O port test. 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 312630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt if (!test_hga_b(0x66, 0x0f)) /* cursor low register */ 313630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt goto error; 314630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt 315630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt if (!test_hga_b(0x99, 0x0f)) /* cursor low register */ 316630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt goto error; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* See if the card is a Hercules, by checking whether the vsync 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit of the status register is changing. This test lasts for 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * approximately 1/10th of a second. 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_save = q_save = inb_p(HGA_STATUS_PORT) & HGA_STATUS_VSYNC; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (count=0; count < 50000 && p_save == q_save; count++) { 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds q_save = inb(HGA_STATUS_PORT) & HGA_STATUS_VSYNC; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(2); 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p_save == q_save) 331630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt goto error; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (inb_p(HGA_STATUS_PORT) & 0x70) { 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x10: 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type = TYPE_HERCPLUS; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type_name = "HerculesPlus"; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x50: 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type = TYPE_HERCCOLOR; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type_name = "HerculesColor"; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type = TYPE_HERC; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type_name = "Hercules"; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 348630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helterror: 349630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt if (release_io_ports) 350630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt release_region(0x3b0, 12); 351630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt if (release_io_port) 352630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt release_region(0x3bf, 1); 353630c270183133ac25bef8c8d726ac448df9b169aKrzysztof Helt return 0; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hgafb_open - open the framebuffer device 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @info:pointer to fb_info object containing info for current hga board 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @int:open by console system or userland. 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hgafb_open(struct fb_info *info, int init) 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_gfx_mode(); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_clear_screen(); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!nologo) hga_show_logo(info); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hgafb_open - open the framebuffer device 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @info:pointer to fb_info object containing info for current hga board 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @int:open by console system or userland. 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hgafb_release(struct fb_info *info, int init) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_txt_mode(); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_clear_screen(); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hgafb_setcolreg - set color registers 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @regno:register index to set 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @red:red value, unused 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @green:green value, unused 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @blue:blue value, unused 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @transp:transparency value, unused 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @info:unused 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This callback function is used to set the color registers of a HGA 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * board. Since we have only two fixed colors only @regno is checked. 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A zero is returned on success and 1 for failure. 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int transp, struct fb_info *info) 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regno > 1) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hga_pan_display - pan or wrap the display 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @var:contains new xoffset, yoffset and vmode values 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @info:pointer to fb_info object containing info for current hga board 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * flag in @var. If input parameters are correct it calls hga_pan() to 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * program the hardware. @info->var is updated to the new values. 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A zero is returned on success and %-EINVAL for failure. 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hgafb_pan_display(struct fb_var_screeninfo *var, 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_info *info) 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (var->vmode & FB_VMODE_YWRAP) { 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (var->yoffset < 0 || 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds var->yoffset >= info->var.yres_virtual || 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds var->xoffset) 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4257b116e54920ff9b8bf082fb3c371187ed075ac38Laurent Pinchart if (var->xoffset + info->var.xres > info->var.xres_virtual 4267b116e54920ff9b8bf082fb3c371187ed075ac38Laurent Pinchart || var->yoffset + info->var.yres > info->var.yres_virtual 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || var->yoffset % 8) 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_pan(var->xoffset, var->yoffset); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hgafb_blank - (un)blank the screen 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @blank_mode:blanking method to use 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @info:unused 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Blank the screen if blank_mode != 0, else unblank. 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Implements VESA suspend and powerdown modes on hardware that supports 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disabling hsync/vsync: 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @blank_mode == 2 means suspend vsync, 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @blank_mode == 3 means suspend hsync, 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @blank_mode == 4 means powerdown. 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int hgafb_blank(int blank_mode, struct fb_info *info) 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_blank(blank_mode); 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Accel functions 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hgafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int rows, y; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 __iomem *dest; 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y = rect->dy; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (rows = rect->height; rows--; y++) { 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest = rowaddr(info, y) + (rect->dx >> 3); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (rect->rop) { 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ROP_COPY: 468529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook memset_io(dest, rect->color, (rect->width >> 3)); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ROP_XOR: 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fb_writeb(~(fb_readb(dest)), dest); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int rows, y1, y2; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 __iomem *src; 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 __iomem *dest; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (area->dy <= area->sy) { 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y1 = area->sy; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y2 = area->dy; 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (rows = area->height; rows--; ) { 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = rowaddr(info, y1) + (area->sx >> 3); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest = rowaddr(info, y2) + (area->dx >> 3); 490529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook memmove(dest, src, (area->width >> 3)); 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y1++; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y2++; 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y1 = area->sy + area->height - 1; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y2 = area->dy + area->height - 1; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (rows = area->height; rows--;) { 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds src = rowaddr(info, y1) + (area->sx >> 3); 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest = rowaddr(info, y2) + (area->dx >> 3); 501529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook memmove(dest, src, (area->width >> 3)); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y1--; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds y2--; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void hgafb_imageblit(struct fb_info *info, const struct fb_image *image) 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 __iomem *dest; 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 *cdat = (u8 *) image->data; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int rows, y = image->dy; 513529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook u_int x; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 d; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (rows = image->height; rows--; y++) { 517529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook for (x = 0; x < image->width; x+= 8) { 518529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook d = *cdat++; 519529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook dest = rowaddr(info, y) + ((image->dx + x)>> 3); 520529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook fb_writeb(d, dest); 521529ed806d4540d23ca2f68b28c3715d1566fc3acBrent Cook } 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct fb_ops hgafb_ops = { 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_open = hgafb_open, 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_release = hgafb_release, 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_setcolreg = hgafb_setcolreg, 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_pan_display = hgafb_pan_display, 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_blank = hgafb_blank, 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_fillrect = hgafb_fillrect, 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_copyarea = hgafb_copyarea, 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .fb_imageblit = hgafb_imageblit, 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------------------- * 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Functions in fb_info 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ------------------------------------------------------------------------- */ 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------------------- */ 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initialization 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54948c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int hgafb_probe(struct platform_device *pdev) 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5511d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas struct fb_info *info; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (! hga_card_detect()) { 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "hgafb: HGA card not detected.\n"); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (hga_vram) 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(hga_vram); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_type_name, hga_vram_len/1024); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5632870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt info = framebuffer_alloc(0, &pdev->dev); 5641d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (!info) { 5651d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas iounmap(hga_vram); 5661d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas return -ENOMEM; 5671d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas } 5681d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_fix.smem_start = (unsigned long)hga_vram; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_fix.smem_len = hga_vram_len; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5721d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 5731d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->var = hga_default_var; 5741d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->fix = hga_fix; 5751d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->monspecs.hfmin = 0; 5761d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->monspecs.hfmax = 0; 5771d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->monspecs.vfmin = 10000; 5781d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->monspecs.vfmax = 10000; 5791d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->monspecs.dpms = 0; 5801d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->fbops = &hgafb_ops; 5811d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas info->screen_base = hga_vram; 5821d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 5831d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (register_framebuffer(info) < 0) { 5841d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas framebuffer_release(info); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(hga_vram); 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 58931b6780c15a4e3a90fe260e977f5186772ce7afbJoe Perches fb_info(info, "%s frame buffer device\n", info->fix.id); 5902870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt platform_set_drvdata(pdev, info); 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59448c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int hgafb_remove(struct platform_device *pdev) 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5962870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt struct fb_info *info = platform_get_drvdata(pdev); 5971d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_txt_mode(); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hga_clear_screen(); 6001d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6011d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (info) { 6021d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas unregister_framebuffer(info); 6031d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas framebuffer_release(info); 6041d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas } 6051d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iounmap(hga_vram); 6071d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6081d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (release_io_ports) 6091d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas release_region(0x3b0, 12); 6101d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6111d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (release_io_port) 6121d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas release_region(0x3bf, 1); 6131d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6141d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas return 0; 6151d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas} 6161d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6172870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Heltstatic struct platform_driver hgafb_driver = { 6181d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas .probe = hgafb_probe, 61948c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman .remove = hgafb_remove, 6202870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt .driver = { 6212870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt .name = "hgafb", 6222870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt }, 6231d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas}; 6241d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6252870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Heltstatic struct platform_device *hgafb_device; 6261d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6271d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplasstatic int __init hgafb_init(void) 6281d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas{ 6291d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas int ret; 6301d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6311d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (fb_get_options("hgafb", NULL)) 6321d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas return -ENODEV; 6331d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6342870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt ret = platform_driver_register(&hgafb_driver); 6351d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6361d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas if (!ret) { 6372870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt hgafb_device = platform_device_register_simple("hgafb", 0, NULL, 0); 6382870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt 6392870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt if (IS_ERR(hgafb_device)) { 6402870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt platform_driver_unregister(&hgafb_driver); 6412870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt ret = PTR_ERR(hgafb_device); 6422870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt } 6431d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas } 6441d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6451d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas return ret; 6461d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas} 6471d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas 6481d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplasstatic void __exit hgafb_exit(void) 6491d204ef3e4ea61058e49453af393ca754b529b85Antonino A. Daplas{ 6502870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt platform_device_unregister(hgafb_device); 6512870086e9f2032bdd95b8da9bd187e3c16fc6d49Krzysztof Helt platform_driver_unregister(&hgafb_driver); 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------------------- 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modularization 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ------------------------------------------------------------------------- */ 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Ferenc Bakonyi (fero@drama.obuda.kando.hu)"); 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor"); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(nologo, bool, 0); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)"); 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(hgafb_init); 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(hgafb_exit); 668