linux lcdデバイス駆動プロファイル1

6420 ワード

s 3 c 2440 lcd駆動ソースファイルはdrivers/video/s 3 c 2410 fbである.c
駆動ソースコードを見るにはまず入口関数を見ます.ここはs 3 c 2410 fbです.init関数
int __init s3c2410fb_init(void)
{
	/*     s3c2410fb_driver     */
	int ret = platform_driver_register(&s3c2410fb_driver);

	if (ret == 0)
		ret = platform_driver_register(&s3c2412fb_driver);;

	return ret;
}

出口関数は、当然s 3 c 2410 fbをログアウトします.driverプラットフォーム駆動
static void __exit s3c2410fb_cleanup(void)
{
	platform_driver_unregister(&s3c2410fb_driver);
	platform_driver_unregister(&s3c2412fb_driver);
}

私たちが研究したのはs 3 c 2440で、s 3 c 2410 fbだけに関心を持っています.driver,s3c2412fb_driverは気にしないでください.
static struct platform_driver s3c2410fb_driver = {
	.probe		= s3c2410fb_probe,
	.remove		= s3c2410fb_remove,
	.suspend	= s3c2410fb_suspend,
	.resume		= s3c2410fb_resume,
	.driver		= {
		.name	= "s3c2410-lcd",
		.owner	= THIS_MODULE,
	},
};

ここでs 3 c 2410 fb_が見えますdriverのnameフィールドはs 3 c 2410-lcdです.このお金の前の章で述べた知識を振り返ると、linuxシステムに同名のプラットフォームデバイスが存在する場合、プラットフォーム駆動のprobe関数が呼び出されます.ここで、「s 3 c 2410−lcd」という名前のプラットフォームデバイスが存在する場合、s 3 c 2410 fb_が呼び出されるdriverのs 3 c 2410 fb_probe関数.
source insightでs 3 c 2410-lcdを検索するとarch/arm/plat-s 3 c 24 xx/devsがすぐに検索できる.cにはそんな一節がある
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
	}
};

EXPORT_SYMBOL(s3c_device_lcd);

その中でプラットフォームデバイスの中で重要なのはメンバーがresourceで、ここではs 3 c_です.lcd_resource
static struct resource s3c_lcd_resource[] = {
	[0] = {
		.start = S3C24XX_PA_LCD,				/* 0x4D000000 */
		.end   = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
		.flags = IORESOURCE_MEM,
	},
	[1] = {
		.start = IRQ_LCD,						/* IRQ = 32 */
		.end   = IRQ_LCD,
		.flags = IORESOURCE_IRQ,
	}

};

static u64 s3c_device_lcd_dmamask = 0xffffffffUL;

次はもちろんprobe関数を分析します
static int __init s3c2410fb_probe(struct platform_device *pdev)
{
	return s3c24xxfb_probe(pdev, DRV_S3C2410);
}

s3c2410fb_probe関数呼び出しs 3 c 24 xxfb_probe関数はlcd駆動の重要な関数の一つであり、「linux lcdデバイス駆動剖析二」に残して分析するが、この関数を分析する前に、いくつかの構造体を熟知する必要がある.
linux lcdドライバにはフレームバッファというキーワードがあり、これはlinuxが表示装置に提供するインタフェースであり、アプリケーションがグラフィックモードで直接表示バッファを読み書き操作することを可能にし、ユーザーは物理表示バッファの具体的な位置と保存方式に関心を持つ必要はなく、これらはフレームバッファ装置ドライバ自体が完成する.
フレームバッファ装置は標準文字装置であり、主装置番号は29であり、/dev/fbn装置ファイルに対応し、フレームバッファ装置の最も重要なデータ構造はfb_である.info構造体は、フレームバッファ装置の属性と動作に関する完全な説明を含む.
struct fb_info {
	int node;						//        
	int flags;
	struct mutex lock;				//  open/release/ioctl    
	struct fb_var_screeninfo var;	//    ,  
	struct fb_fix_screeninfo fix;	//    ,  
	struct fb_monspecs monspecs;	//     
	struct work_struct queue;		//      
	struct fb_pixmap pixmap;		//      
	struct fb_pixmap sprite;		//      
	struct fb_cmap cmap;			//     
	struct list_head modelist;      //    
	struct fb_videomode *mode;		//  video  

	char __iomem *screen_base;		//     
	unsigned long screen_size;		//    
	void *pseudo_palette;			// 16    
#define FBINFO_STATE_RUNNING	0
#define FBINFO_STATE_SUSPENDED	1
	u32 state;						//    ,   
	void *fbcon_par;                //       
	void *par;						//info->par                
};

s3c2410fb_info構造体、これはs 3 c 2410抽出像から出た特有の情報です
struct s3c2410fb_info {
	struct device		*dev;			//  
	struct clk			*clk;			//  

	struct resource		*mem;			//  
	void __iomem		*io;			//IO  
	void __iomem		*irq_base;		//IRQ  

	enum s3c_drv_type	drv_type;		//    ,S3C2410 S3C2412
	struct s3c2410fb_hw	regs;			//s3c2410 lcd     

	unsigned int		palette_ready;	//          

	/* keep these registers in case we need to re-write palette */
	u32			palette_buffer[256];	//      
	u32			pseudo_pal[16];			//    
};

s3c2410fb_解像度、LCDタイプ、BPPなどのLCDパラメータの説明
/* LCD description */
struct s3c2410fb_display {
	/* LCD type */
	unsigned type;

	/* Screen size */
	unsigned short width;
	unsigned short height;

	/* Screen info */
	unsigned short xres;
	unsigned short yres;
	unsigned short bpp;

	unsigned pixclock;			 /* pixclock in picoseconds */
	unsigned setclkval;			 /* clkval */
	unsigned short left_margin;  /* value in pixels (TFT) or HCLKs (STN) */
	unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
	unsigned short hsync_len;    /* value in pixels (TFT) or HCLKs (STN) */
	unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
	unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
	unsigned short vsync_len;	 /* value in lines (TFT) or 0 (STN) */

	/* lcd configuration registers */
	unsigned long	lcdcon5;
};

TQ 24440の液晶パネルの例は、tq 2440_であるlcd_cfgは、ここで他の解像度のパラメータ設定を省略して参照しやすいように
/* LCD driver info */
static struct s3c2410fb_display tq2440_lcd_cfg __initdata = {
	.lcdcon5	= S3C2410_LCDCON5_FRM565 |
			  S3C2410_LCDCON5_INVVLINE |
			  S3C2410_LCDCON5_INVVFRAME |
			  S3C2410_LCDCON5_PWREN |
			  S3C2410_LCDCON5_HWSWP,
	.type		= S3C2410_LCDCON1_TFT,
	/* TQ2440    4.3  ,    480*272 */
#elif defined(CONFIG_FB_S3C24X0_TFT480272)  /* config_EmbedSky_W43:CONFIG_FB_S3C24X0_TFT480272=y */
	.width		= 480,
	.height		= 272,

	.pixclock	= 40000,    /* HCLK 100 MHz, divisor 1 */
	.setclkval	= 0x4,
	.xres		= 480,
	.yres		= 272,
	.bpp		= 16,
	.left_margin	= 19,	/* for HFPD*/
	.right_margin	= 10,	/* for HBPD*/
	.hsync_len	= 30,		/* for HSPW*/
	.upper_margin	= 4,	/* for VFPD*/
	.lower_margin	= 2,	/* for VBPD*/
	.vsync_len	= 8,		/* for VSPW*/
};

s3c2410fb_mach_info構造体、s 3 c 2410 fb_を含むディスプレイ構造体
struct s3c2410fb_mach_info {
	struct s3c2410fb_display *displays;		//s3c2410fb_display   
	unsigned num_displays;					//displays   
	unsigned default_display;				//   default_display  

	/* GPIOs */
	unsigned long	gpcup;					//GPC
	unsigned long	gpcup_mask;
	unsigned long	gpccon;
	unsigned long	gpccon_mask;
	unsigned long	gpdup;					//GPD
	unsigned long	gpdup_mask;
	unsigned long	gpdcon;
	unsigned long	gpdcon_mask;

	/* lpc3600 control register */
	unsigned long	lpcsel;
};

s 3 c 24 xxfb_を理解するにはprobe関数は,まず上の幾つかの構造体間の関係を整理しなければならない.