我是靠谱客的博主 辛勤抽屉,最近开发中收集的这篇文章主要介绍LCD驱动中的xxx_probe()函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

LCD驱动是一个标准的platform驱动。当驱动和设备匹配以后,mxsfb_probe 函数就会执行。
mxsfb_probe 函数的主要工作是:
1)、申请fb_info。

framebuffer_alloc()

2)、初始化fb_info结构体中,各个成员变量。
3)、初始化eLCDIF控制器。
4)、使用register_frambebuffer函数向Linux内核注册初始化好的fb_info结构体。
mxsfb_probe 函数中,重要函数/结构体的简要的说明:
1)、
Linux内核将所有的Framebuffer抽象为一个叫fb_info的结构体,fb_info结构体里面包含Framerbuffer设备完整的属性和操作集合,因此,每一个Framebuffer都必须有一个fb_info结构体。换言之,就是lcd驱动,实质上,就是构建fb_info结构体,并且向系统注册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 位调色板 */
......
};

这个结构体里面的成员变量很多,重要的有如上六个。
2)、register_framebuffer 函数

int register_framebuffer(struct fb_info *fb_info)

3)、mxsfb_probe 函数的主要梳理:
①、

struct mxsfb_info *host;

定义结构体指针变量host,表示IMX6ULL的LCD主控接口,这个结构体是自定义的,里面的成员变量记录了Framebuffer 设备详细信息,比如时钟、 eLCDIF控制器寄存器基地址、 fb_info(struct fb_info *fb_info) 等
②、

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

从设备树中,获取eLCDIF接口控制器的寄存器首地址。寄存器首地址信息,已经在设备树中的,对应的lcd节点中设置了。

lcdif: lcdif@021c8000 {
		compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
	。。。。。。
	};

③、给host、fb_info申请内存

host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);

④、通过这一步就将前面申请的 host 和 fb_info 联系在了一起。

host->fb_info = fb_info;
fb_info->par = host;  

⑤、对从设备树中获取到的寄存器首地址(res)进行内存映射,得到虚拟地址,并保存到host的base成员变量里面。之后,只要通过访问 host 的 base 成员即可访问 I.MX6ULL 的整个 eLCDIF寄存器。

host->base = devm_ioremap_resource(&pdev->dev, res);

⑥、给pseudo_palette申请内存。

fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,GFP_KERNEL);

⑦、调用 mxsfb_init_fbinfo 函数初始化 fb_info,重点是 fb_info 的 var、 fix、 fbops(操作集),screen_base 和 screen_size。

mxsfb_init_fbinfo(host);
//从设备树中,获取LCD各个参数的信息
    -mxsfb_init_fbinfo_dt(host);
//申请LCD的帧缓冲内存(就是缓存)
    -mxsfb_map_videomem(fb_info)

类似于字符设备操作集file_operations(这里面的函数,已经由芯片厂商写好):

static struct fb_ops mxsfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = mxsfb_check_var,
.fb_set_par = mxsfb_set_par,
.fb_ioctl = mxsfb_ioctl,
.fb_blank = mxsfb_blank,
.fb_pan_display = mxsfb_pan_display,
.fb_mmap = mxsfb_mmap,
……
};

⑧、设置eLCDIF控制器相应的寄存器

mxsfb_set_par(fb_info); //函数里面包含大量的writel()函数
eg:
 {   writel(CTRL1_FIFO_CLEAR, host->base + REG_SET);
     writel(ctrl, host->base + LCDC_CTRL);  ……   }
mxsfb_enable_controller(fb_info);  //同上(大量的writel())

⑨、调用 register_framebuffer 函数向 Linux 内核注册 fb_info

最后

以上就是辛勤抽屉为你收集整理的LCD驱动中的xxx_probe()函数的全部内容,希望文章能够帮你解决LCD驱动中的xxx_probe()函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部