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. mysql数据库优化课程---11、mysql普通多表查询

    mysql数据库优化课程---11.mysql普通多表查询 一.总结 一句话总结:select user.username,user.age,class.name,class.ctime from u ...

  2. Mac系统下安装ipython分别支持python2和python3

    操作系统:Mac10.11.5 python2.7.13 python3.6.1 安装python2: brew install python 安装python3: brew install pyth ...

  3. java中的几种实体类对象(PO,VO,DAO,BO,POJO)

    一.PO :(persistant object ),持久对象 可以看成是与数据库中的表相映射的java对象.使用Hibernate来生成PO是不错的选择. 二.VO :(value object) ...

  4. 个人作业4——alpha阶段个人小结

    一.个人总结 在alpha 结束之后, 每位同学写一篇个人博客, 总结自己的alpha 过程: 请用自我评价表:http://www.cnblogs.com/xinz/p/3852177.html 有 ...

  5. JS兼容性汇总

    1.  Frame  (1)问题:在IE中可以用window.top.frameId和window.top.frameName来得到该Frame所代表的Window,Firefox中只能用window ...

  6. UI-隐藏键盘

    键盘的出现于隐藏(代码实现)================================= 1.通知案例: #import "ViewController.h" #import ...

  7. 【git】git知识梳理(二):服务器

    (四) 远程仓库通常只是一个裸仓库(bare repository):.git子目录 四种协议:本地传输, SSH, GIT, HTTP, 除了http,均需要在服务器端安装运行git. SSH:SS ...

  8. java事务(二)——本地事务

    本地事务 事务类型 事务可以分为本地事务和分布式事务两种类型.这两种事务类型是根据访问并更新的数据资源的多少来进行区分的.本地事务是在单个数据源上进行数据的访问和更新,而分布式事务是跨越多个数据源来进 ...

  9. html display和visibility在资源加载上的区别

    想要把一个html里的UI组件设置为可见/不可见,可以用两个属性,display=none/block, visibility=hidden/visible, 网上的解释是display虽然可以让一个 ...

  10. android 字符串string

    String : 字符串类型 http://www.open-open.com/lib/view/open1387942832078.html 一.构造函数     String(byte[ ] by ...