天天看點

mini2440_LCD_x35移植

從linux 2.6起引入了新一套的驅動管理和注冊機制:platform_device 和piatform_driver. (platform代表平台);裝置用platform_device表示,驅動用piatform_driver進行注冊。 

Linuxplatformdriver機制和傳統的devicedriver機制(通過driver_register函數進行注冊)相比,一個十分明顯的優勢在于platform機制将裝置本身的資源注冊進核心,由核心統一管理,在驅動程式中使用這些資源時通過platformdevice提供的标準接口進行申請并使用。這樣提高了驅動和資源管理的獨立性,并且擁有較好的可移植性和安全性(這些标準接口是安全的)。 

Platform機制的本身使用并不複雜,由兩部分組成:platform_device和platfrom_driver。  

通過Platform機制開發底層驅動的大緻流程為:定義resoucre->定義platform_device->定義platform_driver->注冊platform_driver。 

核心裡已經有很完善的lcd驅動了,我們隻要根據所用的LCD進行簡單的修改。 首先要确認的就是裝置的資源資訊,例如裝置的位址,中斷号等。 

在2.6核心中platform裝置用結構體platform_device來描述,該結構體定義在

kernel\include\linux\platform_device.h 

中。 

Struct platform_device{ 

const char *name; u32 id; 

struct device dev; u32 num_resources; 

struct resource  *resource; 

}; 

該結構一個重要的元素是resource,該元素存入了最為重要的裝置資源資訊,定義在

kernel\include\linux\ioport.h中。 struct resource{ 

resource_size_tstart; //描述裝置實體在cpu總線上的線性起始實體位址;       

resource_size_tend; // 描述裝置實體在cpu總線上的線性結尾實體位址;       

const char  *name; // 描述這個裝置實體的名稱,這個名字開發人員可以随意起; 

unsigned long flags; //描述這個裝置實體的一些共性和特性的标志位;      (标示為LCD控制器IO端口,在驅動中引用這個就表示

引用IO端口) 

struct resource *parent, *sibling, *child;// 指針parent、sibling和child:分别為

指向父親、兄弟和子資源的指針。 

}; 

例如: 

1、修改linux-2.6.32.2\arch\arm\palt-s3c24xx\devs.c檔案:添加平台裝置LCD占用的資源。 打開devs.c  

static struct resource s3c_lcd_resource[ ] = { 

 [0] = {   .start = S3C24XX_PA_LCD, //(控制器IO端口開始位址)  

 .end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,//(控制器IO端口結束位址) 

.flags = IORESOURCE_MEM, //(标示為LCD控制器IO端口,在驅動中引用這個

就表示引用IO端口) 

  },  [1] = {   .start = IRQ_LCD,   .end   = IRQ_LCD,   .flags = IORESOURCE_IRQ,  } }; 

有了resource資訊,就可以定義platform_device了: 

2、修改linux-2.6.32.2\arch\arm\plat-s3c24xx\devs.c檔案:添加平台裝置s3c_devce_lcd。如下所示,如果已經有則不用添加。 

static u64 s3c_device_lcd_dmamask = 0xffffffffUL;  

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  } }; 

這裡是定義一個自己的裝置的一些資訊。定義好了platform_device結構體後就可以調用函數platform_add_devices向系統中添加該裝置了,之後可以調用platform_device_register()進行裝置注冊。當注冊成功時會調用platform_driver結構元素probe函數指針,這裡 

就是s3c24xx_i2c_probe,當進入probe函數後,需要擷取裝置的資源資訊,常用擷取資源的函數主要是: 

struct resource *platform_get_resource ( struct platform_device *dev, unsigned int type, unsigned int num); 

根據參數type所指定類型,例如IORESOURCE_MEM,來擷取指定的資源。 

struct int platform_get_irq (struct platform_device *dev,unsigned int num);//擷取資源中的中斷号。(這裡可以不看)導出定義的LCD平台裝置,好在mach-smdk2440.c的smdk2440_devices[]中添加到平台裝置清單。 

EXPORT_SYMBOL(s3c_device_lcd); 

(linux還在/arch/arm/mach-s3c2410/include/mach/fb.h)中為LCD平台裝置定義了一個s3c2410fb_mach_info結構體,該結構體主要是記錄LCD的硬體參數資訊(比如該結構體的s3c2410fb_display成員結構中就用于記錄LCD的螢幕尺寸、螢幕資訊、可變的螢幕參數、LCD配置寄存器等),這樣在寫驅動的時候就直接使用這個結構體。下面,我們來看一下内

核是如何使用這個結構體的。在/arch/arm/mach-s3c2440/mach-smdk2440.c(這裡看自己定義的檔案我的為mach-mini2440.c以後我就用mini2440); 

3. 修改arch\arm\mach-s3c2440\mach-smdk2440.c:配置s3c2440_devices平台裝置資料,注冊s3c2440_devices平台裝置。 

static struct platform_device *mini2440_devices[] __initdata = {                           &s3c_device_usb,                           &s3c_device_lcd,(前面第二步已經定義了這個結構體了)                           &s3c_device_wdt,                           &s3c_device_i2c0,                           &s3c_device_iis,                              &s3c_device_nand,                               &mini2440_device_eth, 

}; 

4. 修改arch\arm\mach-s3c2440\mach-mini2440.c:配置mini2440_devices_lcd平台裝置資料。  

static struct s3c2410fb_display mini2440_lcd_cfg __initdata = { #if !defined (LCD_CON5)  .lcdcon5 = S3C2410_LCDCON5_FRM565 |      S3C2410_LCDCON5_INVVLINE |      S3C2410_LCDCON5_INVVFRAME |      S3C2410_LCDCON5_PWREN |      S3C2410_LCDCON5_HWSWP,  #else   .lcdcon5 = LCD_CON5,  #endif  .type  = S3C2410_LCDCON1_TFT,  .width  = LCD_WIDTH,  .height  = LCD_HEIGHT,  .pixclock =LCD_PIXCLOCK,  .xres  = LCD_WIDTH,  .yres  =LCD_HEIGHT,  .bpp  = 16,  .left_margin = LCD_LEFT_MARGIN +1,  .right_margin =LCD_RIGHT_MARGIN +1,  .hsync_len = LCD_HSYNC_LEN+1,  .upper_margin = LCD_UPPER_MARGIN+1,  .lower_margin =  LCD_LOWER_MARGIN+1,  .vsync_len =LCD_VSYNC_LEN+1 , }; 

5. 修改mach-mini2440.c添加X35屏支援。(這一部分要放在第四步的前面) #define LCD_WIDTH 240  //屏寬 #define LCD_HEIGHT 320  //屏高 

#define LCD_PIXCLOCK 170000  //時鐘 #define LCD_RIGHT_MARGIN 25  //左邊界 

#define LCD_LEFT_MARGIN 0  //右邊界 #define LCD_HSYNC_LEN 4  //行同步 #define LCD_UPPER_MARGIN 0  //上邊界 #define LCD_LOWER_MARGIN 4  //下邊界 #define LCD_VSYNC_LEN 9 //幀同步 

#define LCD_CON5 (S3C2410_LCDCON5_FRM565 | \      S3C2410_LCDCON5_INVVFRAME | \      S3C2410_LCDCON5_INVVLINE | \      S3C2410_LCDCON5_INVVFRAME | \      S3C2410_LCDCON5_INVVDEN | \      S3C2410_LCDCON5_PWREN | \      S3C2410_LCDCON5_BSWP ) 

6. 修改arch\arm\mach-s3c2440\mach-mini2440.c:配置s3c2440_devices平台裝置資料,注冊s3c2440_devices平台裝置,加LCD背光 

(因為mini2440的3.5英寸液晶顯示屏的背光是由s3c2440的GPG4引腳來控制的,) static struct s3c2410fb_mach_info  mini2440_fb_info __initdata ={    .displays = &mini2440_lcd_cfg,// (第5步已經設定過mini2440_lcd_cfg)          .num_displays = 1,    .default_display = 0,//(注釋:default為未履行的)    .gpccon= 0xaa955699,    .gpccon_mask= 0xffc003cc,    .gpcup= 0x0000ffff,    .gpcup_mask= 0xffffffff,    .gpdcon= 0xaa95aaa1,    .gpdcon_mask= 0xffc0fff0,    .gpdup= 0x0000faff,    .gpdup_mask= 0xffffffff,    .lpcsel =0xf82,  }; 

static void __init mini2440_machine_init(void) { 

 s3c24xx_fb_set_platdata(&mini2440_fb_info); (設定s3c2440_devices平台裝置資料)  

 s3c_i2c0_set_platdata(NULL);  

 s3c2410_gpio_cfgpin(S3C2410_GPG(4),S3C2410_GPIO_OUTPUT);(配置lcd管腳)(要添加  #include<linux/gpio.h> ) 

 s3c2410_gpio_setpin(S3C2410_GPG(4),1);  

         s3c_device_nand.dev.platform_data = &mini2440_nand_info;   

  //s3c_device_sdi.dev.platform_data=&s3c2410_mmc_cfg; 

platform_add_devices (mini2440_devices, ARRAY_SIZE(mini2440_devices));(将LCD平台裝置注冊到核心) 

 //s3c_pm_init();  

 //mini2440_machine_init();(這些用不到的可以屏蔽掉) } 

7. 修改inux-2.6.32.2/drivers/video/Kconfig檔案. config  FB_S3C2410_X240320 

  boolean"3.5 inch 240X320 SONY LCD (X35-ACX502BMU) "   depends on FB_S3C2410   help 

    3.5 inch 240X320 SONY LCD (X35-ACX502BMU)  8.make menuconfig  Device Driver: 

 <*>support for frame buffer devices -    [* ] Enable frameware EDID 

 [* ] Enable Vidoe Mode Handling Helpers  <*>S3C24X0 LCD framebuffer support Console display driver support --  <*> Framebuffer Console Support [* ] Bootup Logo -- 

  <*> Standard 224-color Linux logo 最後啟動核心後就可以看見企鵝了。

版權聲明:本文為CSDN部落客「weixin_34009794」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/weixin_34009794/article/details/92597827