Linux的LCD驱动源码分析及移植.doc_第1页
Linux的LCD驱动源码分析及移植.doc_第2页
Linux的LCD驱动源码分析及移植.doc_第3页
Linux的LCD驱动源码分析及移植.doc_第4页
Linux的LCD驱动源码分析及移植.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux的LCD驱动源码分析及移植(三部曲)第一部分:基于ARM9处理器的linux-操作系统内核移植手记part5.1(LCD驱动源码分析及移植之platform device)1.与LCD控制器硬件相关的寄存器内容请参照三星S3C2440A技术手册中的第15章。2.LCD Controller的平台设备定义如下(文件位于 linux/arch/arm/plat-s3c24xx/devs.c):1. /*LCD Controller*/2.3. static struct resource s3c_lcd_resource=4. 0=5. .start=S3C24XX_PA_LCD,6. .end=S3C24XX_PA_LCD+S3C24XX_SZ_LCD-1,7. .flags=IORESOURCE_MEM,8. ,9. 1=10. .start=IRQ_LCD,11. .end=IRQ_LCD,12. .flags=IORESOURCE_IRQ,13. 14.15. ;16.17. static u64 s3c_device_lcd_dmamask=0xffffffffUL;18.19. struct platform_device s3c_device_lcd=20. .name=s3c2410-lcd,21. .id=-1,22. .num_resources=ARRAY_SIZE(s3c_lcd_resource),23. .resource=s3c_lcd_resource,24. .dev=25. .dma_mask=&s3c_device_lcd_dmamask,26. .coherent_dma_mask=0xffffffffUL27. 28. ;29.30. EXPORT_SYMBOL(s3c_device_lcd);平台设备的结构体定义为s3c_device_lcd,该设备在平台总线中的名字取为s3c2410-lcd,该平台设备申请的两个板级资源为以S3C24XX_PA_LCD为起始的IORESOURCE_MEM资源和一个定义为IRQ_LCD的IORESOURCE_IRQ资源。其中,1. #define S3C24XX_PA_LCD S3C2410_PA_LCD1. /*LCD controller*/2. #define S3C2410_PA_LCD(0x4D000000)3. #define S3C24XX_SZ_LCD SZ_1M0x4D000000为LCDCON1寄存器的地址。3. LCD Controller的平台设备的注册如下(文件位于linux/arch/arm/mach-s3c2440/mach-smdk2440.c):1. static struct platform_device*smdk2440_devices_initdata=2. &s3c_device_usb,3.4. &s3c_device_lcd,5.6. &s3c_device_wdt,7. &s3c_device_i2c0,8. &s3c_device_iis,9. &s3c_device_rtc,10. ;以上第4行代码将lcd平台设备注册进内核。4.在系统初始化时将smdk2440_fb_info结构体添加进平台设备的私有结构中。具体流程如下:4.11. MACHINE_START(S3C2440,SMDK2440)2. /*Maintainer:Ben Dooks*/3. .phys_io=S3C2410_PA_UART,4. .io_pg_offst=(u32)S3C24XX_VA_UART)18)&0xfffc,5. .boot_params=S3C2410_SDRAM_PA+0x100,6.7. .init_irq=s3c24xx_init_irq,8. .map_io=smdk2440_map_io,9. .init_machine=smdk2440_machine_init,10. .timer=&s3c24xx_timer,11. MACHINE_END启动S3C2440机器,系统将通过“.init_machine=smdk2440_machine_init,”调用smdk2440_machine_init()函数。4.21. static void _init smdk2440_machine_init(void)2. 3. s3c24xx_fb_set_platdata(&smdk2440_fb_info);4. s3c_i2c0_set_platdata(NULL);5.6. platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices);7. smdk_machine_init();8. 在smdk2440_machine_init函数中,通过“ s3c24xx_fb_set_platdata(&smdk2440_fb_info);”将smdk2440_fb_info添加进平台设备的私有结构中。4.31. void _init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info*pd)2. 3. struct s3c2410fb_mach_info*npd;4.5. npd=kmalloc(sizeof(*npd),GFP_KERNEL);6. if(npd)7. memcpy(npd,pd,sizeof(*npd);8. s3c_device_lcd.dev.platform_data=npd;9. else10. printk(KERN_ERRno memory for LCD platform datan);11. 12. 以上代码为smdk2440_fb_info结构的添加过程,其中“s3c_device_lcd.dev.platform_data=npd;”为核心实现部分。4.41. static struct s3c2410fb_mach_info smdk2440_fb_info _initdata=2. .displays=&smdk2440_lcd_cfg,3. .num_displays=1,4. .default_display=0,5.6. #if07. /*currently setup by downloader*/8. .gpccon=0xaa940659,9. .gpccon_mask=0xffffffff,10. .gpcup=0x0000ffff,11. .gpcup_mask=0xffffffff,12. .gpdcon=0xaa84aaa0,13. .gpdcon_mask=0xffffffff,14. .gpdup=0x0000faff,15. .gpdup_mask=0xffffffff,16. #endif17.18. /.lpcsel=(0xCE6)&7)|14,19. ;以上为smdk2440_fb_info结构体定义。在此需要注释掉源码中的“.lpcsel=(0xCE6)&7)|1dev.platform_data;16. if(mach_info=NULL)17. dev_err(&pdev-dev,18. no platform data for lcd, cannot attachn);19. return-EINVAL;20. 21.22. if(mach_info-default_display=mach_info-num_displays)23. dev_err(&pdev-dev,default is %d but only %d displaysn,24. mach_info-default_display,mach_info-num_displays);25. return-EINVAL;26. 27.28. display=mach_info-displays+mach_info-default_display;29.30. irq=platform_get_irq(pdev,0);31. if(irqdev,no irq for devicen);33. return-ENOENT;34. 35.36. fbinfo=framebuffer_alloc(sizeof(struct s3c2410fb_info),&pdev-dev);37. if(!fbinfo)38. return-ENOMEM;39.40. platform_set_drvdata(pdev,fbinfo);41.42. info=fbinfo-par;43. info-dev=&pdev-dev;44. info-drv_type=drv_type;45.46. res=platform_get_resource(pdev,IORESOURCE_MEM,0);47. if(res=NULL)48. dev_err(&pdev-dev,failed to get memory registersn);49. ret=-ENXIO;50. goto dealloc_fb;51. 52.53. size=(res-end-res-start)+1;54. info-mem=request_mem_region(res-start,size,pdev-name);55. if(info-mem=NULL)56. dev_err(&pdev-dev,failed to get memory regionn);57. ret=-ENOENT;58. goto dealloc_fb;59. 60.61. info-io=ioremap(res-start,size);62. if(info-io=NULL)63. dev_err(&pdev-dev,ioremap() of registers failedn);64. ret=-ENXIO;65. goto release_mem;66. 67.68. info-irq_base=info-io+(drv_type=DRV_S3C2412)?S3C2412_LCDINTBASE:S3C2410_LCDINTBASE);69.70. dprintk(devinitn);71.72. strcpy(fbinfo-fix.id,driver_name);73.74. /*Stop the video*/75. lcdcon1=readl(info-io+S3C2410_LCDCON1);76. writel(lcdcon1&S3C2410_LCDCON1_ENVID,info-io+S3C2410_LCDCON1);77.78. fbinfo-fix.type=FB_TYPE_PACKED_PIXELS;79. fbinfo-fix.type_aux=0;80. fbinfo-fix.xpanstep=0;81. fbinfo-fix.ypanstep=0;82. fbinfo-fix.ywrapstep=0;83. fbinfo-fix.accel=FB_ACCEL_NONE;84.85. fbinfo-var.nonstd=0;86. fbinfo-var.activate=FB_ACTIVATE_NOW;87. fbinfo-var.accel_flags=0;88. fbinfo-var.vmode=FB_VMODE_NONINTERLACED;89.90. fbinfo-fbops=&s3c2410fb_ops;91. fbinfo-flags=FBINFO_FLAG_DEFAULT;92. fbinfo-pseudo_palette=&info-pseudo_pal;93.94. for(i=0;ipalette_bufferi=PALETTE_BUFF_CLEAR;96.97. ret=request_irq(irq,s3c2410fb_irq,IRQF_DISABLED,pdev-name,info);98. if(ret)99. dev_err(&pdev-dev,cannot get irq %d - err %dn,irq,ret);100. ret=-EBUSY;101. goto release_regs;102. 103.104. info-clk=clk_get(NULL,lcd);105. if(!info-clk|IS_ERR(info-clk)106. printk(KERN_ERRfailed to get lcd clock sourcen);107. ret=-ENOENT;108. goto release_irq;109. 110.111. clk_enable(info-clk);112. dprintk(got and enabled clockn);113.114. msleep(1);115.116. info-clk_rate=clk_get_rate(info-clk);117.118. /*find maximum required memory sizefordisplay*/119. for(i=0;inum_displays;i+)120. unsigned long smem_len=mach_info-displaysi.xres;121.122. smem_len*=mach_info-displaysi.yres;123. smem_len*=mach_info-displaysi.bpp;124. smem_len=3;125. if(fbinfo-fix.smem_lenfix.smem_len=smem_len;127. 128.129. /*Initialize video memory*/130. ret=s3c2410fb_map_video_memory(fbinfo);131. if(ret)132. printk(KERN_ERRFailed to allocate video RAM: %dn,ret);133. ret=-ENOMEM;134. goto release_clock;135. 136.137. dprintk(got video memoryn);138.139. fbinfo-var.xres=display-xres;140. fbinfo-var.yres=display-yres;141. fbinfo-var.bits_per_pixel=display-bpp;142.143. s3c2410fb_init_registers(fbinfo);144.145. s3c2410fb_check_var(&fbinfo-var,fbinfo);146.147. ret=s3c2410fb_cpufreq_register(info);148. if(retdev,Failed to register cpufreqn);150. goto free_video_memory;151. 152.153. ret=register_framebuffer(fbinfo);154. if(retdev,&dev_attr_debug);162. if(ret)163. printk(KERN_ERRfailed to add debug attributen);164. 165.166. printk(KERN_INFOfb%d: %s frame buffer devicen,167. fbinfo-node,fbinfo-fix.id);168.169. return 0;170.171. free_cpufreq:172. s3c2410fb_cpufreq_deregister(info);173. free_video_memory:174. s3c2410fb_unmap_video_memory(fbinfo);175. release_clock:176. clk_disable(info-clk);177. clk_put(info-clk);178. release_irq:179. free_irq(irq,info);180. release_regs:181. iounmap(info-io);182. release_mem:183. release_resource(info-mem);184. kfree(info-mem);185. dealloc_fb:186. platform_set_drvdata(pdev,NULL);187. framebuffer_release(fbinfo);188. return ret;189. 7.11. mach_info=pdev-dev.platform_data;2. if(mach_info=NULL)3. dev_err(&pdev-dev,4. no platform data for lcd, cannot attachn);5. return-EINVAL;6. 7.8. if(mach_info-default_display=mach_info-num_displays)9. dev_err(&pdev-dev,default is %d but only %d displaysn,10. mach_info-default_display,mach_info-num_displays);11. return-EINVAL;12. 13.14. display=mach_info-displays+mach_info-default_display;第一行用于获取platform device中定义的平台数据(已经在本博客的上一篇文章中提及)。其中的mach_info定义如下:1. struct s3c2410fb_mach_info*mach_info;1. struct s3c2410fb_mach_info2.3. struct s3c2410fb_display*displays;/*attached diplays info*/4. unsigned num_displays;/*number of defined displays*/5. unsigned default_display;6.7. /*GPIOs*/8.9. unsigned longgpcup;10. unsigned longgpcup_mask;11. unsigned longgpccon;12. unsigned longgpccon_mask;13. unsigned longgpdup;14. unsigned longgpdup_mask;15. unsigned longgpdcon;16. unsigned longgpdcon_mask;17.18. /*lpc3600 control register*/19. unsigned longlpcsel;20. ;主要是记录LCD的一些属性,包括与显示参数相关的“ struct s3c2410fb_display*displays;”及使用的GPIO引脚。而”if(mach_info-default_display=mach_info-num_displays).“用来查看显示屏幕的具体规格。7.21. irq=platform_get_irq(pdev,0);2. if(irqdev,no irq for devicen);4. return-ENOENT;5. 获取设备中断号(定义于mach-smdk2440.c中)。7.31. fbinfo=framebuffer_alloc(sizeof(struct s3c2410fb_info),&pdev-dev);2. if(!fbinfo)3. return-ENOMEM;4.5. platform_set_drvdata(pdev,fbinfo);在内存中申请sizeof(struct s3c2410fb_info)+sizeof(struct fb_info)大小的空间,然后将获得的fbinfo设置为平台设备的驱动数据。其中framebuffer_alloc源码如下:1. /*2. *framebuffer_alloc-creates a new frame buffer info structure3. *4. *size:size of driverprivatedata,can be zero5. *dev:pointertothe deviceforthis fb,this can beNULL6. *7. *Creates a new frame buffer info structure.Also reserves size bytes8. *fordriverprivatedata(info-par).info-par(ifany)will be9. *alignedtosizeof(long).10. *11. *Returns the new structure,orNULLifanerroroccured.12. *13. */14. struct fb_info*framebuffer_alloc(size_t size,struct device*dev)15. 16. #define BYTES_PER_LONG(BITS_PER_LONG/8)17. #define PADDING(BYTES_PER_LONG-(sizeof(struct fb_info)%BYTES_PER_LONG)18. intfb_info_size=sizeof(struct fb_info);19. struct fb_info*info;20. char*p;21.22. if(size)23. fb_info_size+=PADDING;24.25. p=kzalloc(fb_info_size+size,GFP_KERNEL);26.27. if(!p)28. returnNULL;29.30. info=(struct fb_info*)p;31.32. if(size)33. info-par=p+fb_info_size;34.35. info-device=dev;36.37. #ifdef CONFIG_FB_BACKLIGHT38. mutex_init(&info-bl_curve_mutex);39. #endif40.41. return info;42. #undef PADDING43. #undef BYTES_PER_LONG44. 45. EXPORT_SYMBOL(framebuffer_alloc);其中platform_set_drvdata宏如下:1. #define platform_set_drvdata(_dev,data)dev_set_drvdata(&(_dev)-dev,(data)7.41. info=fbinfo-par;2. info-dev=&pdev-dev;3. info-drv_type=drv_type;设置驱动数据。7.51. res=platform_get_resource(pdev,IORESOURCE_MEM,0);2. if(res=NULL)3. dev_err(&pdev-dev,failed to get memory registersn);4. ret=-ENXIO;5. goto dealloc_fb;6. 7.8. size=(res-end-res-start)+1;9. info-mem=request_mem_region(res-start,size,pdev-name);10. if(info-mem=NULL)11. dev_err(&pdev-dev,failed to get memory regionn);12. ret=-ENOENT;13. goto dealloc_fb;14. 15.16. info-io=ioremap(res-start,size);17. if(info-io=NULL)18. dev_err(&pdev-dev,ioremap() of registers failedn);19. ret=-ENXIO;20. goto release_mem;21. 映射内核资源(IO口,中断号,硬件地址转虚拟地址)。7.61. lcdcon1=readl(info-io+S3C2410_LCDCON1);2. writel(lcdcon1&S3C2410_LCDCON1_ENVID,info-io+S3C2410_LCDCON1);关闭显示屏幕7.71. fbinfo-fix.type=FB_TYPE_PACKED_PIXELS;2. fbinfo-fix.type_aux=0;3. fbinfo-fix.xpanstep=0;4. fbinfo-fix.ypanstep=0;5. fbinfo-fix.ywrapstep=0;6. fbinfo-fix.accel=FB_ACCEL_NONE;7.8. fbinfo-var.nonstd=0;9. fbinfo-var.activate=FB_ACTIVATE_NOW;10. fbinfo-var.accel_flags=0;11. fbinfo-var.vmode=FB_VMODE_NONINTERLACED;12.13. fbinfo-fbops=&s3c2410fb_ops;14. fbinfo-flags=FBINFO_FLAG_DEFAULT;15. fbinfo-pseudo_palette=&info-pseudo_pal;16.17. for(i=0;ipalette_bufferi=PALETTE_BUFF_CLEAR;对fbinfo进行赋值。7.81. ret=request_irq(irq,s3c2410fb_irq,IRQF_DISABLED,pdev-name,info);2. if(ret)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论