linux-old/drivers/video/skeletonfb.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
   3 *
   4 *  Created 28 Dec 1997 by Geert Uytterhoeven
   5 *
   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
   8 * for more details.
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/kernel.h>
  13#include <linux/errno.h>
  14#include <linux/string.h>
  15#include <linux/mm.h>
  16#include <linux/tty.h>
  17#include <linux/slab.h>
  18#include <linux/delay.h>
  19#include <linux/fb.h>
  20#include <linux/init.h>
  21
  22#include <video/fbcon.h>
  23
  24
  25    /*
  26     *  This is just simple sample code.
  27     *
  28     *  No warranty that it actually compiles.
  29     *  Even less warranty that it actually works :-)
  30     */
  31
  32
  33struct xxxfb_info {
  34    /*
  35     *  Choose _one_ of the two alternatives:
  36     *
  37     *    1. Use the generic frame buffer operations (fbgen_*).
  38     */
  39    struct fb_info_gen gen;
  40    /*
  41     *    2. Provide your own frame buffer operations.
  42     */
  43    struct fb_info info;
  44
  45    /* Here starts the frame buffer device dependent part */
  46    /* You can use this to store e.g. the board number if you support */
  47    /* multiple boards */
  48};
  49
  50
  51struct xxxfb_par {
  52    /*
  53     *  The hardware specific data in this structure uniquely defines a video
  54     *  mode.
  55     *
  56     *  If your hardware supports only one video mode, you can leave it empty.
  57     */
  58};
  59
  60
  61    /*
  62     *  If your driver supports multiple boards, you should make these arrays,
  63     *  or allocate them dynamically (using kmalloc()).
  64     */
  65
  66static struct xxxfb_info fb_info;
  67static struct xxxfb_par current_par;
  68static int current_par_valid = 0;
  69static struct display disp;
  70
  71static struct fb_var_screeninfo default_var;
  72
  73static int currcon = 0;
  74static int inverse = 0;
  75
  76int xxxfb_init(void);
  77int xxxfb_setup(char*);
  78
  79/* ------------------- chipset specific functions -------------------------- */
  80
  81
  82static void xxx_detect(void)
  83{
  84    /*
  85     *  This function should detect the current video mode settings and store
  86     *  it as the default video mode
  87     */
  88
  89    struct xxxfb_par par;
  90
  91    /* ... */
  92    xxx_get_par(&par);
  93    xxx_encode_var(&default_var, &par);
  94}
  95
  96static int xxx_encode_fix(struct fb_fix_screeninfo *fix, struct xxxfb_par *par,
  97                          const struct fb_info *info)
  98{
  99    /*
 100     *  This function should fill in the 'fix' structure based on the values
 101     *  in the `par' structure.
 102     */
 103
 104    /* ... */
 105    return 0;
 106}
 107
 108static int xxx_decode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
 109                          const struct fb_info *info)
 110{
 111    /*
 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.
 114     *
 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.
 118     */
 119
 120    /* ... */
 121
 122    /* pixclock in picos, htotal in pixels, vtotal in scanlines */
 123    if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
 124            return -EINVAL;
 125
 126    return 0;
 127}
 128
 129static int xxx_encode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
 130                          const struct fb_info *info)
 131{
 132    /*
 133     *  Fill the 'var' structure based on the values in 'par' and maybe other
 134     *  values read out of the hardware.
 135     */
 136
 137    /* ... */
 138    return 0;
 139}
 140
 141static void xxx_get_par(struct xxxfb_par *par, const struct fb_info *info)
 142{
 143    /*
 144     *  Fill the hardware's 'par' structure.
 145     */
 146
 147    if (current_par_valid)
 148        *par = current_par;
 149    else {
 150        /* ... */
 151    }
 152}
 153
 154static void xxx_set_par(struct xxxfb_par *par, const struct fb_info *info)
 155{
 156    /*
 157     *  Set the hardware according to 'par'.
 158     */
 159
 160    current_par = *par;
 161    current_par_valid = 1;
 162    /* ... */
 163}
 164
 165static int xxx_getcolreg(unsigned regno, unsigned *red, unsigned *green,
 166                         unsigned *blue, unsigned *transp,
 167                         const struct fb_info *info)
 168{
 169    /*
 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.
 173     */
 174
 175    /* ... */
 176    return 0;
 177}
 178
 179static int xxx_setcolreg(unsigned regno, unsigned red, unsigned green,
 180                         unsigned blue, unsigned transp,
 181                         const struct fb_info *info)
 182{
 183    /*
 184     *  Set a single color register. The values supplied have a 16 bit
 185     *  magnitude.
 186     *  Return != 0 for invalid regno.
 187     */
 188
 189    if (regno < 16) {
 190        /*
 191         *  Make the first 16 colors of the palette available to fbcon
 192         */
 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) |
 203                                         (green & 0xff00) |
 204                                         ((blue & 0xff00) >> 8);
 205        if (is_cfb32)           /* RGBA 8888 */
 206            ...fbcon_cmap.cfb32[regno] = ((red & 0xff00) << 16) |
 207                                         ((green & 0xff00) << 8) |
 208                                         (blue & 0xff00) |
 209                                         ((transp & 0xff00) >> 8);
 210    }
 211    /* ... */
 212    return 0;
 213}
 214
 215static int xxx_pan_display(struct fb_var_screeninfo *var,
 216                           struct xxxfb_par *par, const struct fb_info *info)
 217{
 218    /*
 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.
 222     */
 223
 224    /* ... */
 225    return 0;
 226}
 227
 228static int xxx_blank(int blank_mode, const struct fb_info *info)
 229{
 230    /*
 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
 239     */
 240
 241    /* ... */
 242    return 0;
 243}
 244
 245static void xxx_set_disp(const void *par, struct display *disp,
 246                         struct fb_info_gen *info)
 247{
 248    /*
 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.
 256     */
 257    disp->screen_base = virtual_frame_buffer_address;
 258#ifdef FBCON_HAS_CFB8
 259    if (is_cfb8) {
 260        disp->dispsw = fbcon_cfb8;
 261    } else
 262#endif
 263#ifdef FBCON_HAS_CFB16
 264    if (is_cfb16) {
 265        disp->dispsw = fbcon_cfb16;
 266        disp->dispsw_data = ...fbcon_cmap.cfb16;        /* console palette */
 267    } else
 268#endif
 269#ifdef FBCON_HAS_CFB24
 270    if (is_cfb24) {
 271        disp->dispsw = fbcon_cfb24;
 272        disp->dispsw_data = ...fbcon_cmap.cfb24;        /* console palette */
 273    } else
 274#endif
 275#ifdef FBCON_HAS_CFB32
 276    if (is_cfb32) {
 277        disp->dispsw = fbcon_cfb32;
 278        disp->dispsw_data = ...fbcon_cmap.cfb32;        /* console palette */
 279    } else
 280#endif
 281        disp->dispsw = &fbcon_dummy;
 282}
 283
 284
 285/* ------------ Interfaces to hardware functions ------------ */
 286
 287
 288struct 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,
 291    xxx_set_disp
 292};
 293
 294
 295
 296/* ------------ Hardware Independent Functions ------------ */
 297
 298
 299    /*
 300     *  Initialization
 301     */
 302
 303int __init xxxfb_init(void)
 304{
 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)
 322        return -EINVAL;
 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);
 325
 326    /* uncomment this if your driver cannot be unloaded */
 327    /* MOD_INC_USE_COUNT; */
 328    return 0;
 329}
 330
 331
 332    /*
 333     *  Cleanup
 334     */
 335
 336void xxxfb_cleanup(struct fb_info *info)
 337{
 338    /*
 339     *  If your driver supports multiple boards, you should unregister and
 340     *  clean up all instances.
 341     */
 342
 343    unregister_framebuffer(info);
 344    /* ... */
 345}
 346
 347
 348    /*
 349     *  Setup
 350     */
 351
 352int __init xxxfb_setup(char *options)
 353{
 354    /* Parse user speficied options (`video=xxxfb:') */
 355}
 356
 357
 358/* ------------------------------------------------------------------------- */
 359
 360
 361    /*
 362     *  Frame buffer operations
 363     */
 364
 365/* If all you need is that - just don't define ->fb_open */
 366static int xxxfb_open(const struct fb_info *info, int user)
 367{
 368    return 0;
 369}
 370
 371/* If all you need is that - just don't define ->fb_release */
 372static int xxxfb_release(const struct fb_info *info, int user)
 373{
 374    return 0;
 375}
 376
 377
 378    /*
 379     *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
 380     *  However, you're free to fill in your own replacements.
 381     */
 382
 383static struct fb_ops xxxfb_ops = {
 384        owner:          THIS_MODULE,
 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 */
 394};
 395
 396
 397/* ------------------------------------------------------------------------- */
 398
 399
 400    /*
 401     *  Modularization
 402     */
 403
 404#ifdef MODULE
 405MODULE_LICENSE("GPL");
 406int init_module(void)
 407{
 408    return xxxfb_init();
 409}
 410
 411void cleanup_module(void)
 412{
 413    xxxfb_cleanup(void);
 414}
 415#endif /* MODULE */
 416
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.