1. 程式人生 > >LCD驅動程式架構和分析

LCD驅動程式架構和分析

一、LCD驅動程式架構
1.裸機驅動程式碼分析
①LCD初始化:控制器初始化,埠初始化,指明幀緩衝
②LCD圖形顯示:將圖形資料寫入幀緩衝
  1. void lcd_init()
  2. {
  3.     lcd_port_init();     //初始化gpdcon和gpccon初始化
  4.     lcd_control_init();   //時序初始化和幀緩衝初始化
  5.     //開啟LCD電源
  6.     GPGCON |= 0b11<<8;
  7.     LCDCON5 |= (1<<3);
  8.     LCDCON1 |
    = 1;
  9. }
2.幀緩衝體驗
幀緩衝:記憶體中的一段區域,通過對記憶體的修改。LCD控制器從記憶體中獲取資料,自動的控制LCD的顯示。
  1. # cat tq2440.bin > /dev/fb0
將圖片顯示到lcd。

3.幀緩衝架構
/dev/fb0就是幀緩衝,字元裝置
fbmem_init():
  1. static int __init
  2. fbmem_init(void)
  3. {
  4.     proc_create("fb", 0, NULL, &fb_proc_fops);
  5.     if (register_chrdev(
    FB_MAJOR,"fb",&fb_fops))                                                    //註冊裝置檔案,註冊幀緩衝,fp_fops是操作函式集
  6.         printk("unable to get major %d for fb devs\n", FB_MAJOR);
  7.     fb_class = class_create(THIS_MODULE, "graphics");
  8.     if (IS_ERR(fb_class)) {
  9.         printk(KERN_WARNING "Unable to create fb class; errno = %ld\n"
    , PTR_ERR(fb_class));
  10.         fb_class = NULL;
  11.     }
  12.     return 0;
  13. }
fb_ops:
  1. static const struct file_operations fb_fops = {
  2.     .owner =    THIS_MODULE,
  3.     .read =        fb_read,                                        //寫入
  4.     .write =    fb_write,
  5.     .unlocked_ioctl = fb_ioctl,
  6. #ifdef CONFIG_COMPAT
  7.     .compat_ioctl = fb_compat_ioctl,
  8. #endif
  9.     .mmap =        fb_mmap,
  10.     .open =        fb_open,
  11.     .release =    fb_release,
  12. #ifdef HAVE_ARCH_FB_UNMAPPED_AREA
  13.     .get_unmapped_area = get_fb_unmapped_area,
  14. #endif
  15. #ifdef CONFIG_FB_DEFERRED_IO
  16.     .fsync =    fb_deferred_io_fsync,
  17. #endif
  18. };
fb_write:
  1. static ssize_t
  2. fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
  3. {
  4.     unsigned long p = *ppos;
  5.     struct inode *inode = file->f_path.dentry->d_inode;
  6.     int fbidx = iminor(inode);
  7.     struct fb_info *info = registered_fb[fbidx];
  8.     u32 *buffer, *src;
  9.     u32 __iomem *dst;
  10.     int c, i, cnt = 0, err = 0;
  11.     unsigned long total_size;
  12.     if (!info || !info->screen_base)
  13.         return -ENODEV;
  14.     if (info->state != FBINFO_STATE_RUNNING)
  15.         return -EPERM;
  16.     if (info->fbops->fb_write)
  17.         return info->fbops->fb_write(info, buf, count, ppos);
  18.     total_size = info->screen_size;
  19.     if (total_size == 0)
  20.         total_size = info->fix.smem_len;
  21.     if (p > total_size)
  22.         return -EFBIG;
  23.     if (count > total_size) {
  24.         err = -EFBIG;
  25.         count = total_size;
  26.     }
  27.     if (count + p > total_size) {
  28.     .........各種info
  29. }

info結構:
  1. struct fb_info {
  2.     int node;
  3.     int flags;
  4.     struct mutex lock;                                //控制io操作鎖
  5.     struct fb_var_screeninfo var;/*LCD可變引數*/
  6.     struct fb_fix_screeninfo fix;/*LCD固定引數*/
  7.     struct fb_monspecs monspecs; /*LCD顯示器標準*/
  8.     struct work_struct queue; /*幀緩衝事件佇列*/
  9.     struct fb_pixmap pixmap; /*影象硬體mapper*/
  10.     struct fb_pixmap sprite; /*游標硬體mapper*/
  11.     struct fb_cmap cmap; /*當前的顏色表*/
  12.     struct fb_videomode *mode; /*當前的顯示模式*/
  13. #ifdef CONFIG_FB_BACKLIGHT
  14.     struct backlight_device *bl_dev;/*對應的背光裝置*/
  15.     struct mutex bl_curve_mutex;
  16.     u8 bl_curve[FB_BACKLIGHT_LEVELS];/*背光調整*/
  17. #endif
  18. #ifdef CONFIG_FB_DEFERRED_IO
  19.     struct delayed_work deferred_work;
  20.     struct fb_deferred_io *fbdefio;
  21. #endif
  22.     struct fb_ops *fbops; /*對底層硬體操作的函式指標*/
  23.     struct device *device;
  24.     struct device *dev; /*fb裝置*/
  25.     int class_flag;
  26. #ifdef CONFIG_FB_TILEBLITTING
  27.     struct fb_tile_ops *tileops; /*圖塊Blitting*/
  28. #endif
  29.     char __iomem *screen_base; /*虛擬基地址*/
  30.     unsigned long screen_size; /*LCD IO對映的虛擬記憶體大小*/
  31.     void *pseudo_palette; /*偽16色顏色表*/
  32. #define FBINFO_STATE_RUNNING 0
  33. #define FBINFO_STATE_SUSPENDED 1
  34.     u32 state; /*LCD的掛起或恢復狀態*/
  35.     void *fbcon_par;
  36.     void *par;
  37. };
主要是fb_var_screeninfo、fb_fix_screeninfo、fb_ops三個結構體:
struct fb_var_screeninfo:主要記錄使用者可以修改的控制器的引數。
  1. struct fb_var_screeninfo {
  2.     __u32 xres;            /* visible resolution        */
  3.     __u32 yres;
  4.     __u32 xres_virtual;        /* virtual resolution        */
  5.     __u32 yres_virtual;
  6.     __u32 xoffset;            /* offset from virtual to visible */
  7.     __u32 yoffset;            /* resolution            */
  8.     __u32 bits_per_pixel;        /* guess what            */每個畫素的位數即BPP
  9.     __u32 grayscale;        /* != 0 Graylevels instead of colors */
  10.     struct fb_bitfield red;        /* bitfield in fb mem if true color, */
  11.     struct fb_bitfield green;    /* else only length is significant */
  12.     struct fb_bitfield blue;
  13.     struct fb_bitfield transp;    /* transparency            */    
  14.     __u32 nonstd;            /* != 0 Non standard pixel format */
  15.     __u32 activate;            /* see FB_ACTIVATE_*        */
  16.     __u32 height;            /* height of picture in mm */
  17.     __u32 width;            /* width of picture in mm */
  18.     __u32 accel_flags;        /* (OBSOLETE) see fb_info.flags */
  19.     /* Timing: All values in pixclocks, except pixclock (of course) */
  20.     __u32 pixclock;            /* pixel clock in ps (pico seconds) */
  21.     __u32 left_margin;        /* time from sync to picture    */
  22.     __u32 right_margin;        /* time from picture to sync    */
  23.     __u32 upper_margin;        /* time from sync to picture    */
  24.     __u32 lower_margin;
  25.     __u32 hsync_len;        /* length of horizontal sync    */
  26.     __u32 vsync_len;        /* length of vertical sync    */
  27.     __u32 sync;            /* see FB_SYNC_*        */
  28.     __u32 vmode;            /* see FB_VMODE_*        */
  29.     __u32 rotate;            /* angle we rotate counter clockwise */
  30.     __u32 reserved[5];        /* Reserved for future compatibility */
  31. };
fb_fix_screeninfo:主要記錄使用者不可以修改的控制器的引數
  1. struct fb_fix_screeninfo {
  2.     char id[16];            /* identification string eg "TT Builtin" */
  3.     unsigned long smem_start;    /* Start of frame buffer mem */
  4.                     /* (physical address) */
  5.     __u32 smem_len;            /* Length of frame buffer mem */
  6.     __u32 type;            /* see FB_TYPE_*        */
  7.     __u32 type_aux;            /* Interleave for interleaved Planes */
  8.     __u32 visual;            /* see FB_VISUAL_*        */
  9.     __u16 xpanstep;            /* zero if no hardware panning */
  10.     __u16 ypanstep;            /* zero if no hardware panning */
  11.     __u16 ywrapstep;        /* zero if no hardware ywrap */
  12.     __u32 line_length;        /* length of a line in bytes */
  13.     unsigned long mmio_start;    /* Start of Memory Mapped I/O */
  14.                     /* (physical address) */
  15.     __u32 mmio_len;            /* Length of Memory Mapped I/O */
  16.     __u32 accel;            /* Indicate to driver which    */
  17.                     /* specific chip/card we have    */
  18.     __u16 reserved[3];        /* Reserved for future compatibility */
  19. };
fb_ops:底層硬體操作的函式指標
  1. struct fb_ops {
  2.     /* open/release and usage marking */
  3.     struct module *owner;
  4.     int (*fb_open)(struct fb_info *info, int user);
  5.     int (*fb_release)(struct fb_info *info, int user);
  6.     /* For framebuffers with strange non linear layouts or that do not
  7.      * work with normal memory mapped access
  8.      */
  9.     ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
  10.              size_t count, loff_t *ppos);
  11.     ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
  12.              size_t count, loff_t *ppos);
  13.     /* checks var and eventually tweaks it to something supported,
  14.      * DO NOT MODIFY PAR */
  15.     int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
  16.     /* set the video mode according to info->var */
  17.     int (*fb_set_par)(struct fb_info *info);
  18.     /* set color register */
  19.     int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
  20.              unsigned blue, unsigned transp, struct fb_info *info);
  21.     /* set color registers in batch */
  22.     int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
  23.     /* blank display */
  24.     int (*fb_blank)(int blank, struct fb_info *info);
  25.     /* pan display */
  26.     int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
  27.     /* Draws a rectangle */
  28.     void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
  29.     /* Copy data from area to another */
  30.     void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
  31.     /* Draws a image to the display */
  32.     void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
  33.     /* Draws cursor */
  34.     int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
  35.     /* Rotates the display */
  36.     void (*fb_rotate)(struct fb_info *info, int angle);
  37.     /* wait for blit idle, optional */
  38.     int (*fb_sync)(struct fb_info *info);
  39.     /* perform fb specific ioctl (optional) */
  40.     int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
  41.             unsigned long arg);
  42.     /* Handle 32bit compat ioctl (optional) */
  43.     int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
  44.             unsigned long arg);
  45.     /* perform fb specific mmap */
  46.     int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
  47.     /* save current hardware state */
  48.     void (*fb_save_state)(struct fb_info *info);
  49.     /* restore saved state */
  50.     void (*fb_restore_state)(struct fb_info *info);
  51.     /* get capability given var */
  52.     void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
  53.              struct fb_var_screeninfo *var);
  54. };
http://www.cnblogs.com/lishixian/articles/2999923.html

二、LCD驅動程式分析
s3c2410fb_init:
  1. int __init s3c2410fb_init(void)
  2. {
  3.     int ret = platform_driver_register(&s3c2410fb_driver);                        //註冊平臺驅動裝置
  4.     if (ret == 0)
  5.         ret = platform_driver_register(&s3c2412fb_driver);;
  6.     return ret;
  7. }
s3c2410fb_driver:
  1. static struct platform_driver s3c2410fb_driver = {
  2.     .probe        = s3c2410fb_probe,                                                //probe函式,裡面呼叫了s3c24xxfb_probe
  3.     .remove        = s3c2410fb_remove,
  4.     .suspend    = s3c2410fb_suspend,
  5.     .resume        = s3c2410fb_resume,
  6.     .driver        = {
  7.         .name    = "s3c2410-lcd",
  8.         .owner    = THIS_MODULE,
  9.     },
  10. };
s3c24xxfb_probe:
  1. static int __init s3c24xxfb_probe(struct platform_device *pdev,
  2.                  enum s3c_drv_type drv_type)
  3. {
  4.     struct s3c2410fb_info *info;
  5.     struct s3c2410fb_display *display;
  6.     struct fb_info *fbinfo;
  7.     struct s3c2410fb_mach_info *mach_info;
  8.     struct resource *res;
  9.     int ret;
  10.     int irq;
  11.     int i;
  12.     int size;
  13.     u32 lcdcon1;
  14.     mach_info = pdev->dev.platform_data;
  15.     if (mach_info == NULL) {
  16.         dev_err(&pdev->dev,
  17.             "no platform data for lcd, cannot attach\n");
  18.         return -EINVAL;
  19.     }
  20.     if (mach_info->default_display >= mach_info->num_displays) {
  21.         dev_err(&pdev->dev, "default is %d but only %d displays\n",
  22.             mach_info->default_display, mach_info->num_displays);
  23.         return -EINVAL;
  24.     }
  25.     display = mach_info->displays + mach_info->default_display;
  26.     irq = platform_get_irq(pdev, 0);                                                       //獲取中斷號
  27.     if (irq < 0) {
  28.         dev_err(&pdev->dev, "no irq for device\n");
  29.         return -ENOENT;
  30.     }
  31.     fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);                 //分配fb_info結構
  32.     if (!fbinfo)
  33.         return -ENOMEM;
  34.     platform_set_drvdata(pdev, fbinfo);
  35.     info = fbinfo->par;
  36.     info->dev = &pdev->dev;
  37.     info->drv_type = drv_type;
  38.     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);                                   //獲取暫存器地址
  39.     if (res == NULL) {
  40.         dev_err(&pdev->dev, "failed to get memory registers\n");
  41.         ret = -ENXIO;
  42.         goto dealloc_fb;
  43.     }
  44.     size = (res->end - res->start) + 1;
  45.     info->mem = request_mem_region(res->start, size, pdev->name);
  46.     if (info->mem == NULL) {
  47.         dev_err(&pdev->dev, "failed to get memory region\n");
  48.         ret = -ENOENT;
  49.         goto dealloc_fb;
  50.     }
  51.     info->io =<