IMX6ULL LCD驱动(一)

IMX6 专栏收录该内容
11 篇文章 0 订阅

本小节来分析Linux内核中的LCD框架,只分析基于RGB接口的LCD框架,如果是涉及GPU的那就比较复杂了,

有过应用层对LCD操作的应该知道,上层应用是通过一些Ioctl函数操作/dev/fbxxx,这些函数对内核同统一出来的一套LCD的操作函数,还有,对于不同的单板,其LCD控制器的操作肯定是不同的

所以,从这两方面来看,内核LCD框架肯定有两部分工作要完成

  1. 初始化具体单板的LCD控制器
  2. 注册统一的操作函数为上层应用使用

驱动大多都是这样,应用不关心下面具体的单板,具体的单板只需要实现自己的操作函数,然后注册给内核,通过应用来调用,都是这个套路

在开始之前先来提一个概念,一个RGB接口的LCD对应到/dev/下的一个fb,这个fb就包含了这个屏幕所有的信息,一个fb的数据是由一个fb_info结构体来描述,所以,一个LCD就是一个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 */
	struct fb_fix_screeninfo fix;	/* Current fix */
	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 */

    ......
	struct fb_ops *fbops;
}

fb_info结构体中有一些固定的参数,一些可变的参数,可变参数就包括LCD的那些时间参数,最重要的就是fb_ops操作函数,就是为应用提供的操作函数.

现在开始分析驱动,不从所谓的核心层开始分析,直接从具体的设备分析,平台为飞思卡尔的RGB LCD驱动,  drivers\video\fbdev\mxsfb.c

注册平台设备驱动,如果要添加LCD的话需要注意匹配列表,

分析probe函数

static int mxsfb_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct mxsfb_info *host;
	struct fb_info *fb_info;
	struct pinctrl *pinctrl;

	gpio = of_get_named_gpio(pdev->dev.of_node, "enable-gpio", 0);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

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


	fb_info = framebuffer_alloc(0, &pdev->dev);

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

	ret = devm_request_irq(&pdev->dev, irq, mxsfb_irq_handler, 0, dev_name(&pdev->dev), host);


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

	platform_set_drvdata(pdev, host);


	INIT_LIST_HEAD(&fb_info->modelist);

	ret = mxsfb_init_fbinfo(host);
	
	ret = mxsfb_dispdrv_init(pdev, fb_info);

	ret = register_framebuffer(fb_info);

	mxsfb_overlay_init(host);

	return 0;
}

probe函数很长,我尽量留下了一些必要的信息,

  1. 函数一开始,定义了一个struct mxsfb_info结构体类型的变量,这个结构体是厂商自己定义的,点进去就会发现,其内部包含了一个struct fb_info,重点就是对它进行设置和注册,其余的一些是辅助变量,根据具体情况而定
  2. 申请"enable-gpio",有的屏幕需要由一个IO来控制整个屏幕的上电和下电,视具体情况而定
  3. 通过platform_get_resource函数获取平台驱动的IORESOURCE_MEM类型的变量,在设备树中就是reg的值,reg就是某一款单板的LCD控制器的基地址,这里就是去获取基地址的值
  4. 分配一些变量的空间,host和fb_info,然后两者关联在一起
  5. 中断相关操作
  6. 很重要,映射LCD控制寄存器的基地址,放到host->base中,有了基地址,根据偏移值就可以访问到LCD控制器的寄存器地址
  7. 一些时钟的设置,这里省略掉了
  8. 调用mxsfb_init_fbinfo函数做一些初始化工作

这个函数很重要,

一开始是设置fb_info的一些变量,fix是固定的意思,设置一个固定参数的值,关键是设置操作函数fb_info->fbops = &mxsfb_ops;

然后调用mxsfb_init_fbinfo_dt函数进一步设置,这个函数是获取设备树中的信息来设置屏幕参数的可变信息,也就是时序

函数很长,不列出函数体,作总结即可

  1. host->id = of_alias_get_id(np, "lcdif"); 读取设备树的lcdif节点,这个节点就对应的是LCD接口的节点
  2. of_property_read_u32(display_np, "bus-width", &width);  获取总线宽度,就是多少根数据线传输LCD数据
  3. of_property_read_u32(display_np, "bits-per-pixel",&var->bits_per_pixel);  每一个像素点占多少个bit
  4. of_find_node_by_name(display_np,"display-timings"); 获取时序参数了,在设备树的display-timings中指定
  5. 接下来是一个循环,如果有多个display-timings的话就把所有的参数都读出来放到vm中,然后从vm中把参数复制到变量fb_vm中, 再把fb_vm添加到fb_info的modelist中fb_add_videomode(&fb_vm, &fb_info->modelist);

到这里就执行完了,所以mxsfb_init_fbinfo_dt函数是循环读取设备树的时序参数,如果有多个的话,就把他们都添加到fb_info的modelist链表中

接着分析mxsfb_init_fbinfo函数,设置完modelist之后会把第一个作为默认的显示参数,赋值为var,

然后调用mxsfb_check_var函数检查参数,这个函数中做分辨率和总线宽度的检查,

紧接着计算行分辨率的字节数和缓存大小,然后调用mxsfb_map_videomem函数分配LCD的显存空间

最后一个函数mxsfb_restore_mode,点进去可以发现,这里就是根据前面读出来的屏幕参数去设置LCD控制寄存器了,

最后,缓存清零

这个调用分支就看完了,是去读取参数设置具体单板的LCD控制寄存器的,这一动作执行完毕之后,那接下来,就无疑是去注册前面辛苦设置的fb_info结构体了

回到前面接着分析probe函数

最后调用register_framebuffer函数注册fb_info结构体

总结一下

  1. 申请fb_info结构体
  2. 获取屏幕参数以设置LCD控制寄存器
  3. 注册fb_info结构体

本小节内容也相对较多了,注册fb_info结构体的分析放到下一小节分析.

 

 

 

  • 1
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

1 引言 4 1.1 课程设计目标 4 1.2 编程工具(编程环境)介绍 4 1.3 实施时间及主要实施步骤 4 2 需求分析 5 3 系统总体设计 6 4 数据库设计 6 5 主要功能模块的设计与实现 10 5.1 功能模块1详细设计(综合查询员工信息)..........................................................10 5.1.1 详细设计.......................................................................................................10 5.1.2 算法流程........................................................................................................15 5.1.3 界面设计及测试结果.....................................................................................15 6 调试分析 15 7 用户手册 16 8 测试结果 17 8.1 员工信息的添加...................................................................................................17 8.2 员工信息的修改...................................................................................................17 8.3 员工信息的删除...................................................................................................18 8.4 员工信息的综合查询...........................................................................................18 8.5 员工信息按性别统计的结果................................................................................19 8.6 员工信息按状态统计的结果...............................................................................19 8.7 员工信息按职称统计的结果................................................................................20 9 结论 20 10 参考文献 20
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值