Linux设备驱动--LCD平台设备与驱动(smdk2440)

来源:互联网 发布:手机直播软件 编辑:程序博客网 时间:2024/06/05 19:12

转自http://blog.csdn.net/q1302182594/article/details/52368040

  Host:Ubuntu14.04(64bit)

    Target:smdk2440

    Kernel:Linux-2.6.39.4

    类似于《Linux设备驱动--WDT平台设备与驱动》,本文再以LCD为例进行说明。本文的源码均来自linux内核(linux-2.6.39.4貌似对mini2440 LCD移植还不完善,因此本文以smdk2440为例,在源码中已经完美支持该开发板的LCD)。

2 平台设备

2.1 定义

(1)平台设备

    定义全局变量s3c_device_lcd,并且通过EXPORT_SYMBOL(s3c_device_lcd)使其在别的源文件可见:

[cpp] view plain copy print?
  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);  
源文件:arch/arm/plat-s3c24xx/devs.c

(2)平台资源

    上述LCD设备所引用的平台设备资源如下所定义:

[cpp] view plain copy print?
  1. static struct resource s3c_lcd_resource[] = {  
  2.     [0] = {  
  3.         .start = S3C24XX_PA_LCD, /* 0x4D000000 */  
  4.         .end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,/* S3C24XX_SZ_LCD=0x00100000(1M) */                                                                                                                           
  5.         .flags = IORESOURCE_MEM, /* 0x00000200 */                                                                                                                                                
  6.     },                                                                                                                                                                          
  7.     [1] = {                                                                                                                                                                     
  8.         .start = IRQ_LCD, /* 32 */                                                                                                                                                      
  9.         .end   = IRQ_LCD,                                                                                                                                                       
  10.         .flags = IORESOURCE_IRQ, /* 0x00000400 */                                                                                                                                                
  11.     }                                                                                                                                                                                                                                                                                                                                                    
  12. };   

源文件:arch/arm/plat-s3c24xx/devs.c

2.2 引用

    定义一个平台设备数组smdk2440_devices,该数组包含了smdk2440开发板的所有平台设备,其中当然包括上述s3c_device_lcd,如下第3行所示:

[cpp] view plain copy print?
  1. static struct platform_device *smdk2440_devices[] __initdata = {  
  2.     &s3c_device_ohci,  
  3.     &s3c_device_lcd,  
  4.     &s3c_device_wdt,  
  5.     &s3c_device_i2c0,  
  6.     &s3c_device_iis,  
  7. };  
源文件:arch/arm/mach-s3c2440/mach-smdk2440.c

2.3 注册

(1)注册函数    

    在smdk2440_machine_init()函数中调用platform_add_devices()函数将上述smdk2440_devices注册到系统,即可完成平台设备的注册,如下第4行所示:

[cpp] view plain copy print?
  1. static void __init smdk2440_machine_init(void)  
  2. {  
  3.     s3c24xx_fb_set_platdata(&smdk2440_fb_info);  
  4.     s3c_i2c0_set_platdata(NULL);  
  5.   
  6.     platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));  
    int platform_add_devices(struct platform_device **devs, int num)
    {
        int i, ret = 0;
        for (i = 0; i < num; i++) {
            ret = platform_device_register(devs[i]);
            if (ret) {
                while (–i >= 0)
                    platform_device_unregister(devs[i]);
                break;
            }
        }
        return ret;
    }
  7.     smdk_machine_init();  
  8. }  

源文件:arch/arm/mach-s3c2440/mach-smdk2440.c

(2)注册时机

    上述smdk2440_machine_init()函数是何时被调用的呢?答案是在内核初始化设备的时候,如下第6行所示:

[cpp] view plain copy print?
  1. MACHINE_START(S3C2440, "SMDK2440")  
  2.     /* Maintainer: Ben Dooks <ben-linux@fluff.org> */  
  3.     .boot_params    = S3C2410_SDRAM_PA + 0x100, /* 0x30000100 */  
  4.     .init_irq   = s3c24xx_init_irq,  
  5.     .map_io     = smdk2440_map_io,  
  6.     .init_machine   = smdk2440_machine_init,  
  7.     .timer      = &s3c24xx_timer,  
  8. MACHINE_END     

源文件:arch/arm/mach-s3c2440/mach-smdk2440.c

3 平台驱动

3.1 定义

    为了和平台设备匹配,平台驱动的name要与平台设备的name一致:

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

源文件:drivers/video/s3c2410fb.c

    上述s3c2410fb_probes3c2410fb_removes3c2410fb_shutdowns3c2410fb_suspend以及s3c2410fb_resume都在同一个源文件中定义,详见源文件drivers/video/s3c2410fb.c。

    上述s3c2410fb_probe()调用s3c24xxfb_probe(),并且在s3c24xxfb_probe()中实现framebuffer的创建,初始化与注册,详见《Linux设备驱动--framebuffer》。

3.2 注册

     在模块加载函数s3c2410fb_init()中调用platform_driver_register()函数注册上述平台驱动s3c2410fb_driver

[cpp] view plain copy print?
  1. int __init s3c2410fb_init(void)                                                                                                                                                 
  2. {                                                                                                                                                                               
  3.     int ret = platform_driver_register(&s3c2410fb_driver);                                                                                                                      
  4.                                                                                                                                                                                                                                                                                                                                                      
  5.     if (ret == 0)                                                                                                                                                               
  6.         ret = platform_driver_register(&s3c2412fb_driver);                                                                                                                      
  7.                                                                                                                                                                                 
  8.     return ret;                                                                                                                                                                 
  9. }    
源文件:drivers/video/s3c2410fb.c

4 设备与驱动匹配

    同《Linux设备驱动--WDT平台设备与驱动》第4节。

参考资料

[1]Linux下LCD驱动详细分析(一)

[2]Linux LCD驱动参数的配置与编译(完全)

[3]Linux的LCD驱动 

[4]Linux下LCD编程

[5]Tiny 4412 lcd 驱动分析

[6]tiny4412LCD驱动加字符显示

[7]平台设备的识别