framebuffer 設備即幀緩沖設備(簡寫fb)提供了顯示接口的抽象描述。他同時代表著顯示接口的存儲區(qū),應用程序通過定義好的函數(shù)訪問,不需要知道底層的任何操作。 Framebuffer 驅(qū)動使用的設備節(jié)點,通常位于/dev 目錄,如/dev/fb*.從用戶角度看,fb 設備和其他/dev 下面的設備類似:普通的字符設備,主設備號29,次設備號定義fb 的索引。通常,使用如下方式(前面的數(shù)字表示次設備號)0 = /dev/fb0 第一個fb 設備,1 = /dev/fb1 第二個fb 設備,fb 也是一種普通的內(nèi)存設備,可以讀寫其內(nèi)容。例如,屏幕抓屏:cp /dev/fb0 myfile,fb 雖然可以像內(nèi)存設備(/dev/mem)一樣,對其read,write,seek 以及mmap。但區(qū)別在于fb 使用的不是整個內(nèi)存區(qū),而是顯存部分。通過ioctl 可以讀取或設定fb 設備參數(shù),很重要的一點,顏色表(cmap)也要通過Ioctl 設定。你可以獲取設備一些不變的信息,如設備名,屏幕的組織(平面,象素,...)對應內(nèi)存區(qū)的長度和起始地址。也可以獲取能夠改變的信息,例如位深,顏色格式,時序等。如果你改變這些值,驅(qū)動程序?qū)χ颠M行優(yōu)化,以滿足設備特性。framebuffer是LCD控制器相關的驅(qū)動,CPU可以通過尋址的方式訪問LCD控制器,所以framebuffer一般是platform driver,所以用platform driver的架構(gòu)來編寫framebuffer驅(qū)動。? ?
?
當我們想編寫一個FB設備驅(qū)動時,一個比較好的方法是注冊platform設備,然后將FB設備的注冊,IO映射操作,硬件初始化等操作放在在probe中進行,從而整體上結(jié)構(gòu)清晰。
一. 重要數(shù)據(jù)結(jié)構(gòu)
1. 幀緩沖區(qū)描述符 fb_info
struct?fb_info?{
??????????????????? atomic_t count;
??????????????????? int node;
??????????????????? int flags;
??????????????????? struct mutex lock;??/* Lock for open/release/ioctl funcs */
??????????????????? struct mutex mm_lock;??/* Lock for fb_mmap and smem_* fields */
????????????????????struct fb_var_screeninfo var;?/* Current var */?????//緩沖區(qū)可變參數(shù)
??????????????????? struct fb_fix_screeninfo fix;?/* Current fix */?????????//緩沖區(qū)固定參數(shù)
??????????????????? struct fb_monspecs monspecs;?/* Current Monitor specs */????//當前顯示器
????????????????????struct work_struct queue;?/* Framebuffer event queue */?????//事件工作隊列
??????????????????? struct fb_pixmap pixmap;?/* Image hardware mapper */??????//圖像硬件映射
??????????????????? struct fb_pixmap sprite;?/* Cursor hardware mapper */????????//光標硬件映射
????????????????????struct fb_cmap cmap;??/* Current cmap */
??????????????????? struct list_head modelist;????? /* mode list */????????????//視頻模式鏈表
??????????????????? struct fb_videomode *mode;?/* current mode */????//當前視頻模式??????
??????????? #ifdef CONFIG_FB_BACKLIGHT???????????//支持背光的參數(shù)
??????????????????? struct backlight_device *bl_dev;
??????????????????? struct mutex bl_curve_mutex;?
????????????????????u8 bl_curve[FB_BACKLIGHT_LEVELS];
??????????? #endif
??????????? #ifdef CONFIG_FB_DEFERRED_IO
??????????????????? struct delayed_work deferred_work;
??????????????????? struct fb_deferred_io *fbdefio;
??????????? #endif
????????????????????struct fb_ops *fbops;??????//幀緩沖區(qū)操作函數(shù),framebuffer驅(qū)動的核心數(shù)據(jù)結(jié)構(gòu)
??????????????????? struct device *device;??/* This is the parent */????//父設備
??????????????????? struct device *dev;??/* This is this fb device */????//FB設備
??????????????????? int class_flag;??????????????????? /* private sysfs flags */
????????????#ifdef CONFIG_FB_TILEBLITTING
??????????????????? struct fb_tile_ops *tileops;??? /* Tile Blitting */
??????????? #endif
??????????????????? char __iomem *screen_base;?/* Virtual address */
??????????????????? unsigned long screen_size;?/* Amount of ioremapped VRAM or 0 */
??????????????????? void *pseudo_palette;??/* Fake palette of 16 colors */?
??????????? #define FBINFO_STATE_RUNNING?0
??????????? #define FBINFO_STATE_SUSPENDED?1
??????????????????? u32 state;???/* Hardware state i.e suspend */
??????????????????? void *fbcon_par;??????????????? /* fbcon use-only private area */
??????????????????? void *par;
??????????????????? struct apertures_struct {
??????????????????????????? unsigned int count;
??????????????????????????? struct aperture {
???????????????????????????????????? resource_size_t base;
???????????????????????????????????? resource_size_t size;
???????????????????????????? } ranges[0];
??????????????????? } *apertures;
??????????? };
2. 幀緩沖區(qū)操作函數(shù)表 fb_ops
struct fb_ops {
?????????????????????? struct module *owner;??????????//模塊所有者
?????????????????????? int (*fb_open)(struct fb_info *info, int user);????????//FB打開操作
?????????????????????? int (*fb_release)(struct fb_info *info, int user);???//FB釋放操作
?????????????????????? ssize_t (*fb_read)(struct fb_info *info, char __user *buf,size_t count, loff_t *ppos);????//FB讀操作
?????????????????????? ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,size_t count, loff_t *ppos);?//FB寫操作
?????????????????????? int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);//檢查FB可變變量,并調(diào)整為可用值
?????????????????????? int (*fb_set_par)(struct fb_info *info);??????????//設置視頻模式
???????????????????????int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,unsigned blue, unsigned transp, struct fb_info *info);?//設置顏色寄存器
?????????????????????? int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);?//批量設置顏色寄存器,并設置顏色表
?????????????????????? int (*fb_blank)(int blank, struct fb_info *info);???? //空白顯示
?????????????????????? int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);?//面板顯示
?????????????????????? void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);??????????????//畫矩形
?????????????????????? void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);//把數(shù)據(jù)拷貝到另外一個區(qū)域
?????????????????????? void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);//在幀緩沖去中顯示一個圖片
?????????????????????? int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);????????????????????//繪制光標
?????????????????????? void (*fb_rotate)(struct fb_info *info, int angle);??????????????????????????????????????????????//旋轉(zhuǎn)顯示
?????????????????????? int (*fb_sync)(struct fb_info *info);??????????????????????????????????????????????????????//等待并同步圖像顯示完成
?????????????????????? int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,unsigned long arg);//FB的IOCTL操作
?????????????????????? int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,unsigned long arg);????
?????????????????????? int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);??//FB的內(nèi)存映射MMAP操作
?????????????????????? void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,struct fb_var_screeninfo *var);
???????????????????????void (*fb_destroy)(struct fb_info *info);
?????????????????????? int (*fb_debug_enter)(struct fb_info *info);
?????????????????????? int (*fb_debug_leave)(struct fb_info *info);
????????????? };
3. 固定參數(shù)描述符
struct fb_fix_screeninfo {
???????????????????????????char id[16];?????????????????????????????????????????? /* identification string eg "TT Builtin" *///FB ID
?????????????????????????? unsigned long smem_start;??????????? /* Start of frame buffer mem */???????//FB緩存開始位置
????????????????????????????????????????????????????????????????????????????????????????? /* (physical address) */???????????????????//物理地址相關
?????????????????????????? __u32 smem_len;???????????????????????????? /* Length of frame buffer mem */???//FB緩存長度
?????????????????????????? __u32 type;????????????????????????????????????????? /* see FB_TYPE_*??*/???????????????????????//FB類型
?????????????????????????? __u32 type_aux;???????????????????????????????? /* Interleave for interleaved Planes *///FB分界
?????????????????????????? __u32 visual;?????????????????????????????????????? /* see FB_VISUAL_*??*/???????????????????//FB色彩模式
?????????????????????????? __u16 xpanstep;???????????????????????????????? /* zero if no hardware panning? */??//沒有硬件PAN則賦0
?????????????????????????? __u16 ypanstep;???????????????????????????????? /* zero if no hardware panning? */????????????
?????????????????????????? __u16 ywrapstep;?????????????????????????????? /* zero if no hardware ywrap??? */
?????????????????????????? __u32 line_length;???????????????????????????? /* length of a line in bytes??? */???????//1行的字節(jié)數(shù)
?????????????????????????? unsigned long mmio_start;????????????? /* Start of Memory Mapped I/O*///內(nèi)存IO映射的開始地址
????????????????????????????????????????????????????????????????????????????????????????? /* (physical address) */
?????????????????????????? __u32 mmio_len;?????????????????????????????? /* Length of Memory Mapped I/O? *///IO 長度
?????????????????????????? __u32 accel;??????????????????????????????????????? /* Indicate to driver which?*/
????????????????????????????????????????????????????????????????????????????????????????? /*? specific chip/card we have?*/
?????????????????????????? __u16 capabilities;???????????????????????????? /* see FB_CAP_*???*/
?????????????????????????? __u16 reserved[2];???????????????????????????? /* Reserved for future compatibility */
????????????????? };
4. 可變參數(shù)描述符
struct fb_var_screeninfo {
????????????????????????? __u32 xres;???/* visible resolution??*/???????????????????????????//可見解析度,分辨率的X軸寬度
????????????????????????? __u32 yres;?????????????????????????????????????????????????????????????????????//可見解析度,分辨率的Y軸寬度
????????????????????????? __u32 xres_virtual;??/* virtual resolution??*/????????????????//虛擬解析度X軸寬度
????????????????????????? __u32 yres_virtual;????????????????????????????????????????????????????????//虛擬解析度Y軸寬度
????????????????????????? __u32 xoffset;???/* offset from virtual to visible */???????//虛擬與可見解析度之間X軸偏移
????????????????????????? __u32 yoffset;???/* resolution???*/???????????????????????????????????//虛擬與可見解析度之間Y軸偏移
????????????????????????? __u32 bits_per_pixel;??/* guess what???*/???????????????????//每像素點的位數(shù)
????????????????????????? __u32 grayscale;??/* 0 = color, 1 = grayscale,?*/????????//灰度級別,0表示彩色
????????????????????????????????????????????????????????????????? /* >1 = FOURCC???*/
????????????????????????? struct fb_bitfield red;??/* bitfield in fb mem if true color, */?//RGB位域的紅色
????????????????????????? struct fb_bitfield green;?/* else only length is significant */?//RGB位域的綠色
????????????????????????? struct fb_bitfield blue;??????????????????????????????????????????????????????//RGB位域的藍色
????????????????????????? struct fb_bitfield transp;?/* transparency???*/?????????????????//透明色
????????????????????????? __u32 nonstd;???/* != 0 Non standard pixel format */???//如果該值不為0,非標準像素格式
????????????????????????? __u32 activate;???/* see FB_ACTIVATE_*??*/
????????????????????????? __u32 height;???/* height of picture in mm??? */?????????????//圖像在屏幕中的高度
????????????????????????? __u32 width;???/* width of picture in mm???? */????????????????//圖像在屏幕中的寬度
????????????????????????? __u32 accel_flags;??/* (OBSOLETE) see fb_info.flags */
????????????????????????? __u32 pixclock;???/* pixel clock in ps (pico seconds) */??//像點時鐘
????????????????????????? __u32 left_margin;??/*time from sync to picture*///行切換時,顯示與同步間的延時左邊空隙
????????????????????????? __u32 right_margin;?/*time from picture to sync*///行切換時,顯示與同步間的延時右邊空隙
????????????????????????? __u32 upper_margin;/*time from sync to picture*///幀切換時,顯示與同步間的延時上邊空隙
????????????????????????? __u32 lower_margin;?????????????????????????????????????????????//幀切換時,顯示與同步間的延時上邊空隙
????????????????????????? __u32 hsync_len;??/* length of horizontal sync?*/???//行同步長度
????????????????????????? __u32 vsync_len;??/* length of vertical sync?*/????????//幀同步長度
????????????????????????? __u32 sync;???/* see FB_SYNC_*??*/??????????????????????????????????????????????????????????
????????????????????????? __u32 vmode;???/* see FB_VMODE_*??*/
????????????????????????? __u32 rotate;???/* angle we rotate counter clockwise */???//順時針旋轉(zhuǎn)角度
????????????????????????? __u32 colorspace;??/* colorspace for FOURCC-based modes *///顏色空間
????????????????????????? __u32 reserved[5];??/* Reserved for future compatibility */
?????????????????? };
5. 調(diào)色板描述符
struct fb_cmap {
?????????????????????????? __u32 start;???/* First entry?*/?????????????????????????????????????????????//第一個顏色入口
?????????????????????????? __u32 len;???/* Number of entries */????????????????????????????????//顏色總數(shù)
?????????????????????????? __u16 *red;???/* Red values?*/??????????????????????????????????????????//RGB紅色值
?????????????????????????? __u16 *green;?????????????????????????????????????????????????????????????????????//RGB紅綠值
???????????????????????????__u16 *blue;???????????????????????????????????????????????????????????????????????//RGB紅藍值
?????????????????????????? __u16 *transp;???/* transparency, can be NULL */????????//透明度值
??????????????????? };
二. 主要函數(shù)
1.?framebuffer_alloc, 為FB驅(qū)動分配內(nèi)存空間并初始化,這個函數(shù)的核心的作用是申請一塊空間,并轉(zhuǎn)換為struct fb_info 指針返回,在這個申請過程私有數(shù)據(jù)空間size并非是必須的,需要的話可以有但并非必須。
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
?????????????? {
??????????????????????? #define BYTES_PER_LONG (BITS_PER_LONG/8)
??????????????????????? #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
??????????????????????? int fb_info_size = sizeof(struct fb_info);
??????????????????????? struct fb_info *info;
??????????????????????? char *p;
??????????????????????? if (size)
?????????????????????????????? fb_info_size += PADDING;
??????????????????????? p = kzalloc(fb_info_size + size, GFP_KERNEL);
??????????????????????? if (!p)
????????????????????????????? return NULL;
????????????????????????info = (struct fb_info *) p;
??????????????????????? if (size)
?????????????????????????????? info->par = p + fb_info_size;
??????????????????????? info->device = dev;
??????????????????????? #ifdef CONFIG_FB_BACKLIGHT
??????????????????????????????? mutex_init(&info->bl_curve_mutex);
??????????????????????? #endif
???????????????????????????????? return info;
??????????????????????? #undef PADDING
??????????????????????? #undef BYTES_PER_LONG
?????????????? }
2. register_framebuffer,向系統(tǒng)注冊FB。
int?register_framebuffer(struct fb_info *fb_info)
??????????????? {
????????????????????? int ret;
????????????????????? mutex_lock(?istration_lock);
????????????????????? ret = do_register_framebuffer(fb_info);
??????????????????????mutex_unlock(?istration_lock);
????????????????????? return ret;
??????????????? }
三. 實現(xiàn)framebuffer驅(qū)動程序的一個例子的步驟
1. 包含頭文件
#include
#include
#include
2. 定義及初始化相關FB參數(shù)結(jié)構(gòu)體
struct fb_var_screeninfo dnfb_var__devinitdata = {
?????????????????????????????.xres??= 1280,
?????????????????????????????.yres??= 1024,
???????????????????????????? .xres_virtual?= 2048,
???????????????????????????? .yres_virtual?= 1024,
???????????????????????????? .bits_per_pixel?= 1,
?????????????????????????????.height??= -1,
???????????????????????????? .width??= -1,
???????????????????????????? .vmode??= FB_VMODE_NONINTERLACED,
????????????????????? };
static struct fb_fix_screeninfo dnfb_fix__devinitdata = {
????????????????????????????? .id??= "Apollo Mono",
????????????????????????????? .smem_start?= (FRAME_BUFFER_START + IO_BASE),
????????????????????????????? .smem_len?= FRAME_BUFFER_LEN,
??????????????????????????????.type??= FB_TYPE_PACKED_PIXELS,
??????????????????????????????.visual??= FB_VISUAL_MONO10,
??????????????????????????????.line_length?= 256,
????????????????????? };
3. 定義及實現(xiàn)結(jié)構(gòu) fb_ops與它的成員函數(shù)
static int?dnfb_blank(int blank, struct fb_info *info)
????????????????????? {
???????????????????????????? if (blank)
??????????????????????????????????? out_8(AP_CONTROL_3A, 0x0);
???????????????????????????? else
????????????????????????????????????out_8(AP_CONTROL_3A, 0x1);
?????????????????????????????return 0;
????????????????????? }
void?cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
????????????????????? {
?????????????????????????????? unsigned long pat, pat2, fg;
?????????????????????????????? unsigned long width = rect->width, height = rect->height;
???????????????????????????????int bits = BITS_PER_LONG, bytes = bits >> 3;
?????????????????????????????? u32 bpp = p->var.bits_per_pixel;
?????????????????????????????? unsigned long __iomem *dst;
?????????????????????????????? int dst_idx, left;
?????????????????????????????? if (p->state != FBINFO_STATE_RUNNING)
????????????????????????????????????? return;
?????????????????????????????? if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR )
????????????????????????????????????? fg = ((u32 *) (p->pseudo_palette))[rect->color];
???????????????????????????????else
????????????????????????????????????? fg = rect->color;
?????????????????????????????? pat = pixel_to_pat(bpp, fg);
?????????????????????????????? dst = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));
?????????????????????????????? dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8;
?????????????????????????????? dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
?????????????????????????????? left = bits % bpp;
?????????????????????????????? if (p->fbops->fb_sync)
???????????????????????????????????????p->fbops->fb_sync(p);
???????????????????????????????if (!left) {
?????????????????????????????????????? u32 bswapmask = fb_compute_bswapmask(p);
?????????????????????????????????????? void (*fill_op32)(struct fb_info *p,unsigned long __iomem *dst, int dst_idx,unsigned long pat, unsigned n, int bits,u32 bswapmask) = NULL;
switch (rect->rop) {
?????????????????????????????????????? case ROP_XOR:
??????????????????????????????????????????????? fill_op32 = bitfill_aligned_rev;
????????????????????????????????????????????????break;
?????????????????????????????????????? case ROP_COPY:
??????????????????????????????????????????????? fill_op32 = bitfill_aligned;
??????????????????????????????????????????????? break;
?????????????????????????????????????? default:
????????????????????????????????????????????????printk( KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY
");
??????????????????????????????????????????????? fill_op32 = bitfill_aligned;
????????????????????????????????????????????????break;
??????????????????????????????????????? }
??????????????????????????????????????? while (height--) {
????????????????????????????????????????????????dst += dst_idx >> (ffs(bits) - 1);
??????????????????????????????????????????????? dst_idx &= (bits - 1);
??????????????????????????????????????????????? fill_op32(p, dst, dst_idx, pat, width*bpp, bits, bswapmask);
????????????????????????????????????????????????dst_idx += p->fix.line_length*8;
??????????????????????????????????????? }
??????????????????????????????? } else {
??????????????????????????????????????? int right, r;
??????????????????????????????????????? void (*fill_op)(struct fb_info *p, unsigned long __iomem *dst,int dst_idx, unsigned long pat, int left,int right, unsigned n, int bits) = NULL;
??????????????????????????????????????? right = bpp - left;
??????????????????????????????????????? switch (rect->rop) {
?????????????????????????????????????????????? case ROP_XOR:
??????????????????????????????????????????????????????? fill_op = bitfill_unaligned_rev;
??????????????????????????????????????????????????????? break;
?????????????????????????????????????????????? case ROP_COPY:
??????????????????????????????????????????????????????? fill_op = bitfill_unaligned;
??????????????????????????????????????????????????????? break;
???????????????????????????????????????????????default:
????????????????????????????????????????????????????????printk(KERN_ERR "cfb_fillrect(): unknown rop, defaulting to ROP_COPY
");
??????????????????????????????????????????????????????? fill_op = bitfill_unaligned;
??????????????????????????????????????????????????????? break;
?????????????????????????????????????????}
???????????????????????????????????????? while (height--) {
???????????????????????????????????????????????? dst += dst_idx / bits;
???????????????????????????????????????????????? dst_idx &= (bits - 1);
????????????????????????????????????????????????? r = dst_idx % bpp;
????????????????????????????????????????????????? pat2 = le_long_to_cpu(rolx(cpu_to_le_long(pat), r, bpp));
????????????????????????????????????????????????? fill_op(p, dst, dst_idx, pat2, left, right,width*bpp, bits);
????????????????????????????????????????????????? dst_idx += p->fix.line_length*8;
???????????????????????????????????????? }
????????????????????????????????? }
????????????????????????? }
static void?dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
????????????????????????? {
}
void?cfb_imageblit(struct fb_info *p, const struct fb_image *image)
???????????????????????? {
??????????????????????????????? u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
????????????????????????????????u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
??????????????????????????????? u32 width = image->width;
??????????????????????????????? u32 dx = image->dx, dy = image->dy;
??????????????????????????????? u8 __iomem *dst1;
??????????????????????????????? if (p->state != FBINFO_STATE_RUNNING)
???????????????????????????????????? return;
??????????????????????????????? bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
??????????????????????????????? start_index = bitstart & (32 - 1);
??????????????????????????????? pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
??????????????????????????????? bitstart /= 8;
??????????????????????????????? bitstart &= ~(bpl - 1);
????????????????????????????????dst1 = p->screen_base + bitstart;
??????????????????????????????? if (p->fbops->fb_sync)
????????????????????????????????????? p->fbops->fb_sync(p);
??????????????????????????????? if (image->depth == 1) {
??????????????????????????????????????? if (p->fix.visual == FB_VISUAL_TRUECOLOR || p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
?????????????????????????????????????????????? fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
?????????????????????????????????????????????? bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
??????????????????????????????????????? } else {
?????????????????????????????????????????????? fgcolor = image->fg_color;
?????????????????????????????????????????????? bgcolor = image->bg_color;
???????????????????????????????? }?
???????????????????????????????? if (32 % bpp == 0 && !start_index && !pitch_index && ((width & (32/bpp-1)) == 0) && bpp >= 8 && bpp <= 32)????
????????????????????????????????????????fast_imageblit(image, p, dst1, fgcolor, bgcolor);
???????????????????????????????? else?
????????????????????????????????????????slow_imageblit(image, p, dst1, fgcolor, bgcolor,start_index, pitch_index);
??????????????????????????? } else
???????????????????????????????????? color_imageblit(image, p, dst1, start_index, pitch_index);
??????????????????????}
static struct fb_ops dn_fb_ops = {
???????????????????????????? .owner??= THIS_MODULE,
?????????????????????????????.fb_blank?= dnfb_blank,
?????????????????????????????.fb_fillrect?= cfb_fillrect,
???????????????????????????? .fb_copyarea?= dnfb_copyarea,
???????????????????????????? .fb_imageblit?= cfb_imageblit,
????????????????????? };
4. 定義及實現(xiàn)總線驅(qū)動結(jié)構(gòu)體及成員函數(shù),如果FB驅(qū)動是掛載在platform總線上,則定義platform_driver結(jié)構(gòu),如果是別的總線,比如PCI總線,在定義pci_driver結(jié)構(gòu)。一般會在總線驅(qū)動成員的probe函數(shù)中調(diào)用FB的函數(shù)framebuffer_alloc與register_framebuffer來申請FB設備及注冊到系統(tǒng)。
static int __devinit dnfb_probe(struct platform_device *dev)
???????????????????? {
??????????????????????????? struct fb_info *info;
??????????????????????????? int err = 0;
??????????????????????????? info =?framebuffer_alloc(0, &dev->dev);
??????????????????????????? if (!info)
????????????????????????????????? return -ENOMEM;
??????????????????????????? info->fbops = &dn_fb_ops;
??????????????????????????? info->fix = dnfb_fix;
??????????????????????????? info->var = dnfb_var;
??????????????????????????? info->var.red.length = 1;
??????????????????????????? info->var.red.offset = 0;
??????????????????????????? info->var.green = info->var.blue = info->var.red;
??????????????????????????? info->screen_base = (u_char *) info->fix.smem_start;
??????????????????????????? err = fb_alloc_cmap(&info->cmap, 2, 0);
??????????????????????????? if (err < 0) {
?????????????????????????????????? framebuffer_release(info);
?????????????????????????????????? return err;
??????????????????????????? }
??????????????????????????? err =?register_framebuffer(info);
??????????????????????????? if (err < 0) {
?????????????????????????????????? fb_dealloc_cmap(&info->cmap);
?????????????????????????????????? framebuffer_release(info);
?????????????????????????????????? return err;
???????????????????????????? }
???????????????????????????? platform_set_drvdata(dev, info);
???????????????????????????? out_8(AP_CONTROL_3A, RESET_CREG);
???????????????????????????? out_be16(AP_WRITE_ENABLE, 0x0);
???????????????????????????? out_8(AP_CONTROL_0, NORMAL_MODE);
???????????????????????????? out_8(AP_CONTROL_1, (AD_BLT | DST_EQ_SRC | NORM_CREG1));
???????????????????????????? out_8(AP_CONTROL_2, S_DATA_PLN);
?????????????????????????????out_be16(AP_ROP_1, SWAP(0x3));
???????????????????????????? return err;
?????????????????????? }
static struct platform_driver dnfb_driver = {
???????????????????????????? .probe?= dnfb_probe,
???????????????????????????? .driver?= {
???????????????????????????????????? .name?= "dnfb",
????????????????????????????? },
?????????????????????? };
???????????????????????static struct platform_device dnfb_device = {
????????????????????????????? .name?= "dnfb",
?????????????????????? };
5. 調(diào)用總線驅(qū)動注冊函數(shù)把FB驅(qū)動注冊到系統(tǒng)。
int __init dnfb_init(void)
???????????????????? {
?????????????????????????? int ret;
?????????????????????????? if (!MACH_IS_APOLLO)
???????????????????????????????? return -ENODEV;
???????????????????????????if (fb_get_options("dnfb", NULL))
???????????????????????????????? return -ENODEV;
???????????????????????????ret =?platform_driver_register(&dnfb_driver);
?????????????????????????? if (!ret) {
???????????????????????????????? ret =?platform_device_register(&dnfb_device);
?????????????????????????? if (ret)
???????????????????????????????? platform_driver_unregister(&dnfb_driver);
?????????????????????????? }
?????????????????????????? return ret;
???????????????????? }
???????????????????? module_init(dnfb_init);
?
評論
查看更多