diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/skeletonfb.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/video/skeletonfb.c')
-rw-r--r-- | drivers/video/skeletonfb.c | 684 |
1 files changed, 684 insertions, 0 deletions
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c new file mode 100644 index 000000000000..7b43716ab665 --- /dev/null +++ b/drivers/video/skeletonfb.c | |||
@@ -0,0 +1,684 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device | ||
3 | * | ||
4 | * Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com) | ||
5 | * | ||
6 | * Created 28 Dec 1997 by Geert Uytterhoeven | ||
7 | * | ||
8 | * | ||
9 | * I have started rewriting this driver as a example of the upcoming new API | ||
10 | * The primary goal is to remove the console code from fbdev and place it | ||
11 | * into fbcon.c. This reduces the code and makes writing a new fbdev driver | ||
12 | * easy since the author doesn't need to worry about console internals. It | ||
13 | * also allows the ability to run fbdev without a console/tty system on top | ||
14 | * of it. | ||
15 | * | ||
16 | * First the roles of struct fb_info and struct display have changed. Struct | ||
17 | * display will go away. The way the the new framebuffer console code will | ||
18 | * work is that it will act to translate data about the tty/console in | ||
19 | * struct vc_data to data in a device independent way in struct fb_info. Then | ||
20 | * various functions in struct fb_ops will be called to store the device | ||
21 | * dependent state in the par field in struct fb_info and to change the | ||
22 | * hardware to that state. This allows a very clean separation of the fbdev | ||
23 | * layer from the console layer. It also allows one to use fbdev on its own | ||
24 | * which is a bounus for embedded devices. The reason this approach works is | ||
25 | * for each framebuffer device when used as a tty/console device is allocated | ||
26 | * a set of virtual terminals to it. Only one virtual terminal can be active | ||
27 | * per framebuffer device. We already have all the data we need in struct | ||
28 | * vc_data so why store a bunch of colormaps and other fbdev specific data | ||
29 | * per virtual terminal. | ||
30 | * | ||
31 | * As you can see doing this makes the con parameter pretty much useless | ||
32 | * for struct fb_ops functions, as it should be. Also having struct | ||
33 | * fb_var_screeninfo and other data in fb_info pretty much eliminates the | ||
34 | * need for get_fix and get_var. Once all drivers use the fix, var, and cmap | ||
35 | * fbcon can be written around these fields. This will also eliminate the | ||
36 | * need to regenerate struct fb_var_screeninfo, struct fb_fix_screeninfo | ||
37 | * struct fb_cmap every time get_var, get_fix, get_cmap functions are called | ||
38 | * as many drivers do now. | ||
39 | * | ||
40 | * This file is subject to the terms and conditions of the GNU General Public | ||
41 | * License. See the file COPYING in the main directory of this archive for | ||
42 | * more details. | ||
43 | */ | ||
44 | |||
45 | #include <linux/module.h> | ||
46 | #include <linux/kernel.h> | ||
47 | #include <linux/errno.h> | ||
48 | #include <linux/string.h> | ||
49 | #include <linux/mm.h> | ||
50 | #include <linux/tty.h> | ||
51 | #include <linux/slab.h> | ||
52 | #include <linux/delay.h> | ||
53 | #include <linux/fb.h> | ||
54 | #include <linux/init.h> | ||
55 | |||
56 | /* | ||
57 | * This is just simple sample code. | ||
58 | * | ||
59 | * No warranty that it actually compiles. | ||
60 | * Even less warranty that it actually works :-) | ||
61 | */ | ||
62 | |||
63 | /* | ||
64 | * If your driver supports multiple boards, you should make the | ||
65 | * below data types arrays, or allocate them dynamically (using kmalloc()). | ||
66 | */ | ||
67 | |||
68 | /* | ||
69 | * This structure defines the hardware state of the graphics card. Normally | ||
70 | * you place this in a header file in linux/include/video. This file usually | ||
71 | * also includes register information. That allows other driver subsystems | ||
72 | * and userland applications the ability to use the same header file to | ||
73 | * avoid duplicate work and easy porting of software. | ||
74 | */ | ||
75 | struct xxx_par; | ||
76 | |||
77 | /* | ||
78 | * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo | ||
79 | * if we don't use modedb. If we do use modedb see xxxfb_init how to use it | ||
80 | * to get a fb_var_screeninfo. Otherwise define a default var as well. | ||
81 | */ | ||
82 | static struct fb_fix_screeninfo xxxfb_fix __initdata = { | ||
83 | .id = "FB's name", | ||
84 | .type = FB_TYPE_PACKED_PIXELS, | ||
85 | .visual = FB_VISUAL_PSEUDOCOLOR, | ||
86 | .xpanstep = 1, | ||
87 | .ypanstep = 1, | ||
88 | .ywrapstep = 1, | ||
89 | .accel = FB_ACCEL_NONE, | ||
90 | }; | ||
91 | |||
92 | /* | ||
93 | * Modern graphical hardware not only supports pipelines but some | ||
94 | * also support multiple monitors where each display can have its | ||
95 | * its own unique data. In this case each display could be | ||
96 | * represented by a separate framebuffer device thus a separate | ||
97 | * struct fb_info. Now the struct xxx_par represents the graphics | ||
98 | * hardware state thus only one exist per card. In this case the | ||
99 | * struct xxx_par for each graphics card would be shared between | ||
100 | * every struct fb_info that represents a framebuffer on that card. | ||
101 | * This allows when one display changes it video resolution (info->var) | ||
102 | * the other displays know instantly. Each display can always be | ||
103 | * aware of the entire hardware state that affects it because they share | ||
104 | * the same xxx_par struct. The other side of the coin is multiple | ||
105 | * graphics cards that pass data around until it is finally displayed | ||
106 | * on one monitor. Such examples are the voodoo 1 cards and high end | ||
107 | * NUMA graphics servers. For this case we have a bunch of pars, each | ||
108 | * one that represents a graphics state, that belong to one struct | ||
109 | * fb_info. Their you would want to have *par point to a array of device | ||
110 | * states and have each struct fb_ops function deal with all those | ||
111 | * states. I hope this covers every possible hardware design. If not | ||
112 | * feel free to send your ideas at jsimmons@users.sf.net | ||
113 | */ | ||
114 | |||
115 | /* | ||
116 | * If your driver supports multiple boards or it supports multiple | ||
117 | * framebuffers, you should make these arrays, or allocate them | ||
118 | * dynamically (using kmalloc()). | ||
119 | */ | ||
120 | static struct fb_info info; | ||
121 | |||
122 | /* | ||
123 | * Each one represents the state of the hardware. Most hardware have | ||
124 | * just one hardware state. These here represent the default state(s). | ||
125 | */ | ||
126 | static struct xxx_par __initdata current_par; | ||
127 | |||
128 | int xxxfb_init(void); | ||
129 | int xxxfb_setup(char*); | ||
130 | |||
131 | /** | ||
132 | * xxxfb_open - Optional function. Called when the framebuffer is | ||
133 | * first accessed. | ||
134 | * @info: frame buffer structure that represents a single frame buffer | ||
135 | * @user: tell us if the userland (value=1) or the console is accessing | ||
136 | * the framebuffer. | ||
137 | * | ||
138 | * This function is the first function called in the framebuffer api. | ||
139 | * Usually you don't need to provide this function. The case where it | ||
140 | * is used is to change from a text mode hardware state to a graphics | ||
141 | * mode state. | ||
142 | * | ||
143 | * Returns negative errno on error, or zero on success. | ||
144 | */ | ||
145 | static int xxxfb_open(const struct fb_info *info, int user) | ||
146 | { | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * xxxfb_release - Optional function. Called when the framebuffer | ||
152 | * device is closed. | ||
153 | * @info: frame buffer structure that represents a single frame buffer | ||
154 | * @user: tell us if the userland (value=1) or the console is accessing | ||
155 | * the framebuffer. | ||
156 | * | ||
157 | * Thus function is called when we close /dev/fb or the framebuffer | ||
158 | * console system is released. Usually you don't need this function. | ||
159 | * The case where it is usually used is to go from a graphics state | ||
160 | * to a text mode state. | ||
161 | * | ||
162 | * Returns negative errno on error, or zero on success. | ||
163 | */ | ||
164 | static int xxxfb_release(const struct fb_info *info, int user) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * xxxfb_check_var - Optional function. Validates a var passed in. | ||
171 | * @var: frame buffer variable screen structure | ||
172 | * @info: frame buffer structure that represents a single frame buffer | ||
173 | * | ||
174 | * Checks to see if the hardware supports the state requested by | ||
175 | * var passed in. This function does not alter the hardware state!!! | ||
176 | * This means the data stored in struct fb_info and struct xxx_par do | ||
177 | * not change. This includes the var inside of struct fb_info. | ||
178 | * Do NOT change these. This function can be called on its own if we | ||
179 | * intent to only test a mode and not actually set it. The stuff in | ||
180 | * modedb.c is a example of this. If the var passed in is slightly | ||
181 | * off by what the hardware can support then we alter the var PASSED in | ||
182 | * to what we can do. If the hardware doesn't support mode change | ||
183 | * a -EINVAL will be returned by the upper layers. You don't need to | ||
184 | * implement this function then. If you hardware doesn't support | ||
185 | * changing the resolution then this function is not needed. In this | ||
186 | * case the driver woudl just provide a var that represents the static | ||
187 | * state the screen is in. | ||
188 | * | ||
189 | * Returns negative errno on error, or zero on success. | ||
190 | */ | ||
191 | static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
192 | { | ||
193 | const struct xxx_par *par = (const struct xxx_par *) info->par; | ||
194 | /* ... */ | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * xxxfb_set_par - Optional function. Alters the hardware state. | ||
200 | * @info: frame buffer structure that represents a single frame buffer | ||
201 | * | ||
202 | * Using the fb_var_screeninfo in fb_info we set the resolution of the | ||
203 | * this particular framebuffer. This function alters the par AND the | ||
204 | * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in | ||
205 | * fb_info since we are using that data. This means we depend on the | ||
206 | * data in var inside fb_info to be supported by the hardware. | ||
207 | * xxxfb_check_var is always called before xxxfb_set_par to ensure this. | ||
208 | * Again if you can't change the resolution you don't need this function. | ||
209 | * | ||
210 | * Returns negative errno on error, or zero on success. | ||
211 | */ | ||
212 | static int xxxfb_set_par(struct fb_info *info) | ||
213 | { | ||
214 | struct xxx_par *par = (struct xxx_par *) info->par; | ||
215 | /* ... */ | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * xxxfb_setcolreg - Optional function. Sets a color register. | ||
221 | * @regno: Which register in the CLUT we are programming | ||
222 | * @red: The red value which can be up to 16 bits wide | ||
223 | * @green: The green value which can be up to 16 bits wide | ||
224 | * @blue: The blue value which can be up to 16 bits wide. | ||
225 | * @transp: If supported, the alpha value which can be up to 16 bits wide. | ||
226 | * @info: frame buffer info structure | ||
227 | * | ||
228 | * Set a single color register. The values supplied have a 16 bit | ||
229 | * magnitude which needs to be scaled in this function for the hardware. | ||
230 | * Things to take into consideration are how many color registers, if | ||
231 | * any, are supported with the current color visual. With truecolor mode | ||
232 | * no color palettes are supported. Here a pseudo palette is created | ||
233 | * which we store the value in pseudo_palette in struct fb_info. For | ||
234 | * pseudocolor mode we have a limited color palette. To deal with this | ||
235 | * we can program what color is displayed for a particular pixel value. | ||
236 | * DirectColor is similar in that we can program each color field. If | ||
237 | * we have a static colormap we don't need to implement this function. | ||
238 | * | ||
239 | * Returns negative errno on error, or zero on success. | ||
240 | */ | ||
241 | static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
242 | unsigned blue, unsigned transp, | ||
243 | const struct fb_info *info) | ||
244 | { | ||
245 | if (regno >= 256) /* no. of hw registers */ | ||
246 | return -EINVAL; | ||
247 | /* | ||
248 | * Program hardware... do anything you want with transp | ||
249 | */ | ||
250 | |||
251 | /* grayscale works only partially under directcolor */ | ||
252 | if (info->var.grayscale) { | ||
253 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
254 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
255 | } | ||
256 | |||
257 | /* Directcolor: | ||
258 | * var->{color}.offset contains start of bitfield | ||
259 | * var->{color}.length contains length of bitfield | ||
260 | * {hardwarespecific} contains width of DAC | ||
261 | * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) | ||
262 | * RAMDAC[X] is programmed to (red, green, blue) | ||
263 | * | ||
264 | * Pseudocolor: | ||
265 | * uses offset = 0 && length = DAC register width. | ||
266 | * var->{color}.offset is 0 | ||
267 | * var->{color}.length contains widht of DAC | ||
268 | * cmap is not used | ||
269 | * DAC[X] is programmed to (red, green, blue) | ||
270 | * Truecolor: | ||
271 | * does not use RAMDAC (usually has 3 of them). | ||
272 | * var->{color}.offset contains start of bitfield | ||
273 | * var->{color}.length contains length of bitfield | ||
274 | * cmap is programmed to (red << red.offset) | (green << green.offset) | | ||
275 | * (blue << blue.offset) | (transp << transp.offset) | ||
276 | * RAMDAC does not exist | ||
277 | */ | ||
278 | #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) | ||
279 | switch (info->fix.visual) { | ||
280 | case FB_VISUAL_TRUECOLOR: | ||
281 | case FB_VISUAL_PSEUDOCOLOR: | ||
282 | red = CNVT_TOHW(red, info->var.red.length); | ||
283 | green = CNVT_TOHW(green, info->var.green.length); | ||
284 | blue = CNVT_TOHW(blue, info->var.blue.length); | ||
285 | transp = CNVT_TOHW(transp, info->var.transp.length); | ||
286 | break; | ||
287 | case FB_VISUAL_DIRECTCOLOR: | ||
288 | /* example here assumes 8 bit DAC. Might be different | ||
289 | * for your hardware */ | ||
290 | red = CNVT_TOHW(red, 8); | ||
291 | green = CNVT_TOHW(green, 8); | ||
292 | blue = CNVT_TOHW(blue, 8); | ||
293 | /* hey, there is bug in transp handling... */ | ||
294 | transp = CNVT_TOHW(transp, 8); | ||
295 | break; | ||
296 | } | ||
297 | #undef CNVT_TOHW | ||
298 | /* Truecolor has hardware independent palette */ | ||
299 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
300 | u32 v; | ||
301 | |||
302 | if (regno >= 16) | ||
303 | return -EINVAL; | ||
304 | |||
305 | v = (red << info->var.red.offset) | | ||
306 | (green << info->var.green.offset) | | ||
307 | (blue << info->var.blue.offset) | | ||
308 | (transp << info->var.transp.offset); | ||
309 | |||
310 | switch (info->var.bits_per_pixel) { | ||
311 | case 8: | ||
312 | /* Yes some hand held devices have this. */ | ||
313 | ((u8*)(info->pseudo_palette))[regno] = v; | ||
314 | break; | ||
315 | case 16: | ||
316 | ((u16*)(info->pseudo_palette))[regno] = v; | ||
317 | break; | ||
318 | case 24: | ||
319 | case 32: | ||
320 | ((u32*)(info->pseudo_palette))[regno] = v; | ||
321 | break; | ||
322 | } | ||
323 | return 0; | ||
324 | } | ||
325 | /* ... */ | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * xxxfb_pan_display - NOT a required function. Pans the display. | ||
331 | * @var: frame buffer variable screen structure | ||
332 | * @info: frame buffer structure that represents a single frame buffer | ||
333 | * | ||
334 | * Pan (or wrap, depending on the `vmode' field) the display using the | ||
335 | * `xoffset' and `yoffset' fields of the `var' structure. | ||
336 | * If the values don't fit, return -EINVAL. | ||
337 | * | ||
338 | * Returns negative errno on error, or zero on success. | ||
339 | */ | ||
340 | static int xxxfb_pan_display(struct fb_var_screeninfo *var, | ||
341 | const struct fb_info *info) | ||
342 | { | ||
343 | /* ... */ | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * xxxfb_blank - NOT a required function. Blanks the display. | ||
349 | * @blank_mode: the blank mode we want. | ||
350 | * @info: frame buffer structure that represents a single frame buffer | ||
351 | * | ||
352 | * Blank the screen if blank_mode != 0, else unblank. Return 0 if | ||
353 | * blanking succeeded, != 0 if un-/blanking failed due to e.g. a | ||
354 | * video mode which doesn't support it. Implements VESA suspend | ||
355 | * and powerdown modes on hardware that supports disabling hsync/vsync: | ||
356 | * blank_mode == 2: suspend vsync | ||
357 | * blank_mode == 3: suspend hsync | ||
358 | * blank_mode == 4: powerdown | ||
359 | * | ||
360 | * Returns negative errno on error, or zero on success. | ||
361 | * | ||
362 | */ | ||
363 | static int xxxfb_blank(int blank_mode, const struct fb_info *info) | ||
364 | { | ||
365 | /* ... */ | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | /* ------------ Accelerated Functions --------------------- */ | ||
370 | |||
371 | /* | ||
372 | * We provide our own functions if we have hardware acceleration | ||
373 | * or non packed pixel format layouts. If we have no hardware | ||
374 | * acceleration, we can use a generic unaccelerated function. If using | ||
375 | * a pack pixel format just use the functions in cfb_*.c. Each file | ||
376 | * has one of the three different accel functions we support. | ||
377 | */ | ||
378 | |||
379 | /** | ||
380 | * xxxfb_fillrect - REQUIRED function. Can use generic routines if | ||
381 | * non acclerated hardware and packed pixel based. | ||
382 | * Draws a rectangle on the screen. | ||
383 | * | ||
384 | * @info: frame buffer structure that represents a single frame buffer | ||
385 | * @region: The structure representing the rectangular region we | ||
386 | * wish to draw to. | ||
387 | * | ||
388 | * This drawing operation places/removes a retangle on the screen | ||
389 | * depending on the rastering operation with the value of color which | ||
390 | * is in the current color depth format. | ||
391 | */ | ||
392 | void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region) | ||
393 | { | ||
394 | /* Meaning of struct fb_fillrect | ||
395 | * | ||
396 | * @dx: The x and y corrdinates of the upper left hand corner of the | ||
397 | * @dy: area we want to draw to. | ||
398 | * @width: How wide the rectangle is we want to draw. | ||
399 | * @height: How tall the rectangle is we want to draw. | ||
400 | * @color: The color to fill in the rectangle with. | ||
401 | * @rop: The raster operation. We can draw the rectangle with a COPY | ||
402 | * of XOR which provides erasing effect. | ||
403 | */ | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * xxxfb_copyarea - REQUIRED function. Can use generic routines if | ||
408 | * non acclerated hardware and packed pixel based. | ||
409 | * Copies one area of the screen to another area. | ||
410 | * | ||
411 | * @info: frame buffer structure that represents a single frame buffer | ||
412 | * @area: Structure providing the data to copy the framebuffer contents | ||
413 | * from one region to another. | ||
414 | * | ||
415 | * This drawing operation copies a rectangular area from one area of the | ||
416 | * screen to another area. | ||
417 | */ | ||
418 | void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) | ||
419 | { | ||
420 | /* | ||
421 | * @dx: The x and y coordinates of the upper left hand corner of the | ||
422 | * @dy: destination area on the screen. | ||
423 | * @width: How wide the rectangle is we want to copy. | ||
424 | * @height: How tall the rectangle is we want to copy. | ||
425 | * @sx: The x and y coordinates of the upper left hand corner of the | ||
426 | * @sy: source area on the screen. | ||
427 | */ | ||
428 | } | ||
429 | |||
430 | |||
431 | /** | ||
432 | * xxxfb_imageblit - REQUIRED function. Can use generic routines if | ||
433 | * non acclerated hardware and packed pixel based. | ||
434 | * Copies a image from system memory to the screen. | ||
435 | * | ||
436 | * @info: frame buffer structure that represents a single frame buffer | ||
437 | * @image: structure defining the image. | ||
438 | * | ||
439 | * This drawing operation draws a image on the screen. It can be a | ||
440 | * mono image (needed for font handling) or a color image (needed for | ||
441 | * tux). | ||
442 | */ | ||
443 | void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) | ||
444 | { | ||
445 | /* | ||
446 | * @dx: The x and y coordinates of the upper left hand corner of the | ||
447 | * @dy: destination area to place the image on the screen. | ||
448 | * @width: How wide the image is we want to copy. | ||
449 | * @height: How tall the image is we want to copy. | ||
450 | * @fg_color: For mono bitmap images this is color data for | ||
451 | * @bg_color: the foreground and background of the image to | ||
452 | * write directly to the frmaebuffer. | ||
453 | * @depth: How many bits represent a single pixel for this image. | ||
454 | * @data: The actual data used to construct the image on the display. | ||
455 | * @cmap: The colormap used for color images. | ||
456 | */ | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * xxxfb_cursor - REQUIRED function. If your hardware lacks support | ||
461 | * for a cursor you can use the default cursor whose | ||
462 | * function is called soft_cursor. It will always | ||
463 | * work since it uses xxxfb_imageblit function which | ||
464 | * is required. | ||
465 | * | ||
466 | * @info: frame buffer structure that represents a single frame buffer | ||
467 | * @cursor: structure defining the cursor to draw. | ||
468 | * | ||
469 | * This operation is used to set or alter the properities of the | ||
470 | * cursor. | ||
471 | * | ||
472 | * Returns negative errno on error, or zero on success. | ||
473 | */ | ||
474 | int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
475 | { | ||
476 | /* | ||
477 | * @set: Which fields we are altering in struct fb_cursor | ||
478 | * @enable: Disable or enable the cursor | ||
479 | * @rop: The bit operation we want to do. | ||
480 | * @mask: This is the cursor mask bitmap. | ||
481 | * @dest: A image of the area we are going to display the cursor. | ||
482 | * Used internally by the driver. | ||
483 | * @hot: The hot spot. | ||
484 | * @image: The actual data for the cursor image. | ||
485 | * | ||
486 | * NOTES ON FLAGS (cursor->set): | ||
487 | * | ||
488 | * FB_CUR_SETIMAGE - the cursor image has changed (cursor->image.data) | ||
489 | * FB_CUR_SETPOS - the cursor position has changed (cursor->image.dx|dy) | ||
490 | * FB_CUR_SETHOT - the cursor hot spot has changed (cursor->hot.dx|dy) | ||
491 | * FB_CUR_SETCMAP - the cursor colors has changed (cursor->fg_color|bg_color) | ||
492 | * FB_CUR_SETSHAPE - the cursor bitmask has changed (cursor->mask) | ||
493 | * FB_CUR_SETSIZE - the cursor size has changed (cursor->width|height) | ||
494 | * FB_CUR_SETALL - everything has changed | ||
495 | * | ||
496 | * NOTES ON ROPs (cursor->rop, Raster Operation) | ||
497 | * | ||
498 | * ROP_XOR - cursor->image.data XOR cursor->mask | ||
499 | * ROP_COPY - curosr->image.data AND cursor->mask | ||
500 | * | ||
501 | * OTHER NOTES: | ||
502 | * | ||
503 | * - fbcon only supports a 2-color cursor (cursor->image.depth = 1) | ||
504 | * - The fb_cursor structure, @cursor, _will_ always contain valid | ||
505 | * fields, whether any particular bitfields in cursor->set is set | ||
506 | * or not. | ||
507 | */ | ||
508 | } | ||
509 | |||
510 | /** | ||
511 | * xxxfb_rotate - NOT a required function. If your hardware | ||
512 | * supports rotation the whole screen then | ||
513 | * you would provide a hook for this. | ||
514 | * | ||
515 | * @info: frame buffer structure that represents a single frame buffer | ||
516 | * @angle: The angle we rotate the screen. | ||
517 | * | ||
518 | * This operation is used to set or alter the properities of the | ||
519 | * cursor. | ||
520 | */ | ||
521 | void xxxfb_rotate(struct fb_info *info, int angle) | ||
522 | { | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * xxxfb_poll - NOT a required function. The purpose of this | ||
527 | * function is to provide a way for some process | ||
528 | * to wait until a specific hardware event occurs | ||
529 | * for the framebuffer device. | ||
530 | * | ||
531 | * @info: frame buffer structure that represents a single frame buffer | ||
532 | * @wait: poll table where we store process that await a event. | ||
533 | */ | ||
534 | void xxxfb_poll(struct fb_info *info, poll_table *wait) | ||
535 | { | ||
536 | } | ||
537 | |||
538 | /** | ||
539 | * xxxfb_sync - NOT a required function. Normally the accel engine | ||
540 | * for a graphics card take a specific amount of time. | ||
541 | * Often we have to wait for the accelerator to finish | ||
542 | * its operation before we can write to the framebuffer | ||
543 | * so we can have consistent display output. | ||
544 | * | ||
545 | * @info: frame buffer structure that represents a single frame buffer | ||
546 | */ | ||
547 | void xxxfb_sync(struct fb_info *info) | ||
548 | { | ||
549 | } | ||
550 | |||
551 | /* | ||
552 | * Initialization | ||
553 | */ | ||
554 | |||
555 | int __init xxxfb_init(void) | ||
556 | { | ||
557 | int cmap_len, retval; | ||
558 | |||
559 | /* | ||
560 | * For kernel boot options (in 'video=xxxfb:<options>' format) | ||
561 | */ | ||
562 | #ifndef MODULE | ||
563 | char *option = NULL; | ||
564 | |||
565 | if (fb_get_options("xxxfb", &option)) | ||
566 | return -ENODEV; | ||
567 | xxxfb_setup(option); | ||
568 | #endif | ||
569 | |||
570 | /* | ||
571 | * Here we set the screen_base to the virtual memory address | ||
572 | * for the framebuffer. Usually we obtain the resource address | ||
573 | * from the bus layer and then translate it to virtual memory | ||
574 | * space via ioremap. Consult ioport.h. | ||
575 | */ | ||
576 | info.screen_base = framebuffer_virtual_memory; | ||
577 | info.fbops = &xxxfb_ops; | ||
578 | info.fix = xxxfb_fix; | ||
579 | info.pseudo_palette = pseudo_palette; | ||
580 | |||
581 | /* | ||
582 | * Set up flags to indicate what sort of acceleration your | ||
583 | * driver can provide (pan/wrap/copyarea/etc.) and whether it | ||
584 | * is a module -- see FBINFO_* in include/linux/fb.h | ||
585 | */ | ||
586 | info.flags = FBINFO_DEFAULT; | ||
587 | info.par = current_par; | ||
588 | |||
589 | /* | ||
590 | * This should give a reasonable default video mode. The following is | ||
591 | * done when we can set a video mode. | ||
592 | */ | ||
593 | if (!mode_option) | ||
594 | mode_option = "640x480@60"; | ||
595 | |||
596 | retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8); | ||
597 | |||
598 | if (!retval || retval == 4) | ||
599 | return -EINVAL; | ||
600 | |||
601 | /* This has to been done !!! */ | ||
602 | fb_alloc_cmap(&info.cmap, cmap_len, 0); | ||
603 | |||
604 | /* | ||
605 | * The following is done in the case of having hardware with a static | ||
606 | * mode. If we are setting the mode ourselves we don't call this. | ||
607 | */ | ||
608 | info.var = xxxfb_var; | ||
609 | |||
610 | if (register_framebuffer(&info) < 0) | ||
611 | return -EINVAL; | ||
612 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, | ||
613 | info.fix.id); | ||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | /* | ||
618 | * Cleanup | ||
619 | */ | ||
620 | |||
621 | static void __exit xxxfb_cleanup(void) | ||
622 | { | ||
623 | /* | ||
624 | * If your driver supports multiple boards, you should unregister and | ||
625 | * clean up all instances. | ||
626 | */ | ||
627 | |||
628 | unregister_framebuffer(info); | ||
629 | fb_dealloc_cmap(&info.cmap); | ||
630 | /* ... */ | ||
631 | } | ||
632 | |||
633 | /* | ||
634 | * Setup | ||
635 | */ | ||
636 | |||
637 | /* | ||
638 | * Only necessary if your driver takes special options, | ||
639 | * otherwise we fall back on the generic fb_setup(). | ||
640 | */ | ||
641 | int __init xxxfb_setup(char *options) | ||
642 | { | ||
643 | /* Parse user speficied options (`video=xxxfb:') */ | ||
644 | } | ||
645 | |||
646 | /* ------------------------------------------------------------------------- */ | ||
647 | |||
648 | /* | ||
649 | * Frame buffer operations | ||
650 | */ | ||
651 | |||
652 | static struct fb_ops xxxfb_ops = { | ||
653 | .owner = THIS_MODULE, | ||
654 | .fb_open = xxxfb_open, | ||
655 | .fb_read = xxxfb_read, | ||
656 | .fb_write = xxxfb_write, | ||
657 | .fb_release = xxxfb_release, | ||
658 | .fb_check_var = xxxfb_check_var, | ||
659 | .fb_set_par = xxxfb_set_par, | ||
660 | .fb_setcolreg = xxxfb_setcolreg, | ||
661 | .fb_blank = xxxfb_blank, | ||
662 | .fb_pan_display = xxxfb_pan_display, | ||
663 | .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ | ||
664 | .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ | ||
665 | .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ | ||
666 | .fb_cursor = xxxfb_cursor, /* Needed !!! */ | ||
667 | .fb_rotate = xxxfb_rotate, | ||
668 | .fb_poll = xxxfb_poll, | ||
669 | .fb_sync = xxxfb_sync, | ||
670 | .fb_ioctl = xxxfb_ioctl, | ||
671 | .fb_mmap = xxxfb_mmap, | ||
672 | }; | ||
673 | |||
674 | /* ------------------------------------------------------------------------- */ | ||
675 | |||
676 | |||
677 | /* | ||
678 | * Modularization | ||
679 | */ | ||
680 | |||
681 | module_init(xxxfb_init); | ||
682 | module_exit(xxxfb_cleanup); | ||
683 | |||
684 | MODULE_LICENSE("GPL"); | ||