linux lcd设备驱动剖析一
s3c2440 lcd驱动源码文件是:drivers/video/s3c2410fb.c
看驱动源码首先当然是先看入口函数,这里是s3c2410fb_init函数
plain?
- int __init s3c2410fb_init(void)
- {
- /* 注册一个s3c2410fb_driver平台驱动 */
- int ret = platform_driver_register(&s3c2410fb_driver);
- if (ret == 0)
- ret = platform_driver_register(&s3c2412fb_driver);;
- return ret;
- }
出口函数,自然是注销s3c2410fb_driver平台驱动
plain?
- static void __exit s3c2410fb_cleanup(void)
- {
- platform_driver_unregister(&s3c2410fb_driver);
- platform_driver_unregister(&s3c2412fb_driver);
- }
我们研究的是s3c2440,只关心s3c2410fb_driver,s3c2412fb_driver不用理会。
plain?
- static struct platform_driver s3c2410fb_driver = {
- .probe = s3c2410fb_probe,
- .remove = s3c2410fb_remove,
- .suspend = s3c2410fb_suspend,
- .resume = s3c2410fb_resume,
- .driver = {
- .name = "s3c2410-lcd",
- .owner = THIS_MODULE,
- },
- };
这里看到s3c2410fb_driver的name字段为s3c2410-lcd。回顾这钱前面章节说过的知识,如果linux系统中存在同名的平台设备时,就会调用平台驱动的probe函数。这里,如果存在有同名"s3c2410-lcd"的平台设备,就会调用s3c2410fb_driver的s3c2410fb_probe函数。
在source insight搜索s3c2410-lcd,很快就能搜索到arch/arm/plat-s3c24xx/devs.c中有那么一段
plain?
- struct platform_device s3c_device_lcd = {
- .name = "s3c2410-lcd",
- .id = -1,
- .num_resources = ARRAY_SIZE(s3c_lcd_resource),
- .resource = s3c_lcd_resource,
- .dev = {
- .dma_mask = &s3c_device_lcd_dmamask,
- .coherent_dma_mask = 0xffffffffUL
- }
- };
- EXPORT_SYMBOL(s3c_device_lcd);
其中平台设备中比较重要的是成员是resource,这里是s3c_lcd_resource
plain?
- static struct resource s3c_lcd_resource[] = {
- [0] = {
- .start = S3C24XX_PA_LCD, /* 0x4D000000 */
- .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = IRQ_LCD, /* IRQ = 32 */
- .end = IRQ_LCD,
- .flags = IORESOURCE_IRQ,
- }
- };
- static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
那么接下来当然是要分析probe函数了
plain?
- static int __init s3c2410fb_probe(struct platform_device *pdev)
- {
- return s3c24xxfb_probe(pdev, DRV_S3C2410);
- }
s3c2410fb_probe函数调用s3c24xxfb_probe函数,这是lcd驱动的关键函数之一,留到"linux
lcd设备驱动剖析二"再分析,但是在分析这个函数前,需要来熟悉一下几个结构体。
linux lcd驱动中有个关键词叫帧缓冲,它是linux为显示设备提供的一个接口,它允许应用程序在图形模式下直接对显示缓冲区进行读写操作,用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。
帧缓冲设备为标准字符设备,主设备号为29,对应/dev/fbn 设备文件,帧缓冲设备最关键的一个数据结构是fb_info结构体,它包括了关于帧缓冲设备属性和操作的完整描述。
plain?
- struct fb_info {
- int node; //用作次设备号索引
- int flags;
- struct mutex lock; //用于open/release/ioctl函数的锁
- struct fb_var_screeninfo var; //可变参数,重点
- struct fb_fix_screeninfo fix; //固定参数,重点
- struct fb_monspecs monspecs; //显示器标准
- struct work_struct queue; //帧缓冲区队列
- struct fb_pixmap pixmap; //图像硬件映射
- struct fb_pixmap sprite; //光标硬件映射
- struct fb_cmap cmap; //当前颜色表
- struct list_head modelist; //模式链表
- struct fb_videomode *mode; //当前video模式
- char __iomem *screen_base; //显存基地址
- unsigned long screen_size; //显存大小
- void *pseudo_palette; //伪16色颜色表
- #define FBINFO_STATE_RUNNING 0
- #define FBINFO_STATE_SUSPENDED 1
- u32 state; //硬件状态,如挂起
- void *fbcon_par; //用作私有数据区
- void *par; //info->par指向了额外多申请内存空间的首地址
- };
s3c2410fb_info结构体,这是s3c2410抽像出来的特有信息
plain?
- struct s3c2410fb_info {
- struct device *dev; //设备
- struct clk *clk; //时钟
- struct resource *mem; //资源
- void __iomem *io; //IO地址
- void __iomem *irq_base; //IRQ基数
- enum s3c_drv_type drv_type; //驱动类型,S3C2410或S3C2412
- struct s3c2410fb_hw regs; //s3c2410 lcd硬件寄存器
- unsigned int palette_ready; //调色板是否就绪标志位
- /* keep these registers in case we need to re-write palette */
- u32 palette_buffer[256]; //调色板缓冲区
- u32 pseudo_pal[16]; //伪颜色表
- };
s3c2410fb_display结构体,关于LCD参数的描述,如分辨率,LCD类型,BPP等等
plain?
- /* LCD description */
- struct s3c2410fb_display {
- /* LCD type */
- unsigned type;
- /* Screen size */
- unsigned short width;
- unsigned short height;
- /* Screen info */
- unsigned short xres;
- unsigned short yres;
- unsigned short bpp;
- unsigned pixclock; /* pixclock in picoseconds */
- unsigned setclkval; /* clkval */
- unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
- unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
- unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
- unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
- unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
- unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
- /* lcd configuration registers */
- unsigned long lcdcon5;
- };
对于TQ2440的液晶屏实例为tq2440_lcd_cfg,为方便查阅这里省略了其他分辨率的参数设置
plain?
- /* LCD driver info */
- static struct s3c2410fb_display tq2440_lcd_cfg __initdata = {
- .lcdcon5 = S3C2410_LCDCON5_FRM565 |
- S3C2410_LCDCON5_INVVLINE |
- S3C2410_LCDCON5_INVVFRAME |
- S3C2410_LCDCON5_PWREN |
- S3C2410_LCDCON5_HWSWP,
- .type = S3C2410_LCDCON1_TFT,
- /* TQ2440的液晶是4.3寸的,分辨率是480*272 */
- #elif defined(CONFIG_FB_S3C24X0_TFT480272) /* config_EmbedSky_W43:CONFIG_FB_S3C24X0_TFT480272=y */
- .width = 480,
- .height = 272,
- .pixclock = 40000, /* HCLK 100 MHz, divisor 1 */
- .setclkval = 0x4,
- .xres = 480,
- .yres = 272,
- .bpp = 16,
- .left_margin = 19, /* for HFPD*/
- .right_margin = 10, /* for HBPD*/
- .hsync_len = 30, /* for HSPW*/
- .upper_margin = 4, /* for VFPD*/
- .lower_margin = 2, /* for VBPD*/
- .vsync_len = 8, /* for VSPW*/
- };
s3c2410fb_mach_info结构体,它包括了s3c2410fb_display结构体
plain?
- struct s3c2410fb_mach_info {
- struct s3c2410fb_display *displays; //s3c2410fb_display结构体
- unsigned num_displays; //displays的个数
- unsigned default_display; //默认的default_display个数
- /* GPIOs */
- unsigned long gpcup; //GPC
- unsigned long gpcup_mask;
- unsigned long gpccon;
- unsigned long gpccon_mask;
- unsigned long gpdup; //GPD
- unsigned long gpdup_mask;
- unsigned long gpdcon;
- unsigned long gpdcon_mask;
- /* lpc3600 control register */
- unsigned long lpcsel;
- };
要理解s3c24xxfb_probe函数,首先必须理清上面几个结构体之间的关系。
linux lcd设备驱动剖析一的更多相关文章
- linux lcd设备驱动剖析四
在"linux lcd设备驱动剖析二"文章中,我们详细分析了s3c24xxfb_probe函数. 文章链接:http://blog.csdn.net/lwj103862095/ar ...
- linux lcd设备驱动剖析三
上一节文章中详细地剖析了probe函数,但是从始至终都没有看到打开读写文件接口的操作函数,只看到了下面这个操作结构体 [cpp] view plain? static struct fb_ops s3 ...
- linux lcd设备驱动剖析二
上一节中,分析了s3c2410fb,c的入口出口函数,以及一些重要结构体的分析,初步知道了这是一个平台驱动的架构. 上一节文章链接:http://blog.csdn.net/lwj103862095/ ...
- 深入理解Linux字符设备驱动
文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解.本文整合之前发表的& ...
- linux块设备驱动之实例
1.注册:向内核注册个块设备驱动,其实就是用主设备号告诉内核这个代表块设备驱动 sbull_major = register_blkdev(sbull_major, "sbull&quo ...
- Linux 视频设备驱动V4L2最常用的控制命令
http://blog.csdn.net/shaolyh/article/details/6583226 Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02) 命令 功能 VIDIOC ...
- Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】
本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...
- Smart210学习记录----beep linux字符设备驱动
今天搞定了beep linux字符设备驱动,心里还是很开心的,哈哈...但在完成的过程中却遇到了一个非常棘手的问题,花费了我大量的时间,,,, 还是把问题描述一下吧,好像这个问题很普遍的,网上许多解决 ...
- Linux块设备驱动详解
<机械硬盘> a:磁盘结构 -----传统的机械硬盘一般为3.5英寸硬盘,并由多个圆形蝶片组成,每个蝶片拥有独立的机械臂和磁头,每个堞片的圆形平面被划分了不同的同心圆,每一个同心圆称为一个 ...
随机推荐
- Educational Codeforces Round 23D
给n个数求每个子区间的价值,区间的价值是最大值-最小值 套路题= =,分别算最大值和最小值的贡献,用并查集维护,把相邻点连一条边,然后sort,求最大是按边价值(两个点的最大价值)小的排,求最小是按最 ...
- SimpleDateFormat函数语法
SimpleDateFormat函数语法: G 年代标志符 y 年 M 月 d 日 h 时 在上午或下午 (1~12) ...
- day5-shutil模块
一.概述 我们通过python操作文件时,除正常读写操作外,有时还需要进行拷贝.删除.打包等操作,虽然os模块提供了部分功能,但还是不够完善,这里要讲讲专业的高级的文件,文件夹,压缩包处理模块shut ...
- null与""的区别
两者的区别与 “数字0和没有不是同一种概念”是一个道理.null是空对象,""是空字符串null可以赋值给任何对象,而""就不行了,只能赋值给字符串对象如:St ...
- 远程登录MySQL
mysql 远程连接数据库的二种方法 一.连接远程数据库: 1.显示密码 如:MySQL 连接远程数据库(192.168.5.116),端口“3306”,用户名为“root”,密码“123456” ...
- 用百度地图API打造方便自己使用的手机地图
有钱人咱就不说了,因为偶是个穷银--因为穷,所以去年买的Huawei C8650+到现在还在上岗,对于没有钱买好的配置的手机的童鞋来说,类似于百度,谷歌,高德等商家的地图在自己的机器上跑起来确实是有点 ...
- Ganymed实现基本的自动化部署API
Ganymed SSH-2 for Java是一个纯Java实现的SHH2库,官网为http://www.ganymed.ethz.ch/ssh2/,最新的更新时间为2006年10月,在用之前,请仔细 ...
- 边缘检测︱基于 HED网络TensorFlow 和 OpenCV 实现图片边缘检测
本文摘录自<手机端运行卷积神经网络的一次实践 – 基于 TensorFlow 和 OpenCV 实现文档检测功能> 只截取感兴趣 的片段. . 一.边缘检测 1.传统边缘检测 Google ...
- 11.求二元查找树的镜像[MirrorOfBST]
[题目] 输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点.用递归和循环两种方法完成树的镜像转换. 例如输入: 8 / \ 6 1 ...
- DEV控件 皮肤问题
今天用cnPack清理了下整个工程的引用单元,清理完,问题来了,TcxPageControl不透明了. 折腾了一会,找到原因,清理单元时将dxSkinscxPCPainter也清掉了,导致皮肤无法正常 ...