LCD驱动--二 写lcd驱动 1.分配,设置fb_info (转载)

一:步骤分析:

在上一节LCD层次分析中,得出写个LCD驱动入口函数,需要以下4步:

  •   1) 分配一个fb_info结构体: framebuffer_alloc();
      2) 设置fb_info
      3) 设置硬件相关的操作
      4) 使能LCD,并注册fb_info: register_framebuffer()
    

具体步骤如下:

在驱动init入口函数中:

1)分配一个fb_info结构体

2)设置fb_info

2.1)设置固定的参数fb_info-> fix

2.2) 设置可变的参数fb_info-> var

2.3) 设置操作函数fb_info-> fbops

2.4) 设置fb_info 其它的成员

3)设置硬件相关的操作

3.1)配置LCD引脚

3.2)根据LCD手册设置LCD控制器

3.3)分配显存(framebuffer),把地址告诉LCD控制器和fb_info

4)开启LCD,并注册fb_info: register_framebuffer()

4.1) 直接在init函数中开启LCD(后面讲到电源管理,再来优化)

控制LCDCON5允许PWREN信号,

然后控制LCDCON1输出PWREN信号,

输出GPB0高电平来开背光,

4.2) 注册fb_info

二: 分配,设置fb_info结构体

具体操作

   1)分配一个fb_info结构体     
   2)设置fb_info
        2.1)设置固定的参数fb_info-> fix
       2.2) 设置可变的参数fb_info-> var       
       2.3) 设置操作函数fb_info-> fbops       
       2.4) 设置fb_info 其它的成员

相关API:
1.分配一个fb_info结构体

    struct fb_info *framebuffer_alloc(size_t size, struct device *dev);      //申请一个fb_info结构体,
//size:额外的内存,
//*dev:指针, 这里填0,表示这个申请的结构体里没有内容

2.fb_info结构体如下:

struct fb_info {
        ... ...
       struct fb_var_screeninfo var;       //可变的参数
       struct fb_fix_screeninfo fix;        //固定的参数
       ... ...
       struct fb_ops *fbops;              //操作函数
       ... ...
       char __iomem *screen_base;        //显存虚拟起始地址
       unsigned long screen_size;          //显存虚拟地址长度
  
       void *pseudo_palette;                
//假的16色调色板,里面存放了16色的数据,可以通过8bpp数据来找到调色板里面的16色颜色索引值,模拟出16色颜色来,节省内存,不需要的话就指向一个不用的数组即可
       ... ...
};

3.固定的参数fb_info-> fix 结构体如下:

struct fb_fix_screeninfo {
       char id[16];                   //id名字
       unsigned long smem_start;  //framebuffer物理起始地址                          
       __u32 smem_len;           //framebuffer长度,字节为单位
       __u32 type;                 //lcd类型,默认值0即可
       __u32 type_aux;               //附加类型,为0
       __u32 visual;                     //画面设置,常用参数如下
// FB_VISUAL_MONO01             0   单色,0:白色,1:黑色
// FB_VISUAL_MONO10             1    单色,1:白色,0:黑色
// FB_VISUAL_TRUECOLOR          2     真彩(TFT:真彩)
// FB_VISUAL_PSEUDOCOLOR     3     伪彩
// FB_VISUAL_DIRECTCOLOR        4     直彩

    __u16 xpanstep;                /*如果没有硬件panning就赋值为0 */
    __u16 ypanstep;                /*如果没有硬件panning就赋值为0 */
    __u16 ywrapstep;                 /*如果没有硬件ywrap就赋值为0 */

    __u32 line_length;                 /*一行的字节数 ,例:(RGB565)240*320,那么这里就等于240*16/8 */

    /*以下成员都可以不需要*/
    unsigned long mmio_start;        /*内存映射IO的起始地址,用于应用层直接访问寄存器,可以不需要*/                                   
       __u32 mmio_len;                   /* 内存映射IO的长度,可以不需要*/
       __u32 accel;                 
       __u16 reserved[3];        

};

4.可变的参数fb_info-> var 结构体如下:

structfb_var_screeninfo{                                    
   __u32xres;                    /*可见屏幕一行有多少个像素点*/
    __u32 yres;                      /*可见屏幕一列有多少个像素点*/
    __u32 xres_virtual;         /*虚拟屏幕一行有多少个像素点 */       
    __u32  yres_virtual;       /*虚拟屏幕一列有多少个像素点*/
    __u32 xoffset;                 /*虚拟到可见屏幕之间的行偏移,若可见和虚拟的分辨率一样,就直接设为0*/
    __u32 yoffset;                 /*虚拟到可见屏幕之间的列偏移*/
    __u32  bits_per_pixel;    /*每个像素的位数即BPP,比如:RGB565则填入16*/
    __u32 grayscale;           /*非0时,指的是灰度,真彩直接填0即可*/

    struct fb_bitfield red;          //fb缓存的R位域, fb_bitfield结构体成员如下:
//__u32 offset;          区域偏移值,比如RGB565中的R,就在第11位
//__u32 length;                   区域长度,比如RGB565的R,共有5位
//__u32 msb_right;  msb_right ==0,表示数据左边最大, msb_right!=0,表示数据右边最大


    struct fb_bitfield green;    /*fb缓存的G位域*/
    struct fb_bitfield blue;       /*fb缓存的B位域*/

   /*以下参数都可以不填,默认为0*/
    struct fb_bitfield transp;   /*透明度,不需要填0即可*/    
 
    __u32nonstd;                    /* != 0表示非标准像素格式*/
    __u32 activate;                 /*设为0即可*/
    __u32height;                     /*外设高度(单位mm),一般不需要填*/
    __u32width;                      /*外设宽度(单位mm),一般不需要填*/
    __u32 accel_flags;        /*过时的参数,不需要填*/

    /* 除了pixclock本身外,其他的都以像素时钟为 单位*/ 
    __u32pixclock;                   /*像素时钟(皮秒)*/
    __u32 left_margin;         /*行切换,从同步到绘图之间的延迟*/
    __u32right_margin;        /*行切换,从绘图到同步之间的延迟*/
    __u32upper_margin;       /*帧切换,从同步到绘图之间的延迟*/
    __u32lower_margin;       /*帧切换,从绘图到同步之间的延迟*/
    __u32hsync_len;              /*水平同步的长度*/
    __u32 vsync_len;           /*垂直同步的长度*/
    __u32 sync;
    __u32 vmode;
    __u32 rotate;
    __u32reserved[5];        /*保留*/

}

5.操作函数fb_info-> fbops 结构体写法如下:

static struct fb_ops s3c_lcdfb_ops = {
         .owner                = THIS_MODULE,

         .fb_setcolreg    = my_lcdfb_setcolreg,//设置调色板fb_info-> pseudo_palette,自己构造该函数

         .fb_fillrect      = cfb_fillrect,     //填充矩形,用/drivers/video/ cfbfillrect.c里的函数即可

         .fb_copyarea    = cfb_copyarea,  //复制数据, 用/drivers/video/cfbcopyarea.c里的函数即可

         .fb_imageblit    = cfb_imageblit, //绘画图形, 用/drivers/video/imageblit.c里的函数即可
};

具体代码如下:

    static int lcd_init(void)
{
/*1.分配一个fb_info结构体:framebuffer_alloc*/
	s3c_lcd_info = framebuffer_alloc(0, NULL);  /*申请一个fb_info结构体,size:额外的内存,这里为0,表示不需要,*dev:指针, 这里填NULL,表示这个申请的结构体里没有内容*/

/*2.设置fb_info*/
    /*2.1设置固定参数fd_info->fix*/
	strcpy(s3c_lcd_info->fix.id,"mylcd");     //id名字,将mylcd字符串复制到fix.id数组
	s3c_lcd_info->fix.smem_len= 480*272*2;    //显存farmebuffer长度
	s3c_lcd_info->fix.type = FB_TYPE_PACKED_PIXELS;   //lcd类型,就取默认值
	s3c_lcd_info->fix.visual = FB_VISUAL_TRUECOLOR;    //lcd颜色,黑白还是彩色
	s3c_lcd_info->fix.line_length = 480*2;             //一行的长度


	
	
	/*2.2设置可变参数fd_info->var*/
	s3c_lcd_info->var.xres = 480;               //行分辨率 480
	s3c_lcd_info->var.yres = 272;               //列分辨率 272
	s3c_lcd_info->var.xres_virtual = 480;
	s3c_lcd_info->var.yres_virtual = 272;
	s3c_lcd_info->var.bits_per_pixel = 16;    //每个像素的位数即BPP,比如:RGB565则填入16

	/*设置RGB的位域:565*/
	s3c_lcd_info->var.red.offset = 11;
	s3c_lcd_info->var.red.length = 5;

	s3c_lcd_info->var.green.offset = 5;
	s3c_lcd_info->var.green.length = 6;

	s3c_lcd_info->var.blue.offset = 0;
	s3c_lcd_info->var.blue.length = 5;


	s3c_lcd_info->var.activate = FB_ACTIVATE_NOW;
	
	  /*2.3设置操作函数fd_info->fbops*/

	s3c_lcd_info->fbops = &s3c2440_ops;
	  
	  /*2.4其他设置*/
	s3c_lcd_info->screen_size = 480*272*16/8;       //显存的大小
	//s3c_lcd_info->screen_base = ;                  	//显存的虚拟地址
	s3c_lcd_info->pseudo_palette = pseudo_palette;                //假调色板
	
/*3.硬件相关操作*/

转载自https://www.cnblogs.com/lifexy/p/7604011.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值