急驰的蚂蚁的笔记 https://bbs.21ic.com/?587964 [收藏] [复制] [RSS]

日志

linux2.6.28下6410LCD驱动分析

已有 2544 次阅读2010-5-4 02:52 |个人分类:linux驱动|系统分类:ARM


    本文不详细分析lcd的每行代码 ,只是做简单的构架分析,   要详细的分析可以参考http://www.cnitblog.com/luofuchong/archive/2007/10/30/35570.html,里面虽然是多2410的分析,但都大同小异。


    LCD驱动是用了device 和driver架构,首先看arch/arm/mach-s3c6410/mach-smdk6410.c文件,在353行有这样一个数组


static struct platform_device *smdk6410_devices[] __initdata = {


……………………


&s3c_device_lcd,


……………………


}


我们在进里面了解详情,在arch/arm/palt-s3c64xx/devs.c文件里有s3c_device_lcd变量的定义


static struct resource s3c_lcd_resource[] = {
 [0] = {
  .start = S3C64XX_PA_LCD,                          //lcd寄存器的起始地址
  .end   = S3C64XX_PA_LCD + SZ_1M - 1,    //lcd寄存器的结束地址,


  .flags = IORESOURCE_MEM,
 },
 [1] = {
  .start = IRQ_LCD_VSYNC,                        //lcd中断寄存器起始地址,在s3cfb_probe用
  .end   = IRQ_LCD_SYSTEM,
  .flags = IORESOURCE_IRQ,
 }
};


static u64 s3c_device_lcd_dmamask = 0xffffffffUL;


struct platform_device s3c_device_lcd = {
 .name    = "s3c-lcd",                                              //这个会和driver中的name一样,driver


                                                                             //根据这个进行匹配
 .id    = -1,
 .num_resources   = ARRAY_SIZE(s3c_lcd_resource),
 .resource   = s3c_lcd_resource,
 .dev              = {
  .dma_mask  = &s3c_device_lcd_dmamask,
  .coherent_dma_mask = 0xffffffffUL
 }
};


在arch/arm/mach-s3c6410/mach-smdk6410.c文件的


static void __init smdk6410_machine_init(void)函数中有这么一句话


platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));


这个就是对device设备进行注册,在注册driver驱动时,会根据name找到相应的device进行匹配,然后会调用probe。


    下面分析driver,在drivers/video/samsung/s3cfb.c文件的最下面有这样的一段代码


static struct platform_driver s3cfb_driver = {
 .probe  = s3cfb_probe,                       //匹配的话会调用这个函数
 .remove  = s3cfb_remove,
 .suspend = s3cfb_suspend,
 .resume  = s3cfb_resume,
        .driver  = {
  .name = "s3c-lcd",                                 //上面说的,内核会根据这个来找到相应的device
  .owner = THIS_MODULE,
 },
};


int __devinit s3cfb_init(void)
{
 return platform_driver_register(&s3cfb_driver);//进行drive注册
}


匹配后会掉用s3cfb_probe();


这个函数里面对fbinfo进行初始化,对相关寄存器进行初始化,在6410lcd驱动中,主要要修改的几个文件是:drivers/video/samsung目录下的s3cfb.c,假设你在配置的时候即用make menuconfig命令,在里面选择的是480WV,他对应的文件时s3cfb_lte480wv.c,s3cfb_lte480wv.c是和屏参数相关的文件。还有个要改的文件是s3cfb_fimd4x.c,这个文件主要是涉及寄存器的一些参数的配置。


    主要几个重点:对构架的分析,理清楚各个文件的关系。s3cfb.c中的s3cfb_probe主要是在根据s3cfb_fimd4x.c和s3cfb_lte480wv.c文件来初始fbinfo,并且写相关LCD寄存器。s3cfb_lte480wv.c主要是记录屏的参数,在这里进行修改来满足不同的lcd屏。s3cfb_fimd4x.c是对寄存器的值进行初始化,比如各个窗口的显示模式、颜色表寄存器的模式、各个窗口的控制寄存器,此文件还包含6410对于lcd的特殊功能,用ioctl来进行实现的。fbmem.c这个是fb字符设备驱动,每个窗口都是一个字符设备,在s3cfb_probe中通过调用register_buffer进行注册,注意,里面有一个fb_notifier_call_chain,他最终会调用drivers/video/console/fbcon.c中的fbcon_init,里面会有对logo的调用;fbmem.c文件里还有通用的ioctl功能调用,适合所有带lcd控制器的处理器,这个文件时通用的,每个处理器的fbmem都是一样的,做成了和硬件无关。


 


                                                lcd驱动简单构架图 


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)