diff -urNX .diffex linux-2.6.7-prev/drivers/video/Makefile linux-2.6.7/drivers/video/Makefile
--- linux-2.6.7-prev/drivers/video/Makefile	2004-06-16 08:34:25.000000000 +0100
+++ linux-2.6.7/drivers/video/Makefile	2004-06-16 08:44:33.000000000 +0100
@@ -42,6 +42,7 @@
 obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o
 obj-$(CONFIG_FB_TRIDENT)	  += tridentfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_S3TRIO)           += S3triofb.o
+obj-$(CONFIG_FB_IBME15)           += ibm_e15fb.o
 obj-$(CONFIG_FB_TGA)              += tgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_VGA16)            += vga16fb.o cfbfillrect.o cfbcopyarea.o \
diff -urNX .diffex linux-2.6.7-prev/drivers/video/fbmem.c linux-2.6.7/drivers/video/fbmem.c
--- linux-2.6.7-prev/drivers/video/fbmem.c	2004-06-16 08:34:25.000000000 +0100
+++ linux-2.6.7/drivers/video/fbmem.c	2004-06-16 08:44:33.000000000 +0100
@@ -96,6 +96,8 @@
 extern int virgefb_setup(char*);
 extern int resolver_video_setup(char*);
 extern int s3triofb_init(void);
+extern int ibm_e15fb_init(void);
+extern int ibm_e15fb_setup(char *options);
 extern int vesafb_init(void);
 extern int vesafb_setup(char*);
 extern int vga16fb_init(void);
@@ -251,6 +253,9 @@
 #ifdef CONFIG_FB_S3TRIO
 	{ "s3triofb", s3triofb_init, NULL },
 #endif 
+#ifdef CONFIG_FB_IBME15
+	{ "ibm_e15", ibm_e15fb_init, ibm_e15fb_setup },
+#endif 
 #ifdef CONFIG_FB_FM2
 	{ "fm2fb", fm2fb_init, fm2fb_setup },
 #endif 
diff -urNX .diffex linux-2.6.7-prev/drivers/video/ibm_e15fb.c linux-2.6.7/drivers/video/ibm_e15fb.c
--- linux-2.6.7-prev/drivers/video/ibm_e15fb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.7/drivers/video/ibm_e15fb.c	2004-06-16 08:44:33.000000000 +0100
@@ -0,0 +1,1141 @@
+/*
+ * linux/drivers/video/ibm_e15fb.c -- Frame buffer device for the S3 864
+ * + SDAC combination built into an IBM PPS 850.
+ *
+ *  Currently this only supports 8bpp with no acceleration.
+ *
+ *  Based on skeletonfb.c created 28 Dec 1997 by Geert Uytterhoeven
+ *  David Monro Mar 11 2000
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Version	Comments
+ * 0.1		Initial version
+ *
+ * 0.2		Added support for modes up to 1024x768, dot clock up to
+ * 		67.5 MHz. Forced the mclock to 60 MHz or I got horrible
+ * 		snow. Added soft blanking code (palette manipulation).
+ *
+ * 0.3		Fix for people using CONFIG_ALL_PPC - use isa_mem_base
+ * 		instead of PREP_ISA_MEM_BASE etc.
+ *
+ * Updated 03/2003 Brian Ruth:
+ * Modified to compile on 2.4.20 kernel
+ * Swap existing soft-blanking code (doesn't work on 2.4.x) for code derived
+ * from technique in XFree86 3.3.6 S3 driver, add in VESA DPMS support from 
+ * same.
+ *
+ * TODO:
+ * Pixmux mode for higher clocks.
+ * Truecolour modes (much harder)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/selection.h>
+
+#include <asm/pgtable.h>
+#include <asm/io.h>
+#include <linux/ioport.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+
+#include <linux/pci.h>
+
+#include "ibm_e15fb.h"
+#include "vga.h"
+
+static char ibm_e15_name[] = "IBM_E15";
+
+/* Must fix this - discuss PCI resources with Gabriel */
+#define DEFAULT_VIDBASE 0x20000000
+
+#define VIDSIZE (2*1024*1024)
+
+static int screen_cleared = 0;
+
+
+    /*
+     *  If your driver supports multiple boards, you should make these arrays,
+     *  or allocate them dynamically (using kmalloc()).
+     */
+
+static struct ibm_e15fb_info fb_info;
+static int device_present = 0;
+static struct display disp;
+struct fbgen_hwswitch ibm_e15_switch;
+int vesa_blanked = 0;
+
+/*
+ * Prefined Video Modes
+ */
+static const struct {
+	const char *name;
+	struct fb_var_screeninfo var;
+} ibm_e15fb_predefined[] __initdata =
+{
+    { "640x480-60",
+        { 640, 480, 640, 480, 0, 0, 8, 0,
+	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+	0, 0, -1, -1, FB_ACCEL_NONE, 39722, 40, 24, 32, 11, 96, 2,
+	0,
+	FB_VMODE_NONINTERLACED
+        }
+    }
+};
+
+#define NUM_TOTAL_MODES	arraysize(ibm_e15fb_predefined)
+static struct fb_var_screeninfo ibm_e15fb_default;
+
+/* Interfaces */
+int ibm_e15fb_init(void);
+void ibm_e15fb_cleanup(struct fb_info *info);
+int ibm_e15fb_setup(char *options, int *ints);
+
+void ibm_e15_detect(void);
+int ibm_e15_encode_fix(struct fb_fix_screeninfo *fix, const
+    void *par, struct fb_info_gen *info);
+int ibm_e15_decode_var(const struct fb_var_screeninfo *var, void *par,
+    struct fb_info_gen *info);
+int ibm_e15_encode_var(struct fb_var_screeninfo *var, const
+    void *par, struct fb_info_gen *info);
+void ibm_e15_get_par(void *par, struct fb_info_gen *info);
+void ibm_e15_set_par(const void *par, struct fb_info_gen *info);
+int ibm_e15_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+     unsigned *blue, unsigned *transp, struct fb_info *info);
+int ibm_e15_setcolreg(unsigned regno, unsigned red, unsigned green,
+     unsigned blue, unsigned transp, struct fb_info *info);
+
+int ibm_e15fb_update_var(int con, struct fb_info *info);
+
+static int ibm_e15_pan_display(const struct fb_var_screeninfo *var,
+	struct fb_info_gen *info);
+int ibm_e15_blank(int blank_mode, struct fb_info_gen *info);
+int ibm_e15_soft_blank(int blank_mode, struct fb_info_gen *info);
+int ibm_e15_vesa_blank(int blank_mode, struct fb_info_gen *info);
+void ibm_e15_set_disp(const void *par, struct display *disp,
+	 struct fb_info_gen *info);
+
+/* Internal interfaces */
+static int ibm_e15fb_open(struct fb_info *info, int user);
+static int ibm_e15fb_release(struct fb_info *info, int user);
+static int ibm_e15_calcclock(long clockfreq, int *m ,int *n1, int*n2);
+
+/* ------------------- chipset specific functions -------------------------- */
+
+
+void ibm_e15_detect(void)
+{
+    /*
+     *  This function should detect the current video mode settings and store
+     *  it as the default video mode
+     */
+
+    struct pci_dev *pcidev;
+    int retval;
+
+    fb_info.fb_phys_membase = 0xdeadbeef;
+    fb_info.fb_virt_membase = 0xdeadbeef;
+
+    pcidev = pci_find_device(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_864_2,
+NULL);
+    if(!pcidev) {
+	printk(KERN_DEBUG "%s: could not find S3 864 in system\n",
+		ibm_e15_name);
+	return;
+    }
+    retval = pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &fb_info.fb_phys_membase);
+    if (retval != PCIBIOS_SUCCESSFUL) {
+	printk(KERN_ERR "%s: pci_read_config_dword failed, error was %d\n",
+		ibm_e15_name, retval);
+	return;
+    }
+    if (fb_info.fb_phys_membase == 0xdeadbeef) {
+	printk(KERN_ERR "%s: pci_read_config_dword returned sucess but"
+	    " didn't set a value?!?\n", ibm_e15_name);
+	return;
+    }
+    if (fb_info.fb_phys_membase == 0) {
+	printk(KERN_WARNING "%s: No PCI linear framebuffer base address "
+	    " assigned to 864.\n", ibm_e15_name);
+	printk(KERN_WARNING "%s: This is normal. Using default of 0x%08x.\n",
+	    ibm_e15_name, DEFAULT_VIDBASE);
+	fb_info.fb_phys_membase = DEFAULT_VIDBASE;
+	retval = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0,
+		fb_info.fb_phys_membase);
+	if (retval != PCIBIOS_SUCCESSFUL) {
+		printk(KERN_ERR "%s: pci_write_config_dword failed, error was %d\n",
+		ibm_e15_name, retval);
+		return;
+	}
+    }
+    printk(KERN_INFO "%s: detected S3 864, linear frame buffer at 0x%08x\n",
+	ibm_e15_name, fb_info.fb_phys_membase);
+
+    fb_info.fb_phys_membase += isa_mem_base;
+
+    device_present = 1;
+    request_region(0x3c0, 32, "ibm_e15");
+    fb_info.fb_virt_membase = (u32)ioremap(fb_info.fb_phys_membase, VIDSIZE);
+    printk(KERN_INFO "Video ram virt base = %p\n", (char*)fb_info.fb_virt_membase);
+    return;
+}
+
+int ibm_e15_encode_fix(struct fb_fix_screeninfo *fix, const
+	void *par, struct fb_info_gen *info)
+{
+    struct ibm_e15fb_par *mpar = (struct ibm_e15fb_par *) par;
+    /*
+     *  This function should fill in the 'fix' structure based on the values
+     *  in the `par' structure.
+     */
+
+    sprintf(fix->id, "IBM E15");
+    fix->smem_start = fb_info.fb_phys_membase;
+    fix->smem_len = VIDSIZE;	/* Need to get this from the card */
+    fix->type = FB_TYPE_PACKED_PIXELS;	/* No plane modes yet */
+    fix->type_aux = 0;	/* Only for plane modes */
+    fix->visual = FB_VISUAL_PSEUDOCOLOR; /* Only 8bit for now */
+    fix->xpanstep = 0;
+    fix->ypanstep = 0;
+    fix->ywrapstep = 0;
+    fix->line_length = mpar->xres; /* 8bit = 1byte/pixel */
+    fix->accel = FB_ACCEL_NONE;
+
+    return 0;
+}
+
+int ibm_e15_decode_var(const struct fb_var_screeninfo *var, void *par,
+    struct fb_info_gen *info)
+{
+    /*
+     *  Get the video params out of 'var'. If a value doesn't fit, round it up,
+     *  if it's too big, return -EINVAL.
+     *
+     *  Suggestion: Round up in the following order: bits_per_pixel, xres,
+     *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+     *  bitfields, horizontal timing, vertical timing.
+     */
+
+    struct ibm_e15fb_par *mpar = (struct ibm_e15fb_par *) par;
+    int retval;
+
+    if (var->bits_per_pixel > 8) return -EINVAL;
+    if (var->xres >1024) return -EINVAL;
+    if (var->yres >768) return -EINVAL;
+    if (1000000000/var->pixclock > SDAC_MAXNONMUXCLOCK) return -EINVAL;
+
+    if ((var->xres < 640) || (var->yres < 480)) {
+	    /* This is needed because we set the enhanced mode bits on
+	     * the card which assume 640x480 or better. I don't think
+	     * anybody will seriously want less than that anyway.
+	     */
+	    var = &ibm_e15fb_default;
+    }
+
+    mpar->freq = 1000000000/var->pixclock;
+    retval = ibm_e15_calcclock(1000000000/var->pixclock, &(mpar->clock_m),
+	    &(mpar->clock_n1), &(mpar->clock_n2));
+    if (retval != 0) {
+	    return -EINVAL;
+    }
+    mpar->xres = var->xres;
+    mpar->yres = var->yres;
+    mpar->xfrontporch = var->right_margin;
+    mpar->xsync = var->hsync_len;
+    mpar->xbackporch = var->left_margin;
+    mpar->yfrontporch = var->lower_margin;
+    mpar->ysync = var->vsync_len;
+    mpar->ybackporch = var->upper_margin;
+    mpar->bpp = var->bits_per_pixel;
+    mpar->syncflags = var->sync;
+
+#if 0
+    /* pixclock in picos, htotal in pixels, vtotal in scanlines */
+    if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
+	    return -EINVAL;
+#endif
+
+    return 0;
+}
+
+int ibm_e15_encode_var(struct fb_var_screeninfo *var, const
+void *par, struct fb_info_gen *info)
+{
+    /*
+     *  Fill the 'var' structure based on the values in 'par' and maybe other
+     *  values read out of the hardware.
+     */
+
+    struct ibm_e15fb_par *mpar = (struct ibm_e15fb_par *) par;
+
+    if (!var) {
+	    return EINVAL;
+    }
+    var->xres = mpar->xres;
+    var->yres = mpar->yres;
+    var->xres_virtual = mpar->xres;
+    var->yres_virtual = mpar->yres;
+    var->xoffset = 0;
+    var->yoffset = 0;
+    var->bits_per_pixel = 8;
+    var->grayscale = 0;
+    var->red.offset = var->green.offset = var->blue.offset = 0;
+    var->red.length = var->green.length = var->blue.length = 8;
+    var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;
+    var->transp.offset = var->transp.length = var->transp.msb_right = 0;
+    var->nonstd = 0;
+    var->activate = 0;
+    var->accel_flags = 0;
+    var->pixclock = 1000000000/mpar->freq;
+    var->left_margin = mpar->xbackporch;
+    var->right_margin = mpar->xfrontporch;
+    var->upper_margin = mpar->ybackporch;
+    var->lower_margin = mpar->yfrontporch;
+    var->hsync_len = mpar->xsync;
+    var->vsync_len = mpar->ysync;
+    var->sync = mpar->syncflags;
+    var->vmode = FB_VMODE_NONINTERLACED;
+
+    return 0;
+}
+
+void ibm_e15_get_par(void *par, struct fb_info_gen *info)
+{
+    /*
+     *  Fill the hardware's 'par' structure.
+     */
+
+    struct ibm_e15fb_par *mpar = (struct ibm_e15fb_par *) par;
+
+    *mpar = fb_info.current_par;
+}
+
+static int ibm_e15_calcclock(long clockfreq, int *m ,int *n1, int *n2)
+{
+	int error;
+
+	if (clockfreq > SDAC_MAXNONMUXCLOCK) {
+		printk(KERN_ERR "%s: Requested clock %ld greater than maximum %d.\n",
+			ibm_e15_name, clockfreq, SDAC_MAXNONMUXCLOCK);
+		return -EINVAL;
+	}
+	for (*n2 = SDAC_MAX_N2; *n2 >= SDAC_MIN_N2; (*n2)--) {
+		if ((clockfreq*(1<<*n2)) < SDAC_MAX_VCO)
+			break;
+	}
+	if (*n2 < SDAC_MIN_N2) {
+		/* This should never happen */
+		printk(KERN_ERR "%s: unable to find suitable n2 for clock frequency %ld.\n",
+			ibm_e15_name, clockfreq);
+		return -EINVAL;
+	}
+
+	for (*m = SDAC_MIN_M; *m <= SDAC_MAX_M; (*m)++) {
+		for (*n1 = SDAC_MIN_N1; *n1 <= SDAC_MAX_N1; (*n1)++) {
+			error = (clockfreq) - ((*m*SDAC_REFCLK)/(*n1*(1<<*n2)));
+			if (error < 0) error = -error;
+			if ((error == 0) || ((clockfreq/error) > SDAC_MAXERR)) {
+				break;
+			}
+		}
+		if ((error == 0) || ((clockfreq/error) > SDAC_MAXERR)) {
+			break;
+		}
+	}
+	if ((*m > SDAC_MAX_M) || (*n1 > SDAC_MAX_N1)) {
+		printk(KERN_ERR "%s: unable to find suitable m and n1 for clock frequency %ld.\n",
+			ibm_e15_name, clockfreq);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void ibm_e15_set_crts(const  struct ibm_e15fb_par *par)
+{
+    u8 cregs[VGA_CRTC_REGS], CR55, SDI;
+    int i, tmp, itmp;
+    int m, n = 255; /* extended memctl paramters */
+
+    int xvis =  par->xres/8, xss = xvis + par->xfrontporch/8, xse = xss
+	    + par->xsync/8, xtot = xse + par->xbackporch/8;
+    int yvis = par->yres, yss = yvis + par->yfrontporch, yse = yss +
+	    par->ysync, ytot = yse + par->ybackporch;
+
+    cregs[VGA_CRTC_H_TOTAL] = xtot - 5;
+    cregs[VGA_CRTC_H_DISP] = xvis - 1;
+    cregs[VGA_CRTC_H_BLANK_START] = xss -1;
+    cregs[VGA_CRTC_H_BLANK_END] = (xse & 0x1F) | 0x80;
+    cregs[VGA_CRTC_H_SYNC_START] = xss;
+    cregs[VGA_CRTC_H_SYNC_END] = ((xse & 0x20) << 2) | (xse & 0x1F);
+
+    cregs[VGA_CRTC_V_TOTAL] = (ytot -2) & 0xFF;
+    /* VGA_CRTC_OVERFLOW is a mess - we need:
+     * 0  Bit 8 of Vertical Total (3d4h index 6)
+     * 1  Bit 8 of Vertical Display End (3d4h index 12h)
+     * 2  Bit 8 of Vertical Retrace Start (3d4h index 10h)
+     * 3  Bit 8 of Start Vertical Blanking (3d4h index 15h)
+     * 4  Bit 8 of Line Compare Register (3d4h index 18h)
+     * 5  Bit 9 of Vertical Total (3d4h index 6)
+     * 6  Bit 9 of Vertical Display End (3d4h index 12h)
+     * 7  Bit 9 of Vertical Retrace Start (3d4h index 10h)
+     */
+    cregs[VGA_CRTC_OVERFLOW] = (((ytot - 2) & 0x100) >> 8)
+	| (((yvis - 1) & 0x100) >> 7)
+	| ((yss & 0x100) >> 6)
+	| ((yss & 0x100) >> 5)
+	| 0x10 /* Line compare disabled */
+	| (((ytot - 2) & 0x200) >> 4)
+	| (((yvis -1) & 0x200) >> 3)
+	| ((yss & 0x200) >> 2);
+    /* that was bletcherous.... */
+    cregs[VGA_CRTC_PRESET_ROW] = 0;
+
+    /* We don't support vertical doubling so this is just:
+     * 5  Bit 9 of Start Vertical Blanking
+     * 6  Bit 9 of Line Compare Register (always 1)
+     */
+
+    cregs[VGA_CRTC_MAX_SCAN] = ((yss & 0x200) >>4) | 0x40;
+    cregs[VGA_CRTC_CURSOR_START] = 0x00;
+    cregs[VGA_CRTC_CURSOR_END] = 0x0;
+    cregs[VGA_CRTC_START_HI] = 0;	/* No virtual panning */
+    cregs[VGA_CRTC_START_LO] = 0;
+    cregs[VGA_CRTC_CURSOR_HI] = 0; /* Cursor is off anyway */
+    cregs[VGA_CRTC_CURSOR_LO] = 0;
+    cregs[VGA_CRTC_V_SYNC_START] = yss & 0xFF;
+    cregs[VGA_CRTC_V_SYNC_END] = (yse & 0x0F) | 0x20; /* disable irq */
+    cregs[VGA_CRTC_V_DISP_END] = (yvis -1) & 0xFF;
+#if 0	/* BUSWIDTH */
+    cregs[VGA_CRTC_OFFSET] = (par->xres >> 4) & 0xFF;  /* bytes/line */
+#else
+    /* From the S3 init code in the x servver */
+    cregs[VGA_CRTC_OFFSET] = (par->xres >> 3) & 0xFF;  /* bytes/line */
+#endif
+    cregs[VGA_CRTC_UNDERLINE] = 0x00;
+    cregs[VGA_CRTC_V_BLANK_START] = yss & 0xFF;
+    cregs[VGA_CRTC_V_BLANK_END] = (yse +1) & 0xFF;
+#if 0	/* BUSWIDTH */
+    cregs[VGA_CRTC_MODE] = 0xC3;
+#else
+    /* From the S3 init code in the xserver */
+    cregs[VGA_CRTC_MODE] = 0xE3;
+#endif
+    cregs[VGA_CRTC_LINE_COMPARE] = 0xFF;
+
+    /* Deprotect registers 0-7 */
+    outb_p(VGA_CRTC_V_SYNC_END, VGA_CRT_IC);
+    outb_p(cregs[VGA_CRTC_V_SYNC_END] & 0x7f, VGA_CRT_DC);
+
+    for (i = 0; i < VGA_CRT_C; i ++) {
+	outb_p(i, VGA_CRT_IC);
+	outb_p(cregs[i], VGA_CRT_DC);
+    }
+
+    /* Reprotect the registers 0-7 */
+    outb_p(VGA_CRTC_V_SYNC_END, VGA_CRT_IC);
+    outb_p(cregs[VGA_CRTC_V_SYNC_END] | 0x80, VGA_CRT_DC);
+
+    /* unlock '864 specials */
+    outb_p(0x38, VGA_CRT_IC);
+    outb_p(0x48, VGA_CRT_DC);
+    outb_p(0x39, VGA_CRT_IC);
+    outb_p(0xa5, VGA_CRT_DC);
+
+    /* Program them */
+
+    /* CR31 */
+    outb_p(0x31, VGA_CRT_IC);
+    if (par->xres == 2048) {
+	outb_p(0x8f, VGA_CRT_DC);
+    } else {
+	outb_p(0x8d, VGA_CRT_DC);
+    }
+
+    /* CR32-34 */
+    outb_p(0x32, VGA_CRT_IC);
+    outb_p(0x00, VGA_CRT_DC);
+    outb_p(0x33, VGA_CRT_IC);
+    outb_p(0x20, VGA_CRT_DC);
+    outb_p(0x34, VGA_CRT_IC);
+    outb_p(0x10, VGA_CRT_DC);
+
+    /* CR66 - must be set before CR3A */
+    outb_p(0x66, VGA_CRT_IC);
+    tmp = inb_p(VGA_CRT_DC);
+    outb_p(tmp | 0x80, VGA_CRT_DC);
+
+    /* CR3A */
+    outb_p(0x3A, VGA_CRT_IC);	/* enable enhanced mode  for 256 */
+    outb_p(0xb5, VGA_CRT_DC);
+
+    /* CR3B */
+    outb_p(0x3B, VGA_CRT_IC);
+    outb_p((cregs[0] + cregs[4] + 1)/2, VGA_CRT_DC);
+
+    /* CR3C */
+    outb_p(0x3C, VGA_CRT_IC);
+    outb_p(cregs[0]/2, VGA_CRT_DC);	/* Interlace mode frame offset */
+
+    /* CR40 */
+    outb_p(0x40, VGA_CRT_IC);
+    tmp = inb_p(VGA_CRT_DC) & 0xf6;
+    outb_p(tmp | 0x01, VGA_CRT_DC);
+
+    /* CR43 */
+    outb_p(0x43, VGA_CRT_IC);	/* 8 bpp only */
+    outb_p(0x00, VGA_CRT_DC);
+
+    /* CR44 - ? */
+    outb_p(0x44, VGA_CRT_IC);
+    outb_p(0x00, VGA_CRT_DC);
+
+    /* CR45 */
+    outb_p(0x45, VGA_CRT_IC);	/* Change for more than 8bpp */
+    tmp = inb_p(VGA_CRT_DC) & 0xf2;
+    outb_p(tmp, VGA_CRT_DC);
+
+    /* CR50 - graphics engine, ignore */ 
+
+    /* CR51  - includes logical screen with hgh bits */
+    outb_p(0x51, VGA_CRT_IC);
+    tmp = (inb_p(VGA_CRT_DC) & 0xC0) | ((xvis >> 4) & 0x30);
+    outb_p(tmp, VGA_CRT_DC);
+
+    /* CR53 */
+    outb_p(0x53, VGA_CRT_IC);
+    tmp = inb_p(VGA_CRT_DC);
+    tmp &= ~0x18;	/* No mmio regs */
+    outb_p(tmp, VGA_CRT_DC);
+
+    /* CR54 memclk - this is messy */
+    /* Blech - floating point... */
+    /*
+    m = (int)((SDAC_MEMCLK/1000.0*.72+16.867)*89.736/(par->freq/1000.0+39)-21.1543);
+    */
+    m = (((((720*SDAC_MEMCLK)+16867000)/(par->freq+39000))*89736)-21154300)/1000000;
+    if (m > 31) m = 31;
+    else if (m < 0) {
+	    m = 0;
+	    n = 16;
+    }
+    outb_p(0x54, VGA_CRT_IC);
+    outb_p(m << 3, VGA_CRT_DC);
+
+    /* CR60 - adjust stuff */
+    if (n < 0) n = 0;
+    else if (n > 255) n = 255;
+    outb_p(0x60, VGA_CRT_IC);
+    outb_p(n, VGA_CRT_DC);
+
+    /* CR5E - vertical overflows */
+    outb_p(0x5E, VGA_CRT_IC);
+    i = (((ytot - 2) & 0x400) >> 10) |
+	(((yvis - 1) & 0x400) >> 9) |
+	((yss & 0x400) >> 8) |
+	((yss & 0x400) >> 6) | 0x40;
+    outb_p(i, VGA_CRT_DC);
+
+    /* calculate stuff */
+    i = (((xtot -5) & 0x100) >> 8) |
+	(((xvis -1) & 0x100) >> 7) |
+	(((xss- 1) & 0x100) >> 6) |
+	((xse & 0x100) >> 7);
+    if ((xse - xss) > 64 ) {
+	i |= 0x08;
+    }
+    if ((xse - xss) > 32) {
+	i |= 0x20;
+    }
+
+    /* CR3B - again */
+    outb_p(0x3B, VGA_CRT_IC);
+    itmp = (cregs[0] + ((i&0x01)<<8) +
+	    cregs[4] + ((i&0x10)<<4) + 1) / 2;
+    if (itmp - (cregs[4] + ((i&0x10)<<4)) < 4)  {
+	if (cregs[4] + ((i&0x10)<<4) + 4 <= cregs[0] + ((i&0x01)<<8)) 
+	    itmp = cregs[4] + ((i&0x10)<<4) + 4;
+	else
+	    itmp = cregs[0] + ((i&0x01)<<8) + 1;
+    }
+    outb_p(itmp & 0xff, VGA_CRT_DC);
+    i |= ((itmp&0x100) >> 2);
+
+    /* CR3C - again */
+    outb_p(0x3C, VGA_CRT_IC);
+    outb_p((cregs[0] + ((i&0x01)<<8)) /2, VGA_CRT_DC);
+
+    /* CR5D */
+    outb_p(0x5D, VGA_CRT_IC);
+    tmp = (inb_p(VGA_CRT_DC) & 0x80) | i;
+    outb_p(tmp, VGA_CRT_DC);
+
+#if 0	/* BUSWIDTH */
+    i = xvis + 1;	/* We have 2M ram and run 8bpp */
+#else
+    i = xvis * 2 + 1;
+#endif
+
+    /* CR61,62 */
+    outb_p(0x61, VGA_CRT_IC);
+    tmp = 0x80 | inb_p(VGA_CRT_DC) | (i >> 8);
+    outb_p(tmp, VGA_CRT_DC);
+    outb_p(0x62, VGA_CRT_IC);
+    outb_p(i & 0xff, VGA_CRT_DC);
+
+    /* CR42 */
+    outb_p(0x42, VGA_CRT_IC);	/* non-interlaced */
+    i = inb(VGA_CRT_DC);
+    outb_p(i & ~20, VGA_CRT_DC);
+
+    outb_p(0x58, VGA_CRT_IC);	/* Enable linear addressing */
+    outb_p(0x12, VGA_CRT_DC);
+
+    outb_p(0x67, VGA_CRT_IC);	/* Pixel format 0 (8bpp, no mux) */
+    outb_p(0x00, VGA_CRT_DC);
+
+    outb_p(0x6D, VGA_CRT_IC);	/* No delays on signals */
+    outb_p(0x00, VGA_CRT_DC);
+
+    /* Set the clock and other bits of the dac */
+
+    outb_p(0xef, VGA_MIS_W); /* Clock select for base VGA */
+    outb_p(0x42, VGA_CRT_IC); /* select clock 2, non-interlaced */
+    outb_p(0x02, VGA_CRT_DC);
+
+    outb_p(0x55, VGA_CRT_IC); 	/* Access the dac registers 4-7 */
+    CR55 = inb_p(VGA_CRT_DC);
+    outb_p(CR55 | 0x01, VGA_CRT_DC);
+
+    outb_p(0x00, SDAC_REG06);	/* Dac pixel format 0 (8bpp, no mux) */
+    SDI=inb_p(SDAC_REG04);
+    outb_p(0x02, SDAC_REG04); /* Select index 2 (f2) */
+    outb_p(par->clock_m - 2, SDAC_REG05);
+    outb_p(((par->clock_n1 - 2) | (par->clock_n2 << 5)), SDAC_REG05);
+
+    {
+	    int m, n1, n2;
+	    ibm_e15_calcclock(SDAC_MEMCLK, &m, &n1, &n2);
+	    outb_p(0x0A, SDAC_REG04); /* Clock 0a is memclk */
+	    outb_p(m - 2, SDAC_REG05);
+	    outb_p(((n1-2)| (n2 << 5)), SDAC_REG05);
+    }
+
+    outb_p(SDI, SDAC_REG04);
+
+    outb_p(0x55, VGA_CRT_IC);	/* Normal dac register access */
+    outb_p(CR55, VGA_CRT_DC);
+
+    /* relock '864 specials */
+    outb_p(0x38, VGA_CRT_IC);
+    outb_p(0x00, VGA_CRT_DC);
+    outb_p(0x39, VGA_CRT_IC);
+    outb_p(0x5a, VGA_CRT_DC);
+
+
+}
+
+
+void ibm_e15_set_par(const void *par, struct fb_info_gen *info)
+{
+    /*
+     *  Set the hardware according to 'par'.
+     */
+
+    int tmp;
+
+    struct ibm_e15fb_par *mpar = (struct ibm_e15fb_par *) par;
+
+    fb_info.current_par = *mpar;
+
+    outb_p(0xe3, VGA_MIS_W); /* 480 lines sync pol, 25MHz clock, colour */
+
+    /* Turn off screen  */
+    outb_p(0x01, VGA_SEQ_I);
+    tmp = inb(VGA_SEQ_D);
+    outb_p(tmp | 0x20, VGA_SEQ_D);
+
+    /* Sync reset on */
+    outb_p(0x00, VGA_SEQ_I);
+    outb_p(0x01, VGA_SEQ_D);
+
+    /* turn off screen and enable palette registers */
+    tmp = inb(VGA_IS1_RC);
+    outb(0x00, VGA_ATT_IW);
+
+    /* Program the sequencer regs */
+    outb_p(0x01, VGA_SEQ_I);
+    outb_p(0x21, VGA_SEQ_D);	 /* Sane clocking mode, screen off */
+
+    outb_p(0x02, VGA_SEQ_I);	 /* Enable all planes */
+    outb_p(0x0f, VGA_SEQ_D);
+
+    outb_p(0x03, VGA_SEQ_I);	 /* Character map? */
+    outb_p(0x00, VGA_SEQ_D);
+
+    outb_p(0x04, VGA_SEQ_I);	 /* 256 colour mode */
+    outb_p(0x0e, VGA_SEQ_D);
+
+
+    /* Program the Graphics regs */
+    outb_p(0x00, VGA_GFX_I);
+    outb_p(0x00, VGA_GFX_D);
+
+    outb_p(0x01, VGA_GFX_I);
+    outb_p(0x00, VGA_GFX_D);
+
+    outb_p(0x02, VGA_GFX_I);
+    outb_p(0x00, VGA_GFX_D);
+
+    outb_p(0x03, VGA_GFX_I);
+    outb_p(0x00, VGA_GFX_D);
+
+    outb_p(0x04, VGA_GFX_I);
+    outb_p(0x00, VGA_GFX_D);
+
+    outb_p(0x05, VGA_GFX_I);	/* 256 colour mode */
+    outb_p(0x40, VGA_GFX_D);
+
+    outb_p(0x06, VGA_GFX_I);	/* use A0000-AFFFF, graphics */
+    outb_p(0x05, VGA_GFX_D);
+
+    outb_p(0x07, VGA_GFX_I);	/* Don't ignore any bits */
+    outb_p(0x0F, VGA_GFX_D);
+
+    outb_p(0x08, VGA_GFX_I);	/* enable all bits for writing */
+    outb_p(0xFF, VGA_GFX_D);
+
+    /* Colour attribute registers */
+
+    inb_p (VGA_IS1_RC);	/* reset VGA_ATT_IW flipflop */
+    for(tmp=0;tmp<16;tmp++) {
+	outb_p(tmp, VGA_ATT_IW);
+	outb_p(tmp, VGA_ATT_IW);
+    }
+
+    outb_p(0x10, VGA_ATT_IW);	/* 8 bit pixels, graphics mode */
+    outb_p(0x41, VGA_ATT_IW);
+    
+    outb_p(0x11, VGA_ATT_IW);	/* Overscan colour */
+    outb_p(0x02, VGA_ATT_IW);
+
+    outb_p(0x12, VGA_ATT_IW);	/* Enable all planes */
+    outb_p(0x0F, VGA_ATT_IW);
+
+    outb_p(0x13, VGA_ATT_IW);	/* Don't shift the display */
+    outb_p(0x00, VGA_ATT_IW);
+
+    outb_p(0x14, VGA_ATT_IW);	
+    outb_p(0x00, VGA_ATT_IW);
+
+
+    /* Progam the VGA_CRTC regs */
+    ibm_e15_set_crts(mpar);
+
+
+    /* Reenable screen */
+    outb_p(0x01, VGA_SEQ_I);
+    tmp = inb_p(VGA_SEQ_D);
+    outb_p(tmp & 0xDF, VGA_SEQ_D);
+
+    /* Restart sequencer */
+    outb_p(0x00, VGA_SEQ_I);
+    outb_p(0x03, VGA_SEQ_D);
+
+    /* Screen enabled, palette locked */
+    tmp = inb(VGA_IS1_RC);
+    outb(0x20, VGA_ATT_IW);
+
+    if (!screen_cleared) {
+	    /* Clear the video memory */
+	    int i;
+	    for(i=0;i<VIDSIZE;i++) {
+		    writeb(0, ((char*)fb_info.fb_virt_membase)+i);
+	    }
+	    screen_cleared = 1;
+    }
+
+}
+
+int ibm_e15_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+     unsigned *blue, unsigned *transp, struct fb_info *info)
+
+{
+    /*
+     *  Read a single color register and split it into colors/transparent.
+     *  The return values must have a 16 bit magnitude.
+     *  Return != 0 for invalid regno.
+     */
+
+    unsigned char bred, bgreen, bblue;
+
+    if (regno > 255) {
+	return 1;
+    }
+    
+    outb_p(regno, VGA_PEL_IR);
+    bred = inb_p(VGA_PEL_D);
+    bgreen = inb_p(VGA_PEL_D);
+    bblue = inb_p(VGA_PEL_D);
+    *red = (bred<<10) | (bred<<4) | (bred>>2);
+    *green = (bgreen<<10) | (bgreen<<4) | (bgreen>>2);
+    *blue = (bblue<<10) | (bblue<<4) | (bblue>>2);
+    *transp = 0;
+    
+    return 0;   
+}
+
+int ibm_e15_setcolreg(unsigned regno, unsigned red, unsigned green,
+			 unsigned blue, unsigned transp,
+			 struct fb_info *info)
+{
+    /*
+     *  Set a single color register. The values supplied have a 16 bit
+     *  magnitude.
+     *  Return != 0 for invalid regno.
+     */
+
+    if(regno > 255) {
+	return 1;
+    } 
+    red >>= 10;
+    green >>= 10;
+    blue >>= 10;
+
+    outb_p(regno, VGA_PEL_IW);
+    outb_p(red, VGA_PEL_D);
+    outb_p(green, VGA_PEL_D);
+    outb_p(blue, VGA_PEL_D);
+    return 0;
+}
+
+static int ibm_e15_pan_display(const struct fb_var_screeninfo *var,
+			   struct fb_info_gen *info)
+{
+    /*
+     *  Pan (or wrap, depending on the `vmode' field) the display using the
+     *  `xoffset' and `yoffset' fields of the `var' structure.
+     *  If the values don't fit, return -EINVAL.
+     */
+
+printk(KERN_DEBUG "ibm_e15_pan_display called?\n");
+    /* ... */
+    return -EINVAL;
+}
+
+/* Begin inserted B.Ruth - Screen blanking / VESA stuff derived from 
+   XFree86 3.3.6 S3 driver */
+int ibm_e15_blank(int blank, struct fb_info_gen *info)
+{
+  switch (blank) {
+  case 0:
+    if (vesa_blanked) {
+      ibm_e15_vesa_blank(blank, info);
+      vesa_blanked = 0;
+    }
+    ibm_e15_soft_blank(blank, info);
+    break;
+  case 1:
+    ibm_e15_soft_blank(blank, info);
+    break;
+  default:
+    ibm_e15_vesa_blank(blank, info);
+    vesa_blanked = 1;
+    break;
+  }
+  return 0;
+}
+
+int ibm_e15_soft_blank(int blank, struct fb_info_gen *info)
+{
+    unsigned char x;
+
+    outb_p(0x1, VGA_SEQ_I);
+    x = inb_p(VGA_SEQ_D);
+    if (!blank) {
+      x &= 0xdf;  /* Enable screen */
+    } else {
+      x |= 0x20;  /* Blank the screen */
+    }
+    outw_p(0x100, VGA_SEQ_I);
+    outw_p((x << 8) | 0x01, VGA_SEQ_I);
+    outw_p(0x300, VGA_SEQ_I);
+
+    return 0;
+}
+
+int ibm_e15_vesa_blank(int blank, struct fb_info_gen *info)
+{
+  unsigned char seq1, extsync;
+  switch (blank)
+    {
+    case 0:
+      /* On */
+      seq1 = 0x00;
+      extsync = 0x00;
+      break;
+    case 2:
+      /* Suspend - no Vsync */
+      seq1 = 0x20;
+      extsync = 0x40;
+      break;
+    case 3:
+      /* Standby - no Hsync */
+      seq1 = 0x20;
+      extsync = 0x10;
+      break;
+    case 4:
+      /* Off - no Hsync or Vsync */
+      seq1 = 0x20;
+      extsync = 0x50;
+      break;
+    }
+  outw_p(0x0608, VGA_SEQ_I); /* Unlock SRD */
+  outw_p(0x0100, VGA_SEQ_I); /* Synchronous Reset */
+  outb_p(0x1, VGA_SEQ_I); /* Select SEQ1 */
+  seq1 |= inb_p(VGA_SEQ_D) & ~0x20; 
+  outb_p(seq1, VGA_SEQ_D);
+  outb_p(0x0d, VGA_SEQ_I); /* Select SEQD */
+  extsync |= inb_p(VGA_SEQ_D) & ~0xf0;
+  mdelay(10);
+  outb_p(extsync, VGA_SEQ_D);
+  outw_p(0x0300, VGA_SEQ_I); /* End Reset */
+  outw_p(0x0008, VGA_SEQ_I); /* Lock SRD */
+
+  return 0;
+}
+/* End inserted B.Ruth */
+
+
+
+void ibm_e15_set_disp(const void *par, struct display *disp,
+			 struct fb_info_gen *info)
+{
+    /*
+     *  Fill in a pointer with the virtual address of the mapped frame buffer.
+     *  Fill in a pointer to appropriate low level text console operations (and
+     *  optionally a pointer to help data) for the video mode `par' of your
+     *  video hardware. These can be generic software routines, or hardware
+     *  accelerated routines specifically tailored for your hardware.
+     *  If you don't have any appropriate operations, you must fill in a
+     *  pointer to dummy operations, and there will be no text output.
+     */
+
+    struct ibm_e15fb_par *_par = (struct ibm_e15fb_par*)par;
+
+    printk(KERN_INFO "%s: Text console mode: ", ibm_e15_name);
+    disp->screen_base = (unsigned char*)fb_info.fb_virt_membase;
+    switch (_par->bpp)
+    {
+#ifdef FBCON_HAS_MFB
+    case 1:
+	printk("monochrome\n");
+	disp->dispsw = &fbcon_mfb;
+	break;
+#endif
+#ifdef FBCON_HAS_CFB8
+    case 8:
+	printk("8 bit color depth\n");
+	disp->dispsw = &fbcon_cfb8;
+	break;
+#endif
+#if 0
+#ifdef FBCON_HAS_CFB16
+    case 16:
+	printk("16 bit color depth\n");
+	disp->dispsw = &fbcon_cfb16;
+	disp->dispsw_data = &fbcon_cfb16_cmap;
+	break;
+#endif
+#ifdef FBCON_HAS_CFB24
+    case 24:
+	printk("24 bit color depth\n");
+	disp->dispsw = &fbcon_cfb24;
+	disp->dispsw_data =  &fbcon_cfb24_cmap;
+	break;
+#endif
+#ifdef FBCON_HAS_CFB32
+    case 32:
+	printk("32 bit color depth\n");
+	disp->dispsw = &fbcon_cfb32;
+	disp->dispsw_data = &fbcon_cfb32_cmap;
+	break;
+#endif
+#endif
+
+    default:
+	printk("unsupported color depth\n");
+	disp->dispsw = &fbcon_dummy;
+	break;
+    }
+    disp->scrollmode = SCROLL_YREDRAW;
+}
+
+
+/* ------------ Interfaces to hardware functions ------------ */
+
+
+struct fbgen_hwswitch ibm_e15_switch = {
+    ibm_e15_detect,
+    ibm_e15_encode_fix,
+    ibm_e15_decode_var,
+    ibm_e15_encode_var,
+    ibm_e15_get_par,
+    ibm_e15_set_par,
+    ibm_e15_getcolreg,
+    ibm_e15_setcolreg,
+    ibm_e15_pan_display,
+    ibm_e15_blank,
+    ibm_e15_set_disp
+};
+
+static struct fb_ops ibm_e15fb_ops = {
+    fb_open:ibm_e15fb_open,
+    fb_release:ibm_e15fb_release,
+    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,
+};
+
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+
+    /*
+     *  Initialization
+     */
+
+int __init ibm_e15fb_init(void)
+{
+
+    int retval;
+    printk(KERN_INFO "%s: initializing\n", ibm_e15_name);
+    fb_info.gen.parsize = sizeof(struct ibm_e15fb_par);
+    fb_info.gen.fbhw = &ibm_e15_switch;
+    fb_info.gen.fbhw->detect();
+    if(!device_present) {
+	return ENODEV;
+    }
+    strcpy(fb_info.gen.info.modename, ibm_e15_name);
+    fb_info.gen.info.changevar = NULL;
+    fb_info.gen.info.node = -1;
+    fb_info.gen.info.fbops = &ibm_e15fb_ops;
+    fb_info.gen.info.disp = &disp;
+    fb_info.gen.info.switch_con = &fbgen_switch;
+    fb_info.gen.info.updatevar = &fbgen_update_var;
+    fb_info.gen.info.blank = &fbgen_blank;
+    fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
+    /* This should give a reasonable default video mode */
+    ibm_e15fb_default = ibm_e15fb_predefined[0].var;
+    ibm_e15fb_default.activate = FB_ACTIVATE_NOW;
+    fbgen_do_set_var(&ibm_e15fb_default, 1, &fb_info.gen);
+    disp.var = ibm_e15fb_default;
+    fbgen_set_disp(-1, &fb_info.gen);
+    fbgen_install_cmap(0, &fb_info.gen);
+    if ((retval = register_framebuffer(&fb_info.gen.info)) < 0) {
+	printk(KERN_ERR "%s: register_framebuffer() failed, error was %d\n",
+	    ibm_e15_name, retval);
+	return retval;
+    }
+    printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+	   fb_info.gen.info.modename);
+
+    /* uncomment this if your driver cannot be unloaded */
+    /* MOD_INC_USE_COUNT; */
+    return 0;
+}
+
+
+    /*
+     *  Cleanup
+     */
+
+void ibm_e15fb_cleanup(struct fb_info *info)
+{
+    /*
+     *  If your driver supports multiple boards, you should unregister and
+     *  clean up all instances.
+     */
+
+    unregister_framebuffer(info);
+    printk(KERN_INFO "%s: shutting down framebuffer\n", ibm_e15_name);
+    iounmap((char*)(fb_info.fb_virt_membase));
+}
+
+
+    /*
+     *  Setup
+     */
+
+int __init ibm_e15fb_setup(char *options, int *ints)
+{
+    /* Parse user speficied options (`video=ibm_e15fb:') */
+    printk(KERN_DEBUG "dummy ibm_e15fb_setup called\n");
+    return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Frame buffer operations
+     */
+
+static int ibm_e15fb_open(struct fb_info *info, int user)
+{
+
+    /* Nothing, only a usage count for the moment */
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+static int ibm_e15fb_release(struct fb_info *info, int user)
+{
+
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+
+    /*
+     *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
+     *  However, you're free to fill in your own replacements.
+     */
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Modularization
+     */
+
+#ifdef MODULE
+int init_module(void)
+{
+    return ibm_e15fb_init();
+    return 0;
+}
+
+void cleanup_module(void)
+{
+    ibm_e15fb_cleanup(&fb_info.gen.info);
+}
+#endif /* MODULE */
diff -urNX .diffex linux-2.6.7-prev/drivers/video/ibm_e15fb.h linux-2.6.7/drivers/video/ibm_e15fb.h
--- linux-2.6.7-prev/drivers/video/ibm_e15fb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.7/drivers/video/ibm_e15fb.h	2004-06-16 08:44:33.000000000 +0100
@@ -0,0 +1,62 @@
+/*
+ * linux/drivers/video/ibm_e15fb.h
+ *
+ * Copyright (C) 2000 David Monro
+ *
+ */
+#ifndef IBM_E15FB_H
+#define IBM_E15FB_H
+
+struct ibm_e15fb_par {
+    /*
+     *  The hardware specific data in this structure uniquely defines a video
+     *  mode.
+     */
+
+    long freq;
+    int clock_m, clock_n1, clock_n2;
+    int bpp;
+    int syncflags;
+
+    long xres;
+    long xfrontporch;
+    long xsync;
+    long xbackporch;
+
+    long yres;
+    long yfrontporch;
+    long ysync;
+    long ybackporch;
+};
+
+struct ibm_e15fb_info {
+    struct fb_info_gen gen;
+
+    u32 fb_virt_membase;
+    u32 fb_phys_membase;
+    
+    struct ibm_e15fb_par current_par;
+};
+
+#define SDAC_REG04 (0x3C8)
+#define SDAC_REG05 (0x3C9)
+#define SDAC_REG06 (0x3C6)
+#define SDAC_REG07 (0x3C7)
+
+#define SDAC_MAXNONMUXCLOCK (67500)
+#define SDAC_MIN_M (3)
+#define SDAC_MAX_M (129)
+#define SDAC_MIN_N1 (3)
+#define SDAC_MAX_N1 (33)
+#define SDAC_MIN_N2 (0)
+#define SDAC_MAX_N2 (3)
+
+#define SDAC_MEMCLK (60000) /* This should work... */
+
+#define SDAC_MAX_VCO	(270000)
+#define SDAC_MIN_VCO	(60000)
+#define SDAC_REFCLK	(14318)
+
+#define SDAC_MAXERR (200) /* = 0.5% */
+
+#endif
