Chinaunix首页 | 论坛 | 博客
  • 博客访问: 526039
  • 博文数量: 87
  • 博客积分: 4086
  • 博客等级: 上校
  • 技术积分: 900
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-23 15:55
文章分类

全部博文(87)

文章存档

2012年(3)

2010年(13)

2009年(7)

2008年(64)

我的朋友

分类: LINUX

2008-05-24 09:10:01

一、lcd驱动移植网上参考资料
http://blog.chinaunix.net/u1/49924/showart_495463.html
linux-2.6.20的lcd驱动分析

module_init()函数在include/linux/init.h中定义。
内核与buffer驱动发生关系的第一次地点是在s3c2410fb_init函数,该函数就只有一条语句:
 

return platform_driver_register (&s3c2410fb_driver)


在driver/video/s3c2410fb.c中,s3c2410fb_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,
   },
  };

为了向内核添加一个platform设备,程序员应该填写两个数据结构platform_device 和platform_driver,
这两个数据结构的定义都可以在include/linux/platform_device.h文件中找到:

struct platform_device {
 const char * name;
 int id;
 struct device dev;
 u32 num_resources;
 struct resource * resource;
};

struct platform_driver {
 int (*probe)(struct platform_device *);
 int (*remove)(struct platform_device *);
 void (*shutdown)(struct platform_device *);
 int (*suspend)(struct platform_device *, pm_message_t state);
 int (*suspend_late)(struct platform_device *, pm_message_t state);
 int (*resume_early)(struct platform_device *);
 int (*resume)(struct platform_device *);
 struct device_driver driver;
};


arch/arm/plat-s3c24xx/devs.c可以找到填写platform_device的代码:

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

void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
 struct s3c2410fb_mach_info *npd;
 npd = kmalloc(sizeof(*npd), GFP_KERNEL);
 if (npd) {
  memcpy(npd, pd, sizeof(*npd));
  s3c_device_lcd.dev.platform_data = npd;
 } else {
  printk(KERN_ERR "no memory for LCD platform data\n");
 }
}


然后在arch/arm/mach-s3c2410/mach-smdk2410.c的smdk2410_map_io函数中调用s3c24xx_fb_set_platdata( ),具体为:
s3c24xx_fb_set_platdata(&smdk2410_lcd_platdata);
 
在调用platform_driver_register (&s3c2410fb_driver);函数时,传给s3c2410fb_probe()函数的参数为s3c_device_lcd数据结构的地址,platform_device和platform_driver数据结构之间的联系通过name字段来联系。
 
上面主要是讲了platform_device和platform_driver之间的关系和实现的过程,下面讲lcd控制器的硬件和软件参数设置。
 
相关的数据结构定义于include/asm-arm/arch-s3c2410/fb.h中,列出如下:

struct s3c2410fb_hw {
 unsigned long lcdcon1;
 unsigned long lcdcon2;
 unsigned long lcdcon3;
 unsigned long lcdcon4;
 unsigned long lcdcon5;
};

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

struct s3c2410fb_mach_info {
 struct s3c2410fb_display *displays; /* attached diplays info */
 unsigned num_displays; /* number of defined displays */
 unsigned default_display;
 /* GPIOs */
 unsigned long gpcup;
 unsigned long gpcup_mask;
 unsigned long gpccon;
 unsigned long gpccon_mask;
 unsigned long gpdup;
 unsigned long gpdup_mask;
 unsigned long gpdcon;
 unsigned long gpdcon_mask;
 /* lpc3600 control register */
 unsigned long lpcsel;
};


下面的结构定义于include/linux/fb.h

struct fb_info {
 int node;
 int flags;
 struct fb_var_screeninfo var; /* Current var */
 struct fb_fix_screeninfo fix; /* Current fix */
 struct fb_monspecs monspecs; /* Current Monitor specs */
 struct work_struct queue; /* Framebuffer event queue */
 struct fb_pixmap pixmap; /* Image hardware mapper */
 struct fb_pixmap sprite; /* Cursor hardware mapper */
 struct fb_cmap cmap; /* Current cmap */
 struct list_head modelist; /* mode list */
 struct fb_videomode *mode; /* current mode */
#ifdef CONFIG_FB_BACKLIGHT
 /* assigned backlight device */
 /* set before framebuffer registration, remove after unregister */
 struct backlight_device *bl_dev;
 /* Backlight level curve */
 struct mutex bl_curve_mutex;
 u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
 struct delayed_work deferred_work;
 struct fb_deferred_io *fbdefio;
#endif
 struct fb_ops *fbops;
 struct device *device; /* This is the parent */
 struct device *dev; /* This is this fb device */
 int class_flag; /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
 struct fb_tile_ops *tileops; /* Tile Blitting */
#endif
 char __iomem *screen_base; /* Virtual address */
 unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */
 void *pseudo_palette; /* Fake palette of 16 colors */
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
 u32 state; /* Hardware state i.e suspend */
 void *fbcon_par; /* fbcon use-only private area */
 /* From here on everything is device dependent */
 void *par;
};

阅读(1534) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~