zoukankan      html  css  js  c++  java
  • 驱动硬件Framebuffer驱动程序框架 skeletonfb.c 分析

    新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正

        Framebuffer驱动程序框架 skeletonfb.c 析分

        近来想好好研究一下lcd驱动发开程过,lcd驱动发开重要就是framebuffer的编写了,这里只要想做framebuffer驱动的发开可能这里是必经之路,因为这里这个skeletnfb.c是framebuffer驱动程序发开的骨架,他没有体具去实现任何能功,没有针对任何设备,但是,他的作用却非常惊人,他就是使用说明档文一样,教你怎样一步一步行进framebuffer驱动编写

        写贴出这个构架的实现程过,面下再渐渐析分:

        这里就开始渐渐啃一啃这个硬骨架吧

        

    1. /*
    2.  * linux/drivers/video/skeletonfb.-- 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. #include <linux/module.h>
    45. #include <linux/kernel.h>
    46. #include <linux/errno.h>
    47. #include <linux/string.h>
    48. #include <linux/mm.h>
    49. #include <linux/slab.h>
    50. #include <linux/delay.h>
    51. #include <linux/fb.h>
    52. #include <linux/init.h>
    53. #include <linux/pci.h>

    54. /*
    55.  * This is just simple sample code.
    56.  * No warranty that it actually compiles.
    57.  * Even less warranty that it actually works :-)
    58.  */

    59. /*
    60.  * Driver data
    61.  */
    62. static char *mode_option __devinitdata;

    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.  * This structure defines the hardware state of the graphics card. Normally
    69.  * you place this in a header file in linux/include/video. This file usually
    70.  * also includes register information. That allows other driver subsystems
    71.  * and userland applications the ability to use the same header file to 
    72.  * avoid duplicate work and easy porting of software. 
    73.  */
    74. struct xxx_par;

    75. /*
    76.  * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
    77.  * if we don't use modedb. If we do use modedb see xxxfb_init how to use it
    78.  * to get a fb_var_screeninfo. Otherwise define a default var as well. 
    79.  */
    80. static struct fb_fix_screeninfo xxxfb_fix __devinitdata = {
    81.     .id =        "FB's name", 
    82.     .type =        FB_TYPE_PACKED_PIXELS,
    83.     .visual =    FB_VISUAL_PSEUDOCOLOR,
    84.     .xpanstep =    1,
    85.     .ypanstep =    1,
    86.     .ywrapstep = 1, 
    87.     .accel =    FB_ACCEL_NONE,
    88. };

    89. /*
    90.  * Modern graphical hardware not only supports pipelines but some 
    91.  * also support multiple monitors where each display can have its 
    92.  * its own unique data. In this case each display could be 
    93.  * represented by a separate framebuffer device thus a separate 
    94.  * struct fb_info. Now the struct xxx_par represents the graphics
    95.  * hardware state thus only one exist per card. In this case the 
    96.  * struct xxx_par for each graphics card would be shared between 
    97.  * every struct fb_info that represents a framebuffer on that card. 
    98.  * This allows when one display changes it video resolution (info->var) 
    99.  * the other displays know instantly. Each display can always be
    100.  * aware of the entire hardware state that affects it because they share
    101.  * the same xxx_par struct. The other side of the coin is multiple
    102.  * graphics cards that pass data around until it is finally displayed
    103.  * on one monitor. Such examples are the voodoo 1 cards and high end
    104.  * NUMA graphics servers. For this case we have a bunch of pars, each
    105.  * one that represents a graphics state, that belong to one struct 
    106.  * fb_info. Their you would want to have *par point to a array of device
    107.  * states and have each struct fb_ops function deal with all those 
    108.  * states. I hope this covers every possible hardware design. If not
    109.  * feel free to send your ideas at jsimmons@users.sf.net 
    110.  */

    111. /*
    112.  * If your driver supports multiple boards or it supports multiple 
    113.  * framebuffers, you should make these arrays, or allocate them 
    114.  * dynamically using framebuffer_alloc() and free them with
    115.  * framebuffer_release().
    116.  */ 
    117. static struct fb_info info;

    118. /* 
    119.  * Each one represents the state of the hardware. Most hardware have
    120.  * just one hardware state. These here represent the default state(s). 
    121.  */
    122. static struct xxx_par __initdata current_par;

    123. int xxxfb_init(void);

    124. /**
    125.  *    xxxfb_open - Optional function. Called when the framebuffer is first accessed.
    126.  *    @info: frame buffer structure that represents a single frame buffer
    127.  *    @user: tell us if the userland (value=1) or the console is accessing the framebuffer. 
    128.  *
    129.  *    This function is the first function called in the framebuffer api.
    130.  *    Usually you don't need to provide this function. The case where it 
    131.  *    is used is to change from a text mode hardware state to a graphics
    132.  *     mode state. 
    133.  *
    134.  *    Returns negative errno on error, or zero on success.
    135.  */
    136. static int xxxfb_open(struct fb_info *info, int user)
    137. {
    138.     return 0;
    139. }

    140. /**
    141.  *    xxxfb_release - Optional function. Called when the framebuffer device is closed. 
    142.  *    @info: frame buffer structure that represents a single frame buffer
    143.  *    @user: tell us if the userland (value=1) or the console is accessing the framebuffer. 
    144.  *    
    145.  *    Thus function is called when we close /dev/fb or the framebuffer 
    146.  *    console system is released. Usually you don't need this function.
    147.  *    The case where it is usually used is to go from a graphics state
    148.  *    to a text mode state.
    149.  *
    150.  *    Returns negative errno on error, or zero on success.
    151.  */
    152. static int xxxfb_release(struct fb_info *info, int user)
    153. {
    154.     return 0;
    155. }

    156. /**
    157.  * xxxfb_check_var - Optional function. Validates a var passed in. 
    158.  * @var: frame buffer variable screen structure
    159.  * @info: frame buffer structure that represents a single frame buffer 
    160.  *    检查我们传入的var是不是是硬件支持的属性,这个法方不变改硬件,也就是fb_info中保存的data不会变改
    161.       这个法方用在我们只是想测试一下硬件,但并非真正设置硬件属性
    162.  *    Checks to see if the hardware supports the state requested by
    163.  *    var passed in. This function does not alter the hardware 
    164.  *    This means the data stored in struct fb_info and struct xxx_par do 
    165.  *    not change. This includes the var inside of struct fb_info. 
    166.  *    Do NOT change these. This function can be called on its own if we
    167.  *    intent to only test a mode and not actually set it. The stuff in 
    168.  *    modedb.is a example of this. If the var passed in is slightly 
    169.  *    off by what the hardware can support then we alter the var PASSED in
    170.  *    to what we can do.
    171.  *
    172.  * For values that are off, this function must round them _up_ to the
    173.  * next value that is supported by the hardware. If the value is
    174.  * greater than the highest value supported by the hardware, then this
    175.  * function must return -EINVAL.
    176.  *
    177.  * Exception to the above rule: Some drivers have a fixed mode, ie,
    178.  * the hardware is already set at boot up, and cannot be changed. In
    179.  * this case, it is more acceptable that this function just return
    180.  * a copy of the currently working var (info->var). Better is to not
    181.  * implement this function, as the upper layer will do the copying
    182.  * of the current var for you.
    183.  *
    184.  * Note: This is the only function where the contents of var can be
    185.  * freely adjusted after the driver has been registered. If you find
    186.  * that you have code outside of this function that alters the content
    187.  * of var, then you are doing something wrong. Note also that the
    188.  * contents of info->var must be left untouched at all times after
    189.  * driver registration.
    190.  *
    191.  *    Returns negative errno on error, or zero on success.
    192.  */
    193. static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
    194. {
    195.     /* ... */
    196.     return 0;         
    197. }

    198. /**
    199.  * xxxfb_set_par - Optional function. Alters the hardware state.
    200.  * @info: frame buffer structure that represents a single frame buffer
    201.  *    使用这个法方是用来设置framebuffer属性的,会变改fb_info中的par和fb_fix_screeinfo数据,
    202.       但是不变改var的数据
    203.  *    Using the fb_var_screeninfo in fb_info we set the resolution of the
    204.  *    this particular framebuffer. This function alters the par AND the
    205.  *    fb_fix_screeninfo stored in fb_info. It doesn'not alter var in 
    206.  *    fb_info since we are using that data. This means we depend on the
    207.  *    data in var inside fb_info to be supported by the hardware. 
    208.  *
    209.  * This function is also used to recover/restore the hardware to a
    210.  * known working state.
    211.  *
    212.  *    xxxfb_check_var is always called before xxxfb_set_par to ensure that
    213.  * the contents of var is always valid.
    214.  *
    215.  *    Again if you can't change the resolution you don't need this function.
    216.  *
    217.  * However, even if your hardware does not support mode changing,
    218.  * a set_par might be needed to at least initialize the hardware to
    219.  * a known working state, especially if it came back from another
    220.  * process that also modifies the same hardware, such as X.
    221.  *
    222.  * If this is the case, a combination such as the following should work:
    223.  *
    224.  * static int xxxfb_check_var(struct fb_var_screeninfo *var,
    225.  * struct fb_info *info)
    226.  * {
    227.  * *var = info->var;
    228.  * return 0;
    229.  * }
    230.  *
    231.  * static int xxxfb_set_par(struct fb_info *info)
    232.  * {
    233.  * init your hardware here
    234.  * }
    235.  *
    236.  *    Returns negative errno on error, or zero on success.
    237.  */
    238. static int xxxfb_set_par(struct fb_info *info)
    239. {
    240.     struct xxx_par *par = info->par;
    241.     /* ... */
    242.     return 0;    
    243. }

    244. /**
    245.  *     xxxfb_setcolreg - Optional function. Sets a color register.
    246.  * @regno: Which register in the CLUT we are programming 
    247.  * @red: The red value which can be up to 16 bits wide 
    248.  *    @green: The green value which can be up to 16 bits wide 
    249.  *    @blue: The blue value which can be up to 16 bits wide.
    250.  *    @transp: If supported, the alpha value which can be up to 16 bits wide.
    251.  * @info: frame buffer info structure
    252.  * 
    253.  *     Set a single color register. The values supplied have a 16 bit
    254.  *     magnitude which needs to be scaled in this function for the hardware. 
    255.  *    Things to take into consideration are how many color registers, if
    256.  *    any, are supported with the current color visual. With truecolor mode
    257.  *    no color palettes are supported. Here a pseudo palette is created
    258.  *    which we store the value in pseudo_palette in struct fb_info. For
    259.  *    pseudocolor mode we have a limited color palette. To deal with this
    260.  *    we can program what color is displayed for a particular pixel value.
    261.  *    DirectColor is similar in that we can program each color field. If
    262.  *    we have a static colormap we don't need to implement this function. 
    263.  * 
    264.  *    Returns negative errno on error, or zero on success.
    265.  */
    266. static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
    267.              unsigned blue, unsigned transp,
    268.              struct fb_info *info)
    269. {
    270.     if (regno >= 256) /* no. of hw registers */
    271.        return -EINVAL;
    272.     /*
    273.      * Program hardware... do anything you want with transp
    274.      */

    275.     /* grayscale works only partially under directcolor */
    276.     if (info->var.grayscale) {
    277.        /* grayscale = 0.30*+ 0.59*+ 0.11**/
    278.        red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
    279.     }

    280.     /* Directcolor:
    281.      * var->{color}.offset contains start of bitfield
    282.      * var->{color}.length contains length of bitfield
    283.      * {hardwarespecific} contains width of DAC
    284.      * pseudo_palette[X] is programmed to (<< red.offset) |
    285.      * (<< green.offset) |
    286.      * (<< blue.offset)
    287.      * RAMDAC[X] is programmed to (red, green, blue)
    288.      * color depth = SUM(var->{color}.length)
    289.      *
    290.      *     Pseudocolor:
    291.      * var->{color}.offset is 0 unless the palette index takes less than
    292.      * bits_per_pixel bits and is stored in the upper
    293.      * bits of the pixel value
    294.      * var->{color}.length is set so that 1 << length is the number of
    295.      * available palette entries
    296.      * pseudo_palette is not used
    297.      * RAMDAC[X] is programmed to (red, green, blue)
    298.      * color depth = var->{color}.length
    299.      *
    300.      *     Static pseudocolor:
    301.      * same as Pseudocolor, but the RAMDAC is not programmed (read-only)
    302.      *
    303.      *     Mono01/Mono10:
    304.      * Has only 2 values, black on white or white on black (fg on bg),
    305.      * var->{color}.offset is 0
    306.      * white = (<< var->{color}.length) - 1, black = 0
    307.      * pseudo_palette is not used
    308.      * RAMDAC does not exist
    309.      * color depth is always 2
    310.      *
    311.      *     Truecolor:
    312.      * does not use RAMDAC (usually has 3 of them).
    313.      * var->{color}.offset contains start of bitfield
    314.      * var->{color}.length contains length of bitfield
    315.      * pseudo_palette is programmed to (red << red.offset) |
    316.      * (green << green.offset) |
    317.      * (blue << blue.offset) |
    318.      * (transp << transp.offset)
    319.      * RAMDAC does not exist
    320.      * color depth = SUM(var->{color}.length})
    321.      *
    322.      *     The color depth is used by fbcon for choosing the logo and also
    323.      *     for color palette transformation if color depth < 4
    324.      *
    325.      *    As can be seen from the above, the field bits_per_pixel is _NOT_
    326.      *    a criteria for describing the color visual.
    327.      *
    328.      *    A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor,
    329.      *    and higher than that, true/directcolor. This is incorrect, one needs
    330.      *    to look at the fix->visual.
    331.      *
    332.      *     Another common mistake is using bits_per_pixel to calculate the color
    333.      *     depth. The bits_per_pixel field does not directly translate to color
    334.      *     depth. You have to compute for the color depth (using the color
    335.      *     bitfields) and fix->visual as seen above.
    336.      */

    337.     /*
    338.      *     This is the point where the color is converted to something that
    339.      *     is acceptable by the hardware.
    340.      */
    341. #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
    342.     red = CNVT_TOHW(red, info->var.red.length);
    343.     green = CNVT_TOHW(green, info->var.green.length);
    344.     blue = CNVT_TOHW(blue, info->var.blue.length);
    345.     transp = CNVT_TOHW(transp, info->var.transp.length);
    346. #undef CNVT_TOHW
    347.     /*
    348.      * This is the point where the function feeds the color to the hardware
    349.      * palette after converting the colors to something acceptable by
    350.      * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and
    351.      * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette.
    352.      * If you have code that writes to the hardware CLUT, and it'not
    353.      * any of the above visuals, then you are doing something wrong.
    354.      */
    355.     if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
    356.     info->fix.visual == FB_VISUAL_TRUECOLOR)
    357.      write_{red|green|blue|transp}_to_clut();

    358.     /*This is the point were you need to fill up the contents of
    359.      * info->pseudo_palette. This structure is used _only_ by fbcon, thus
    360.      * it only contains 16 entries to match the number of colors supported
    361.      * by the console. The pseudo_palette is used only if the visual is
    362.      * in directcolor or truecolor mode. With other visuals, the
    363.      * pseudo_palette is not used. (This might change in the future.)
    364.      *
    365.      * The contents of the pseudo_palette is in raw pixel format. Ie, each
    366.      * entry can be written directly to the framebuffer without any conversion.
    367.      * The pseudo_palette is (void *). However, if using the generic
    368.      * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette
    369.      * must be casted to (u32 *) _regardless_ of the bits per pixel. If the
    370.      * driver is using its own drawing functions, then it can use whatever
    371.      * size it wants.
    372.      */
    373.     if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
    374.     info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
    375.      u32 v;

    376.      if (regno >= 16)
    377.          return -EINVAL;

    378.      v = (red << info->var.red.offset) |
    379.          (green << info->var.green.offset) |
    380.          (blue << info->var.blue.offset) |
    381.          (transp << info->var.transp.offset);

    382.      ((u32*)(info->pseudo_palette))[regno] = v;
    383.     }

    384.     /* ... */
    385.     return 0;
    386. }

    387. /**
    388.  * xxxfb_pan_display - NOT a required function. Pans the display.
    389.  * @var: frame buffer variable screen structure
    390.  * @info: frame buffer structure that represents a single frame buffer
    391.  *
    392.  * Pan (or wrap, depending on the `vmode' field) the display using the
    393.  * 'xoffset' and `yoffset' fields of the `var' structure.
    394.  * If the values don't fit, return -EINVAL.
    395.  *
    396.  * Returns negative errno on error, or zero on success.
    397.  */
    398. static int xxxfb_pan_display(struct fb_var_screeninfo *var,
    399.              struct fb_info *info)
    400. {
    401.     /*
    402.      * If your hardware does not support panning, _do_ _not_ implement this
    403.      * function. Creating a dummy function will just confuse user apps.
    404.      */

    405.     /*
    406.      * Note that even if this function is fully functional, a setting of
    407.      * 0 in both xpanstep and ypanstep means that this function will never
    408.      * get called.
    409.      */

    410.     /* ... */
    411.     return 0;
    412. }

    413. /**
    414.  * xxxfb_blank - NOT a required function. Blanks the display.
    415.  * @blank_mode: the blank mode we want. 
    416.  * @info: frame buffer structure that represents a single frame buffer
    417.  *
    418.  * Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank.
    419.  * Return 0 if blanking succeeded, != 0 if un-/blanking failed due to
    420.  * e.g. a video mode which doesn't support it.
    421.  *
    422.  * Implements VESA suspend and powerdown modes on hardware that supports
    423.  * disabling hsync/vsync:
    424.  *
    425.  * FB_BLANK_NORMAL = display is blanked, syncs are on.
    426.  * FB_BLANK_HSYNC_SUSPEND = hsync off
    427.  * FB_BLANK_VSYNC_SUSPEND = vsync off
    428.  * FB_BLANK_POWERDOWN = hsync and vsync off
    429.  *
    430.  * If implementing this function, at least support FB_BLANK_UNBLANK.
    431.  * Return !for any modes that are unimplemented.
    432.  *
    433.  */
    434. static int xxxfb_blank(int blank_mode, struct fb_info *info)
    435. {
    436.     /* ... */
    437.     return 0;
    438. }

    439. /* ------------ Accelerated Functions --------------------- */

    440. /*
    441.  * We provide our own functions if we have hardware acceleration
    442.  * or non packed pixel format layouts. If we have no hardware 
    443.  * acceleration, we can use a generic unaccelerated function. If using
    444.  * a pack pixel format just use the functions in cfb_*.c. Each file 
    445.  * has one of the three different accel functions we support.
    446.  */

    447. /**
    448.  * xxxfb_fillrect - REQUIRED function. Can use generic routines if 
    449.  *              non acclerated hardware and packed pixel based.
    450.  *             Draws a rectangle on the screen.        
    451.  *
    452.  * @info: frame buffer structure that represents a single frame buffer
    453.  *    @region: The structure representing the rectangular region we 
    454.  *         wish to draw to.
    455.  *
    456.  *    This drawing operation places/removes a retangle on the screen 
    457.  *    depending on the rastering operation with the value of color which
    458.  *    is in the current color depth format.
    459.  */
    460. void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
    461. {
    462. /*    Meaning of struct fb_fillrect
    463.  *
    464.  *    @dx: The x and y corrdinates of the upper left hand corner of the 
    465.  *    @dy: area we want to draw to. 
    466.  *    @width: How wide the rectangle is we want to draw.
    467.  *    @height: How tall the rectangle is we want to draw.
    468.  *    @color:    The color to fill in the rectangle with. 
    469.  *    @rop: The raster operation. We can draw the rectangle with a COPY
    470.  *     of XOR which provides erasing effect. 
    471.  */
    472. }

    473. /**
    474.  * xxxfb_copyarea - REQUIRED function. Can use generic routines if
    475.  * non acclerated hardware and packed pixel based.
    476.  * Copies one area of the screen to another area.
    477.  *
    478.  * @info: frame buffer structure that represents a single frame buffer
    479.  * @area: Structure providing the data to copy the framebuffer contents
    480.  *     from one region to another.
    481.  *
    482.  * This drawing operation copies a rectangular area from one area of the
    483.  *    screen to another area.
    484.  */
    485. void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 
    486. {
    487. /*
    488.  * @dx: The x and y coordinates of the upper left hand corner of the
    489.  *    @dy: destination area on the screen.
    490.  * @width: How wide the rectangle is we want to copy.
    491.  * @height: How tall the rectangle is we want to copy.
    492.  * @sx: The x and y coordinates of the upper left hand corner of the
    493.  * @sy: source area on the screen.
    494.  */
    495. }


    496. /**
    497.  * xxxfb_imageblit - REQUIRED function. Can use generic routines if
    498.  * non acclerated hardware and packed pixel based.
    499.  * Copies a image from system memory to the screen. 
    500.  *
    501.  * @info: frame buffer structure that represents a single frame buffer
    502.  *    @image:    structure defining the image.
    503.  *
    504.  * This drawing operation draws a image on the screen. It can be a 
    505.  *    mono image (needed for font handling) or a color image (needed for
    506.  *    tux). 
    507.  */
    508. void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) 
    509. {
    510. /*
    511.  * @dx: The x and y coordinates of the upper left hand corner of the
    512.  *    @dy: destination area to place the image on the screen.
    513.  * @width: How wide the image is we want to copy.
    514.  * @height: How tall the image is we want to copy.
    515.  * @fg_color: For mono bitmap images this is color data for 
    516.  * @bg_color: the foreground and background of the image to
    517.  *         write directly to the frmaebuffer.
    518.  *    @depth:    How many bits represent a single pixel for this image.
    519.  *    @data: The actual data used to construct the image on the display.
    520.  *    @cmap: The colormap used for color images. 
    521.  */

    522. /*
    523.  * The generic function, cfb_imageblit, expects that the bitmap scanlines are
    524.  * padded to the next byte. Most hardware accelerators may require padding to
    525.  * the next u16 or the next u32. If that is the case, the driver can specify
    526.  * this by setting info->pixmap.scan_align = 2 or 4. See a more
    527.  * comprehensive description of the pixmap below.
    528.  */
    529. }

    530. /**
    531.  *    xxxfb_cursor -     OPTIONAL. If your hardware lacks support
    532.  *            for a cursor, leave this field NULL.
    533.  *
    534.  * @info: frame buffer structure that represents a single frame buffer
    535.  *    @cursor: structure defining the cursor to draw.
    536.  *
    537.  * This operation is used to set or alter the properities of the cursor.
    538.  *
    539.  *    Returns negative errno on error, or zero on success.
    540.  */
    541. int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
    542. {
    543. /*
    544.  * @set:     Which fields we are altering in struct fb_cursor 
    545.  *    @enable: Disable or enable the cursor 
    546.  * @rop:     The bit operation we want to do. 
    547.  * @mask: This is the cursor mask bitmap. 
    548.  * @dest: A image of the area we are going to display the cursor.
    549.  *        Used internally by the driver.     
    550.  * @hot:    The hot spot. 
    551.  *    @image:    The actual data for the cursor image.
    552.  *
    553.  * NOTES ON FLAGS (cursor->set):
    554.  *
    555.  * FB_CUR_SETIMAGE - the cursor image has changed (cursor->image.data)
    556.  * FB_CUR_SETPOS - the cursor position has changed (cursor->image.dx|dy)
    557.  * FB_CUR_SETHOT - the cursor hot spot has changed (cursor->hot.dx|dy)
    558.  * FB_CUR_SETCMAP - the cursor colors has changed (cursor->fg_color|bg_color)
    559.  * FB_CUR_SETSHAPE - the cursor bitmask has changed (cursor->mask)
    560.  * FB_CUR_SETSIZE - the cursor size has changed (cursor->width|height)
    561.  * FB_CUR_SETALL - everything has changed
    562.  *
    563.  * NOTES ON ROPs (cursor->rop, Raster Operation)
    564.  *
    565.  * ROP_XOR - cursor->image.data XOR cursor->mask
    566.  * ROP_COPY - curosr->image.data AND cursor->mask
    567.  *
    568.  * OTHER NOTES:
    569.  *
    570.  * - fbcon only supports a 2-color cursor (cursor->image.depth = 1)
    571.  * - The fb_cursor structure, @cursor, _will_ always contain valid
    572.  * fields, whether any particular bitfields in cursor->set is set
    573.  * or not.
    574.  */
    575. }

    576. /**
    577.  *    xxxfb_rotate - NOT a required function. If your hardware
    578.  *            supports rotation the whole screen then 
    579.  *            you would provide a hook for this. 
    580.  *
    581.  * @info: frame buffer structure that represents a single frame buffer
    582.  *    @angle: The angle we rotate the screen. 
    583.  *
    584.  * This operation is used to set or alter the properities of the
    585.  *    cursor.
    586.  */
    587. void xxxfb_rotate(struct fb_info *info, int angle)
    588. {
    589. /* Will be deprecated */
    590. }

    591. /**
    592.  *    xxxfb_sync - NOT a required function. Normally the accel engine 
    593.  *         for a graphics card take a specific amount of time.
    594.  *         Often we have to wait for the accelerator to finish
    595.  *         its operation before we can write to the framebuffer
    596.  *         so we can have consistent display output. 
    597.  *
    598.  * @info: frame buffer structure that represents a single frame buffer
    599.  *
    600.  * If the driver has implemented its own hardware-based drawing function,
    601.  * implementing this function is highly recommended.
    602.  */
    603. int xxxfb_sync(struct fb_info *info)
    604. {
    605.     return 0;
    606. }

    607.     /*
    608.      * Frame buffer operations
    609.      */

    610. static struct fb_ops xxxfb_ops = {
    611.     .owner        = THIS_MODULE,
    612.     .fb_open    = xxxfb_open,
    613.     .fb_read    = xxxfb_read,
    614.     .fb_write    = xxxfb_write,
    615.     .fb_release    = xxxfb_release,
    616.     .fb_check_var    = xxxfb_check_var,
    617.     .fb_set_par    = xxxfb_set_par,
    618.     .fb_setcolreg    = xxxfb_setcolreg,
    619.     .fb_blank    = xxxfb_blank,
    620.     .fb_pan_display    = xxxfb_pan_display,
    621.     .fb_fillrect    = xxxfb_fillrect,     /* Needed !!! */
    622.     .fb_copyarea    = xxxfb_copyarea,    /* Needed !!! */
    623.     .fb_imageblit    = xxxfb_imageblit,    /* Needed !!! */
    624.     .fb_cursor    = xxxfb_cursor,        /* Optional !!! */
    625.     .fb_rotate    = xxxfb_rotate,
    626.     .fb_sync    = xxxfb_sync,
    627.     .fb_ioctl    = xxxfb_ioctl,
    628.     .fb_mmap    = xxxfb_mmap,
    629. };

    630. /* ------------------------------------------------------------------------- */

    631. /*
    632.  * Initialization
    633.  */
    634. 这里他们的定义是不一样的,唯一的不同
    635. /* static int __init xxfb_probe (struct platform_device *pdev) -- for platform devs */
    636. static int __devinit xxxfb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
    637. {
    638.     struct fb_info *info;
    639.     struct xxx_par *par;
    640.     struct device *device = &dev->dev; /* or &pdev->dev */
    641.     int cmap_len, retval;    
    642.    
    643.     /*
    644.      * Dynamically allocate info and par
    645.      */
    646.     info = framebuffer_alloc(sizeof(struct xxx_par), device);

    647.     if (!info) {
    648.      /* goto error path */
    649.     }

    650.     par = info->par;把我们驱动中的私有数据指向info->par,我们在上面已经通过framebuffer_alloc为他申请了内存

    651.     /* 
    652.      * Here we set the screen_base to the virtual memory address
    653.      * for the framebuffer. Usually we obtain the resource address
    654.      * from the bus layer and then translate it to virtual memory
    655.      * space via ioremap. Consult ioport.h. 
    656.      */
    657.     这里注释也已经说的很清楚了,我们通常通过注册好的设备信息获取到memory address,然后把这个地址转换为virtual memory通过ioremap这个法方
    658.     info->screen_base = framebuffer_virtual_memory;
    659.     info->fbops = &xxxfb_ops;这个定义好的xxxfb_ops结构中包含了用户空间访问driver的所有法方,用户访问/dev/fb0最终通过fbmem中注册的法方调用这里的法方
    660.     info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be used, so mark it as __devinitdata */
    661.     info->pseudo_palette = pseudo_palette; /* The pseudopalette is an 16-member array*/
    662.     /*
    663.      * Set up flags to indicate what sort of acceleration your
    664.      * driver can provide (pan/wrap/copyarea/etc.) and whether it
    665.      * is a module -- see FBINFO_* in include/linux/fb.h
    666.      *
    667.      * If your hardware can support any of the hardware accelerated functions
    668.      * fbcon performance will improve if info->flags is set properly.
    669.      *
    670.      * FBINFO_HWACCEL_COPYAREA - hardware moves
    671.      * FBINFO_HWACCEL_FILLRECT - hardware fills
    672.      * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion
    673.      * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis
    674.      * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis
    675.      * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled
    676.      * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion
    677.      * FBINFO_MISC_TILEBLITTING - hardware can do tile blits
    678.      *
    679.      * NOTE: These are for fbcon use only.
    680.      */
    681.     info->flags = FBINFO_DEFAULT;

    682. /********************* This stage is optional ******************************/
    683.      /*
    684.      * The struct pixmap is a scratch pad for the drawing functions. This
    685.      * is where the monochrome bitmap is constructed by the higher layers
    686.      * and then passed to the accelerator. For drivers that uses
    687.      * cfb_imageblit, you can skip this part. For those that have a more
    688.      * rigorous requirement, this stage is needed
    689.      */

    690.     /* PIXMAP_SIZE should be small enough to optimize drawing, but not
    691.      * large enough that memory is wasted. A safe size is
    692.      * (max_xres * max_font_height/8). max_xres is driver dependent,
    693.      * max_font_height is 32.
    694.      */
    695.     info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL);
    696.     if (!info->pixmap.addr) {
    697.      /* goto error */
    698.     }

    699.     info->pixmap.size = PIXMAP_SIZE;

    700.     /*
    701.      * FB_PIXMAP_SYSTEM - memory is in system ram
    702.      * FB_PIXMAP_IO - memory is iomapped
    703.      * FB_PIXMAP_SYNC - if set, will call fb_sync() per access to pixmap,
    704.      * usually if FB_PIXMAP_IO is set.
    705.      *
    706.      * Currently, FB_PIXMAP_IO is unimplemented.
    707.      */
    708.     info->pixmap.flags = FB_PIXMAP_SYSTEM;

    709.     /*
    710.      * scan_align is the number of padding for each scanline. It is in bytes.
    711.      * Thus for accelerators that need padding to the next u32, put 4 here.
    712.      */
    713.     info->pixmap.scan_align = 4;

    714.     /*
    715.      * buf_align is the amount to be padded for the buffer. For example,
    716.      * the i810fb needs a scan_align of 2 but expects it to be fed with
    717.      * dwords, so a buf_align = 4 is required.
    718.      */
    719.     info->pixmap.buf_align = 4;

    720.     /* access_align is how many bits can be accessed from the framebuffer
    721.      * ie. some epson cards allow 16-bit access only. Most drivers will
    722.      * be safe with u32 here.
    723.      *
    724.      * NOTE: This field is currently unused.
    725.      */
    726.     info->pixmap.access_align = 32;
    727. /***************************** End optional stage ***************************/

    728.     /*
    729.      * This should give a reasonable default video mode. The following is
    730.      * done when we can set a video mode. 
    731.      */
    732.     if (!mode_option)
    733.     mode_option = "640x480@60";         

    734.     retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
    735.   
    736.     if (!retval || retval == 4)
    737.     return -EINVAL;            

    738.     /* This has to be */
    739.     if (fb_alloc_cmap(&info->cmap, cmap_len, 0))
    740.     return -ENOMEM;
    741.     
    742.     /* 
    743.      * The following is done in the case of having hardware with a static 
    744.      * mode. If we are setting the mode ourselves we don'call this. 
    745.      */    
    746.     info->var = xxxfb_var;

    747.     /*
    748.      * For drivers that can...
    749.      */
    750.     xxxfb_check_var(&info->var, info);

    751.     /*
    752.      * Does a call to fb_set_par() before register_framebuffer needed? This
    753.      * will depend on you and the hardware. If you are sure that your driver
    754.      * is the only device in the system, a call to fb_set_par() is safe.
    755.      *
    756.      * Hardware in x86 systems has a VGA core. Calling set_par() at this
    757.      * point will corrupt the VGA console, so it might be safer to skip a
    758.      * call to set_par here and just allow fbcon to do it for you.
    759.      */
    760.     /* xxxfb_set_par(info); */

    761.     if (register_framebuffer(info) < 0) {注册设备,fbmem中负责注册了一个fb 字符设备,只有调用了这个法方,才真正创建了这个fb字符设备
    762.     fb_dealloc_cmap(&info->cmap);
    763.     return -EINVAL;
    764.     }
    765.     printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
    766.      info->fix.id);
    767.     pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */方便后面使用info这个结构中的所有数据
    768.     return 0;
    769. }

    770.     /*
    771.      * Cleanup
    772.      */
    773. /* static void __devexit xxxfb_remove(struct platform_device *pdev) */
    774. static void __devexit xxxfb_remove(struct pci_dev *dev)
    775. {
    776.     struct fb_info *info = pci_get_drvdata(dev);
    777.     /* or platform_get_drvdata(pdev); */

    778.     if (info) {
    779.         unregister_framebuffer(info);
    780.         fb_dealloc_cmap(&info->cmap);
    781.         /* ... */
    782.         framebuffer_release(info);
    783.     }
    784. }

    785. #ifdef CONFIG_PCI
    786. #ifdef CONFIG_PM
    787. /**
    788.  *    xxxfb_suspend - Optional but recommended function. Suspend the device.
    789.  *    @dev: PCI device
    790.  *    @msg: the suspend event code.
    791.  *
    792.  * See Documentation/power/devices.txt for more information
    793.  */
    794. static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg)
    795. {
    796.     struct fb_info *info = pci_get_drvdata(dev);
    797.     struct xxxfb_par *par = info->par;

    798.     /* suspend here */
    799.     return 0;
    800. }

    801. /**
    802.  *    xxxfb_resume - Optional but recommended function. Resume the device.
    803.  *    @dev: PCI device
    804.  *
    805.  * See Documentation/power/devices.txt for more information
    806.  */
    807. static int xxxfb_resume(struct pci_dev *dev)
    808. {
    809.     struct fb_info *info = pci_get_drvdata(dev);
    810.     struct xxxfb_par *par = info->par;

    811.     /* resume here */
    812.     return 0;
    813. }
    814. #else
    815. #define xxxfb_suspend NULL
    816. #define xxxfb_resume NULL
    817. #endif /* CONFIG_PM */

    818. static struct pci_device_id xxxfb_id_table[] = {
    819.     { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX,
    820.      PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
    821.      PCI_CLASS_MASK, 0 },
    822.     { 0, }
    823. };

    824. /* For PCI drivers */
    825. static struct pci_driver xxxfb_driver = {
    826.     .name =        "xxxfb",
    827.     .id_table =    xxxfb_id_table,
    828.     .probe =    xxxfb_probe,
    829.     .remove =    __devexit_p(xxxfb_remove),
    830.     .suspend = xxxfb_suspend, /* optional but recommended */
    831.     .resume = xxxfb_resume, /* optional but recommended */
    832. };

    833. MODULE_DEVICE_TABLE(pci, xxxfb_id_table);

    834. int __init xxxfb_init(void)
    835. {
    836.     /*
    837.      * For kernel boot options (in 'video=xxxfb:<options>' format)
    838.      */
    839. #ifndef MODULE
    840.     char *option = NULL;

    841.     if (fb_get_options("xxxfb", &option))
    842.         return -ENODEV;
    843.     xxxfb_setup(option);
    844. #endif

    845.     return pci_register_driver(&xxxfb_driver);
    846. }

    847. static void __exit xxxfb_exit(void)
    848. {
    849.     pci_unregister_driver(&xxxfb_driver);
    850. }
    851. #else /* non PCI, platform drivers */
    852. #include <linux/platform_device.h>
    853. /* for platform devices */

    854. #ifdef CONFIG_PM
    855. /**
    856.  *    xxxfb_suspend - Optional but recommended function. Suspend the device.
    857.  *    @dev: platform device
    858.  *    @msg: the suspend event code.
    859.  *
    860.  * See Documentation/power/devices.txt for more information
    861.  */
    862. static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg)
    863. {
    864.     struct fb_info *info = platform_get_drvdata(dev);
    865.     struct xxxfb_par *par = info->par;

    866.     /* suspend here */
    867.     return 0;
    868. }

    869. /**
    870.  *    xxxfb_resume - Optional but recommended function. Resume the device.
    871.  *    @dev: platform device
    872.  *
    873.  * See Documentation/power/devices.txt for more information
    874.  */
    875. static int xxxfb_resume(struct platform_dev *dev)
    876. {
    877.     struct fb_info *info = platform_get_drvdata(dev);
    878.     struct xxxfb_par *par = info->par;

    879.     /* resume here */
    880.     return 0;
    881. }
    882. #else
    883. #define xxxfb_suspend NULL
    884. #define xxxfb_resume NULL
    885. #endif /* CONFIG_PM */

    886. static struct platform_device_driver xxxfb_driver = {
    887.     .probe = xxxfb_probe,
    888.     .remove = xxxfb_remove,
    889.     .suspend = xxxfb_suspend, /* optional but recommended */
    890.     .resume = xxxfb_resume, /* optional but recommended */
    891.     .driver = {
    892.         .name = "xxxfb",
    893.     },
    894. };

    895. static struct platform_device *xxxfb_device;

    896. #ifndef MODULE
    897.     /*
    898.      * Setup
    899.      */

    900. /*
    901.  * Only necessary if your driver takes special options,
    902.  * otherwise we fall back on the generic fb_setup().
    903.  */
    904. int __init xxxfb_setup(char *options)
    905. {
    906.     /* Parse user speficied options (`video=xxxfb:') */
    907. }
    908. #endif /* MODULE */

    909. static int __init xxxfb_init(void)
    910. {
    911.     int ret;
    912.     /*
    913.      * For kernel boot options (in 'video=xxxfb:<options>' format)
    914.      */
    915. #ifndef MODULE
    916.     char *option = NULL;

    917.     if (fb_get_options("xxxfb", &option))
    918.         return -ENODEV;
    919.     xxxfb_setup(option);
    920. #endif
    921.     ret = platform_driver_register(&xxxfb_driver);

    922.     if (!ret) {
    923.         xxxfb_device = platform_device_register_simple("xxxfb", 0,
    924.                                 NULL, 0);

    925.         if (IS_ERR(xxxfb_device)) {
    926.             platform_driver_unregister(&xxxfb_driver);
    927.             ret = PTR_ERR(xxxfb_device);
    928.         }
    929.     }

    930.     return ret;
    931. }

    932. static void __exit xxxfb_exit(void)
    933. {
    934.     platform_device_unregister(xxxfb_device);
    935.     platform_driver_unregister(&xxxfb_driver);
    936. }
    937. #endif /* CONFIG_PCI */

    938. /* ------------------------------------------------------------------------- */


    939.     /*
    940.      * Modularization
    941.      */

    942. module_init(xxxfb_init);
    943. module_exit(xxxfb_remove);

    944. MODULE_LICENSE("GPL");
        每日一道理
    美丽是平凡的,平凡得让你感觉不到她的存在;美丽是平淡的,平淡得只剩下温馨的回忆;美丽又是平静的,平静得只有你费尽心思才能激起她的涟漪。

        这里就开始渐渐啃一啃这个硬骨架吧

        毫无疑问,先找到module_init(xxxfb_init),xxxfb_init这个方式是这个驱动的入口,我们要找到这个法方,代码中我已经标注出来,原来在这个构架中采用了两种法方来实现framebuffer驱动,分别是pci子系统方式和platform子系统方式,这里他们的实现法方基本相似,只是在匹配device时有所不同,我们没有必要过于关注这里,大家也可以看到,他们的proble法方是一样的,这个proble才是我们要真正好好析分的

        第一件事就是为fb_info动态申请内存空间,很有必要析分一下这个法方

        

    1. /**
    2.  * framebuffer_alloc - creates a new frame buffer info structure
    3.  *
    4.  * @size: size of driver private data, can be zero
    5.  * @dev: pointer to the device for this fb, this can be NULL
    6.  *
    7.  * Creates a new frame buffer info structure. Also reserves @size bytes
    8.  * for driver private data (info->par). info->par (if any) will be
    9.  * aligned to sizeof(long).
    10.  *
    11.  * Returns the new structure, or NULL if an error occured.
    12.  *
    13.  */
    14. struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
    15. {
    16. #define BYTES_PER_LONG (BITS_PER_LONG/8)
    17. #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
    18.     int fb_info_size = sizeof(struct fb_info);
    19.     struct fb_info *info;
    20.     char *p;

    21.     if (size)
    22.         fb_info_size += PADDING;

    23.     p = kzalloc(fb_info_size + size, GFP_KERNEL);

    24.     if (!p)
    25.         return NULL;

    26.     info = (struct fb_info *) p;

    27.     if (size)
    28.         info->par = p + fb_info_size;

    29.     info->device = dev;

    30. #ifdef CONFIG_FB_BACKLIGHT
    31.     mutex_init(&info->bl_curve_mutex);
    32. #endif

    33.     return info;
    34. #undef PADDING
    35. #undef BYTES_PER_LONG
    36. }

        其实这里注释也已经说清楚了,这个法方不止为fb_info申请了内存空间,还为fb_info中的一个void型指针par分配了内存空间,这个par将会保存之后在这个驱动中的私有变量,是一个结构,保存了很多driver的相关信息,保存到par中,之后想要使用的时候就很容易得到

        这个构架中的其他法方都没有实现,他们就是访问driver时候体具的处理函数,就是要我们要去花大力气去做的事情

        之后在真正的framebuffer驱动程序中再去好好析分这些法方吧

        待续。。。。。。

    文章结束给大家分享下程序员的一些笑话语录: 打赌
    飞机上,一位工程师和一位程序员坐在一起。程序员问工程师是否乐意和他一起玩一种有趣的游戏。工程师想睡觉,于是他很有礼貌地拒绝了,转身要睡觉。程序员坚持要玩并解释说这是一个非常有趣的游戏:"我问你一个问题,如果你不知道答案,我付你5美元。然后你问我一个问题,如果我答不上来,我付你5美元。"然而,工程师又很有礼貌地拒绝了,又要去睡觉。  程序员这时有些着急了,他说:"好吧,如果你不知道答案,你付5美元;如果我不知道答案,我付50美元。"果然,这的确起了作用,工程师答应了。程序员就问:"从地球到月球有多远?"工程师一句话也没有说,给了程序员5美元。  现在轮到工程师了,他问程序员:"什么上山时有三条腿,下山却有四条腿?"程序员很吃惊地看着工程师,拿出他的便携式电脑,查找里面的资料,过了半个小时,他叫醒工程师并给了工程师50美元。工程师很礼貌地接过钱又要去睡觉。程序员有些恼怒,问:"那么答案是什么呢?"工程师什么也没有说,掏出钱包,拿出5美元给程序员,转身就去睡觉了。

  • 相关阅读:
    石家庄地铁线路查询系统(补)
    构建之法阅读笔记03
    构建之法阅读笔记02
    Day 3-3 内置方法
    Day3-2 函数之递归
    Day3-1 函数
    Day2 列表,元组,字典,集合
    Day1 基础知识
    Day1. Python基础知识
    iptables防火墙配置
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3043309.html
Copyright © 2011-2022 走看看