Chinaunix首页 | 论坛 | 博客
  • 博客访问: 240346
  • 博文数量: 29
  • 博客积分: 1598
  • 博客等级: 上尉
  • 技术积分: 388
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-09 13:35
文章分类
文章存档

2012年(3)

2011年(4)

2010年(1)

2009年(21)

我的朋友

分类: LINUX

2009-05-14 12:49:11

								Lcd ,touchscreen驱动移植
内核版本:2.6.18
实验环境:ubuntu8.10+勤研s3c2410
整个过程看了看<>,
<>
weibing,tekkemma的博客

lcd_ts源码包下载

我的想法:lcd是平台设备 lcd控制器是集成在cpu上的,因此只要将lcd控制器的驱动注册到平台设备驱动,即platform_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, }, };
平台驱动就是初始化开发板上的硬件资源的一个统一形式的接口,不论是lcd,touchscreen或是cs8900驱动都可以采取这样的形式。这个文件里定义了设备的注册,probe probe 等等,然后根据平台驱动的探测函数来完成lcd的初始化。然后lcd驱动本身的初始化函数只需写成如下的形式 static int __init s3c2410fb_init(void) { return platform_driver_register(&s3c2410fb_driver); //注册平台驱动,初始化则交给平台驱动的探测函数完成 } static void __exit s3c2410fb_cleanup(void) { platform_driver_unregister(&s3c2410fb_driver); } module_init(s3c2410ts_init); module_exit(s3c2410ts_exit); 整个lcd驱动的框架就如此了。注册平台驱动,利用平台驱动的探测函数完成lcd的初始化等任务。 S3c2410fb.c文件在内核的driver/video/s3c2410fb.c目录下已经给出了,我们要做的任务只是添加lcd寄存器的配置信息。 声明:网上下的源码可能不太对,自己根据需要修改修改,我把我修改过的也传上来。 lcd 驱动移植:s3c2410fb.c,s3c2410fb.h文件网上都有的,一般不用更改,但有的时候s3c2410fb.c文件需要稍微改改,如 static int __init s3c2410fb_init(void) { return platform_driver_register(&s3c2410fb_driver); //注册平台驱动,初始化则交给平台驱动的探测函数完成 } 原来的函数是return device_driver(&s3c2410fb_driver); 另外要注意的就是头文件的目录问题,可能需要修改,这个随便改改就好。 对于touchscreen驱动移植:内核里面是s3c2410_ts.c和s3c2410_ts.h文件的。也可以网上下载 源码还是很简单的,最好把它看懂,到时出错了也知道怎么改。 //clk_use(adc_clock);//2.6内核不需要2009-5-13 比如在s3c2410_ts.c源码里有个clk_use的函数,我看了内核里的clk.h文件,根本就没有定义clk_usr()函数,所以编译出错。注释掉以后再编译就通过了~~ 具体移植
1 更改linux/arch/arm/mach-s3c2410/mach-smdk2410.c。更准确的说应该是给lcd控制器赋予正确的初始值。Mach-smdk2410.c只需要修改三处,网上有许多修改的版本。经本人猜想,既然lcd和touchscreen驱动原理都一样,那么它们修改方式应该也是一致的。经过偶的实验,果然如此~~ 这个文件的更改方法只需按下面三个步骤:
1) 添加硬件寄存器的信息 /*添加lcd控制寄存器的配置信息,寄存器的值一定要配置正确,如果不正确的话,是看不见小企鹅的。参考板自带的手册或者源码*/ //.type = S3C2410_LCDCON1_TFT, .fixed_syncs = 0, .regs={ .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \ S3C2410_LCDCON1_TFT | \ S3C2410_LCDCON1_CLKVAL(6), .lcdcon2= S3C2410_LCDCON2_VBPD(3) | \ S3C2410_LCDCON2_LINEVAL(319) | \ S3C2410_LCDCON2_VFPD(3) | \ S3C2410_LCDCON2_VSPW(2), .lcdcon3= S3C2410_LCDCON3_HBPD(12) | \ S3C2410_LCDCON3_HOZVAL(239) | \ S3C2410_LCDCON3_HFPD(12), .lcdcon4= S3C2410_LCDCON4_MVAL(13) | \ S3C2410_LCDCON4_HSPW(30), .lcdcon5= S3C2410_LCDCON5_FRM565 | \ S3C2410_LCDCON5_PWREN | \ S3C2410_LCDCON5_HWSWP, }, .lpcsel= 0x0, .gpccon= 0xaaaaaaaa,//这里没弄清楚什么意思 .gpccon_mask= 0xffffffff, .gpcup= 0xffffffff, .gpcup_mask= 0xffffffff, .gpdup = 0xffffffff, .gpdup_mask= 0xffffffff, .gpdcon= 0xaaaaaaaa, .gpdcon_mask= 0, .width= 240, .height= 320, .xres= {240,240,240}, .yres= {320,320,320}, .bpp= {16,16,16}, }; //touchscreen配置信息 static struct s3c2410_ts_mach_info smdk2410_ts_cfg __initdata = { .delay = 100000, .presc = 49, .oversampling_shift = 2, }; 2)在static struct platform_device *smdk2410_devices[] __initdata 中打开你的设备 static struct platform_device *smdk2410_devices[] __initdata = { &s3c_device_usb, &s3c_device_lcd, &s3c_device_wdt, &s3c_device_i2c, &s3c_device_iis, &s3c_device_cs8900, &s3c_device_ts, }; 3)在static void __init smdk2410_map_io函数中实现映射 static void __init smdk2410_map_io(void) { s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); s3c24xx_set_board(&smdk2410_board); s3c24xx_init_touchscreen(&smdk2410_ts_cfg); s3c24xx_init_framebuffer(&smdk2410_lcd_cfg); }
2 更改arch/arm/mach-s3c2410/devs.c ./devs.h文件 1devs.h中添加 extern struct platform_device s3c_device_ts; 2)如何修改devs.c,添加下述信息 /* LCD Controller */ static struct resource s3c_lcd_resource[] = { [0] = { .start = S3C24XX_PA_LCD, .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_LCD, .end = IRQ_LCD, .flags = IORESOURCE_IRQ, } }; static struct s3c2410fb_mach_info s3c2410fb_info; void __init s3c24xx_init_framebuffer(struct s3c2410fb_mach_info *hard_s3c2410fb_info) { memcpy(&s3c2410fb_info,hard_s3c2410fb_info,sizeof(struct s3c2410fb_mach_info)); } EXPORT_SYMBOL(s3c24xx_init_framebuffer); 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_data = &s3c2410fb_info, } }; EXPORT_SYMBOL(s3c_device_lcd); /* ADC */ static struct resource s3c_adc_resource[] = { [0] = { .start = S3C24XX_PA_ADC, .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_TC, .end = IRQ_TC, .flags = IORESOURCE_IRQ, }, [2] = { .start = IRQ_ADC, .end = IRQ_ADC, .flags = IORESOURCE_IRQ, } }; struct platform_device s3c_device_adc = { .name = "s3c2410-adc", .id = -1, .num_resources = ARRAY_SIZE(s3c_adc_resource), .resource = s3c_adc_resource, }; /*在ADC资源的基础上添加touchscreen controller*/ static struct s3c2410_ts_mach_info s3c2410ts_info; void __init s3c24xx_init_touchscreen(struct s3c2410_ts_mach_info *hard_s3c2410ts_info) { memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info)); } EXPORT_SYMBOL(s3c24xx_init_touchscreen); struct platform_device s3c_device_ts = {//去掉了static 居然就编译通过了 这是什么原因?? .name = "s3c2410-ts", .id = -1, .dev = { .platform_data = &s3c2410ts_info, } }; EXPORT_SYMBOL(s3c_device_ts); 为了方便阅读,这个文件里的更改也应该做到lcd 和 ts形式一致~~ 代码修改完后记得修改makefile 和kconfig文件哦 最后就是make menuconfig了~~选上framebuffer support之类的选项,tftp启动,看见了小企鹅,用笔点击触摸平,可以打印出坐标信息,但是我轻轻一点一次会打印3~4条的坐标信息,如果笔放那不动,就会一直打印出坐标信息,呵呵~~ 剩下的问题就是触摸屏的去抖动问题还有校准问题了,写下这篇总结留作纪念~


阅读(4243) | 评论(0) | 转发(0) |
0

上一篇:uboot 之uboot.lds分析

下一篇:文件系统制作

给主人留下些什么吧!~~