LCD驅動程式架構和分析
阿新 • • 發佈:2019-01-04
一、LCD驅動程式架構
1.裸機驅動程式碼分析
①LCD初始化:控制器初始化,埠初始化,指明幀緩衝
②LCD圖形顯示:將圖形資料寫入幀緩衝
幀緩衝:記憶體中的一段區域,通過對記憶體的修改。LCD控制器從記憶體中獲取資料,自動的控制LCD的顯示。
3.幀緩衝架構
/dev/fb0就是幀緩衝,字元裝置
fbmem_init():
info結構:
struct fb_var_screeninfo:主要記錄使用者可以修改的控制器的引數。
二、LCD驅動程式分析
s3c2410fb_init:
1.裸機驅動程式碼分析
①LCD初始化:控制器初始化,埠初始化,指明幀緩衝
②LCD圖形顯示:將圖形資料寫入幀緩衝
-
void lcd_init()
-
{
-
lcd_port_init(); //初始化gpdcon和gpccon初始化
-
lcd_control_init(); //時序初始化和幀緩衝初始化
-
//開啟LCD電源
-
GPGCON |= 0b11<<8;
-
LCDCON5 |= (1<<3);
-
LCDCON1 |
- }
幀緩衝:記憶體中的一段區域,通過對記憶體的修改。LCD控制器從記憶體中獲取資料,自動的控制LCD的顯示。
- # cat tq2440.bin > /dev/fb0
3.幀緩衝架構
/dev/fb0就是幀緩衝,字元裝置
fbmem_init():
-
static int __init
-
fbmem_init(void)
-
{
-
proc_create("fb", 0, NULL, &fb_proc_fops);
-
if (register_chrdev(
-
printk("unable to get major %d for fb devs\n", FB_MAJOR);
-
fb_class = class_create(THIS_MODULE, "graphics");
-
if (IS_ERR(fb_class)) {
-
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n"
-
fb_class = NULL;
-
}
-
return 0;
- }
-
static const struct file_operations fb_fops = {
-
.owner = THIS_MODULE,
-
.read = fb_read, //寫入
-
.write = fb_write,
-
.unlocked_ioctl = fb_ioctl,
-
#ifdef CONFIG_COMPAT
-
.compat_ioctl = fb_compat_ioctl,
-
#endif
-
.mmap = fb_mmap,
-
.open = fb_open,
-
.release = fb_release,
-
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
-
.get_unmapped_area = get_fb_unmapped_area,
-
#endif
-
#ifdef CONFIG_FB_DEFERRED_IO
-
.fsync = fb_deferred_io_fsync,
-
#endif
- };
-
static ssize_t
-
fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
-
{
-
unsigned long p = *ppos;
-
struct inode *inode = file->f_path.dentry->d_inode;
-
int fbidx = iminor(inode);
-
struct fb_info *info = registered_fb[fbidx];
-
u32 *buffer, *src;
-
u32 __iomem *dst;
-
int c, i, cnt = 0, err = 0;
-
unsigned long total_size;
-
if (!info || !info->screen_base)
-
return -ENODEV;
-
if (info->state != FBINFO_STATE_RUNNING)
-
return -EPERM;
-
if (info->fbops->fb_write)
-
return info->fbops->fb_write(info, buf, count, ppos);
-
total_size = info->screen_size;
-
if (total_size == 0)
-
total_size = info->fix.smem_len;
-
if (p > total_size)
-
return -EFBIG;
-
if (count > total_size) {
-
err = -EFBIG;
-
count = total_size;
-
}
-
if (count + p > total_size) {
- .........各種info
- }
info結構:
-
struct fb_info {
-
int node;
-
int flags;
-
struct mutex lock; //控制io操作鎖
-
struct fb_var_screeninfo var;/*LCD可變引數*/
-
struct fb_fix_screeninfo fix;/*LCD固定引數*/
-
struct fb_monspecs monspecs; /*LCD顯示器標準*/
-
struct work_struct queue; /*幀緩衝事件佇列*/
-
struct fb_pixmap pixmap; /*影象硬體mapper*/
-
struct fb_pixmap sprite; /*游標硬體mapper*/
-
struct fb_cmap cmap; /*當前的顏色表*/
-
struct fb_videomode *mode; /*當前的顯示模式*/
-
#ifdef CONFIG_FB_BACKLIGHT
-
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; /*對底層硬體操作的函式指標*/
-
struct device *device;
-
struct device *dev; /*fb裝置*/
-
int class_flag;
-
#ifdef CONFIG_FB_TILEBLITTING
-
struct fb_tile_ops *tileops; /*圖塊Blitting*/
-
#endif
-
char __iomem *screen_base; /*虛擬基地址*/
-
unsigned long screen_size; /*LCD IO對映的虛擬記憶體大小*/
-
void *pseudo_palette; /*偽16色顏色表*/
-
#define FBINFO_STATE_RUNNING 0
-
#define FBINFO_STATE_SUSPENDED 1
-
u32 state; /*LCD的掛起或恢復狀態*/
-
void *fbcon_par;
-
void *par;
- };
struct fb_var_screeninfo:主要記錄使用者可以修改的控制器的引數。
-
struct fb_var_screeninfo {
-
__u32 xres; /* visible resolution */
-
__u32 yres;
-
__u32 xres_virtual; /* virtual resolution */
-
__u32 yres_virtual;
-
__u32 xoffset; /* offset from virtual to visible */
-
__u32 yoffset; /* resolution */
-
__u32 bits_per_pixel; /* guess what */每個畫素的位數即BPP
-
__u32 grayscale; /* != 0 Graylevels instead of colors */
-
struct fb_bitfield red; /* bitfield in fb mem if true color, */
-
struct fb_bitfield green; /* else only length is significant */
-
struct fb_bitfield blue;
-
struct fb_bitfield transp; /* transparency */
-
__u32 nonstd; /* != 0 Non standard pixel format */
-
__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 */
-
/* Timing: All values in pixclocks, except pixclock (of course) */
-
__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 */
-
__u32 reserved[5]; /* Reserved for future compatibility */
- };
-
struct fb_fix_screeninfo {
-
char id[16]; /* identification string eg "TT Builtin" */
-
unsigned long smem_start; /* Start of frame buffer mem */
-
/* (physical address) */
-
__u32 smem_len; /* Length of frame buffer mem */
-
__u32 type; /* see FB_TYPE_* */
-
__u32 type_aux; /* Interleave for interleaved Planes */
-
__u32 visual; /* see FB_VISUAL_* */
-
__u16 xpanstep; /* zero if no hardware panning */
-
__u16 ypanstep; /* zero if no hardware panning */
-
__u16 ywrapstep; /* zero if no hardware ywrap */
-
__u32 line_length; /* length of a line in bytes */
-
unsigned long mmio_start; /* Start of Memory Mapped I/O */
-
/* (physical address) */
-
__u32 mmio_len; /* Length of Memory Mapped I/O */
-
__u32 accel; /* Indicate to driver which */
-
/* specific chip/card we have */
-
__u16 reserved[3]; /* Reserved for future compatibility */
- };
- struct fb_ops {
-
/* open/release and usage marking */
-
struct module *owner;
-
int (*fb_open)(struct fb_info *info, int user);
-
int (*fb_release)(struct fb_info *info, int user);
-
/* For framebuffers with strange non linear layouts or that do not
-
* work with normal memory mapped access
-
*/
-
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
-
size_t count, loff_t *ppos);
-
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
-
size_t count, loff_t *ppos);
-
/* checks var and eventually tweaks it to something supported,
-
* DO NOT MODIFY PAR */
-
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
-
/* set the video mode according to info->var */
-
int (*fb_set_par)(struct fb_info *info);
-
/* set color register */
-
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
-
unsigned blue, unsigned transp, struct fb_info *info);
-
/* set color registers in batch */
-
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
-
/* blank display */
-
int (*fb_blank)(int blank, struct fb_info *info);
-
/* pan display */
-
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
-
/* Draws a rectangle */
-
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
-
/* Copy data from area to another */
-
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
-
/* Draws a image to the display */
-
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
-
/* Draws cursor */
-
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
-
/* Rotates the display */
-
void (*fb_rotate)(struct fb_info *info, int angle);
-
/* wait for blit idle, optional */
-
int (*fb_sync)(struct fb_info *info);
-
/* perform fb specific ioctl (optional) */
-
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
-
unsigned long arg);
-
/* Handle 32bit compat ioctl (optional) */
-
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
-
unsigned long arg);
-
/* perform fb specific mmap */
-
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
-
/* save current hardware state */
-
void (*fb_save_state)(struct fb_info *info);
-
/* restore saved state */
-
void (*fb_restore_state)(struct fb_info *info);
-
/* get capability given var */
-
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
-
struct fb_var_screeninfo *var);
- };
二、LCD驅動程式分析
s3c2410fb_init:
-
int __init s3c2410fb_init(void)
-
{
-
int ret = platform_driver_register(&s3c2410fb_driver); //註冊平臺驅動裝置
-
if (ret == 0)
-
ret = platform_driver_register(&s3c2412fb_driver);;
-
return ret;
- }
-
static struct platform_driver s3c2410fb_driver = {
-
.probe = s3c2410fb_probe, //probe函式,裡面呼叫了s3c24xxfb_probe
-
.remove = s3c2410fb_remove,
-
.suspend = s3c2410fb_suspend,
-
.resume = s3c2410fb_resume,
-
.driver = {
-
.name = "s3c2410-lcd",
-
.owner = THIS_MODULE,
-
},
- };
-
static int __init s3c24xxfb_probe(struct platform_device *pdev,
-
enum s3c_drv_type drv_type)
-
{
-
struct s3c2410fb_info *info;
-
struct s3c2410fb_display *display;
-
struct fb_info *fbinfo;
-
struct s3c2410fb_mach_info *mach_info;
-
struct resource *res;
-
int ret;
-
int irq;
-
int i;
-
int size;
-
u32 lcdcon1;
-
mach_info = pdev->dev.platform_data;
-
if (mach_info == NULL) {
-
dev_err(&pdev->dev,
-
"no platform data for lcd, cannot attach\n");
-
return -EINVAL;
-
}
-
if (mach_info->default_display >= mach_info->num_displays) {
-
dev_err(&pdev->dev, "default is %d but only %d displays\n",
-
mach_info->default_display, mach_info->num_displays);
-
return -EINVAL;
-
}
-
display = mach_info->displays + mach_info->default_display;
-
irq = platform_get_irq(pdev, 0); //獲取中斷號
-
if (irq < 0) {
-
dev_err(&pdev->dev, "no irq for device\n");
-
return -ENOENT;
-
}
-
fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); //分配fb_info結構
-
if (!fbinfo)
-
return -ENOMEM;
-
platform_set_drvdata(pdev, fbinfo);
-
info = fbinfo->par;
-
info->dev = &pdev->dev;
-
info->drv_type = drv_type;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); //獲取暫存器地址
-
if (res == NULL) {
-
dev_err(&pdev->dev, "failed to get memory registers\n");
-
ret = -ENXIO;
-
goto dealloc_fb;
-
}
-
size = (res->end - res->start) + 1;
-
info->mem = request_mem_region(res->start, size, pdev->name);
-
if (info->mem == NULL) {
-
dev_err(&pdev->dev, "failed to get memory region\n");
-
ret = -ENOENT;
-
goto dealloc_fb;
-
}
- info->io =<