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) |