高清嵌入式系统中的DVI驱动开发
4DVI驱动程序设计
4.1 平台驱动
从Linux2.6起引入了一套新的驱动管理和注册机制:platform_device和platform_driver。
设备用platform_device表示,驱动用platform_driver注册。平台设备包括基于端口的设备、外围总线和集成在片上系统中的大多数控制器,作为MX51片上的独立硬件模块。LCD控制器是一个平台设备,因此驱动设计中需包含平台驱动。平台驱动的任务是向系统注册用到的设备,此处包括MX51的LCD控制器和TFP410 DVI视频输出芯片,使得设备驱动加载时可以从系统中查询到相应的设备是已注册的状态,然后执行设备驱动程序中的probe函数。
在arch/arm/machmx51/mx51_3stack.c中,设置platform_device结构变量mxc_fb_device和i2c_board_info。结构变量mxc_i2c1_board_info定义LCD控制器和TFP410设备。
调用函数platform_device_register(&mxc_fb_device)和i2c_register_board_info(1, mxc_i2c1_board_info,ARRAY_SIZE(mxc_i2c1_board_info))向系统注册以上设备。
4.2 设备驱动
4.2.1 LCD控制器驱动
LCD控制器驱动是一个标准的帧缓冲设备驱动。首先在drivers/video/mxc/mxc_ipuv3_fb.c中定义全局结构变量mxcfb_driver:
static struct platform_driver mxcfb_driver={
.driver={
.name=MXCFB_NAME,
},
.probe=mxcfb_probe,
.remove=mxcfb_remove,
.suspend=mxcfb_suspend,
.resume=mxcfb_resume,
};
然后,在驱动入口函数mxcfb_init(void)中调用platform_driver_register(&mxcfb_driver)注册驱动,当驱动加载成功后,会自动调用探测函数mxcfb_probe。
mxcfb_probe是驱动设计中的重要函数。主要负责初始化硬件。申请中断、分配framebuffer所需的内存、注册帧缓冲设备等,以下是与framebuffer相关的操作。
① 调用mxcfb_init_fbinfo(&pdev﹥dev, &mxcfb_ops)函数,在其内通过framebuffer_alloc函数,为mx51帧缓冲信息结构体struct mxcfb_info分配所需空间。参数mxcfb_ops的定义如下:
static struct fb_ops mxcfb_ops={
.owner=THIS_MODULE,
.fb_set_par=mxcfb_set_par,
.fb_check_var=mxcfb_check_var,
.fb_setcolreg=mxcfb_setcolreg,
.fb_pan_display=mxcfb_pan_display,
……
};
mxcfb_ops 定义了指向底层操作的一系列函数,这些函数针对MX51帧缓冲操作,是framebuffer核心驱动操作的具体实现。
② 初始化帧缓冲信息结构体fb_info的固定和可变参数,填充fb_var_screeninfo var和fb_fix_screeninfo fix成员。
定义fbi为struct fb_info 类型的指针,通过fbi﹥fbops = &mxcfb_ops语句,将已定义的文件操作接口mxcfb_ops赋予fb_info结构的fbops成员。
调用mxcfb_check_var(&fbi﹥var, fbi)函数,检查和调整fb_info结构中变量var的值。var是一个struct fb_var_screeninfo类型的变量,表示显示控制器参数,其中与显示输出状态有关的信息,如屏幕分辨率等将在后面的DVI驱动中设置。
调用mxcfb_set_fix(fbi)函数,用于填充一个struct fb_fix_screeninfo结构变量fbi﹥fix,它描述了显示输出设备自身的属性。
③ 调用register_framebuffer(fbi)函数,注册帧缓冲驱动程序,该函数只有一个参数,即前面已定义的、指向struct fb_info结构的指针fbi。
4.2.2DVI设备驱动
LCD控制器将DVI芯片作为它所连接的显示外设,在完成LCD控制器驱动后还需编写DVI设备驱动。在文件drivers/video/mxc/mxcfb_dvi.c中定义驱动结构体:
static struct platform_driver dvi_driver={
.driver={
.name="dvi_tfp410"},
.probe=dvi_probe,
.remove=__devexit_p(dvi_remove),
.suspend=dvi_suspend,
.resume=dvi_resume,
};
然后,在外设驱动入口函数dvi_init(void)中调用platform_driver_register(&dvi_driver)注册DVI驱动,驱动加载后,系统自动调用探测函数dvi_probe,该函数主要实现以下操作:一是指定framebuffer设备,由于MX51 IPU(图像处理单元)支持多个framebuffer设备,此处要确定DVI究竟使用MX51 IPU framebuffer的哪一个设备;二是填充fb_var_screeninfo结构变量var中有关显示输出状态的信息,如屏幕的显示分辨率、画面位置等,为此在程序中定义结构数组video_modes:
static struct fb_videomode video_modes[]={
{
/*1024×768 @ 60 Hz,像素时钟频率为33 MHz */
"DVITFP410", 60, 1024, 768, 33260, 117, 18, 23, 28, 2, 3,
0, FB_VMODE_NONINTERLACED,0,
},
……
};
结构struct fb_videomode用于描述显示输出状态,调用函数"fb_videomode_to_var(&var, &video_modes[0])"将屏幕显示参数转换为var结构变量的相关成员,由于var的部分成员值已在前面LCD控制器驱动中确定,此处完成了对var全部成员的设置。
一个frambuffer设备由一个struct fb_info结构表示,本设计用fb_info结构的全局变量registered_fb表示系统注册的frambuffer设备,驱动程序的主要任务之一是填充这个结构变量。LCD控制器驱动与DVI外设驱动之间的信息传递,通过该全局变量实现。
- 基于新唐M0的DMX512-1990收发例程(11-29)
- 飞思卡尔i.MX51系列满足扩大的嵌入式市场需求(09-12)
- 基于i.MX51的应用处理器开发评估方案设计(01-20)
- 基于framebuffer技术的DVI显示驱动程序的开发(04-30)
- 独立式多分辨率VGA/DVI压缩存储系统(06-05)
- Android 利用addView 动态给Activity添加View组件(09-12)