2 * linux/drivers/video/m532xfb.c -- Coldfire MCF5329 frame buffer driver
4 * Copyright (c) 2006, emlix, Thomas Brinker <tb@emlix.com>
5 * Yaroslav Vinogradov yaroslav.vinogradov@freescale.com
6 * Copyright Freescale Semiconductor, Inc 2006
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * Modified for Coldfire M5329 frame buffer by yaroslav.vinogradov@freescale.com
14 * Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
15 * Created 28 Dec 1997 by Geert Uytterhoeven
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/string.h>
23 #include <linux/tty.h>
24 #include <linux/slab.h>
25 #include <linux/delay.h>
27 #include <linux/init.h>
28 #include <asm/mcfsim.h>
37 static u32 fb_wait_params
[][6] = {
38 /* HWAIT1, HWIDTH, HWAIT2, VWAIT1, VWIDTH, VWAIT2 */
39 /* 640x480 */ {48, 14, 102, 32, 1, 35},
40 /* 800x600 */ {110, 59, 85, 42, 3, 24},
41 /* 240x320 */ {85, 10, 75, 32, 10, 10}
44 #if defined(CONFIG_LCD_640x480)
45 #define MODE_OPTION "640x480@60"
47 #define MODE_WIDTH 640
48 #define MODE_HEIGHT 480
49 #define MODE_VPW MODE_WIDTH
50 #define FB_WAIT_PARAMS(p) (fb_wait_params[0][(p)])
51 #define PIX_CLK_DIV 12
52 #define LCDC_LDCR_VALUE (MCF_LCDC_LDCR_TM(8) | MCF_LCDC_LDCR_HM(4))
54 #elif defined(CONFIG_LCD_800x600)
55 #define MODE_OPTION "800x600@60"
56 #define MODE_BPP 32 /* Default is 32 bits, 16 bits mode is also aviable */
57 #define MODE_WIDTH 800
58 #define MODE_HEIGHT 600
59 #define MODE_VPW (MODE_WIDTH >> (MODE_BPP == 16 ? 1 : 0))
60 #define FB_WAIT_PARAMS(p) (fb_wait_params[1][(p)])
62 #define LCDC_LDCR_VALUE (MCF_LCDC_LDCR_TM(8) | MCF_LCDC_LDCR_HM(4))
64 #elif defined(CONFIG_LCD_240x320)
65 #define MODE_OPTION "240x320@60"
67 #define MODE_WIDTH 240
68 #define MODE_HEIGHT 320
69 #define MODE_VPW (MODE_WIDTH >> (MODE_BPP == 16 ? 1 : 0))
70 #define FB_WAIT_PARAMS(p) (fb_wait_params[2][(p)])
71 #define PIX_CLK_DIV 12
72 #define LCDC_LDCR_VALUE (MCF_LCDC_LDCR_TM(4) | MCF_LCDC_LDCR_HM(8) | MCF_LCDC_LDCR_BURST)
75 #error "LCD display resolution is not specified!"
78 extern int soft_cursor(struct fb_info
* info
, struct fb_cursor
* cursor
);
81 * This structure defines the hardware state of the graphics card. Normally
82 * you place this in a header file in linux/include/video. This file usually
83 * also includes register information. That allows other driver subsystems
84 * and userland applications the ability to use the same header file to
85 * avoid duplicate work and easy porting of software.
94 * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
95 * if we don't use modedb. If we do use modedb see xxxfb_init how to use it
96 * to get a fb_var_screeninfo. Otherwise define a default var as well.
98 static struct fb_fix_screeninfo m532xfb_fix
= {
100 .type
= FB_TYPE_PACKED_PIXELS
,
101 .visual
= FB_VISUAL_TRUECOLOR
,
105 .accel
= FB_ACCEL_NONE
,
109 * Modern graphical hardware not only supports pipelines but some
110 * also support multiple monitors where each display can have its
111 * its own unique data. In this case each display could be
112 * represented by a separate framebuffer device thus a separate
113 * struct fb_info. Now the struct xxx_par represents the graphics
114 * hardware state thus only one exist per card. In this case the
115 * struct xxx_par for each graphics card would be shared between
116 * every struct fb_info that represents a framebuffer on that card.
117 * This allows when one display changes it video resolution (info->var)
118 * the other displays know instantly. Each display can always be
119 * aware of the entire hardware state that affects it because they share
120 * the same xxx_par struct. The other side of the coin is multiple
121 * graphics cards that pass data around until it is finally displayed
122 * on one monitor. Such examples are the voodoo 1 cards and high end
123 * NUMA graphics servers. For this case we have a bunch of pars, each
124 * one that represents a graphics state, that belong to one struct
125 * fb_info. Their you would want to have *par point to a array of device
126 * states and have each struct fb_ops function deal with all those
127 * states. I hope this covers every possible hardware design. If not
128 * feel free to send your ideas at jsimmons@users.sf.net
132 * If your driver supports multiple boards or it supports multiple
133 * framebuffers, you should make these arrays, or allocate them
134 * dynamically (using kmalloc()).
136 static struct fb_info info
;
139 * Each one represents the state of the hardware. Most hardware have
140 * just one hardware state. These here represent the default state(s).
143 #define DUMP_OPTIONS 0x0 /* nothing */
144 //#define DUMP_OPTIONS 0xffffffff /* everything */
146 static struct m532x_par current_par
= {
147 .mode_option
= MODE_OPTION
,
148 .dump
= DUMP_OPTIONS
,
151 static u32 pseudo_palette
[256];
153 int m532xfb_init(void);
154 int m532xfb_setup(char*);
156 /* ----- DUMP start ----- */
158 void m532xfb_dump_var(struct fb_info
*info
)
160 printk("*** FB var: ***\n");
161 printk("resolution: %d x %d\n", info
->var
.xres
, info
->var
.yres
);
162 printk("virtual: %d x %d\n", info
->var
.xres_virtual
, info
->var
.yres_virtual
);
163 printk("offsets: %d x %d\n", info
->var
.xoffset
, info
->var
.yoffset
);
164 printk("bpp: %d\n", info
->var
.bits_per_pixel
);
165 printk("grey: %d\n", info
->var
.grayscale
);
167 printk("red: off: %d len %d msb %d\n", info
->var
.red
.offset
, info
->var
.red
.length
, info
->var
.red
.msb_right
);
168 printk("green: off: %d len %d msb %d\n", info
->var
.green
.offset
, info
->var
.green
.length
, info
->var
.green
.msb_right
);
169 printk("blue: off: %d len %d msb %d\n", info
->var
.blue
.offset
, info
->var
.blue
.length
, info
->var
.blue
.msb_right
);
170 printk("transp:off: %d len %d msb %d\n", info
->var
.transp
.offset
, info
->var
.transp
.length
, info
->var
.transp
.msb_right
);
172 printk("pixelformat:%d\n", info
->var
.nonstd
);
173 printk("activate: %d\n", info
->var
.activate
);
174 printk("dimension: %d x %d\n", info
->var
.height
, info
->var
.width
);
176 printk("pixclock: %lu\n", PICOS2KHZ(info
->var
.pixclock
));
177 printk("margins: %d - %d - %d - %d\n", info
->var
.left_margin
, info
->var
.right_margin
, info
->var
.upper_margin
, info
->var
.lower_margin
);
178 printk("synclen: %d - %d\n", info
->var
.hsync_len
, info
->var
.vsync_len
);
179 printk("sync: %d\n", info
->var
.sync
);
180 printk("vmode: %d\n", info
->var
.vmode
);
181 printk("rotate: %d\n\n", info
->var
.rotate
);
184 void m532xfb_dump_fix(struct fb_info
*info
)
186 printk("*** FB fix: ***\n");
187 printk("id %s\n", info
->fix
.id
);
188 printk("smem_start 0x%08lx\n", info
->fix
.smem_start
);
189 printk("smem_len %d\n", info
->fix
.smem_len
);
190 printk("type: %d\n", info
->fix
.type
);
191 printk("type_aux: %d\n", info
->fix
.type_aux
);
192 printk("visual: %d\n", info
->fix
.visual
);
193 printk("xpanstep %d\n", info
->fix
.xpanstep
);
194 printk("ypanstep %d\n", info
->fix
.ypanstep
);
195 printk("ywrapstep %d\n", info
->fix
.ywrapstep
);
196 printk("line_length %d\n", info
->fix
.line_length
);
197 printk("accel %d\n\n", info
->fix
.accel
);
200 void m532xfb_dump_par(struct fb_info
*info
)
202 struct m532x_par
*par
= (struct m532x_par
*) info
->par
;
203 printk("*** FB par: ***\n");
204 printk("dump: %d\n\n", par
->dump
);
207 void m532xfb_dump_colors(void)
211 void m532xfb_dump_info(struct fb_info
*info
)
213 int dump
= ((struct m532x_par
*) info
->par
)->dump
;
215 printk("-------------------------------------------------------------------\n");
216 printk("*** FB info DUMP ***\n");
217 printk("node: %d\n", info
->node
);
218 printk("flags: %d\n\n", info
->flags
);
219 printk("screenbase: 0x%p\n", info
->screen_base
);
220 printk("screen_size: 0x%08lx\n", info
->screen_size
);
221 printk("state: %d\n\n", info
->state
);
224 m532xfb_dump_fix(info
);
226 m532xfb_dump_var(info
);
228 m532xfb_dump_par(info
);
230 m532xfb_dump_colors();
232 printk("*** LCD-Registers ***\n");
233 printk("MCF_LCDC_LSSAR 0x%08lx\n",MCF_LCDC_LSSAR
);
234 printk("MCF_LCDC_LSR 0x%08lx\n",MCF_LCDC_LSR
);
235 printk("MCF_LCDC_LVPWR 0x%08lx\n",MCF_LCDC_LVPWR
);
236 printk("MCF_LCDC_LCPR 0x%08lx\n",MCF_LCDC_LCPR
);
237 printk("MCF_LCDC_LCWHBR 0x%08lx\n",MCF_LCDC_LCWHBR
);
238 printk("MCF_LCDC_LCCMR 0x%08lx\n",MCF_LCDC_LCCMR
);
239 printk("MCF_LCDC_LPCR 0x%08lx\n",MCF_LCDC_LPCR
);
240 printk("MCF_LCDC_LHCR 0x%08lx\n",MCF_LCDC_LHCR
);
241 printk("MCF_LCDC_LVCR 0x%08lx\n",MCF_LCDC_LVCR
);
242 printk("MCF_LCDC_LPOR 0x%08lx\n",MCF_LCDC_LPOR
);
243 printk("MCF_LCDC_LSCR 0x%08lx\n",MCF_LCDC_LSCR
);
244 printk("MCF_LCDC_LPCCR 0x%08lx\n",MCF_LCDC_LPCCR
);
245 printk("MCF_LCDC_LDCR 0x%08lx\n",MCF_LCDC_LDCR
);
246 printk("MCF_LCDC_LRMCR 0x%08lx\n",MCF_LCDC_LRMCR
);
247 printk("MCF_LCDC_LICR 0x%08lx\n",MCF_LCDC_LICR
);
248 printk("MCF_LCDC_LIER 0x%08lx\n",MCF_LCDC_LIER
);
249 printk("MCF_LCDC_LISR 0x%08lx\n",MCF_LCDC_LISR
);
250 printk("MCF_LCDC_LGWSAR 0x%08lx\n",MCF_LCDC_LGWSAR
);
251 printk("MCF_LCDC_LGWSR 0x%08lx\n",MCF_LCDC_LGWSR
);
252 printk("MCF_LCDC_LGWVPWR 0x%08lx\n",MCF_LCDC_LGWVPWR
);
253 printk("MCF_LCDC_LGWPOR 0x%08lx\n",MCF_LCDC_LGWPOR
);
254 printk("MCF_LCDC_LGWPR 0x%08lx\n",MCF_LCDC_LGWPR
);
255 printk("MCF_LCDC_LGWCR 0x%08lx\n",MCF_LCDC_LGWCR
);
256 printk("MCF_LCDC_LGWDCR 0x%08lx\n",MCF_LCDC_LGWDCR
);
257 printk("MCF_LCDC_BPLUT_BASE 0x%08lx\n",MCF_LCDC_BPLUT_BASE
);
258 printk("MCF_LCDC_GWLUT_BASE 0x%08lx\n",MCF_LCDC_GWLUT_BASE
);
259 printk("-------------------------------------------------------------------\n");
262 /* ----- DUMP end ----- */
265 * xxxfb_setcolreg - Optional function. Sets a color register.
266 * @regno: Which register in the CLUT we are programming
267 * @red: The red value which can be up to 16 bits wide
268 * @green: The green value which can be up to 16 bits wide
269 * @blue: The blue value which can be up to 16 bits wide.
270 * @transp: If supported, the alpha value which can be up to 16 bits wide.
271 * @info: frame buffer info structure
273 * Set a single color register. The values supplied have a 16 bit
274 * magnitude which needs to be scaled in this function for the hardware.
275 * Things to take into consideration are how many color registers, if
276 * any, are supported with the current color visual. With truecolor mode
277 * no color palettes are supported. Here a pseudo palette is created
278 * which we store the value in pseudo_palette in struct fb_info. For
279 * pseudocolor mode we have a limited color palette. To deal with this
280 * we can program what color is displayed for a particular pixel value.
281 * DirectColor is similar in that we can program each color field. If
282 * we have a static colormap we don't need to implement this function.
284 * Returns negative errno on error, or zero on success.
286 static int m532xfb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
287 unsigned blue
, unsigned transp
,
288 const struct fb_info
*info
)
290 if (regno
>= 256) /* no. of hw registers */
293 * Program hardware... do anything you want with transp
296 /* grayscale works only partially under directcolor */
297 if (info
->var
.grayscale
) {
298 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
299 red
= green
= blue
= (red
* 77 + green
* 151 + blue
* 28) >> 8;
303 * var->{color}.offset contains start of bitfield
304 * var->{color}.length contains length of bitfield
305 * {hardwarespecific} contains width of DAC
306 * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
307 * RAMDAC[X] is programmed to (red, green, blue)
310 * uses offset = 0 && length = DAC register width.
311 * var->{color}.offset is 0
312 * var->{color}.length contains widht of DAC
314 * DAC[X] is programmed to (red, green, blue)
316 * does not use RAMDAC (usually has 3 of them).
317 * var->{color}.offset contains start of bitfield
318 * var->{color}.length contains length of bitfield
319 * cmap is programmed to (red << red.offset) | (green << green.offset) |
320 * (blue << blue.offset) | (transp << transp.offset)
321 * RAMDAC does not exist
323 #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
324 switch (info
->fix
.visual
) {
325 case FB_VISUAL_TRUECOLOR
:
326 case FB_VISUAL_PSEUDOCOLOR
:
327 red
= CNVT_TOHW(red
, info
->var
.red
.length
);
328 green
= CNVT_TOHW(green
, info
->var
.green
.length
);
329 blue
= CNVT_TOHW(blue
, info
->var
.blue
.length
);
330 transp
= CNVT_TOHW(transp
, info
->var
.transp
.length
);
332 case FB_VISUAL_DIRECTCOLOR
:
333 /* example here assumes 8 bit DAC. Might be different
334 * for your hardware */
335 red
= CNVT_TOHW(red
, 8);
336 green
= CNVT_TOHW(green
, 8);
337 blue
= CNVT_TOHW(blue
, 8);
338 /* hey, there is bug in transp handling... */
339 transp
= CNVT_TOHW(transp
, 8);
343 /* Truecolor has hardware independent palette */
344 if (info
->fix
.visual
== FB_VISUAL_TRUECOLOR
) {
350 v
= (red
<< info
->var
.red
.offset
) |
351 (green
<< info
->var
.green
.offset
) |
352 (blue
<< info
->var
.blue
.offset
) |
353 (transp
<< info
->var
.transp
.offset
);
355 switch (info
->var
.bits_per_pixel
) {
357 /* Yes some hand held devices have this. */
358 ((u8
*)(info
->pseudo_palette
))[regno
] = v
;
361 ((u16
*)(info
->pseudo_palette
))[regno
] = v
;
365 ((u32
*)(info
->pseudo_palette
))[regno
] = v
;
371 printk("do something with color palette!\n");
374 /* ------------------------------------------------------------------------- */
377 * Frame buffer operations
380 static struct fb_ops m532xfb_ops
= {
381 .owner
= THIS_MODULE
,
382 .fb_fillrect
= cfb_fillrect
, /* Needed !!! */
383 .fb_copyarea
= cfb_copyarea
, /* Needed !!! */
384 .fb_imageblit
= cfb_imageblit
, /* Needed !!! */
385 .fb_cursor
= soft_cursor
, /* Needed !!! */
391 int __init
m532xfb_init(void)
393 int cmap_len
=256, retval
;
394 char* mode_option
=NULL
;
397 * For kernel boot options (in 'video=xxxfb:<options>' format)
402 if (fb_get_options("m532xfb", &option
)) {
403 printk("No fb on command line specified\n");
406 m532xfb_setup(option
);
409 printk("Initing M532x Framebuffer\n");
411 info
.fbops
= &m532xfb_ops
;
412 info
.fix
= m532xfb_fix
;
413 info
.pseudo_palette
= pseudo_palette
;
416 * Set up flags to indicate what sort of acceleration your
417 * driver can provide (pan/wrap/copyarea/etc.) and whether it
418 * is a module -- see FBINFO_* in include/linux/fb.h
420 info
.flags
= FBINFO_DEFAULT
+ FBINFO_HWACCEL_DISABLED
;
421 info
.par
= ¤t_par
;
424 * This should give a reasonable default video mode. The following is
425 * done when we can set a video mode.
428 mode_option
= MODE_OPTION
;
430 retval
= fb_find_mode(&info
.var
, &info
, mode_option
, NULL
, 0, NULL
, MODE_BPP
);
432 if (!retval
|| retval
== 4)
435 info
.screen_size
= (info
.var
.xres
* info
.var
.yres
* info
.var
.bits_per_pixel
) / 8;
436 info
.var
.xres_virtual
= info
.var
.xres
;
437 info
.var
.yres_virtual
= info
.var
.yres
;
440 info
.var
.red
.offset
= 18;
441 info
.var
.red
.length
= 6;
442 info
.var
.red
.msb_right
= 0;
444 info
.var
.green
.offset
= 10;
445 info
.var
.green
.length
= 6;
446 info
.var
.green
.msb_right
= 0;
448 info
.var
.blue
.offset
= 2;
449 info
.var
.blue
.length
= 6;
450 info
.var
.blue
.msb_right
= 0;
452 info
.var
.transp
.offset
= 0;
453 info
.var
.transp
.length
= 0;
454 info
.var
.transp
.msb_right
= 0;
456 info
.var
.red
.offset
= 11;
457 info
.var
.red
.length
= 5;
459 info
.var
.green
.offset
= 5;
460 info
.var
.green
.length
= 6;
462 info
.var
.blue
.offset
= 0;
463 info
.var
.blue
.length
= 5;
467 * Here we set the screen_base to the virtual memory address
468 * for the framebuffer. Usually we obtain the resource address
469 * from the bus layer and then translate it to virtual memory
470 * space via ioremap. Consult ioport.h.
472 info
.screen_base
= (unsigned char *)__get_free_pages(GFP_KERNEL
, get_order(info
.screen_size
));
473 if (!info
.screen_base
) {
474 printk("Unable to allocate %d PAGEs(%ld Bytes) fb memory\n",get_order(info
.screen_size
),info
.screen_size
);
478 info
.fix
.smem_start
= virt_to_phys((void *)info
.screen_base
);
479 info
.fix
.smem_len
= info
.screen_size
;
480 info
.fix
.line_length
= info
.var
.xres
* info
.var
.bits_per_pixel
/ 8;
483 * Set page reserved so that mmap will work. This is necessary
484 * since we'll be remapping normal memory.
487 unsigned char * page
;
488 for (page
= info
.screen_base
;
489 (unsigned long)page
< (PAGE_ALIGN((unsigned long)info
.screen_base
+ info
.screen_size
));
492 SetPageReserved(virt_to_page(page
));
495 memset((void *)info
.screen_base
, 0, info
.screen_size
);
498 MCF_GPIO_PAR_LCDDATA
= 0xff; /* switch all to display */
499 MCF_GPIO_PAR_LCDCTL
= 0x1ff;
504 MCF_LCDC_LSSAR
= (unsigned int)info
.screen_base
;
505 MCF_LCDC_LSR
= MCF_LCDC_LSR_XMAX(MODE_WIDTH
/16) | MCF_LCDC_LSR_YMAX(MODE_HEIGHT
);
506 MCF_LCDC_LVPWR
= MCF_LCDC_LVPWR_VPW(MODE_VPW
);
508 #if defined(CONFIG_LCD_640x480)
509 MCF_LCDC_LPCR
= MCF_LCDC_LPCR_TFT
510 | MCF_LCDC_LPCR_COLOR
511 | MCF_LCDC_LPCR_BPIX_18bpp
513 | MCF_LCDC_LPCR_LPPOL
514 | MCF_LCDC_LPCR_OEPOL
515 | MCF_LCDC_LPCR_CLKPOL
516 | MCF_LCDC_LPCR_SCLKSEL
517 | MCF_LCDC_LPCR_ACDSEL
518 | MCF_LCDC_LPCR_ENDSEL
519 | MCF_LCDC_LPCR_PCD(PIX_CLK_DIV
);
520 #elif defined(CONFIG_LCD_800x600)
521 MCF_LCDC_LPCR
= MCF_LCDC_LPCR_MODE_TFT
523 | MCF_LCDC_LPCR_BPIX_18bpp
525 | MCF_LCDC_LPCR_BPIX_16bpp
528 | MCF_LCDC_LPCR_LPPOL
529 | MCF_LCDC_LPCR_CLKPOL
530 | MCF_LCDC_LPCR_OEPOL
531 | MCF_LCDC_LPCR_ACDSEL
532 | MCF_LCDC_LPCR_SCLKSEL
533 | MCF_LCDC_LPCR_ENDSEL
534 | MCF_LCDC_LPCR_PCD(PIX_CLK_DIV
);
535 #elif defined(CONFIG_LCD_240x320)
536 MCF_LCDC_LPCR
= MCF_LCDC_LPCR_TFT
537 | MCF_LCDC_LPCR_COLOR
538 | MCF_LCDC_LPCR_BPIX_18bpp
540 | MCF_LCDC_LPCR_LPPOL
541 | MCF_LCDC_LPCR_OEPOL
542 | MCF_LCDC_LPCR_CLKPOL
543 | MCF_LCDC_LPCR_SCLKSEL
544 | MCF_LCDC_LPCR_ACDSEL
545 | MCF_LCDC_LPCR_ENDSEL
546 | MCF_LCDC_LPCR_PCD(PIX_CLK_DIV
);
549 MCF_LCDC_LHCR
= MCF_LCDC_LHCR_H_WIDTH(FB_WAIT_PARAMS(FB_HWIDTH
))
550 | MCF_LCDC_LHCR_H_WAIT_1(FB_WAIT_PARAMS(FB_HWAIT1
))
551 | MCF_LCDC_LHCR_H_WAIT_2(FB_WAIT_PARAMS(FB_HWAIT2
));
553 MCF_LCDC_LVCR
= MCF_LCDC_LVCR_V_WIDTH(FB_WAIT_PARAMS(FB_VWIDTH
))
554 | MCF_LCDC_LVCR_V_WAIT_1(FB_WAIT_PARAMS(FB_VWAIT1
))
555 | MCF_LCDC_LVCR_V_WAIT_2(FB_WAIT_PARAMS(FB_VWAIT2
));
557 MCF_LCDC_LPOR
= MCF_LCDC_LPOR_POS(0);
558 MCF_LCDC_LDCR
= LCDC_LDCR_VALUE
;
560 /* connect ldc controller to clock */
561 MCF_CCM_MISCCR
|= MCF_CCM_MISCCR_LCD_CHEN
;
563 /* This has to been done !!! */
564 fb_alloc_cmap(&info
.cmap
, cmap_len
, 0);
567 * The following is done in the case of having hardware with a static
568 * mode. If we are setting the mode ourselves we don't call this.
570 if (register_framebuffer(&info
) < 0)
572 printk(KERN_INFO
"fb%d: %s frame buffer device\n", info
.node
, info
.fix
.id
);
574 m532xfb_dump_info(&info
);
582 static void __exit
m532xfb_cleanup(void)
585 * If your driver supports multiple boards, you should unregister and
586 * clean up all instances.
588 unregister_framebuffer(&info
);
589 fb_dealloc_cmap(&info
.cmap
);
598 * Only necessary if your driver takes special options,
599 * otherwise we fall back on the generic fb_setup().
601 int __init
m532xfb_setup(char *options
)
603 /* Parse user speficied options (`video=xxxfb:') */
606 /* ------------------------------------------------------------------------- */
610 module_init(m532xfb_init
);
611 module_exit(m532xfb_cleanup
);
613 MODULE_AUTHOR("Thomas Brinker <tb@emlix.com>");
614 MODULE_DESCRIPTION("MCF532x Framebuffer");
615 MODULE_LICENSE("GPL");