九鼎创展论坛中文版English
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 4774|回复: 3
打印 上一主题 下一主题

x4412&ibox项目实战59-Linux LCD驱动移植实验

[复制链接]
跳转到指定楼层
楼主
发表于 2014-11-29 17:49:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
LCD驱动的相关源码路径如下:
  1. kernel/arch/arm/mach-x4412.c
  2. kernel/arch/arm/plat-s5p/dev-fimd-s5p.c
  3. kernel/drivers/video/samsung/x4412_lcds.c
  4. kernel/drivers/video/samsung/s3cfb_main.c
  5. kernel/drivers/video/samsung/s3cfb.h
复制代码
LCD驱动的核心就是初始化LCD控制器的相关寄存器,初始化framebuffer,然后显示数据只需往framebuffer里面填充图像即可。在LCD驱动的移植中,往往我们只是做一些屏的更换,因此我们只需要关心不同的屏之间的差异。在无需多窗口混合显示等要求时,我们完全不必要关心其他的一长串寄存器,因此真正在进行LCD驱动的移植时,就会显得相当的简单。
首先分析LCD驱动的加载过程。在s3cfb_main.c的模块初始化函数s3cfb_register中,通过platform_driver_register函数注册了一个名为s3cfb的平台驱动,在dev-fimd-s5p.c中定义了名为s3cfb的平台设备:
  1. struct platform_device s3c_device_fb = {
  2.          .name                   = "s3cfb",
  3. #if defined(CONFIG_ARCH_EXYNOS4)
  4.          .id               = 0,
  5. #else
  6.          .id               = -1,
  7. #endif
  8.          .num_resources   = ARRAY_SIZE(s3cfb_resource),
  9.          .resource    = s3cfb_resource,
  10.          .dev            = {
  11.                    .dma_mask          = &fb_dma_mask,
  12.                    .coherent_dma_mask    = 0xffffffffUL
  13.          }
  14. };
复制代码
在mach-x4412.c中注册该平台设备,故s3cfb_main.c中的探测函数s3cfb_probe得到执行,该探测函数构成了整个LCD驱动的主体,用于初始化相关寄存器,申请framebuffer等。与液晶屏相关的函数为s3cfb_set_lcd_info,在探测函数中用于设置液晶屏硬件参数信息,再通过s3cfb_init_global函数设置寄存器,达到液晶屏初始化的目的。
当我们需要更换LCD屏时,通常情况下只需修改LCD的硬件参数即可。在x4412_lcds.c中定义了五组显示屏的参数,依次为ek070tn93、vs070cxn、vga-1024x768、vga-1280x1024以及vga-1920x1200。他们对应800*480的群创屏AT070TN92,1024*600的视声高清屏VS070CXN,1024*768的VGA输出,1280*1024的VGA输出以及1920*1200的VGA输出。默认x4412使用vs070cxn液晶屏,其硬件参数定义如下:
  1. static struct s3cfb_lcd vs070cxn = {
  2.          .width         = 1024,
  3.          .height        = 600,
  4.          .bpp  = 32,
  5.          .freq  = 60,
  6.          .timing = {
  7.                    .h_fp = 160,
  8.                    .h_bp          = 140,
  9.                    .h_sw         = 20,
  10.                    .v_fp = 12,
  11.                    .v_fpe         = 1,
  12.                    .v_bp          = 20,
  13.                    .v_bpe        = 1,
  14.                    .v_sw         = 3,
  15.          },
  16.          .polarity = {
  17.                    .rise_vclk   = 0,
  18.                    .inv_hsync = 1,
  19.                    .inv_vsync = 1,
  20.                    .inv_vden   = 0,
  21.          },
  22.          .init_ldi = NULL,
  23. };
复制代码
该结构体描述了液晶屏的分辨率,显示位数,帧率,行场前后肩,行场时钟有效信号等。不同的屏,这些参数会有所不同,当更改液晶屏时,基本上修改这些参数就可以大功告成了。为此,我们特别在x4412_lcds.c中定义了多组液晶屏参数,通过uboot传参实现不同显示设备的切换,如下代码用于指定液晶屏名称:
  1. static unsigned char lcd_name[32] = "ek070tn93";
  2. static int __init lcd_setup(char * str)
  3. {
  4.     if((str != NULL) && (*str != '\0'))//如果lcd的定义不为空,则将它的定义赋给lcd_name
  5.     strcpy(lcd_name, str);
  6.          return 1;
  7. }
  8. __setup("lcd=", lcd_setup);//将uboot环境变量中lcd的定义传递给函数lcd_setup
复制代码
默认为ek070tn93,当uboot的环境变量中有关于lcd的定义时,将它定义的值赋给lcd_name,在s3cfb_set_lcd_info函数中,通过lcd_name将对应的硬件参数传递给s3cfb_main.c中的探测函数,达到同一个映像实现多款LCD屏的支持。s3cfb_set_lcd_info函数内容如下:
  1. void s3cfb_set_lcd_info(struct s3cfb_global *ctrl)
  2. {
  3.          struct s3cfb_lcd * lcd = x4412_lcd_config[0].lcd;
  4.          int i;
  5.          for(i = 0; i < ARRAY_SIZE(x4412_lcd_config); i++)
  6.          {
  7.                    if(strcasecmp(x4412_lcd_config[i].name, lcd_name) == 0)
  8.                    {
  9.                             lcd = x4412_lcd_config[i].lcd;
  10.                             break;
  11.                    }
  12.          }
  13.          ctrl->lcd = lcd;
  14.          printk("lcd: select %s\r\n", lcd_name);
  15. }
复制代码
该程序通过lcd_name和数组x4412_lcd_config中的名称进行比对,找到指定名称的LCD,并通过形参传递出去。
回复

使用道具 举报

沙发
发表于 2014-12-12 11:25:47 | 只看该作者
非常感谢您的分享~~~~~~~~
回复 支持 反对

使用道具 举报

板凳
发表于 2014-12-13 18:48:50 | 只看该作者
九鼎越来越精彩了,这个要支持
回复 支持 反对

使用道具 举报

地板
发表于 2015-5-13 08:14:45 | 只看该作者
好好学习,谢谢楼主{:soso_e100:}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳市九鼎创展科技官方论坛 ( 粤ICP备11028681号-2  

GMT+8, 2024-5-3 09:29 , Processed in 0.018209 second(s), 16 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表