基于s3c2410的lcd和触摸屏驱动移植

来源:互联网 发布:java websocket 框架 编辑:程序博客网 时间:2024/04/29 20:42
内核版本:2.6.18
实验环境:ubuntu8.10+勤研s3c2410
整个过程看了看<<s3c2410技术手册>>,
<<s3c2410下lcd驱动程序移植及gui程序编写>>
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文件(1)devs.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条的坐标信息,如果笔放那不动,就会一直打印出坐标信息,呵呵~~剩下的问题就是触摸屏的去抖动问题还有校准问题了,写下这篇总结留作纪念~
0 0
原创粉丝点击