diff options
Diffstat (limited to 'drivers/video/fbdev/skeletonfb.c')
-rw-r--r-- | drivers/video/fbdev/skeletonfb.c | 1037 |
1 files changed, 1037 insertions, 0 deletions
diff --git a/drivers/video/fbdev/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c new file mode 100644 index 000000000000..fefde7c6add7 --- /dev/null +++ b/drivers/video/fbdev/skeletonfb.c | |||
@@ -0,0 +1,1037 @@ | |||
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 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/slab.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/fb.h> | ||
53 | #include <linux/init.h> | ||
54 | #include <linux/pci.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 | * Driver data | ||
65 | */ | ||
66 | static char *mode_option; | ||
67 | |||
68 | /* | ||
69 | * If your driver supports multiple boards, you should make the | ||
70 | * below data types arrays, or allocate them dynamically (using kmalloc()). | ||
71 | */ | ||
72 | |||
73 | /* | ||
74 | * This structure defines the hardware state of the graphics card. Normally | ||
75 | * you place this in a header file in linux/include/video. This file usually | ||
76 | * also includes register information. That allows other driver subsystems | ||
77 | * and userland applications the ability to use the same header file to | ||
78 | * avoid duplicate work and easy porting of software. | ||
79 | */ | ||
80 | struct xxx_par; | ||
81 | |||
82 | /* | ||
83 | * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo | ||
84 | * if we don't use modedb. If we do use modedb see xxxfb_init how to use it | ||
85 | * to get a fb_var_screeninfo. Otherwise define a default var as well. | ||
86 | */ | ||
87 | static struct fb_fix_screeninfo xxxfb_fix = { | ||
88 | .id = "FB's name", | ||
89 | .type = FB_TYPE_PACKED_PIXELS, | ||
90 | .visual = FB_VISUAL_PSEUDOCOLOR, | ||
91 | .xpanstep = 1, | ||
92 | .ypanstep = 1, | ||
93 | .ywrapstep = 1, | ||
94 | .accel = FB_ACCEL_NONE, | ||
95 | }; | ||
96 | |||
97 | /* | ||
98 | * Modern graphical hardware not only supports pipelines but some | ||
99 | * also support multiple monitors where each display can have its | ||
100 | * its own unique data. In this case each display could be | ||
101 | * represented by a separate framebuffer device thus a separate | ||
102 | * struct fb_info. Now the struct xxx_par represents the graphics | ||
103 | * hardware state thus only one exist per card. In this case the | ||
104 | * struct xxx_par for each graphics card would be shared between | ||
105 | * every struct fb_info that represents a framebuffer on that card. | ||
106 | * This allows when one display changes it video resolution (info->var) | ||
107 | * the other displays know instantly. Each display can always be | ||
108 | * aware of the entire hardware state that affects it because they share | ||
109 | * the same xxx_par struct. The other side of the coin is multiple | ||
110 | * graphics cards that pass data around until it is finally displayed | ||
111 | * on one monitor. Such examples are the voodoo 1 cards and high end | ||
112 | * NUMA graphics servers. For this case we have a bunch of pars, each | ||
113 | * one that represents a graphics state, that belong to one struct | ||
114 | * fb_info. Their you would want to have *par point to a array of device | ||
115 | * states and have each struct fb_ops function deal with all those | ||
116 | * states. I hope this covers every possible hardware design. If not | ||
117 | * feel free to send your ideas at jsimmons@users.sf.net | ||
118 | */ | ||
119 | |||
120 | /* | ||
121 | * If your driver supports multiple boards or it supports multiple | ||
122 | * framebuffers, you should make these arrays, or allocate them | ||
123 | * dynamically using framebuffer_alloc() and free them with | ||
124 | * framebuffer_release(). | ||
125 | */ | ||
126 | static struct fb_info info; | ||
127 | |||
128 | /* | ||
129 | * Each one represents the state of the hardware. Most hardware have | ||
130 | * just one hardware state. These here represent the default state(s). | ||
131 | */ | ||
132 | static struct xxx_par __initdata current_par; | ||
133 | |||
134 | int xxxfb_init(void); | ||
135 | |||
136 | /** | ||
137 | * xxxfb_open - Optional function. Called when the framebuffer is | ||
138 | * first accessed. | ||
139 | * @info: frame buffer structure that represents a single frame buffer | ||
140 | * @user: tell us if the userland (value=1) or the console is accessing | ||
141 | * the framebuffer. | ||
142 | * | ||
143 | * This function is the first function called in the framebuffer api. | ||
144 | * Usually you don't need to provide this function. The case where it | ||
145 | * is used is to change from a text mode hardware state to a graphics | ||
146 | * mode state. | ||
147 | * | ||
148 | * Returns negative errno on error, or zero on success. | ||
149 | */ | ||
150 | static int xxxfb_open(struct fb_info *info, int user) | ||
151 | { | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * xxxfb_release - Optional function. Called when the framebuffer | ||
157 | * device is closed. | ||
158 | * @info: frame buffer structure that represents a single frame buffer | ||
159 | * @user: tell us if the userland (value=1) or the console is accessing | ||
160 | * the framebuffer. | ||
161 | * | ||
162 | * Thus function is called when we close /dev/fb or the framebuffer | ||
163 | * console system is released. Usually you don't need this function. | ||
164 | * The case where it is usually used is to go from a graphics state | ||
165 | * to a text mode state. | ||
166 | * | ||
167 | * Returns negative errno on error, or zero on success. | ||
168 | */ | ||
169 | static int xxxfb_release(struct fb_info *info, int user) | ||
170 | { | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * xxxfb_check_var - Optional function. Validates a var passed in. | ||
176 | * @var: frame buffer variable screen structure | ||
177 | * @info: frame buffer structure that represents a single frame buffer | ||
178 | * | ||
179 | * Checks to see if the hardware supports the state requested by | ||
180 | * var passed in. This function does not alter the hardware state!!! | ||
181 | * This means the data stored in struct fb_info and struct xxx_par do | ||
182 | * not change. This includes the var inside of struct fb_info. | ||
183 | * Do NOT change these. This function can be called on its own if we | ||
184 | * intent to only test a mode and not actually set it. The stuff in | ||
185 | * modedb.c is a example of this. If the var passed in is slightly | ||
186 | * off by what the hardware can support then we alter the var PASSED in | ||
187 | * to what we can do. | ||
188 | * | ||
189 | * For values that are off, this function must round them _up_ to the | ||
190 | * next value that is supported by the hardware. If the value is | ||
191 | * greater than the highest value supported by the hardware, then this | ||
192 | * function must return -EINVAL. | ||
193 | * | ||
194 | * Exception to the above rule: Some drivers have a fixed mode, ie, | ||
195 | * the hardware is already set at boot up, and cannot be changed. In | ||
196 | * this case, it is more acceptable that this function just return | ||
197 | * a copy of the currently working var (info->var). Better is to not | ||
198 | * implement this function, as the upper layer will do the copying | ||
199 | * of the current var for you. | ||
200 | * | ||
201 | * Note: This is the only function where the contents of var can be | ||
202 | * freely adjusted after the driver has been registered. If you find | ||
203 | * that you have code outside of this function that alters the content | ||
204 | * of var, then you are doing something wrong. Note also that the | ||
205 | * contents of info->var must be left untouched at all times after | ||
206 | * driver registration. | ||
207 | * | ||
208 | * Returns negative errno on error, or zero on success. | ||
209 | */ | ||
210 | static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | ||
211 | { | ||
212 | /* ... */ | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * xxxfb_set_par - Optional function. Alters the hardware state. | ||
218 | * @info: frame buffer structure that represents a single frame buffer | ||
219 | * | ||
220 | * Using the fb_var_screeninfo in fb_info we set the resolution of the | ||
221 | * this particular framebuffer. This function alters the par AND the | ||
222 | * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in | ||
223 | * fb_info since we are using that data. This means we depend on the | ||
224 | * data in var inside fb_info to be supported by the hardware. | ||
225 | * | ||
226 | * This function is also used to recover/restore the hardware to a | ||
227 | * known working state. | ||
228 | * | ||
229 | * xxxfb_check_var is always called before xxxfb_set_par to ensure that | ||
230 | * the contents of var is always valid. | ||
231 | * | ||
232 | * Again if you can't change the resolution you don't need this function. | ||
233 | * | ||
234 | * However, even if your hardware does not support mode changing, | ||
235 | * a set_par might be needed to at least initialize the hardware to | ||
236 | * a known working state, especially if it came back from another | ||
237 | * process that also modifies the same hardware, such as X. | ||
238 | * | ||
239 | * If this is the case, a combination such as the following should work: | ||
240 | * | ||
241 | * static int xxxfb_check_var(struct fb_var_screeninfo *var, | ||
242 | * struct fb_info *info) | ||
243 | * { | ||
244 | * *var = info->var; | ||
245 | * return 0; | ||
246 | * } | ||
247 | * | ||
248 | * static int xxxfb_set_par(struct fb_info *info) | ||
249 | * { | ||
250 | * init your hardware here | ||
251 | * } | ||
252 | * | ||
253 | * Returns negative errno on error, or zero on success. | ||
254 | */ | ||
255 | static int xxxfb_set_par(struct fb_info *info) | ||
256 | { | ||
257 | struct xxx_par *par = info->par; | ||
258 | /* ... */ | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * xxxfb_setcolreg - Optional function. Sets a color register. | ||
264 | * @regno: Which register in the CLUT we are programming | ||
265 | * @red: The red value which can be up to 16 bits wide | ||
266 | * @green: The green value which can be up to 16 bits wide | ||
267 | * @blue: The blue value which can be up to 16 bits wide. | ||
268 | * @transp: If supported, the alpha value which can be up to 16 bits wide. | ||
269 | * @info: frame buffer info structure | ||
270 | * | ||
271 | * Set a single color register. The values supplied have a 16 bit | ||
272 | * magnitude which needs to be scaled in this function for the hardware. | ||
273 | * Things to take into consideration are how many color registers, if | ||
274 | * any, are supported with the current color visual. With truecolor mode | ||
275 | * no color palettes are supported. Here a pseudo palette is created | ||
276 | * which we store the value in pseudo_palette in struct fb_info. For | ||
277 | * pseudocolor mode we have a limited color palette. To deal with this | ||
278 | * we can program what color is displayed for a particular pixel value. | ||
279 | * DirectColor is similar in that we can program each color field. If | ||
280 | * we have a static colormap we don't need to implement this function. | ||
281 | * | ||
282 | * Returns negative errno on error, or zero on success. | ||
283 | */ | ||
284 | static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, | ||
285 | unsigned blue, unsigned transp, | ||
286 | struct fb_info *info) | ||
287 | { | ||
288 | if (regno >= 256) /* no. of hw registers */ | ||
289 | return -EINVAL; | ||
290 | /* | ||
291 | * Program hardware... do anything you want with transp | ||
292 | */ | ||
293 | |||
294 | /* grayscale works only partially under directcolor */ | ||
295 | if (info->var.grayscale) { | ||
296 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
297 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
298 | } | ||
299 | |||
300 | /* Directcolor: | ||
301 | * var->{color}.offset contains start of bitfield | ||
302 | * var->{color}.length contains length of bitfield | ||
303 | * {hardwarespecific} contains width of DAC | ||
304 | * pseudo_palette[X] is programmed to (X << red.offset) | | ||
305 | * (X << green.offset) | | ||
306 | * (X << blue.offset) | ||
307 | * RAMDAC[X] is programmed to (red, green, blue) | ||
308 | * color depth = SUM(var->{color}.length) | ||
309 | * | ||
310 | * Pseudocolor: | ||
311 | * var->{color}.offset is 0 unless the palette index takes less than | ||
312 | * bits_per_pixel bits and is stored in the upper | ||
313 | * bits of the pixel value | ||
314 | * var->{color}.length is set so that 1 << length is the number of | ||
315 | * available palette entries | ||
316 | * pseudo_palette is not used | ||
317 | * RAMDAC[X] is programmed to (red, green, blue) | ||
318 | * color depth = var->{color}.length | ||
319 | * | ||
320 | * Static pseudocolor: | ||
321 | * same as Pseudocolor, but the RAMDAC is not programmed (read-only) | ||
322 | * | ||
323 | * Mono01/Mono10: | ||
324 | * Has only 2 values, black on white or white on black (fg on bg), | ||
325 | * var->{color}.offset is 0 | ||
326 | * white = (1 << var->{color}.length) - 1, black = 0 | ||
327 | * pseudo_palette is not used | ||
328 | * RAMDAC does not exist | ||
329 | * color depth is always 2 | ||
330 | * | ||
331 | * Truecolor: | ||
332 | * does not use RAMDAC (usually has 3 of them). | ||
333 | * var->{color}.offset contains start of bitfield | ||
334 | * var->{color}.length contains length of bitfield | ||
335 | * pseudo_palette is programmed to (red << red.offset) | | ||
336 | * (green << green.offset) | | ||
337 | * (blue << blue.offset) | | ||
338 | * (transp << transp.offset) | ||
339 | * RAMDAC does not exist | ||
340 | * color depth = SUM(var->{color}.length}) | ||
341 | * | ||
342 | * The color depth is used by fbcon for choosing the logo and also | ||
343 | * for color palette transformation if color depth < 4 | ||
344 | * | ||
345 | * As can be seen from the above, the field bits_per_pixel is _NOT_ | ||
346 | * a criteria for describing the color visual. | ||
347 | * | ||
348 | * A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor, | ||
349 | * and higher than that, true/directcolor. This is incorrect, one needs | ||
350 | * to look at the fix->visual. | ||
351 | * | ||
352 | * Another common mistake is using bits_per_pixel to calculate the color | ||
353 | * depth. The bits_per_pixel field does not directly translate to color | ||
354 | * depth. You have to compute for the color depth (using the color | ||
355 | * bitfields) and fix->visual as seen above. | ||
356 | */ | ||
357 | |||
358 | /* | ||
359 | * This is the point where the color is converted to something that | ||
360 | * is acceptable by the hardware. | ||
361 | */ | ||
362 | #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) | ||
363 | red = CNVT_TOHW(red, info->var.red.length); | ||
364 | green = CNVT_TOHW(green, info->var.green.length); | ||
365 | blue = CNVT_TOHW(blue, info->var.blue.length); | ||
366 | transp = CNVT_TOHW(transp, info->var.transp.length); | ||
367 | #undef CNVT_TOHW | ||
368 | /* | ||
369 | * This is the point where the function feeds the color to the hardware | ||
370 | * palette after converting the colors to something acceptable by | ||
371 | * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and | ||
372 | * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette. | ||
373 | * If you have code that writes to the hardware CLUT, and it's not | ||
374 | * any of the above visuals, then you are doing something wrong. | ||
375 | */ | ||
376 | if (info->fix.visual == FB_VISUAL_DIRECTCOLOR || | ||
377 | info->fix.visual == FB_VISUAL_TRUECOLOR) | ||
378 | write_{red|green|blue|transp}_to_clut(); | ||
379 | |||
380 | /* This is the point were you need to fill up the contents of | ||
381 | * info->pseudo_palette. This structure is used _only_ by fbcon, thus | ||
382 | * it only contains 16 entries to match the number of colors supported | ||
383 | * by the console. The pseudo_palette is used only if the visual is | ||
384 | * in directcolor or truecolor mode. With other visuals, the | ||
385 | * pseudo_palette is not used. (This might change in the future.) | ||
386 | * | ||
387 | * The contents of the pseudo_palette is in raw pixel format. Ie, each | ||
388 | * entry can be written directly to the framebuffer without any conversion. | ||
389 | * The pseudo_palette is (void *). However, if using the generic | ||
390 | * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette | ||
391 | * must be casted to (u32 *) _regardless_ of the bits per pixel. If the | ||
392 | * driver is using its own drawing functions, then it can use whatever | ||
393 | * size it wants. | ||
394 | */ | ||
395 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
396 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
397 | u32 v; | ||
398 | |||
399 | if (regno >= 16) | ||
400 | return -EINVAL; | ||
401 | |||
402 | v = (red << info->var.red.offset) | | ||
403 | (green << info->var.green.offset) | | ||
404 | (blue << info->var.blue.offset) | | ||
405 | (transp << info->var.transp.offset); | ||
406 | |||
407 | ((u32*)(info->pseudo_palette))[regno] = v; | ||
408 | } | ||
409 | |||
410 | /* ... */ | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /** | ||
415 | * xxxfb_pan_display - NOT a required function. Pans the display. | ||
416 | * @var: frame buffer variable screen structure | ||
417 | * @info: frame buffer structure that represents a single frame buffer | ||
418 | * | ||
419 | * Pan (or wrap, depending on the `vmode' field) the display using the | ||
420 | * `xoffset' and `yoffset' fields of the `var' structure. | ||
421 | * If the values don't fit, return -EINVAL. | ||
422 | * | ||
423 | * Returns negative errno on error, or zero on success. | ||
424 | */ | ||
425 | static int xxxfb_pan_display(struct fb_var_screeninfo *var, | ||
426 | struct fb_info *info) | ||
427 | { | ||
428 | /* | ||
429 | * If your hardware does not support panning, _do_ _not_ implement this | ||
430 | * function. Creating a dummy function will just confuse user apps. | ||
431 | */ | ||
432 | |||
433 | /* | ||
434 | * Note that even if this function is fully functional, a setting of | ||
435 | * 0 in both xpanstep and ypanstep means that this function will never | ||
436 | * get called. | ||
437 | */ | ||
438 | |||
439 | /* ... */ | ||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * xxxfb_blank - NOT a required function. Blanks the display. | ||
445 | * @blank_mode: the blank mode we want. | ||
446 | * @info: frame buffer structure that represents a single frame buffer | ||
447 | * | ||
448 | * Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank. | ||
449 | * Return 0 if blanking succeeded, != 0 if un-/blanking failed due to | ||
450 | * e.g. a video mode which doesn't support it. | ||
451 | * | ||
452 | * Implements VESA suspend and powerdown modes on hardware that supports | ||
453 | * disabling hsync/vsync: | ||
454 | * | ||
455 | * FB_BLANK_NORMAL = display is blanked, syncs are on. | ||
456 | * FB_BLANK_HSYNC_SUSPEND = hsync off | ||
457 | * FB_BLANK_VSYNC_SUSPEND = vsync off | ||
458 | * FB_BLANK_POWERDOWN = hsync and vsync off | ||
459 | * | ||
460 | * If implementing this function, at least support FB_BLANK_UNBLANK. | ||
461 | * Return !0 for any modes that are unimplemented. | ||
462 | * | ||
463 | */ | ||
464 | static int xxxfb_blank(int blank_mode, struct fb_info *info) | ||
465 | { | ||
466 | /* ... */ | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | /* ------------ Accelerated Functions --------------------- */ | ||
471 | |||
472 | /* | ||
473 | * We provide our own functions if we have hardware acceleration | ||
474 | * or non packed pixel format layouts. If we have no hardware | ||
475 | * acceleration, we can use a generic unaccelerated function. If using | ||
476 | * a pack pixel format just use the functions in cfb_*.c. Each file | ||
477 | * has one of the three different accel functions we support. | ||
478 | */ | ||
479 | |||
480 | /** | ||
481 | * xxxfb_fillrect - REQUIRED function. Can use generic routines if | ||
482 | * non acclerated hardware and packed pixel based. | ||
483 | * Draws a rectangle on the screen. | ||
484 | * | ||
485 | * @info: frame buffer structure that represents a single frame buffer | ||
486 | * @region: The structure representing the rectangular region we | ||
487 | * wish to draw to. | ||
488 | * | ||
489 | * This drawing operation places/removes a retangle on the screen | ||
490 | * depending on the rastering operation with the value of color which | ||
491 | * is in the current color depth format. | ||
492 | */ | ||
493 | void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region) | ||
494 | { | ||
495 | /* Meaning of struct fb_fillrect | ||
496 | * | ||
497 | * @dx: The x and y corrdinates of the upper left hand corner of the | ||
498 | * @dy: area we want to draw to. | ||
499 | * @width: How wide the rectangle is we want to draw. | ||
500 | * @height: How tall the rectangle is we want to draw. | ||
501 | * @color: The color to fill in the rectangle with. | ||
502 | * @rop: The raster operation. We can draw the rectangle with a COPY | ||
503 | * of XOR which provides erasing effect. | ||
504 | */ | ||
505 | } | ||
506 | |||
507 | /** | ||
508 | * xxxfb_copyarea - REQUIRED function. Can use generic routines if | ||
509 | * non acclerated hardware and packed pixel based. | ||
510 | * Copies one area of the screen to another area. | ||
511 | * | ||
512 | * @info: frame buffer structure that represents a single frame buffer | ||
513 | * @area: Structure providing the data to copy the framebuffer contents | ||
514 | * from one region to another. | ||
515 | * | ||
516 | * This drawing operation copies a rectangular area from one area of the | ||
517 | * screen to another area. | ||
518 | */ | ||
519 | void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) | ||
520 | { | ||
521 | /* | ||
522 | * @dx: The x and y coordinates of the upper left hand corner of the | ||
523 | * @dy: destination area on the screen. | ||
524 | * @width: How wide the rectangle is we want to copy. | ||
525 | * @height: How tall the rectangle is we want to copy. | ||
526 | * @sx: The x and y coordinates of the upper left hand corner of the | ||
527 | * @sy: source area on the screen. | ||
528 | */ | ||
529 | } | ||
530 | |||
531 | |||
532 | /** | ||
533 | * xxxfb_imageblit - REQUIRED function. Can use generic routines if | ||
534 | * non acclerated hardware and packed pixel based. | ||
535 | * Copies a image from system memory to the screen. | ||
536 | * | ||
537 | * @info: frame buffer structure that represents a single frame buffer | ||
538 | * @image: structure defining the image. | ||
539 | * | ||
540 | * This drawing operation draws a image on the screen. It can be a | ||
541 | * mono image (needed for font handling) or a color image (needed for | ||
542 | * tux). | ||
543 | */ | ||
544 | void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) | ||
545 | { | ||
546 | /* | ||
547 | * @dx: The x and y coordinates of the upper left hand corner of the | ||
548 | * @dy: destination area to place the image on the screen. | ||
549 | * @width: How wide the image is we want to copy. | ||
550 | * @height: How tall the image is we want to copy. | ||
551 | * @fg_color: For mono bitmap images this is color data for | ||
552 | * @bg_color: the foreground and background of the image to | ||
553 | * write directly to the frmaebuffer. | ||
554 | * @depth: How many bits represent a single pixel for this image. | ||
555 | * @data: The actual data used to construct the image on the display. | ||
556 | * @cmap: The colormap used for color images. | ||
557 | */ | ||
558 | |||
559 | /* | ||
560 | * The generic function, cfb_imageblit, expects that the bitmap scanlines are | ||
561 | * padded to the next byte. Most hardware accelerators may require padding to | ||
562 | * the next u16 or the next u32. If that is the case, the driver can specify | ||
563 | * this by setting info->pixmap.scan_align = 2 or 4. See a more | ||
564 | * comprehensive description of the pixmap below. | ||
565 | */ | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * xxxfb_cursor - OPTIONAL. If your hardware lacks support | ||
570 | * for a cursor, leave this field NULL. | ||
571 | * | ||
572 | * @info: frame buffer structure that represents a single frame buffer | ||
573 | * @cursor: structure defining the cursor to draw. | ||
574 | * | ||
575 | * This operation is used to set or alter the properities of the | ||
576 | * cursor. | ||
577 | * | ||
578 | * Returns negative errno on error, or zero on success. | ||
579 | */ | ||
580 | int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
581 | { | ||
582 | /* | ||
583 | * @set: Which fields we are altering in struct fb_cursor | ||
584 | * @enable: Disable or enable the cursor | ||
585 | * @rop: The bit operation we want to do. | ||
586 | * @mask: This is the cursor mask bitmap. | ||
587 | * @dest: A image of the area we are going to display the cursor. | ||
588 | * Used internally by the driver. | ||
589 | * @hot: The hot spot. | ||
590 | * @image: The actual data for the cursor image. | ||
591 | * | ||
592 | * NOTES ON FLAGS (cursor->set): | ||
593 | * | ||
594 | * FB_CUR_SETIMAGE - the cursor image has changed (cursor->image.data) | ||
595 | * FB_CUR_SETPOS - the cursor position has changed (cursor->image.dx|dy) | ||
596 | * FB_CUR_SETHOT - the cursor hot spot has changed (cursor->hot.dx|dy) | ||
597 | * FB_CUR_SETCMAP - the cursor colors has changed (cursor->fg_color|bg_color) | ||
598 | * FB_CUR_SETSHAPE - the cursor bitmask has changed (cursor->mask) | ||
599 | * FB_CUR_SETSIZE - the cursor size has changed (cursor->width|height) | ||
600 | * FB_CUR_SETALL - everything has changed | ||
601 | * | ||
602 | * NOTES ON ROPs (cursor->rop, Raster Operation) | ||
603 | * | ||
604 | * ROP_XOR - cursor->image.data XOR cursor->mask | ||
605 | * ROP_COPY - curosr->image.data AND cursor->mask | ||
606 | * | ||
607 | * OTHER NOTES: | ||
608 | * | ||
609 | * - fbcon only supports a 2-color cursor (cursor->image.depth = 1) | ||
610 | * - The fb_cursor structure, @cursor, _will_ always contain valid | ||
611 | * fields, whether any particular bitfields in cursor->set is set | ||
612 | * or not. | ||
613 | */ | ||
614 | } | ||
615 | |||
616 | /** | ||
617 | * xxxfb_rotate - NOT a required function. If your hardware | ||
618 | * supports rotation the whole screen then | ||
619 | * you would provide a hook for this. | ||
620 | * | ||
621 | * @info: frame buffer structure that represents a single frame buffer | ||
622 | * @angle: The angle we rotate the screen. | ||
623 | * | ||
624 | * This operation is used to set or alter the properities of the | ||
625 | * cursor. | ||
626 | */ | ||
627 | void xxxfb_rotate(struct fb_info *info, int angle) | ||
628 | { | ||
629 | /* Will be deprecated */ | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * xxxfb_sync - NOT a required function. Normally the accel engine | ||
634 | * for a graphics card take a specific amount of time. | ||
635 | * Often we have to wait for the accelerator to finish | ||
636 | * its operation before we can write to the framebuffer | ||
637 | * so we can have consistent display output. | ||
638 | * | ||
639 | * @info: frame buffer structure that represents a single frame buffer | ||
640 | * | ||
641 | * If the driver has implemented its own hardware-based drawing function, | ||
642 | * implementing this function is highly recommended. | ||
643 | */ | ||
644 | int xxxfb_sync(struct fb_info *info) | ||
645 | { | ||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Frame buffer operations | ||
651 | */ | ||
652 | |||
653 | static struct fb_ops xxxfb_ops = { | ||
654 | .owner = THIS_MODULE, | ||
655 | .fb_open = xxxfb_open, | ||
656 | .fb_read = xxxfb_read, | ||
657 | .fb_write = xxxfb_write, | ||
658 | .fb_release = xxxfb_release, | ||
659 | .fb_check_var = xxxfb_check_var, | ||
660 | .fb_set_par = xxxfb_set_par, | ||
661 | .fb_setcolreg = xxxfb_setcolreg, | ||
662 | .fb_blank = xxxfb_blank, | ||
663 | .fb_pan_display = xxxfb_pan_display, | ||
664 | .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ | ||
665 | .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ | ||
666 | .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ | ||
667 | .fb_cursor = xxxfb_cursor, /* Optional !!! */ | ||
668 | .fb_rotate = xxxfb_rotate, | ||
669 | .fb_sync = xxxfb_sync, | ||
670 | .fb_ioctl = xxxfb_ioctl, | ||
671 | .fb_mmap = xxxfb_mmap, | ||
672 | }; | ||
673 | |||
674 | /* ------------------------------------------------------------------------- */ | ||
675 | |||
676 | /* | ||
677 | * Initialization | ||
678 | */ | ||
679 | |||
680 | /* static int __init xxfb_probe (struct platform_device *pdev) -- for platform devs */ | ||
681 | static int xxxfb_probe(struct pci_dev *dev, const struct pci_device_id *ent) | ||
682 | { | ||
683 | struct fb_info *info; | ||
684 | struct xxx_par *par; | ||
685 | struct device *device = &dev->dev; /* or &pdev->dev */ | ||
686 | int cmap_len, retval; | ||
687 | |||
688 | /* | ||
689 | * Dynamically allocate info and par | ||
690 | */ | ||
691 | info = framebuffer_alloc(sizeof(struct xxx_par), device); | ||
692 | |||
693 | if (!info) { | ||
694 | /* goto error path */ | ||
695 | } | ||
696 | |||
697 | par = info->par; | ||
698 | |||
699 | /* | ||
700 | * Here we set the screen_base to the virtual memory address | ||
701 | * for the framebuffer. Usually we obtain the resource address | ||
702 | * from the bus layer and then translate it to virtual memory | ||
703 | * space via ioremap. Consult ioport.h. | ||
704 | */ | ||
705 | info->screen_base = framebuffer_virtual_memory; | ||
706 | info->fbops = &xxxfb_ops; | ||
707 | info->fix = xxxfb_fix; | ||
708 | info->pseudo_palette = pseudo_palette; /* The pseudopalette is an | ||
709 | * 16-member array | ||
710 | */ | ||
711 | /* | ||
712 | * Set up flags to indicate what sort of acceleration your | ||
713 | * driver can provide (pan/wrap/copyarea/etc.) and whether it | ||
714 | * is a module -- see FBINFO_* in include/linux/fb.h | ||
715 | * | ||
716 | * If your hardware can support any of the hardware accelerated functions | ||
717 | * fbcon performance will improve if info->flags is set properly. | ||
718 | * | ||
719 | * FBINFO_HWACCEL_COPYAREA - hardware moves | ||
720 | * FBINFO_HWACCEL_FILLRECT - hardware fills | ||
721 | * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion | ||
722 | * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis | ||
723 | * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis | ||
724 | * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled | ||
725 | * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion | ||
726 | * FBINFO_MISC_TILEBLITTING - hardware can do tile blits | ||
727 | * | ||
728 | * NOTE: These are for fbcon use only. | ||
729 | */ | ||
730 | info->flags = FBINFO_DEFAULT; | ||
731 | |||
732 | /********************* This stage is optional ******************************/ | ||
733 | /* | ||
734 | * The struct pixmap is a scratch pad for the drawing functions. This | ||
735 | * is where the monochrome bitmap is constructed by the higher layers | ||
736 | * and then passed to the accelerator. For drivers that uses | ||
737 | * cfb_imageblit, you can skip this part. For those that have a more | ||
738 | * rigorous requirement, this stage is needed | ||
739 | */ | ||
740 | |||
741 | /* PIXMAP_SIZE should be small enough to optimize drawing, but not | ||
742 | * large enough that memory is wasted. A safe size is | ||
743 | * (max_xres * max_font_height/8). max_xres is driver dependent, | ||
744 | * max_font_height is 32. | ||
745 | */ | ||
746 | info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL); | ||
747 | if (!info->pixmap.addr) { | ||
748 | /* goto error */ | ||
749 | } | ||
750 | |||
751 | info->pixmap.size = PIXMAP_SIZE; | ||
752 | |||
753 | /* | ||
754 | * FB_PIXMAP_SYSTEM - memory is in system ram | ||
755 | * FB_PIXMAP_IO - memory is iomapped | ||
756 | * FB_PIXMAP_SYNC - if set, will call fb_sync() per access to pixmap, | ||
757 | * usually if FB_PIXMAP_IO is set. | ||
758 | * | ||
759 | * Currently, FB_PIXMAP_IO is unimplemented. | ||
760 | */ | ||
761 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
762 | |||
763 | /* | ||
764 | * scan_align is the number of padding for each scanline. It is in bytes. | ||
765 | * Thus for accelerators that need padding to the next u32, put 4 here. | ||
766 | */ | ||
767 | info->pixmap.scan_align = 4; | ||
768 | |||
769 | /* | ||
770 | * buf_align is the amount to be padded for the buffer. For example, | ||
771 | * the i810fb needs a scan_align of 2 but expects it to be fed with | ||
772 | * dwords, so a buf_align = 4 is required. | ||
773 | */ | ||
774 | info->pixmap.buf_align = 4; | ||
775 | |||
776 | /* access_align is how many bits can be accessed from the framebuffer | ||
777 | * ie. some epson cards allow 16-bit access only. Most drivers will | ||
778 | * be safe with u32 here. | ||
779 | * | ||
780 | * NOTE: This field is currently unused. | ||
781 | */ | ||
782 | info->pixmap.access_align = 32; | ||
783 | /***************************** End optional stage ***************************/ | ||
784 | |||
785 | /* | ||
786 | * This should give a reasonable default video mode. The following is | ||
787 | * done when we can set a video mode. | ||
788 | */ | ||
789 | if (!mode_option) | ||
790 | mode_option = "640x480@60"; | ||
791 | |||
792 | retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); | ||
793 | |||
794 | if (!retval || retval == 4) | ||
795 | return -EINVAL; | ||
796 | |||
797 | /* This has to be done! */ | ||
798 | if (fb_alloc_cmap(&info->cmap, cmap_len, 0)) | ||
799 | return -ENOMEM; | ||
800 | |||
801 | /* | ||
802 | * The following is done in the case of having hardware with a static | ||
803 | * mode. If we are setting the mode ourselves we don't call this. | ||
804 | */ | ||
805 | info->var = xxxfb_var; | ||
806 | |||
807 | /* | ||
808 | * For drivers that can... | ||
809 | */ | ||
810 | xxxfb_check_var(&info->var, info); | ||
811 | |||
812 | /* | ||
813 | * Does a call to fb_set_par() before register_framebuffer needed? This | ||
814 | * will depend on you and the hardware. If you are sure that your driver | ||
815 | * is the only device in the system, a call to fb_set_par() is safe. | ||
816 | * | ||
817 | * Hardware in x86 systems has a VGA core. Calling set_par() at this | ||
818 | * point will corrupt the VGA console, so it might be safer to skip a | ||
819 | * call to set_par here and just allow fbcon to do it for you. | ||
820 | */ | ||
821 | /* xxxfb_set_par(info); */ | ||
822 | |||
823 | if (register_framebuffer(info) < 0) { | ||
824 | fb_dealloc_cmap(&info->cmap); | ||
825 | return -EINVAL; | ||
826 | } | ||
827 | fb_info(info, "%s frame buffer device\n", info->fix.id); | ||
828 | pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */ | ||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | /* | ||
833 | * Cleanup | ||
834 | */ | ||
835 | /* static void xxxfb_remove(struct platform_device *pdev) */ | ||
836 | static void xxxfb_remove(struct pci_dev *dev) | ||
837 | { | ||
838 | struct fb_info *info = pci_get_drvdata(dev); | ||
839 | /* or platform_get_drvdata(pdev); */ | ||
840 | |||
841 | if (info) { | ||
842 | unregister_framebuffer(info); | ||
843 | fb_dealloc_cmap(&info->cmap); | ||
844 | /* ... */ | ||
845 | framebuffer_release(info); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | #ifdef CONFIG_PCI | ||
850 | #ifdef CONFIG_PM | ||
851 | /** | ||
852 | * xxxfb_suspend - Optional but recommended function. Suspend the device. | ||
853 | * @dev: PCI device | ||
854 | * @msg: the suspend event code. | ||
855 | * | ||
856 | * See Documentation/power/devices.txt for more information | ||
857 | */ | ||
858 | static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg) | ||
859 | { | ||
860 | struct fb_info *info = pci_get_drvdata(dev); | ||
861 | struct xxxfb_par *par = info->par; | ||
862 | |||
863 | /* suspend here */ | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | /** | ||
868 | * xxxfb_resume - Optional but recommended function. Resume the device. | ||
869 | * @dev: PCI device | ||
870 | * | ||
871 | * See Documentation/power/devices.txt for more information | ||
872 | */ | ||
873 | static int xxxfb_resume(struct pci_dev *dev) | ||
874 | { | ||
875 | struct fb_info *info = pci_get_drvdata(dev); | ||
876 | struct xxxfb_par *par = info->par; | ||
877 | |||
878 | /* resume here */ | ||
879 | return 0; | ||
880 | } | ||
881 | #else | ||
882 | #define xxxfb_suspend NULL | ||
883 | #define xxxfb_resume NULL | ||
884 | #endif /* CONFIG_PM */ | ||
885 | |||
886 | static struct pci_device_id xxxfb_id_table[] = { | ||
887 | { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX, | ||
888 | PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, | ||
889 | PCI_CLASS_MASK, 0 }, | ||
890 | { 0, } | ||
891 | }; | ||
892 | |||
893 | /* For PCI drivers */ | ||
894 | static struct pci_driver xxxfb_driver = { | ||
895 | .name = "xxxfb", | ||
896 | .id_table = xxxfb_id_table, | ||
897 | .probe = xxxfb_probe, | ||
898 | .remove = xxxfb_remove, | ||
899 | .suspend = xxxfb_suspend, /* optional but recommended */ | ||
900 | .resume = xxxfb_resume, /* optional but recommended */ | ||
901 | }; | ||
902 | |||
903 | MODULE_DEVICE_TABLE(pci, xxxfb_id_table); | ||
904 | |||
905 | int __init xxxfb_init(void) | ||
906 | { | ||
907 | /* | ||
908 | * For kernel boot options (in 'video=xxxfb:<options>' format) | ||
909 | */ | ||
910 | #ifndef MODULE | ||
911 | char *option = NULL; | ||
912 | |||
913 | if (fb_get_options("xxxfb", &option)) | ||
914 | return -ENODEV; | ||
915 | xxxfb_setup(option); | ||
916 | #endif | ||
917 | |||
918 | return pci_register_driver(&xxxfb_driver); | ||
919 | } | ||
920 | |||
921 | static void __exit xxxfb_exit(void) | ||
922 | { | ||
923 | pci_unregister_driver(&xxxfb_driver); | ||
924 | } | ||
925 | #else /* non PCI, platform drivers */ | ||
926 | #include <linux/platform_device.h> | ||
927 | /* for platform devices */ | ||
928 | |||
929 | #ifdef CONFIG_PM | ||
930 | /** | ||
931 | * xxxfb_suspend - Optional but recommended function. Suspend the device. | ||
932 | * @dev: platform device | ||
933 | * @msg: the suspend event code. | ||
934 | * | ||
935 | * See Documentation/power/devices.txt for more information | ||
936 | */ | ||
937 | static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg) | ||
938 | { | ||
939 | struct fb_info *info = platform_get_drvdata(dev); | ||
940 | struct xxxfb_par *par = info->par; | ||
941 | |||
942 | /* suspend here */ | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | /** | ||
947 | * xxxfb_resume - Optional but recommended function. Resume the device. | ||
948 | * @dev: platform device | ||
949 | * | ||
950 | * See Documentation/power/devices.txt for more information | ||
951 | */ | ||
952 | static int xxxfb_resume(struct platform_dev *dev) | ||
953 | { | ||
954 | struct fb_info *info = platform_get_drvdata(dev); | ||
955 | struct xxxfb_par *par = info->par; | ||
956 | |||
957 | /* resume here */ | ||
958 | return 0; | ||
959 | } | ||
960 | #else | ||
961 | #define xxxfb_suspend NULL | ||
962 | #define xxxfb_resume NULL | ||
963 | #endif /* CONFIG_PM */ | ||
964 | |||
965 | static struct platform_device_driver xxxfb_driver = { | ||
966 | .probe = xxxfb_probe, | ||
967 | .remove = xxxfb_remove, | ||
968 | .suspend = xxxfb_suspend, /* optional but recommended */ | ||
969 | .resume = xxxfb_resume, /* optional but recommended */ | ||
970 | .driver = { | ||
971 | .name = "xxxfb", | ||
972 | }, | ||
973 | }; | ||
974 | |||
975 | static struct platform_device *xxxfb_device; | ||
976 | |||
977 | #ifndef MODULE | ||
978 | /* | ||
979 | * Setup | ||
980 | */ | ||
981 | |||
982 | /* | ||
983 | * Only necessary if your driver takes special options, | ||
984 | * otherwise we fall back on the generic fb_setup(). | ||
985 | */ | ||
986 | int __init xxxfb_setup(char *options) | ||
987 | { | ||
988 | /* Parse user specified options (`video=xxxfb:') */ | ||
989 | } | ||
990 | #endif /* MODULE */ | ||
991 | |||
992 | static int __init xxxfb_init(void) | ||
993 | { | ||
994 | int ret; | ||
995 | /* | ||
996 | * For kernel boot options (in 'video=xxxfb:<options>' format) | ||
997 | */ | ||
998 | #ifndef MODULE | ||
999 | char *option = NULL; | ||
1000 | |||
1001 | if (fb_get_options("xxxfb", &option)) | ||
1002 | return -ENODEV; | ||
1003 | xxxfb_setup(option); | ||
1004 | #endif | ||
1005 | ret = platform_driver_register(&xxxfb_driver); | ||
1006 | |||
1007 | if (!ret) { | ||
1008 | xxxfb_device = platform_device_register_simple("xxxfb", 0, | ||
1009 | NULL, 0); | ||
1010 | |||
1011 | if (IS_ERR(xxxfb_device)) { | ||
1012 | platform_driver_unregister(&xxxfb_driver); | ||
1013 | ret = PTR_ERR(xxxfb_device); | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | return ret; | ||
1018 | } | ||
1019 | |||
1020 | static void __exit xxxfb_exit(void) | ||
1021 | { | ||
1022 | platform_device_unregister(xxxfb_device); | ||
1023 | platform_driver_unregister(&xxxfb_driver); | ||
1024 | } | ||
1025 | #endif /* CONFIG_PCI */ | ||
1026 | |||
1027 | /* ------------------------------------------------------------------------- */ | ||
1028 | |||
1029 | |||
1030 | /* | ||
1031 | * Modularization | ||
1032 | */ | ||
1033 | |||
1034 | module_init(xxxfb_init); | ||
1035 | module_exit(xxxfb_exit); | ||
1036 | |||
1037 | MODULE_LICENSE("GPL"); | ||