s3c2440 lcd驱动源码文件是:drivers/video/s3c2410fb.c

看驱动源码首先当然是先看入口函数,这里是s3c2410fb_init函数

[cpp] view
plain
?
  1. int __init s3c2410fb_init(void)
  2. {
  3. /* 注册一个s3c2410fb_driver平台驱动 */
  4. int ret = platform_driver_register(&s3c2410fb_driver);
  5. if (ret == 0)
  6. ret = platform_driver_register(&s3c2412fb_driver);;
  7. return ret;
  8. }

出口函数,自然是注销s3c2410fb_driver平台驱动

[cpp] view
plain
?
  1. static void __exit s3c2410fb_cleanup(void)
  2. {
  3. platform_driver_unregister(&s3c2410fb_driver);
  4. platform_driver_unregister(&s3c2412fb_driver);
  5. }

我们研究的是s3c2440,只关心s3c2410fb_driver,s3c2412fb_driver不用理会。

[cpp] view
plain
?
  1. static struct platform_driver s3c2410fb_driver = {
  2. .probe      = s3c2410fb_probe,
  3. .remove     = s3c2410fb_remove,
  4. .suspend    = s3c2410fb_suspend,
  5. .resume     = s3c2410fb_resume,
  6. .driver     = {
  7. .name   = "s3c2410-lcd",
  8. .owner  = THIS_MODULE,
  9. },
  10. };

这里看到s3c2410fb_driver的name字段为s3c2410-lcd。回顾这钱前面章节说过的知识,如果linux系统中存在同名的平台设备时,就会调用平台驱动的probe函数。这里,如果存在有同名"s3c2410-lcd"的平台设备,就会调用s3c2410fb_driver的s3c2410fb_probe函数。

在source  insight搜索s3c2410-lcd,很快就能搜索到arch/arm/plat-s3c24xx/devs.c中有那么一段

[cpp] view
plain
?
  1. struct platform_device s3c_device_lcd = {
  2. .name         = "s3c2410-lcd",
  3. .id       = -1,
  4. .num_resources    = ARRAY_SIZE(s3c_lcd_resource),
  5. .resource     = s3c_lcd_resource,
  6. .dev              = {
  7. .dma_mask       = &s3c_device_lcd_dmamask,
  8. .coherent_dma_mask  = 0xffffffffUL
  9. }
  10. };
  11. EXPORT_SYMBOL(s3c_device_lcd);

其中平台设备中比较重要的是成员是resource,这里是s3c_lcd_resource

[cpp] view
plain
?
  1. static struct resource s3c_lcd_resource[] = {
  2. [0] = {
  3. .start = S3C24XX_PA_LCD,                /* 0x4D000000 */
  4. .end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
  5. .flags = IORESOURCE_MEM,
  6. },
  7. [1] = {
  8. .start = IRQ_LCD,                       /* IRQ = 32 */
  9. .end   = IRQ_LCD,
  10. .flags = IORESOURCE_IRQ,
  11. }
  12. };
  13. static u64 s3c_device_lcd_dmamask = 0xffffffffUL;

那么接下来当然是要分析probe函数了

[cpp] view
plain
?
  1. static int __init s3c2410fb_probe(struct platform_device *pdev)
  2. {
  3. return s3c24xxfb_probe(pdev, DRV_S3C2410);
  4. }

s3c2410fb_probe函数调用s3c24xxfb_probe函数,这是lcd驱动的关键函数之一,留到"linux
lcd设备驱动剖析二"再分析,但是在分析这个函数前,需要来熟悉一下几个结构体。

linux lcd驱动中有个关键词叫帧缓冲,它是linux为显示设备提供的一个接口,它允许应用程序在图形模式下直接对显示缓冲区进行读写操作,用户不必关心物理显示缓冲区的具体位置及存放方式,这些都由帧缓冲设备驱动本身来完成。

帧缓冲设备为标准字符设备,主设备号为29,对应/dev/fbn 设备文件,帧缓冲设备最关键的一个数据结构是fb_info结构体,它包括了关于帧缓冲设备属性和操作的完整描述。

[cpp] view
plain
?
  1. struct fb_info {
  2. int node;                       //用作次设备号索引
  3. int flags;
  4. struct mutex lock;              //用于open/release/ioctl函数的锁
  5. struct fb_var_screeninfo var;   //可变参数,重点
  6. struct fb_fix_screeninfo fix;   //固定参数,重点
  7. struct fb_monspecs monspecs;    //显示器标准
  8. struct work_struct queue;       //帧缓冲区队列
  9. struct fb_pixmap pixmap;        //图像硬件映射
  10. struct fb_pixmap sprite;        //光标硬件映射
  11. struct fb_cmap cmap;            //当前颜色表
  12. struct list_head modelist;      //模式链表
  13. struct fb_videomode *mode;      //当前video模式
  14. char __iomem *screen_base;      //显存基地址
  15. unsigned long screen_size;      //显存大小
  16. void *pseudo_palette;           //伪16色颜色表
  17. #define FBINFO_STATE_RUNNING    0
  18. #define FBINFO_STATE_SUSPENDED  1
  19. u32 state;                      //硬件状态,如挂起
  20. void *fbcon_par;                //用作私有数据区
  21. void *par;                      //info->par指向了额外多申请内存空间的首地址
  22. };

s3c2410fb_info结构体,这是s3c2410抽像出来的特有信息

[cpp] view
plain
?
  1. struct s3c2410fb_info {
  2. struct device       *dev;           //设备
  3. struct clk          *clk;           //时钟
  4. struct resource     *mem;           //资源
  5. void __iomem        *io;            //IO地址
  6. void __iomem        *irq_base;      //IRQ基数
  7. enum s3c_drv_type   drv_type;       //驱动类型,S3C2410或S3C2412
  8. struct s3c2410fb_hw regs;           //s3c2410 lcd硬件寄存器
  9. unsigned int        palette_ready;  //调色板是否就绪标志位
  10. /* keep these registers in case we need to re-write palette */
  11. u32         palette_buffer[256];    //调色板缓冲区
  12. u32         pseudo_pal[16];         //伪颜色表
  13. };

s3c2410fb_display结构体,关于LCD参数的描述,如分辨率,LCD类型,BPP等等

[cpp] view
plain
?
  1. /* LCD description */
  2. struct s3c2410fb_display {
  3. /* LCD type */
  4. unsigned type;
  5. /* Screen size */
  6. unsigned short width;
  7. unsigned short height;
  8. /* Screen info */
  9. unsigned short xres;
  10. unsigned short yres;
  11. unsigned short bpp;
  12. unsigned pixclock;           /* pixclock in picoseconds */
  13. unsigned setclkval;          /* clkval */
  14. unsigned short left_margin;  /* value in pixels (TFT) or HCLKs (STN) */
  15. unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
  16. unsigned short hsync_len;    /* value in pixels (TFT) or HCLKs (STN) */
  17. unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
  18. unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
  19. unsigned short vsync_len;    /* value in lines (TFT) or 0 (STN) */
  20. /* lcd configuration registers */
  21. unsigned long   lcdcon5;
  22. };

对于TQ2440的液晶屏实例为tq2440_lcd_cfg,为方便查阅这里省略了其他分辨率的参数设置

[cpp] view
plain
?
  1. /* LCD driver info */
  2. static struct s3c2410fb_display tq2440_lcd_cfg __initdata = {
  3. .lcdcon5    = S3C2410_LCDCON5_FRM565 |
  4. S3C2410_LCDCON5_INVVLINE |
  5. S3C2410_LCDCON5_INVVFRAME |
  6. S3C2410_LCDCON5_PWREN |
  7. S3C2410_LCDCON5_HWSWP,
  8. .type       = S3C2410_LCDCON1_TFT,
  9. /* TQ2440的液晶是4.3寸的,分辨率是480*272 */
  10. #elif defined(CONFIG_FB_S3C24X0_TFT480272)  /* config_EmbedSky_W43:CONFIG_FB_S3C24X0_TFT480272=y */
  11. .width      = 480,
  12. .height     = 272,
  13. .pixclock   = 40000,    /* HCLK 100 MHz, divisor 1 */
  14. .setclkval  = 0x4,
  15. .xres       = 480,
  16. .yres       = 272,
  17. .bpp        = 16,
  18. .left_margin    = 19,   /* for HFPD*/
  19. .right_margin   = 10,   /* for HBPD*/
  20. .hsync_len  = 30,       /* for HSPW*/
  21. .upper_margin   = 4,    /* for VFPD*/
  22. .lower_margin   = 2,    /* for VBPD*/
  23. .vsync_len  = 8,        /* for VSPW*/
  24. };

s3c2410fb_mach_info结构体,它包括了s3c2410fb_display结构体

[cpp] view
plain
?
  1. struct s3c2410fb_mach_info {
  2. struct s3c2410fb_display *displays;     //s3c2410fb_display结构体
  3. unsigned num_displays;                  //displays的个数
  4. unsigned default_display;               //默认的default_display个数
  5. /* GPIOs */
  6. unsigned long   gpcup;                  //GPC
  7. unsigned long   gpcup_mask;
  8. unsigned long   gpccon;
  9. unsigned long   gpccon_mask;
  10. unsigned long   gpdup;                  //GPD
  11. unsigned long   gpdup_mask;
  12. unsigned long   gpdcon;
  13. unsigned long   gpdcon_mask;
  14. /* lpc3600 control register */
  15. unsigned long   lpcsel;
  16. };

要理解s3c24xxfb_probe函数,首先必须理清上面几个结构体之间的关系。

linux lcd设备驱动剖析一的更多相关文章

  1. linux lcd设备驱动剖析四

    在"linux lcd设备驱动剖析二"文章中,我们详细分析了s3c24xxfb_probe函数. 文章链接:http://blog.csdn.net/lwj103862095/ar ...

  2. linux lcd设备驱动剖析三

    上一节文章中详细地剖析了probe函数,但是从始至终都没有看到打开读写文件接口的操作函数,只看到了下面这个操作结构体 [cpp] view plain? static struct fb_ops s3 ...

  3. linux lcd设备驱动剖析二

    上一节中,分析了s3c2410fb,c的入口出口函数,以及一些重要结构体的分析,初步知道了这是一个平台驱动的架构. 上一节文章链接:http://blog.csdn.net/lwj103862095/ ...

  4. 深入理解Linux字符设备驱动

    文章从上层应用访问字符设备驱动开始,一步步地深入分析Linux字符设备的软件层次.组成框架和交互.如何编写驱动.设备文件的创建和mdev原理,对Linux字符设备驱动有全面的讲解.本文整合之前发表的& ...

  5. linux块设备驱动之实例

    1.注册:向内核注册个块设备驱动,其实就是用主设备号告诉内核这个代表块设备驱动 sbull_major  =  register_blkdev(sbull_major, "sbull&quo ...

  6. Linux 视频设备驱动V4L2最常用的控制命令

    http://blog.csdn.net/shaolyh/article/details/6583226 Linux 视频设备驱动V4L2最常用的控制命令使用说明(1.02) 命令 功能 VIDIOC ...

  7. Linux字符设备驱动结构(一)--cdev结构体、设备号相关知识机械【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50839042 一.字符设备基础知识 1.设备驱动分类 linux系统将设备分为3类:字符 ...

  8. Smart210学习记录----beep linux字符设备驱动

    今天搞定了beep linux字符设备驱动,心里还是很开心的,哈哈...但在完成的过程中却遇到了一个非常棘手的问题,花费了我大量的时间,,,, 还是把问题描述一下吧,好像这个问题很普遍的,网上许多解决 ...

  9. Linux块设备驱动详解

    <机械硬盘> a:磁盘结构 -----传统的机械硬盘一般为3.5英寸硬盘,并由多个圆形蝶片组成,每个蝶片拥有独立的机械臂和磁头,每个堞片的圆形平面被划分了不同的同心圆,每一个同心圆称为一个 ...

随机推荐

  1. CSS3 content属性学习

    css3中出现了 ":before",":after"伪类, 你可以这样写: h1:after{ content:'h1后插入的文本'; ... } 这两个选择 ...

  2. easyui datagrid 行编辑功能

    datagrid现在具有行编辑能力了,使用时只须在columns中为需要编辑的列添加一个editor属性,编辑保存时同时具有数据校验能力. 看一个例子效果图: 代码如下: $('#tt').datag ...

  3. 四十二 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mget和bulk批量操作

    注意:前面讲到的各种操作都是一次http请求操作一条数据,如果想要操作多条数据就会产生多次请求,所以就有了mget和bulk批量操作,mget和bulk批量操作是一次请求可以操作多条数据 1.mget ...

  4. 【sparkSQL】DataFrame的常用操作

    scala> import org.apache.spark.sql.SparkSession import org.apache.spark.sql.SparkSession scala> ...

  5. Android移动端网络优化

    介绍下针对移动端的网络优化,不限于 Android,同样适用于 iOS 和 H5 本文为性能优化系列第四篇,目前性能调优专题已完成以下部分: 性能优化总纲——性能问题及性能调优方式 性能优化第四篇—— ...

  6. python之路——文件操作

    阅读目录 初窥文件操作基本流程 文件编码 文件的打开模式 文件内的光标移动 with上下文管理 文件的修改 练习 回到顶部 初窥文件操作基本流程 计算机系统分为:计算机硬件,操作系统,应用程序三部分. ...

  7. linux, windows, mac, ios等平台GCC预编译宏判断

    写跨平台c/c++程序的时候,需要搞清各平台下面的预编译宏,区分各平台代码.而跨平台c/c++编程,GCC基本在各平台都可以使用.整理了一份各平台预编译宏的判断示例. 需要注意几点: * window ...

  8. Python开发简单记事本

    摘要: 本文是使用Python,结合Tkinter开发简单记事本. 本文的操作环境:ubuntu,Python2.7,采用的是Pycharm进行代码编辑,个人很喜欢它的代码自动补齐功能. 最近很想对p ...

  9. 【JavsScript高级程序设计】学习笔记[1]

    1. 在HTML中使用javascript 在使用script嵌入脚本时,脚本内容不能包含'</script>'字符串(会被认为是结束的标志).可以通过转义字符解决('\') 默认scri ...

  10. 剑指Offer面试题:1.实现单例模式

    一 题目:实现单例模式Singleton 题目:设计一个类,我们只能生产该类的一个实例. 只能生成一个实例的类是实现了Singleton(单例)模式的类型.由于设计模式在面向对象程序设计中起着举足轻重 ...