X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2F68328fb.c;h=5e9bcf5a89bb492c57f478186c4a659165095be7;hb=5237fac468d9ad78bc9c09d26426b3425b876540;hp=32c05bc24542f23ed58c10d8efcc5765dcaaca87;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c index 32c05bc24..5e9bcf5a8 100644 --- a/drivers/video/68328fb.c +++ b/drivers/video/68328fb.c @@ -1,29 +1,30 @@ /* - * linux/arch/m68knommu/console/68328fb.c -- Low level implementation of the - * mc68328 LCD frame buffer device + * linux/drivers/video/68328fb.c -- Low level implementation of the + * mc68x328 LCD frame buffer device * - * Copyright (C) 1998,1999 Kenneth Albanowski , - * The Silver Hammer Group, Ltd. - * - * - * This file is based on the Amiga CyberVision frame buffer device (Cyberfb.c): + * Copyright (C) 2003 Georges Menie * - * Copyright (C) 1996 Martin Apel - * Geert Uytterhoeven + * This driver assumes an already configured controller (e.g. from config.c) + * Keep the code clean of board specific initialization. * + * This code has not been tested with colors, colormap management functions + * are minimal (no colormap data written to the 68328 registers...) * - * This file is based on the Amiga frame buffer device (amifb.c): + * initial version of this driver: + * Copyright (C) 1998,1999 Kenneth Albanowski , + * The Silver Hammer Group, Ltd. * - * Copyright (C) 1995 Geert Uytterhoeven + * this version is based on : * + * linux/drivers/video/vfb.c -- Virtual frame buffer device * - * History: - * - 17 Feb 98: Original version by Kenneth Albanowski + * Copyright (C) 2002 James Simmons * + * Copyright (C) 1997 Geert Uytterhoeven * - * 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. + * 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. */ #include @@ -33,417 +34,452 @@ #include #include #include +#include #include -#include -#include -#include -#include -#include +#include +#include #include +#include + +#if defined(CONFIG_M68VZ328) +#include +#elif defined(CONFIG_M68EZ328) +#include +#elif defined(CONFIG_M68328) +#include +#else +#error wrong architecture for the MC68x328 frame buffer device +#endif -#define arraysize(x) (sizeof(x)/sizeof(*(x))) - -static struct fb_info fb_info; +#if defined(CONFIG_FB_68328_INVERT) +#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO01 +#else +#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO10 +#endif - /* - * mc68328vision Graphics Board - */ +static u_long videomemory; +static u_long videomemorysize; -#define CYBER8_WIDTH 1152 -#define CYBER8_HEIGHT 886 -#define CYBER8_PIXCLOCK 12500 /* ++Geert: Just a guess */ +static struct fb_info fb_info; +static u32 mc68x328fb_pseudo_palette[17]; + +static struct fb_var_screeninfo mc68x328fb_default __initdata = { + .red = { 0, 8, 0 }, + .green = { 0, 8, 0 }, + .blue = { 0, 8, 0 }, + .activate = FB_ACTIVATE_TEST, + .height = -1, + .width = -1, + .pixclock = 20000, + .left_margin = 64, + .right_margin = 64, + .upper_margin = 32, + .lower_margin = 32, + .hsync_len = 64, + .vsync_len = 2, + .vmode = FB_VMODE_NONINTERLACED, +}; -#define CYBER16_WIDTH 800 -#define CYBER16_HEIGHT 600 -#define CYBER16_PIXCLOCK 25000 /* ++Geert: Just a guess */ +static struct fb_fix_screeninfo mc68x328fb_fix __initdata = { + .id = "68328fb", + .type = FB_TYPE_PACKED_PIXELS, + .xpanstep = 1, + .ypanstep = 1, + .ywrapstep = 1, + .accel = FB_ACCEL_NONE, +}; -#define PALM_WIDTH 160 -#define PALM_HEIGHT 160 + /* + * Interface used by the world + */ +int mc68x328fb_init(void); +int mc68x328fb_setup(char *); + +static int mc68x328fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info); +static int mc68x328fb_set_par(struct fb_info *info); +static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info); +static int mc68x328fb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info); +static int mc68x328fb_mmap(struct fb_info *info, struct file *file, + struct vm_area_struct *vma); + +static struct fb_ops mc68x328fb_ops = { + .fb_check_var = mc68x328fb_check_var, + .fb_set_par = mc68x328fb_set_par, + .fb_setcolreg = mc68x328fb_setcolreg, + .fb_pan_display = mc68x328fb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_cursor = soft_cursor, + .fb_mmap = mc68x328fb_mmap, +}; -/*static int mc68328Key = 0; -static u_char mc68328_colour_table [256][4];*/ + /* + * Internal routines + */ - /* - * Predefined Video Mode Names - */ +static u_long get_line_length(int xres_virtual, int bpp) +{ + u_long length; -static char *mc68328_fb_modenames[] = { + length = xres_virtual * bpp; + length = (length + 31) & ~31; + length >>= 3; + return (length); +} - /* - * Autodetect (Default) Video Mode - */ + /* + * Setting the video mode has been split into two parts. + * First part, xxxfb_check_var, must not write anything + * to hardware, it should only verify and adjust var. + * This means it doesn't alter par but it does use hardware + * data from it to check this var. + */ - "default", +static int mc68x328fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + u_long line_length; /* - * Predefined Video Modes + * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! + * as FB_VMODE_SMOOTH_XPAN is only used internally */ - "Palm", /* Palm Pilot devices, 1.0 and higher */ - "Palm Grey", /* Palm Pilot devices, 1.0 and higher */ + if (var->vmode & FB_VMODE_CONUPDATE) { + var->vmode |= FB_VMODE_YWRAP; + var->xoffset = info->var.xoffset; + var->yoffset = info->var.yoffset; + } /* - * Dummy Video Modes + * Some very basic checks */ + if (!var->xres) + var->xres = 1; + if (!var->yres) + var->yres = 1; + if (var->xres > var->xres_virtual) + var->xres_virtual = var->xres; + if (var->yres > var->yres_virtual) + var->yres_virtual = var->yres; + if (var->bits_per_pixel <= 1) + var->bits_per_pixel = 1; + else if (var->bits_per_pixel <= 8) + var->bits_per_pixel = 8; + else if (var->bits_per_pixel <= 16) + var->bits_per_pixel = 16; + else if (var->bits_per_pixel <= 24) + var->bits_per_pixel = 24; + else if (var->bits_per_pixel <= 32) + var->bits_per_pixel = 32; + else + return -EINVAL; - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", - "dummy", "dummy", "dummy", "dummy", + if (var->xres_virtual < var->xoffset + var->xres) + var->xres_virtual = var->xoffset + var->xres; + if (var->yres_virtual < var->yoffset + var->yres) + var->yres_virtual = var->yoffset + var->yres; /* - * User Defined Video Modes - * - * This doesn't work yet!! + * Memory limit */ - - "user0", "user1", "user2", "user3", "user4", "user5", "user6", - "user7" -}; - - - /* - * Predefined Video Mode Definitions - */ - -static struct fb_var_screeninfo mc68328_fb_predefined[] = { + line_length = + get_line_length(var->xres_virtual, var->bits_per_pixel); + if (line_length * var->yres_virtual > videomemorysize) + return -ENOMEM; /* - * Autodetect (Default) Video Mode + * Now that we checked it we alter var. The reason being is that the video + * mode passed in might not work but slight changes to it might make it + * work. This way we let the user know what is acceptable. */ + switch (var->bits_per_pixel) { + case 1: + case 8: + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 0; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; + break; + case 16: /* RGBA 5551 */ + if (var->transp.length) { + var->red.offset = 0; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 5; + var->blue.offset = 10; + var->blue.length = 5; + var->transp.offset = 15; + var->transp.length = 1; + } else { /* RGB 565 */ + var->red.offset = 0; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 11; + var->blue.length = 5; + var->transp.offset = 0; + var->transp.length = 0; + } + break; + case 24: /* RGB 888 */ + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 16; + var->blue.length = 8; + var->transp.offset = 0; + var->transp.length = 0; + break; + case 32: /* RGBA 8888 */ + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 16; + var->blue.length = 8; + var->transp.offset = 24; + var->transp.length = 8; + break; + } + var->red.msb_right = 0; + var->green.msb_right = 0; + var->blue.msb_right = 0; + var->transp.msb_right = 0; - {0,}, + return 0; +} - /* - * Predefined Video Modes - */ +/* This routine actually sets the video mode. It's in here where we + * the hardware state info->par and fix which can be affected by the + * change in par. For this driver it doesn't do much. + */ +static int mc68x328fb_set_par(struct fb_info *info) +{ + info->fix.line_length = get_line_length(info->var.xres_virtual, + info->var.bits_per_pixel); + return 0; +} - { - /* Palm */ - PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, - 0, 0, - 1, -1, - {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 0, 0}, - 0, 0, - -1, -1, /* phys height, width */ - FB_ACCEL_NONE, - 0, 0, 0, 0, 0, 0, 0, /* timing */ - 0, /* sync */ - FB_VMODE_NONINTERLACED}, - { - /* Palm Grey */ - PALM_WIDTH, PALM_HEIGHT, PALM_WIDTH, PALM_HEIGHT, - 0, 0, - 2, -1, - {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0}, - 0, 0, - -1, -1, /* phys height, width */ - FB_ACCEL_NONE, - 0, 0, 0, 0, 0, 0, 0, /* timing */ - 0, /* sync */ - FB_VMODE_NONINTERLACED}, + /* + * Set a single color register. The values supplied are already + * rounded down to the hardware's capabilities (according to the + * entries in the var structure). Return != 0 for invalid regno. + */ +static int mc68x328fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info) +{ + if (regno >= 256) /* no. of hw registers */ + return 1; /* - * Dummy Video Modes + * Program hardware... do anything you want with transp */ - {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, - {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, - {0,}, {0,}, + /* grayscale works only partially under directcolor */ + if (info->var.grayscale) { + /* grayscale = 0.30*R + 0.59*G + 0.11*B */ + red = green = blue = + (red * 77 + green * 151 + blue * 28) >> 8; + } - /* - * User Defined Video Modes + /* Directcolor: + * var->{color}.offset contains start of bitfield + * var->{color}.length contains length of bitfield + * {hardwarespecific} contains width of RAMDAC + * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) + * RAMDAC[X] is programmed to (red, green, blue) + * + * Pseudocolor: + * uses offset = 0 && length = RAMDAC register width. + * var->{color}.offset is 0 + * var->{color}.length contains widht of DAC + * cmap is not used + * RAMDAC[X] is programmed to (red, green, blue) + * Truecolor: + * does not use DAC. Usually 3 are present. + * var->{color}.offset contains start of bitfield + * var->{color}.length contains length of bitfield + * cmap is programmed to (red << red.offset) | (green << green.offset) | + * (blue << blue.offset) | (transp << transp.offset) + * RAMDAC does not exist */ - - {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,}, {0,} -}; - -static struct fb_fix_screeninfo mc68328_fix __initdata = { - .id = "mc68328"; - .smem_len = 160 * 160 /8; - .type = FB_TYPE_PACKED_PIXELS; - .accel = FB_ACCEL_NONE; -}; - -#define NUM_TOTAL_MODES arraysize(mc68328_fb_predefined) -#define NUM_PREDEF_MODES (3) - -static int mc68328fb_inverse = 0; -static int mc68328fb_mode = 0; -static int mc68328fbCursorMode = 0; - - /* - * Some default modes - */ - -#define PALM_DEFMODE (1) -#define CYBER16_DEFMODE (2) - - /* - * Interface used by the world - */ -int mc68328_fb_init(void); - -static int mc68328fb_setcolreg(u_int regno, u_int red, u_int green, - u_int blue, u_int transp); -static void mc68328fb_blank(int blank, struct fb_info *info); - - /* - * Accelerated Functions used by the low level console driver - */ - -void mc68328_WaitQueue(u_short fifo); -void mc68328_WaitBlit(void); -void mc68328_BitBLT(u_short curx, u_short cury, u_short destx, - u_short desty, u_short width, u_short height, - u_short mode); -void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height, - u_short mode, u_short color); -void mc68328_MoveCursor(u_short x, u_short y); - - /* - * Internal routines - */ -static int get_video_mode(const char *name); - - /* - * Set a single color register. The values supplied are already - * rounded down to the hardware's capabilities (according to the - * entries in the var structure). Return != 0 for invalid regno. - */ - -static int mc68328fb_setcolreg(u_int regno, u_int red, u_int green, - u_int blue, u_int transp) -{ - return 1; -#if 0 - if (regno > 255) - return (1); - - *(mc68328Regs + 0x3c8) = (char) regno; - mc68328_colour_table[regno][0] = red & 0xff; - mc68328_colour_table[regno][1] = green & 0xff; - mc68328_colour_table[regno][2] = blue & 0xff; - mc68328_colour_table[regno][3] = transp; - - *(mc68328Regs + 0x3c9) = (red & 0xff) >> 2; - *(mc68328Regs + 0x3c9) = (green & 0xff) >> 2; - *(mc68328Regs + 0x3c9) = (blue & 0xff) >> 2; - - return (0); -#endif +#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + case FB_VISUAL_PSEUDOCOLOR: + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); + break; + case FB_VISUAL_DIRECTCOLOR: + red = CNVT_TOHW(red, 8); /* expect 8 bit DAC */ + green = CNVT_TOHW(green, 8); + blue = CNVT_TOHW(blue, 8); + /* hey, there is bug in transp handling... */ + transp = CNVT_TOHW(transp, 8); + break; + } +#undef CNVT_TOHW + /* Truecolor has hardware independent palette */ + if (info->fix.visual == FB_VISUAL_TRUECOLOR) { + u32 v; + + if (regno >= 16) + return 1; + + v = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + switch (info->var.bits_per_pixel) { + case 8: + break; + case 16: + ((u32 *) (info->pseudo_palette))[regno] = v; + break; + case 24: + case 32: + ((u32 *) (info->pseudo_palette))[regno] = v; + break; + } + return 0; + } + return 0; } - /* - * (Un)Blank the screen - */ + /* + * Pan or Wrap the Display + * + * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag + */ -static void mc68328fb_blank(int blank, struct fb_info *info) +static int mc68x328fb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) { -#if 0 - if (blank) - (*(volatile unsigned char *) 0xFFFFFA27) &= ~128; + if (var->vmode & FB_VMODE_YWRAP) { + if (var->yoffset < 0 + || var->yoffset >= info->var.yres_virtual + || var->xoffset) + return -EINVAL; + } else { + if (var->xoffset + var->xres > info->var.xres_virtual || + var->yoffset + var->yres > info->var.yres_virtual) + return -EINVAL; + } + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + if (var->vmode & FB_VMODE_YWRAP) + info->var.vmode |= FB_VMODE_YWRAP; else - (*(volatile unsigned char *) 0xFFFFFA27) |= 128; -#endif -} - - -/************************************************************** - * We are waiting for "fifo" FIFO-slots empty - */ -void mc68328_WaitQueue(u_short fifo) -{ + info->var.vmode &= ~FB_VMODE_YWRAP; + return 0; } -/************************************************************** - * We are waiting for Hardware (Graphics Engine) not busy - */ -void mc68328_WaitBlit(void) -{ -} + /* + * Most drivers don't need their own mmap function + */ -/************************************************************** - * BitBLT - Through the Plane - */ -void mc68328_BitBLT(u_short curx, u_short cury, u_short destx, - u_short desty, u_short width, u_short height, - u_short mode) +static int mc68x328fb_mmap(struct fb_info *info, struct file *file, + struct vm_area_struct *vma) { -#if 0 - u_short blitcmd = S3_BITBLT; - -/* Set drawing direction */ -/* -Y, X maj, -X (default) */ - if (curx > destx) - blitcmd |= 0x0020; /* Drawing direction +X */ - else { - curx += (width - 1); - destx += (width - 1); - } - - if (cury > desty) - blitcmd |= 0x0080; /* Drawing direction +Y */ - else { - cury += (height - 1); - desty += (height - 1); - } - - mc68328_WaitQueue(0x8000); - - *((u_short volatile *) (mc68328Regs + S3_PIXEL_CNTL)) = 0xa000; - *((u_short volatile *) (mc68328Regs + S3_FRGD_MIX)) = - (0x0060 | mode); - - *((u_short volatile *) (mc68328Regs + S3_CUR_X)) = curx; - *((u_short volatile *) (mc68328Regs + S3_CUR_Y)) = cury; +#ifndef MMU + /* this is uClinux (no MMU) specific code */ - *((u_short volatile *) (mc68328Regs + S3_DESTX_DIASTP)) = destx; - *((u_short volatile *) (mc68328Regs + S3_DESTY_AXSTP)) = desty; + vma->vm_flags |= VM_RESERVED; + vma->vm_start = videomemory; - *((u_short volatile *) (mc68328Regs + S3_MIN_AXIS_PCNT)) = - height - 1; - *((u_short volatile *) (mc68328Regs + S3_MAJ_AXIS_PCNT)) = - width - 1; - - *((u_short volatile *) (mc68328Regs + S3_CMD)) = blitcmd; + return 0; +#else + return -EINVAL; #endif } -/************************************************************** - * Rectangle Fill Solid - */ -void mc68328_RectFill(u_short x, u_short y, u_short width, u_short height, - u_short mode, u_short color) +int __init mc68x328fb_setup(char *options) { #if 0 - u_short blitcmd = S3_FILLEDRECT; - - mc68328_WaitQueue(0x8000); - - *((u_short volatile *) (mc68328Regs + S3_PIXEL_CNTL)) = 0xa000; - *((u_short volatile *) (mc68328Regs + S3_FRGD_MIX)) = - (0x0020 | mode); - - *((u_short volatile *) (mc68328Regs + S3_MULT_MISC)) = 0xe000; - *((u_short volatile *) (mc68328Regs + S3_FRGD_COLOR)) = color; - - *((u_short volatile *) (mc68328Regs + S3_CUR_X)) = x; - *((u_short volatile *) (mc68328Regs + S3_CUR_Y)) = y; - - *((u_short volatile *) (mc68328Regs + S3_MIN_AXIS_PCNT)) = - height - 1; - *((u_short volatile *) (mc68328Regs + S3_MAJ_AXIS_PCNT)) = - width - 1; - - *((u_short volatile *) (mc68328Regs + S3_CMD)) = blitcmd; + char *this_opt; #endif -} - -/************************************************************** - * Move cursor to x, y - */ -void mc68328_MoveCursor(u_short x, u_short y) -{ - (*(volatile unsigned short *) 0xFFFFFA18) = - (mc68328fbCursorMode << 14) | x; - (*(volatile unsigned short *) 0xFFFFFA1A) = y; + if (!options || !*options) + return 1; #if 0 - *(mc68328Regs + S3_CRTC_ADR) = 0x39; - *(mc68328Regs + S3_CRTC_DATA) = 0xa0; - - *(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H; - *(mc68328Regs + S3_CRTC_DATA) = (char) ((x & 0x0700) >> 8); - *(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L; - *(mc68328Regs + S3_CRTC_DATA) = (char) (x & 0x00ff); - - *(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H; - *(mc68328Regs + S3_CRTC_DATA) = (char) ((y & 0x0700) >> 8); - *(mc68328Regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L; - *(mc68328Regs + S3_CRTC_DATA) = (char) (y & 0x00ff); + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!*this_opt) + continue; + if (!strncmp(this_opt, "disable", 7)) + mc68x328fb_enable = 0; + } #endif + return 1; } -/* -------------------- Generic routines ------------------------------------ */ - - /* - * Default Colormaps - */ - -static u_short red16[] = - { 0xc000, 0x0000, 0x0000, 0x0000, 0xc000, 0xc000, 0xc000, 0x0000, - 0x8000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff -}; -static u_short green16[] = - { 0xc000, 0x0000, 0xc000, 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, - 0x8000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff -}; -static u_short blue16[] = - { 0xc000, 0x0000, 0x0000, 0xc000, 0x0000, 0xc000, 0x0000, 0x0000, - 0x8000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff -}; - + /* + * Initialisation + */ -static struct fb_cmap default_16_colors = - { 0, 16, red16, green16, blue16, NULL }; - - -static struct fb_cmap *get_default_colormap(int bpp) +int __init mc68x328fb_init(void) { - return (&default_16_colors); -} - - -#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7fff-(val))>>16) -#define CNVT_FROMHW(val,width) (((width) ? ((((val)<<16)-(val)) / \ - ((1<<(width))-1)) : 0)) - -static struct fb_ops mc68328_fb_ops = { - .owner = THIS_MODULE, - .fb_setcolreg = mc68328fb_setcolreg, - .fb_fillrect = cfbfillrect, - .fb_copyarea = cfbcopyarea, - .fb_imageblit = cfbimgblt, - .fb_cursor = softcursor, -}; - + /* + * initialize the default mode from the LCD controller registers + */ + mc68x328fb_default.xres = LXMAX; + mc68x328fb_default.yres = LYMAX+1; + mc68x328fb_default.xres_virtual = mc68x328fb_default.xres; + mc68x328fb_default.yres_virtual = mc68x328fb_default.yres; + mc68x328fb_default.bits_per_pixel = 1 + (LPICF & 0x01); + videomemory = LSSA; + videomemorysize = (mc68x328fb_default.xres_virtual+7) / 8 * + mc68x328fb_default.yres_virtual * mc68x328fb_default.bits_per_pixel; + + fb_info.screen_base = (void *)videomemory; + fb_info.fbops = &mc68x328fb_ops; + fb_info.var = mc68x328fb_default; + fb_info.fix = mc68x328fb_fix; + fb_info.fix.smem_start = videomemory; + fb_info.fix.smem_len = videomemorysize; + fb_info.fix.line_length = + get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel); + fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ? + MC68X328FB_MONO_VISUAL : FB_VISUAL_PSEUDOCOLOR; + fb_info.pseudo_palette = &mc68x328fb_pseudo_palette; + fb_info.flags = FBINFO_FLAG_DEFAULT; + + fb_alloc_cmap(&fb_info.cmap, 256, 0); + + if (register_framebuffer(&fb_info) < 0) { + return -EINVAL; + } - /* - * Initialization - */ + printk(KERN_INFO + "fb%d: %s frame buffer device\n", fb_info.node, fb_info.fix.id); + printk(KERN_INFO + "fb%d: %dx%dx%d at 0x%08lx\n", fb_info.node, + mc68x328fb_default.xres_virtual, mc68x328fb_default.yres_virtual, + 1 << mc68x328fb_default.bits_per_pixel, videomemory); -int __init mc68328_fb_init(void) -{ - if (mc68328fb_mode == -1) - mc68328fb_mode = PALM_DEFMODE; - mc68328_fix.smem_start = (*(volatile unsigned long *) 0xFFFFFA00); - /*kernel_map (board_addr + 0x01400000, 0x00400000, */ - - info->var = mc68328_fb_predefined[mc68328fb_mode]; - - if (info->var.bits_per_pixel == 1) - fix->visual = FB_VISUAL_MONO01; - else - fix->visual = FB_VISUAL_DIRECTCOLOR; - info->screen_base = (u_char *) mc68328_fix.smem_start; - - if (register_framebuffer(&fb_info) < 0) - panic("Cannot register frame buffer\n"); return 0; } - /* - * Get a Video Mode - */ +#ifdef MODULE -static int get_video_mode(const char *name) +static void __exit mc68x328fb_cleanup(void) { - int i; - - for (i = 1; i < NUM_PREDEF_MODES; i++) - if (!strcmp(name, mc68328_fb_modenames[i])) - return (i); - return (0); + unregister_framebuffer(&fb_info); } + +module_init(mc68x328fb_init); +module_exit(mc68x328fb_cleanup); + +MODULE_LICENSE("GPL"); +#endif /* MODULE */