2 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
4 * Created 28 Dec 1997 by Geert Uytterhoeven
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
16 #include <linux/tty.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
20 #include <linux/init.h>
22 #include <video/fbcon.h>
26 * This is just simple sample code.
28 * No warranty that it actually compiles.
29 * Even less warranty that it actually works :-)
35 * Choose _one_ of the two alternatives:
37 * 1. Use the generic frame buffer operations (fbgen_*).
39 struct fb_info_gen gen;
41 * 2. Provide your own frame buffer operations.
45 /* Here starts the frame buffer device dependent part */
46 /* You can use this to store e.g. the board number if you support */
53 * The hardware specific data in this structure uniquely defines a video
56 * If your hardware supports only one video mode, you can leave it empty.
62 * If your driver supports multiple boards, you should make these arrays,
63 * or allocate them dynamically (using kmalloc()).
66 static struct xxxfb_info fb_info;
67 static struct xxxfb_par current_par;
68 static int current_par_valid = 0;
69 static struct display disp;
71 static struct fb_var_screeninfo default_var;
73 static int currcon = 0;
74 static int inverse = 0;
77 int xxxfb_setup(char*);
79 /* ------------------- chipset specific functions -------------------------- */
82 static void xxx_detect(void)
85 * This function should detect the current video mode settings and store
86 * it as the default video mode
93 xxx_encode_var(&default_var, &par);
96 static int xxx_encode_fix(struct fb_fix_screeninfo *fix, struct xxxfb_par *par,
97 const struct fb_info *info)
100 * This function should fill in the 'fix' structure based on the values
101 * in the `par' structure.
108 static int xxx_decode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
109 const struct fb_info *info)
112 * Get the video params out of 'var'. If a value doesn't fit, round it up,
113 * if it's too big, return -EINVAL.
115 * Suggestion: Round up in the following order: bits_per_pixel, xres,
116 * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
117 * bitfields, horizontal timing, vertical timing.
122 /* pixclock in picos, htotal in pixels, vtotal in scanlines */
123 if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
129 static int xxx_encode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
130 const struct fb_info *info)
133 * Fill the 'var' structure based on the values in 'par' and maybe other
134 * values read out of the hardware.
141 static void xxx_get_par(struct xxxfb_par *par, const struct fb_info *info)
144 * Fill the hardware's 'par' structure.
147 if (current_par_valid)
154 static void xxx_set_par(struct xxxfb_par *par, const struct fb_info *info)
157 * Set the hardware according to 'par'.
161 current_par_valid = 1;
165 static int xxx_getcolreg(unsigned regno, unsigned *red, unsigned *green,
166 unsigned *blue, unsigned *transp,
167 const struct fb_info *info)
170 * Read a single color register and split it into colors/transparent.
171 * The return values must have a 16 bit magnitude.
172 * Return != 0 for invalid regno.
179 static int xxx_setcolreg(unsigned regno, unsigned red, unsigned green,
180 unsigned blue, unsigned transp,
181 const struct fb_info *info)
184 * Set a single color register. The values supplied have a 16 bit
186 * Return != 0 for invalid regno.
191 * Make the first 16 colors of the palette available to fbcon
193 if (is_cfb15) /* RGB 555 */
194 ...fbcon_cmap.cfb16[regno] = ((red & 0xf800) >> 1) |
195 ((green & 0xf800) >> 6) |
196 ((blue & 0xf800) >> 11);
197 if (is_cfb16) /* RGB 565 */
198 ...fbcon_cmap.cfb16[regno] = (red & 0xf800) |
199 ((green & 0xfc00) >> 5) |
200 ((blue & 0xf800) >> 11);
201 if (is_cfb24) /* RGB 888 */
202 ...fbcon_cmap.cfb24[regno] = ((red & 0xff00) << 8) |
204 ((blue & 0xff00) >> 8);
205 if (is_cfb32) /* RGBA 8888 */
206 ...fbcon_cmap.cfb32[regno] = ((red & 0xff00) << 16) |
207 ((green & 0xff00) << 8) |
209 ((transp & 0xff00) >> 8);
215 static int xxx_pan_display(struct fb_var_screeninfo *var,
216 struct xxxfb_par *par, const struct fb_info *info)
219 * Pan (or wrap, depending on the `vmode' field) the display using the
220 * `xoffset' and `yoffset' fields of the `var' structure.
221 * If the values don't fit, return -EINVAL.
228 static int xxx_blank(int blank_mode, const struct fb_info *info)
231 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
232 * then the caller blanks by setting the CLUT (Color Look Up Table) to all
233 * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
234 * to e.g. a video mode which doesn't support it. Implements VESA suspend
235 * and powerdown modes on hardware that supports disabling hsync/vsync:
236 * blank_mode == 2: suspend vsync
237 * blank_mode == 3: suspend hsync
238 * blank_mode == 4: powerdown
245 static void xxx_set_disp(const void *par, struct display *disp,
246 struct fb_info_gen *info)
249 * Fill in a pointer with the virtual address of the mapped frame buffer.
250 * Fill in a pointer to appropriate low level text console operations (and
251 * optionally a pointer to help data) for the video mode `par' of your
252 * video hardware. These can be generic software routines, or hardware
253 * accelerated routines specifically tailored for your hardware.
254 * If you don't have any appropriate operations, you must fill in a
255 * pointer to dummy operations, and there will be no text output.
257 disp->screen_base = virtual_frame_buffer_address;
258 #ifdef FBCON_HAS_CFB8
260 disp->dispsw = fbcon_cfb8;
263 #ifdef FBCON_HAS_CFB16
265 disp->dispsw = fbcon_cfb16;
266 disp->dispsw_data = ...fbcon_cmap.cfb16; /* console palette */
269 #ifdef FBCON_HAS_CFB24
271 disp->dispsw = fbcon_cfb24;
272 disp->dispsw_data = ...fbcon_cmap.cfb24; /* console palette */
275 #ifdef FBCON_HAS_CFB32
277 disp->dispsw = fbcon_cfb32;
278 disp->dispsw_data = ...fbcon_cmap.cfb32; /* console palette */
281 disp->dispsw = &fbcon_dummy;
285 /* ------------ Interfaces to hardware functions ------------ */
288 struct fbgen_hwswitch xxx_switch = {
289 xxx_detect, xxx_encode_fix, xxx_decode_var, xxx_encode_var, xxx_get_par,
290 xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_pan_display, xxx_blank,
296 /* ------------ Hardware Independent Functions ------------ */
303 int __init xxxfb_init(void)
305 fb_info.gen.fbhw = &xxx_switch;
306 fb_info.gen.fbhw->detect();
307 strcpy(fb_info.gen.info.modename, "XXX");
308 fb_info.gen.info.changevar = NULL;
309 fb_info.gen.info.node = -1;
310 fb_info.gen.info.fbops = &xxxfb_ops;
311 fb_info.gen.info.disp = &disp;
312 fb_info.gen.info.switch_con = &xxxfb_switch;
313 fb_info.gen.info.updatevar = &xxxfb_update_var;
314 fb_info.gen.info.blank = &xxxfb_blank;
315 fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
316 /* This should give a reasonable default video mode */
317 fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
318 fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
319 fbgen_set_disp(-1, &fb_info.gen);
320 fbgen_install_cmap(0, &fb_info.gen);
321 if (register_framebuffer(&fb_info.gen.info) < 0)
323 printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
324 fb_info.gen.info.modename);
326 /* uncomment this if your driver cannot be unloaded */
327 /* MOD_INC_USE_COUNT; */
336 void xxxfb_cleanup(struct fb_info *info)
339 * If your driver supports multiple boards, you should unregister and
340 * clean up all instances.
343 unregister_framebuffer(info);
352 int __init xxxfb_setup(char *options)
354 /* Parse user speficied options (`video=xxxfb:') */
358 /* ------------------------------------------------------------------------- */
362 * Frame buffer operations
365 /* If all you need is that - just don't define ->fb_open */
366 static int xxxfb_open(const struct fb_info *info, int user)
371 /* If all you need is that - just don't define ->fb_release */
372 static int xxxfb_release(const struct fb_info *info, int user)
379 * In most cases the `generic' routines (fbgen_*) should be satisfactory.
380 * However, you're free to fill in your own replacements.
383 static struct fb_ops xxxfb_ops = {
385 fb_open: xxxfb_open, /* only if you need it to do something */
386 fb_release: xxxfb_release, /* only if you need it to do something */
387 fb_get_fix: fbgen_get_fix,
388 fb_get_var: fbgen_get_var,
389 fb_set_var: fbgen_set_var,
390 fb_get_cmap: fbgen_get_cmap,
391 fb_set_cmap: fbgen_set_cmap,
392 fb_pan_display: fbgen_pan_display,
393 fb_ioctl: xxxfb_ioctl, /* optional */
397 /* ------------------------------------------------------------------------- */
405 MODULE_LICENSE("GPL");
406 int init_module(void)
411 void cleanup_module(void)