skeletonfb.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/errno.h>
  13. #include <linux/string.h>
  14. #include <linux/mm.h>
  15. #include <linux/tty.h>
  16. #include <linux/slab.h>
  17. #include <linux/delay.h>
  18. #include <linux/fb.h>
  19. #include <linux/init.h>
  20. #include <video/fbcon.h>
  21.     /*
  22.      *  This is just simple sample code.
  23.      *
  24.      *  No warranty that it actually compiles.
  25.      *  Even less warranty that it actually works :-)
  26.      */
  27. struct xxxfb_info {
  28.     /*
  29.      *  Choose _one_ of the two alternatives:
  30.      *
  31.      *    1. Use the generic frame buffer operations (fbgen_*).
  32.      */
  33.     struct fb_info_gen gen;
  34.     /*
  35.      *    2. Provide your own frame buffer operations.
  36.      */
  37.     struct fb_info info;
  38.     /* Here starts the frame buffer device dependent part */
  39.     /* You can use this to store e.g. the board number if you support */
  40.     /* multiple boards */
  41. };
  42. struct xxxfb_par {
  43.     /*
  44.      *  The hardware specific data in this structure uniquely defines a video
  45.      *  mode.
  46.      *
  47.      *  If your hardware supports only one video mode, you can leave it empty.
  48.      */
  49. };
  50.     /*
  51.      *  If your driver supports multiple boards, you should make these arrays,
  52.      *  or allocate them dynamically (using kmalloc()).
  53.      */
  54. static struct xxxfb_info fb_info;
  55. static struct xxxfb_par current_par;
  56. static int current_par_valid = 0;
  57. static struct display disp;
  58. static struct fb_var_screeninfo default_var;
  59. static int currcon = 0;
  60. static int inverse = 0;
  61. int xxxfb_init(void);
  62. int xxxfb_setup(char*);
  63. /* ------------------- chipset specific functions -------------------------- */
  64. static void xxx_detect(void)
  65. {
  66.     /*
  67.      *  This function should detect the current video mode settings and store
  68.      *  it as the default video mode
  69.      */
  70.     struct xxxfb_par par;
  71.     /* ... */
  72.     xxx_get_par(&par);
  73.     xxx_encode_var(&default_var, &par);
  74. }
  75. static int xxx_encode_fix(struct fb_fix_screeninfo *fix, struct xxxfb_par *par,
  76.   const struct fb_info *info)
  77. {
  78.     /*
  79.      *  This function should fill in the 'fix' structure based on the values
  80.      *  in the `par' structure.
  81.      */
  82.     /* ... */
  83.     return 0;
  84. }
  85. static int xxx_decode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
  86.   const struct fb_info *info)
  87. {
  88.     /*
  89.      *  Get the video params out of 'var'. If a value doesn't fit, round it up,
  90.      *  if it's too big, return -EINVAL.
  91.      *
  92.      *  Suggestion: Round up in the following order: bits_per_pixel, xres,
  93.      *  yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
  94.      *  bitfields, horizontal timing, vertical timing.
  95.      */
  96.     /* ... */
  97.     /* pixclock in picos, htotal in pixels, vtotal in scanlines */
  98.     if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
  99.     return -EINVAL;
  100.     return 0;
  101. }
  102. static int xxx_encode_var(struct fb_var_screeninfo *var, struct xxxfb_par *par,
  103.   const struct fb_info *info)
  104. {
  105.     /*
  106.      *  Fill the 'var' structure based on the values in 'par' and maybe other
  107.      *  values read out of the hardware.
  108.      */
  109.     /* ... */
  110.     return 0;
  111. }
  112. static void xxx_get_par(struct xxxfb_par *par, const struct fb_info *info)
  113. {
  114.     /*
  115.      *  Fill the hardware's 'par' structure.
  116.      */
  117.     if (current_par_valid)
  118. *par = current_par;
  119.     else {
  120. /* ... */
  121.     }
  122. }
  123. static void xxx_set_par(struct xxxfb_par *par, const struct fb_info *info)
  124. {
  125.     /*
  126.      *  Set the hardware according to 'par'.
  127.      */
  128.     current_par = *par;
  129.     current_par_valid = 1;
  130.     /* ... */
  131. }
  132. static int xxx_getcolreg(unsigned regno, unsigned *red, unsigned *green,
  133.  unsigned *blue, unsigned *transp,
  134.  const struct fb_info *info)
  135. {
  136.     /*
  137.      *  Read a single color register and split it into colors/transparent.
  138.      *  The return values must have a 16 bit magnitude.
  139.      *  Return != 0 for invalid regno.
  140.      */
  141.     /* ... */
  142.     return 0;
  143. }
  144. static int xxx_setcolreg(unsigned regno, unsigned red, unsigned green,
  145.  unsigned blue, unsigned transp,
  146.  const struct fb_info *info)
  147. {
  148.     /*
  149.      *  Set a single color register. The values supplied have a 16 bit
  150.      *  magnitude.
  151.      *  Return != 0 for invalid regno.
  152.      */
  153.     if (regno < 16) {
  154. /*
  155.  *  Make the first 16 colors of the palette available to fbcon
  156.  */
  157. if (is_cfb15) /* RGB 555 */
  158.     ...fbcon_cmap.cfb16[regno] = ((red & 0xf800) >> 1) |
  159.  ((green & 0xf800) >> 6) |
  160.  ((blue & 0xf800) >> 11);
  161. if (is_cfb16) /* RGB 565 */
  162.     ...fbcon_cmap.cfb16[regno] = (red & 0xf800) |
  163.  ((green & 0xfc00) >> 5) |
  164.  ((blue & 0xf800) >> 11);
  165. if (is_cfb24) /* RGB 888 */
  166.     ...fbcon_cmap.cfb24[regno] = ((red & 0xff00) << 8) |
  167.  (green & 0xff00) |
  168.  ((blue & 0xff00) >> 8);
  169. if (is_cfb32) /* RGBA 8888 */
  170.     ...fbcon_cmap.cfb32[regno] = ((red & 0xff00) << 16) |
  171.  ((green & 0xff00) << 8) |
  172.  (blue & 0xff00) |
  173.  ((transp & 0xff00) >> 8);
  174.     }
  175.     /* ... */
  176.     return 0;
  177. }
  178. static int xxx_pan_display(struct fb_var_screeninfo *var,
  179.    struct xxxfb_par *par, const struct fb_info *info)
  180. {
  181.     /*
  182.      *  Pan (or wrap, depending on the `vmode' field) the display using the
  183.      *  `xoffset' and `yoffset' fields of the `var' structure.
  184.      *  If the values don't fit, return -EINVAL.
  185.      */
  186.     /* ... */
  187.     return 0;
  188. }
  189. static int xxx_blank(int blank_mode, const struct fb_info *info)
  190. {
  191.     /*
  192.      *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
  193.      *  then the caller blanks by setting the CLUT (Color Look Up Table) to all
  194.      *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
  195.      *  to e.g. a video mode which doesn't support it. Implements VESA suspend
  196.      *  and powerdown modes on hardware that supports disabling hsync/vsync:
  197.      *    blank_mode == 2: suspend vsync
  198.      *    blank_mode == 3: suspend hsync
  199.      *    blank_mode == 4: powerdown
  200.      */
  201.     /* ... */
  202.     return 0;
  203. }
  204. static void xxx_set_disp(const void *par, struct display *disp,
  205.  struct fb_info_gen *info)
  206. {
  207.     /*
  208.      *  Fill in a pointer with the virtual address of the mapped frame buffer.
  209.      *  Fill in a pointer to appropriate low level text console operations (and
  210.      *  optionally a pointer to help data) for the video mode `par' of your
  211.      *  video hardware. These can be generic software routines, or hardware
  212.      *  accelerated routines specifically tailored for your hardware.
  213.      *  If you don't have any appropriate operations, you must fill in a
  214.      *  pointer to dummy operations, and there will be no text output.
  215.      */
  216.     disp->screen_base = virtual_frame_buffer_address;
  217. #ifdef FBCON_HAS_CFB8
  218.     if (is_cfb8) {
  219. disp->dispsw = fbcon_cfb8;
  220.     } else
  221. #endif
  222. #ifdef FBCON_HAS_CFB16
  223.     if (is_cfb16) {
  224. disp->dispsw = fbcon_cfb16;
  225. disp->dispsw_data = ...fbcon_cmap.cfb16; /* console palette */
  226.     } else
  227. #endif
  228. #ifdef FBCON_HAS_CFB24
  229.     if (is_cfb24) {
  230. disp->dispsw = fbcon_cfb24;
  231. disp->dispsw_data = ...fbcon_cmap.cfb24; /* console palette */
  232.     } else
  233. #endif
  234. #ifdef FBCON_HAS_CFB32
  235.     if (is_cfb32) {
  236. disp->dispsw = fbcon_cfb32;
  237. disp->dispsw_data = ...fbcon_cmap.cfb32; /* console palette */
  238.     } else
  239. #endif
  240. disp->dispsw = &fbcon_dummy;
  241. }
  242. /* ------------ Interfaces to hardware functions ------------ */
  243. struct fbgen_hwswitch xxx_switch = {
  244.     xxx_detect, xxx_encode_fix, xxx_decode_var, xxx_encode_var, xxx_get_par,
  245.     xxx_set_par, xxx_getcolreg, xxx_setcolreg, xxx_pan_display, xxx_blank,
  246.     xxx_set_disp
  247. };
  248. /* ------------ Hardware Independent Functions ------------ */
  249.     /*
  250.      *  Initialization
  251.      */
  252. int __init xxxfb_init(void)
  253. {
  254.     fb_info.gen.fbhw = &xxx_switch;
  255.     fb_info.gen.fbhw->detect();
  256.     strcpy(fb_info.gen.info.modename, "XXX");
  257.     fb_info.gen.info.changevar = NULL;
  258.     fb_info.gen.info.node = -1;
  259.     fb_info.gen.info.fbops = &xxxfb_ops;
  260.     fb_info.gen.info.disp = &disp;
  261.     fb_info.gen.info.switch_con = &xxxfb_switch;
  262.     fb_info.gen.info.updatevar = &xxxfb_update_var;
  263.     fb_info.gen.info.blank = &xxxfb_blank;
  264.     fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
  265.     /* This should give a reasonable default video mode */
  266.     fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
  267.     fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
  268.     fbgen_set_disp(-1, &fb_info.gen);
  269.     fbgen_install_cmap(0, &fb_info.gen);
  270.     if (register_framebuffer(&fb_info.gen.info) < 0)
  271. return -EINVAL;
  272.     printk(KERN_INFO "fb%d: %s frame buffer devicen", GET_FB_IDX(fb_info.gen.info.node),
  273.    fb_info.gen.info.modename);
  274.     /* uncomment this if your driver cannot be unloaded */
  275.     /* MOD_INC_USE_COUNT; */
  276.     return 0;
  277. }
  278.     /*
  279.      *  Cleanup
  280.      */
  281. void xxxfb_cleanup(struct fb_info *info)
  282. {
  283.     /*
  284.      *  If your driver supports multiple boards, you should unregister and
  285.      *  clean up all instances.
  286.      */
  287.     unregister_framebuffer(info);
  288.     /* ... */
  289. }
  290.     /*
  291.      *  Setup
  292.      */
  293. int __init xxxfb_setup(char *options)
  294. {
  295.     /* Parse user speficied options (`video=xxxfb:') */
  296. }
  297. /* ------------------------------------------------------------------------- */
  298.     /*
  299.      *  Frame buffer operations
  300.      */
  301. /* If all you need is that - just don't define ->fb_open */
  302. static int xxxfb_open(const struct fb_info *info, int user)
  303. {
  304.     return 0;
  305. }
  306. /* If all you need is that - just don't define ->fb_release */
  307. static int xxxfb_release(const struct fb_info *info, int user)
  308. {
  309.     return 0;
  310. }
  311.     /*
  312.      *  In most cases the `generic' routines (fbgen_*) should be satisfactory.
  313.      *  However, you're free to fill in your own replacements.
  314.      */
  315. static struct fb_ops xxxfb_ops = {
  316. owner: THIS_MODULE,
  317. fb_open: xxxfb_open,    /* only if you need it to do something */
  318. fb_release: xxxfb_release, /* only if you need it to do something */
  319. fb_get_fix: fbgen_get_fix,
  320. fb_get_var: fbgen_get_var,
  321. fb_set_var: fbgen_set_var,
  322. fb_get_cmap: fbgen_get_cmap,
  323. fb_set_cmap: fbgen_set_cmap,
  324. fb_pan_display: fbgen_pan_display,
  325. fb_ioctl: xxxfb_ioctl,   /* optional */
  326. };
  327. /* ------------------------------------------------------------------------- */
  328.     /*
  329.      *  Modularization
  330.      */
  331. #ifdef MODULE
  332. MODULE_LICENSE("GPL");
  333. int init_module(void)
  334. {
  335.     return xxxfb_init();
  336. }
  337. void cleanup_module(void)
  338. {
  339.     xxxfb_cleanup(void);
  340. }
  341. #endif /* MODULE */