MT6573androidLCDbacklightDriver文档格式.docx
《MT6573androidLCDbacklightDriver文档格式.docx》由会员分享,可在线阅读,更多相关《MT6573androidLCDbacklightDriver文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
LCM_DRIVERnt35510_lcm_drv=
{
.name="
nt35510"
.set_util_funcs=lcm_set_util_funcs,
.get_params=lcm_get_params,
.init=lcm_init,
.suspend=lcm_suspend,
.resume=lcm_resume,
.compare_id=lcm_compare_id,
};
(1)lcm_get_params主要是设置LCM相关的参数,数据结构如下:
typedefstruct
LCM_TYPEtype;
LCM_CTRLctrl;
//!
howtocontrolLCMregisters
unsignedintwidth;
unsignedintheight;
unsignedintio_select_mode;
//DBIorDPIshouldselectIOmodeaccordingtochipspec
/*particularparameters*/
LCM_DBI_PARAMSdbi;
LCM_DPI_PARAMSdpi;
LCM_DSI_PARAMSdsi;
}LCM_PARAMS;
LCM_TYPE定义LCM与HOST间的接口,主要分为3种,DBI,DPI,DSI。
其中DBI又分为parallelDBI和serialDBI。
parallelDBI(B型DBI)的命令和数据都在数据总线D[17:
0]上传输。
CSX为低时数据有效。
WRX线控制D[17:
0]为写时序,RDX控制D[17:
0]为读时序。
D/CX指示D[17:
0]上传输的是命令还是数据。
注:
MT6573使用LPA0线作为D/CX线,LPCE线作为CSX线,LWRB线作为WRX线,LRDB线作为RDX线。
serialDBI(C型DBI)的命令和数据都在SPI接口上传输。
CSX为低时SDA有效。
SCL提供时钟,DIN输入,DOUT输出。
当SDA_EN=1时,DIN线成为双向的SDA线,即可输入又可输出,DOUT线不用。
C型DBI分为3线(没有D/CX线)和4线(有D/CX线)两种。
3线的使用一个D/CXbit来区分命令/数据,4线的使用D/CX线来区分命令/数据。
MT6573使用LSA0线作为D/CX线,LSCE线作为CSX线。
LSCK线作为SCL线,LSDA线作为SDA线。
DPI的命令在SPI上传输,Pixeldata(RGBdata)在D[17:
其命令传输方式与serialDBI相同。
对于Pixeldata(RGBdata),需要自己的4条控制线:
DPICK_PIN(RGB时钟)、DPIDE_PIN(RGB数据有效)、DPIVSYNC(场同步)、DPIHSYNC(行同步)。
typedefenum
LCM_CTRL_NONE=0,
LCM_CTRL_SERIAL_DBI,
LCM_CTRL_PARALLEL_DBI,
LCM_CTRL_GPIO
}
LCM_CTRL定义LCM与HOST之间传递command的方式,有SERIAL_DBI、PARALLEL_DBI、GPIO几种控制方式。
如果是DPI接口,其LCM_CTRL可以选择SERIAL_DBI或者GPIO。
Width和height定义LCM的宽度和高度。
io_select_mode有这些选项:
0(LCD_IO_SEL_16CPU_24RGB),1(LCD_IO_SEL_18CPU_18RGB),2(LCD_IO_SEL_24CPU_8RGB),3(LCD_IO_SEL_24CPU_ONLY)。
根据driverIC的定义填写。
LCM_×
×
_PARAMS根据不同的LCM_TYPE取值,这是针对DBI/DPI/DSI接口类型的详细参数定义。
比如LCM_DPI_PARAMS定义如下:
unsignedintmipi_pll_clk_ref;
//0..1
unsignedintmipi_pll_clk_div1;
//0..63
unsignedintmipi_pll_clk_div2;
//0..15
unsignedintdpi_clk_div;
//2..32
unsignedintdpi_clk_duty;
//(dpi_clk_div-1)..31
/*polarityparameters*/
LCM_POLARITYclk_pol;
LCM_POLARITYde_pol;
LCM_POLARITYvsync_pol;
LCM_POLARITYhsync_pol;
/*timingparameters*/
unsignedinthsync_pulse_width;
unsignedinthsync_back_porch;
unsignedinthsync_front_porch;
unsignedintvsync_pulse_width;
unsignedintvsync_back_porch;
unsignedintvsync_front_porch;
/*outputformatparameters*/
LCM_DPI_FORMATformat;
LCM_COLOR_ORDERrgb_order;
unsignedintis_serial_output;
/*intermediatebuffersparameters*/
unsignedintintermediat_buffer_num;
//2..3
/*iopadparameters*/
LCM_DRIVING_CURRENTio_driving_current;
}LCM_DPI_PARAMS;
其中,第一段前4项用于控制DPI时钟,计算公式如下:
PixelClockFrequency=26MHz*mipi_pll_clk_div1/(mipi_pll_clk_ref+1)/(2*mipi_pll_clk_div2)/dpi_clk_div
第二段4个参数设置DPICK_PIN(RGB时钟)、DPIDE_PIN(RGB数据有效)、DPIVSYNC(场同步)、DPIHSYNC(行同步)线是上升沿还是下降沿有效。
行同步脉冲开始前和开始后的几个时钟周期,是行信号消隐期;
场同步开始前和开始后的几个行周期,是场信号消隐期。
消隐期不传递图像信号。
消隐期特性由第三段六个参数定义:
hsync_pulse_width;
hsync_back_porch;
hsync_front_porch;
vsync_pulse_width;
vsync_back_porch;
vsync_front_porch;
LCM_DPI_FORMAT指定每个像素中RGB各占几个bit.
LCM_COLOR_ORDER指定RGB的顺序。
上述参数的值,均依照LCMspec及驱动ICdatasheet中的定义。
这里要说说一个特别之处。
NT35510使用DPI接口,SERIAL_DBIctrl方式时,没有D/CX线,datasheet上定义的传输方式是9bits,即在数据byte前加个D/CXbit。
但使用了NT35510的LCM——LF040DNYB16a,其spec中却另外定义了其串口使用16bits模式传输。
Byte1是标志byte,前3位分别为R/Wbit,D/CXbit,High/Lowbit;
Byte2则是命令或数据。
NT35510的每个command长度为2byte,还可能带有若干bytes的参数,比如命令F001,参数AA,应该这样传输:
0x200xF00x000x010x400xAA。
(2)lcm_init主要实现LCM的初始化,包括如下步骤:
config_gpio——配置GPIO。
发送reset信号。
RESETpinlow和RESETpinhigh需要持续的时间一般为若干ms,以datasheet为准。
init_lcm_registers——初始化LCM的寄存器。
具体可以厂家提供的初始代码为参考。
一般在此函数末尾,都会使用唤醒命令组(见后文),使LCM进入工作状态。
(3)lcm_suspend使LCM休眠,使用特定的命令,并遵守datasheet定义的时间特性。
常用命令组如下:
0X2800(or0X28)——setdisplayoff
0X1000(or0X10)——entersleepmode
对nt35510而言,还有一种更深睡眠的状态——deepstandbymode,使用如下命令进入:
0X4F000X01
(4)lcm_resume使LCM苏醒,使用特定的命令,并遵守datasheet定义的时间特性。
唤醒命令组:
0X1100(or0X11)——exitsleepmode
0X2900(or0X29)——setdisplayon
对nt35510而言,如果在lcm_suspend中使LCMenterdeepstandbymode,则不能使用唤醒命令组,需要使用reset信号并要重新init_lcm_registers。
四、驱动nt35510_lcm_drv怎样被上层使用
Mtkfb.c中实现了LCM的platformdriver:
staticstructplatform_drivermtkfb_driver=
.driver={
.name=“mtk-fb”,
.bus=&
platform_bus_type,
.probe=mtkfb_probe,
.remove=mtkfb_remove,
.suspend=mtkfb_suspend,
.resume=mtkfb_resume,
},
mtkfb_probe会调用函数mtkfb_find_lcm_driver来发现LCM的硬件层驱动。
mtkfb_find_lcm_driver——DISP_SelectDevice——disp_drv_get_lcm_driver,检查lcm_driver_list[],得到当前使用的LCM及其驱动名称。
Mt6573_devs.c中,定义了framebuffer型的platformdevice,这个设备在mt6573_board_init()调用时被注册。
它所对应的驱动就是上文提到的mtkfb_driver
staticstructplatform_devicemt6573_device_fb={
.name="
mtkfb"
.id=0,
.num_resources=ARRAY_SIZE(resource_fb),
.resource=resource_fb,
.dev={
.dma_mask=&
mtkfb_dmamask,
.coherent_dma_mask=0xffffffff,
},
在linux内核中lcd设备驱动所使用的是framebuffer设备类型,framebuffer设备驱动程序的核心数据结构是fb_ops;
用户空间就是通过此结构体,调用其中的函数来对LCD实现控制。
Mtkfb.c中定义并实现了fb_ops类型的mtkfb_ops。
一个使用mtkfb_ops的例子见\mediatek\source\kernel\drivers\gpu\pvr\services4\3rdparty\mtklfb\mtklfb_displayclass.c。
staticstructfb_opsmtkfb_ops={
.owner=THIS_MODULE,
.fb_open=mtkfb_open,
.fb_release=mtkfb_release,
.fb_setcolreg=mtkfb_setcolreg,//批量配置颜色参数
.fb_pan_display=mtkfb_pan_display_proxy,//虚拟屏幕内容显示
.fb_fillrect=cfb_fillrect,//填充区域显示
.fb_copyarea=cfb_copyarea,//复制区域显示
.fb_imageblit=cfb_imageblit,//显示图象
.fb_cursor=mtkfb_soft_cursor,//光标显示
.fb_check_var=mtkfb_check_var,//检查并配置fb_var_screeninfo参数
.fb_set_par=mtkfb_set_par,//changedisplaymodeandsetparameter
.fb_ioctl=mtkfb_ioctl,//特定ioctl配置LCD屏幕特性
五、FrameBuffer设备驱动
mtkfb_driver中的各个函数会调用到DISP_xxx函数(DISP_drv.c),而DISP_xxx会调用到LCD_xxx函数(lcd_drv.c)以及LCM硬件层驱动。
mtkfb_probe的主要工作如下:
*findlcmdriver
*Registerinterrupthandler(callbackfunction),Initscreenupdatewaitqueue,createscreenupdatekThread
*Allocateandinitializeframebufferdevice(fb_info,mtkfb_device),selectpaneltypeaccordingtomachinetype
*InitializeDisplayDriverPDDLayer(DISP_init)
*Initializefb_infostruct(mtkfb_fbinfo_init)
*Registermtkfb_devicefstosystem(mtkfb_register_sysfs)
*Registerfb_infotosystem(register_framebuffer)
fb_info结构定义如下:
structfb_info{
intnode;
intflags;
structmutexlock;
/*Lockforopen/release/ioctlfuncs*/
structmutexmm_lock;
/*Lockforfb_mmapandsmem_*fields*/
structfb_var_screeninfovar;
/*Currentvar*/
structfb_fix_screeninfofix;
/*Currentfix*/
structfb_monspecsmonspecs;
/*CurrentMonitorspecs*/
structwork_structqueue;
/*Framebuffereventqueue*/
structfb_pixmappixmap;
/*Imagehardwaremapper*/
structfb_pixmapsprite;
/*Cursorhardwaremapper*/
structfb_cmapcmap;
/*Currentcmap*/
structlist_headmodelist;
/*modelist*/
structfb_videomode*mode;
/*currentmode*/
#ifdefCONFIG_FB_BACKLIGHT
structbacklight_device*bl_dev;
structmutexbl_curve_mutex;
u8bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdefCONFIG_FB_DEFERRED_IO
structdelayed_workdeferred_work;
structfb_deferred_io*fbdefio;
structfb_ops*fbops;
structdevice*device;
/*Thisistheparent*/
structdevice*dev;
/*Thisisthisfbdevice*/
intclass_flag;
/*privatesysfsflags*/
#ifdefCONFIG_FB_TILEBLITTING
structfb_tile_ops*tileops;
/*TileBlitting*/
char__iomem*screen_base;
/*Virtualaddress*/
unsignedlongscreen_size;
/*AmountofioremappedVRAMor0*/
void*pseudo_palette;
/*Fakepaletteof16colors*/
#defineFBINFO_STATE_RUNNING0
#defineFBINFO_STATE_SUSPENDED1
u32state;
/*Hardwarestatei.esuspend*/
void*fbcon_par;
/*fbconuse-onlyprivatearea*/
/*Fromhereoneverythingisdevicedependent*/
void*par;
structapertures_struct{
unsignedintcount;
structaperture{
resource_size_tbase;
resource_size_tsize;
}ranges[0];
}*apertures;
1)fb_var_screeninfo
这个结构描述了显示卡的特性:
NOTE:
__u32是表示unsigned不带符号的32bits的数据类型,其余类推。
这是Linux内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用unsignedlong等等来代替
structfb_var_screeninfo
{
__u32xres;
/*visibleresolution*///可视区域
__u32yres;
__u32xres_virtual;
/*virtualresolution*///可视区域
__u32yres_virtual;
__u32xoffset;
/*offsetfromvirtualtovisiblereso