lcd設(shè)備驅(qū)動之全解析_第1頁
lcd設(shè)備驅(qū)動之全解析_第2頁
lcd設(shè)備驅(qū)動之全解析_第3頁
lcd設(shè)備驅(qū)動之全解析_第4頁
lcd設(shè)備驅(qū)動之全解析_第5頁
已閱讀5頁,還剩49頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

linux中LCD設(shè)備驅(qū)動(1)——framebuffer(幀緩沖)1、framebuffer幀緩沖

幀緩沖(framebuffer)是Linux系統(tǒng)為顯示設(shè)備提供的一個接口,它將顯示緩沖區(qū)抽象,屏蔽圖像硬件的底層差異,允許上層應(yīng)用程序在圖形模式下直接對顯示緩沖區(qū)進行讀寫操作。用戶不必關(guān)心物理顯示緩沖區(qū)的具體位置及存放方式,這些都由幀緩沖設(shè)備驅(qū)動本身來完成。

framebuffer機制模仿顯卡的功能,將顯卡硬件結(jié)構(gòu)抽象為一系列的數(shù)據(jù)結(jié)構(gòu),可以通過framebuffer的讀寫直接對顯存進行操作。用戶可以將framebuffer看成是顯存的一個映像,將其映射到進程空間后,就可以直接進行讀寫操作,寫操作會直接反映在屏幕上。

framebuffer是個字符設(shè)備,主設(shè)備號為29,對應(yīng)于/dev/fb%d設(shè)備文件。通常,使用如下方式(前面的數(shù)字表示次設(shè)備號)

0=/dev/fb0第一個fb設(shè)備

1=/dev/fb1第二個fb設(shè)備

fb也是一種普通的內(nèi)存設(shè)備,可以讀寫其內(nèi)容。例如,屏幕抓屏:cp/dev/fb0myfilefb雖然可以像內(nèi)存設(shè)備(/dev/mem)一樣,對其read,write,seek以及mmap。但區(qū)別在于fb使用的不是整個內(nèi)存區(qū),而是顯存部分。2、fb與應(yīng)用程序的交互對于用戶程序而言,它和其他的設(shè)備并沒有什么區(qū)別,用戶可以把fb看成是一塊內(nèi)存,既可以向內(nèi)存中寫數(shù)據(jù),也可以讀數(shù)據(jù)。fb的顯示緩沖區(qū)位于內(nèi)核空間,應(yīng)用程序可以把此空間映射到自己的用戶空間,在進行操作。在應(yīng)用程序中,操作/dev/fbn的一般步驟如下:(1)打開/dev/fbn設(shè)備文件。(2)用ioctl()操作取得當(dāng)前顯示屏幕的參數(shù),如屏幕分辨率、每個像素點的比特數(shù)。根據(jù)屏幕參數(shù)可計算屏幕緩沖區(qū)的大小。(3)用mmap()函數(shù),將屏幕緩沖區(qū)映射到用戶空間。(4)映射后就可以直接讀/寫屏幕緩沖區(qū),進行繪圖和圖片顯示了。3、fb的結(jié)構(gòu)及其相關(guān)結(jié)構(gòu)體在linux中,fb設(shè)備驅(qū)動的源碼主要在Fb.h(linux2.6.28\include\linux)和Fbmem.c(linux2.6.28\drivers\video)兩個文件中,它們是fb設(shè)備驅(qū)動的中間層,為上層提供系統(tǒng)調(diào)用,為底層驅(qū)動提供接口。在fb.h文件中有fb驅(qū)動需要使用的很多結(jié)構(gòu),我們先對這些結(jié)構(gòu)體進行說明:本章共介紹5個結(jié)構(gòu)體:(1)、structfb_info結(jié)構(gòu)體(2)、structfb_ops結(jié)構(gòu)體(3)、structfb_fix_screeninfo結(jié)構(gòu)體(4)、structfb_var_screeninfo結(jié)構(gòu)體(5)、structfb_cmap結(jié)構(gòu)體(1)、structfb_info結(jié)構(gòu)體介紹一個幀緩沖區(qū)對應(yīng)一個structfb_info結(jié)構(gòu),它包括了幀緩沖設(shè)備的屬性和操作的完整集合,每個幀設(shè)備都有一個fb_info結(jié)構(gòu)體。源碼如下:structfb_info{intnode;intflags;structmutexlock;/*Lockforopen/release/ioctlfuncs*/互斥鎖structfb_var_screeninfovar;/*Currentvar*/當(dāng)前緩沖區(qū)的可變參數(shù)structfb_fix_screeninfofix;/*Currentfix*/固定參數(shù)structfb_monspecsmonspecs;/*CurrentMonitorspecs*/當(dāng)前顯示器標(biāo)志structwork_structqueue;/*Framebuffereventqueue*/幀緩沖事件隊列structfb_pixmappixmap;/*Imagehardwaremapper*/圖像硬件mapperstructfb_pixmapsprite;/*Cursorhardwaremapper*/光標(biāo)硬件mapperstructfb_cmapcmap;/*Currentcmap*/當(dāng)前的調(diào)色板structlist_headmodelist;

/*modelist*/structfb_videomode*mode;/*currentmode*/當(dāng)前的視頻模式#ifdefCONFIG_FB_BACKLIGHT如果配置了LCD支持背光燈/*assignedbacklightdevice*//*setbeforeframebufferregistration,

removeafterunregister*/背光調(diào)整structbacklight_device*bl_dev;/*Backlightlevelcurve*/structmutexbl_curve_mutex;u8bl_curve[FB_BACKLIGHT_LEVELS];#endif#ifdefCONFIG_FB_DEFERRED_IOstructdelayed_workdeferred_work;structfb_deferred_io*fbdefio;#endifstructfb_ops*fbops;幀緩沖操作函數(shù)集structdevice*device;/*Thisistheparent*/父設(shè)備structdevice*dev;/*Thisisthisfbdevice*/fb設(shè)備intclass_flag;

/*privatesysfsflags*/私有的sysfs標(biāo)志#ifdefCONFIG_FB_TILEBLITTINGstructfb_tile_ops*tileops;

/*TileBlitting*/圖塊blitting#endifchar__iomem*screen_base;/*Virtualaddress*/虛擬基地址unsignedlongscreen_size;/*AmountofioremappedVRAMor0*/ioremap的虛擬內(nèi)存大小void*pseudo_palette;/*Fakepaletteof16colors*/偽16位調(diào)色板#defineFBINFO_STATE_RUNNING0#defineFBINFO_STATE_SUSPENDED1u32state;

/*Hardwarestatei.esuspend*/硬件的狀態(tài)void*fbcon_par;

/*fbconuse-onlyprivatearea*//*Fromhereoneverythingisdevicedependent*/void*par;

};(2)、structfb_ops結(jié)構(gòu)體介紹/*

*

Framebufferoperations

*

*LOCKINGNOTE:thosefunctionsmust_ALL_becalledwiththeconsole

*semaphoreheld,thisistheonlysuitablelockingmechanismwehave

*in2.6.Somemaybecalledatinterrupttimeatthispointthough.

*/fb_ops結(jié)構(gòu)體用來實現(xiàn)對幀緩沖設(shè)備的操作,這些函數(shù)需要驅(qū)動開發(fā)人員編寫,structfb_ops{/*open/releaseandusagemarking*/structmodule*owner;打開和釋放int(*fb_open)(structfb_info*info,intuser);int(*fb_release)(structfb_info*info,intuser);這兩個函數(shù)對于非線性布局的/常規(guī)內(nèi)存映射無法工作的幀緩沖設(shè)備需要/*Forframebufferswithstrangenonlinearlayoutsorthatdonot*workwithnormalmemorymappedaccess*/ssize_t(*fb_read)(structfb_info*info,char__user*buf,

size_tcount,loff_t*ppos);ssize_t(*fb_write)(structfb_info*info,constchar__user*buf,

size_tcount,loff_t*ppos);檢測可變參數(shù),并調(diào)整到支持的值/*checksvarandeventuallytweaksittosomethingsupported,*DONOTMODIFYPAR*/int(*fb_check_var)(structfb_var_screeninfo*var,structfb_info*info);

設(shè)置視頻模式/*setthevideomodeaccordingtoinfo->var*/int(*fb_set_par)(structfb_info*info);設(shè)置color寄存器的值/*setcolorregister*/int(*fb_setcolreg)(unsignedregno,unsignedred,unsignedgreen,

unsignedblue,unsignedtransp,structfb_info*info);批量設(shè)置color寄存器,設(shè)置顏色表/*setcolorregistersinbatch*/int(*fb_setcmap)(structfb_cmap*cmap,structfb_info*info);顯示空白/*blankdisplay*/int(*fb_blank)(intblank,structfb_info*info);

pan顯示/*pandisplay*/int(*fb_pan_display)(structfb_var_screeninfo*var,structfb_info*info);填充矩形/*Drawsarectangle*/void(*fb_fillrect)(structfb_info*info,conststructfb_fillrect*rect);

數(shù)據(jù)復(fù)制/*Copydatafromareatoanother*/void(*fb_copyarea)(structfb_info*info,conststructfb_copyarea*region);圖形填充/*Drawsaimagetothedisplay*/void(*fb_imageblit)(structfb_info*info,conststructfb_image*image);

繪制光標(biāo)/*Drawscursor*/int(*fb_cursor)(structfb_info*info,structfb_cursor*cursor);

旋轉(zhuǎn)顯示/*Rotatesthedisplay*/void(*fb_rotate)(structfb_info*info,intangle);

等待blit空閑/*waitforblitidle,optional*/int(*fb_sync)(structfb_info*info);

fb特定的ioctl操作/*performfbspecificioctl(optional)*/int(*fb_ioctl)(structfb_info*info,unsignedintcmd,unsignedlongarg);處理32兼容的ioctl操作/*Handle32bitcompatioctl(optional)*/int(*fb_compat_ioctl)(structfb_info*info,unsignedcmd,unsignedlongarg);

fb特定的mmap操作/*performfbspecificmmap*/int(*fb_mmap)(structfb_info*info,structvm_area_struct*vma);保存目前的硬件狀態(tài)/*savecurrenthardwarestate*/void(*fb_save_state)(structfb_info*info);

恢復(fù)被保存的硬件狀態(tài)/*restoresavedstate*/void(*fb_restore_state)(structfb_info*info);通過fb_info獲得framebuffer的能力/*getcapabilitygivenvar*/void(*fb_get_caps)(structfb_info*info,structfb_blit_caps*caps,

structfb_var_screeninfo*var);};(3)、structfb_fix_screeninfo結(jié)構(gòu)體接收fb_fix_screeninfo結(jié)構(gòu)體中,記錄了用戶不能修改的固定顯示控制器參數(shù)。這些固定的參數(shù)如緩沖區(qū)的物理地址、緩沖區(qū)的長度等等。structfb_fix_screeninfo{charid[16];

/*identificationstringeg"TTBuiltin"*/字符串形式的標(biāo)識符unsignedlongsmem_start;/*Startofframebuffermem*//*(physicaladdress)*/fb緩存的開始位置__u32smem_len;/*Lengthofframebuffermem*/

fb緩存的長度__u32type;

/*seeFB_TYPE_**/FB_TYPE_*類型__u32type_aux;/*InterleaveforinterleavedPlanes*/分界__u32visual;

/*seeFB_VISUAL_**/

屏幕使用的色彩模式

__u16xpanstep;/*zeroifnohardwarepanning

*/如果沒有硬件panning,賦0__u16ypanstep;/*zeroifnohardwarepanning

*/__u16ywrapstep;/*zeroifnohardwareywrap

*/1行的字節(jié)數(shù)__u32line_length;/*lengthofalineinbytes

*/內(nèi)存映射I/O的開始位置unsignedlongmmio_start;/*StartofMemoryMappedI/O

*//*(physicaladdress)*/內(nèi)存映射I/O的長度__u32mmio_len;/*LengthofMemoryMappedI/O

*/__u32accel;

/*Indicatetodriverwhich*//*

specificchip/cardwehave*/__u16reserved[3];/*Reservedforfuturecompatibility*/};(4)、structfb_var_screeninfo結(jié)構(gòu)體介紹fb_var_screeninfo結(jié)構(gòu)體中存儲了用戶可以修改的顯示器控制參數(shù),例如屏幕分辨率、透明度等等。structfb_var_screeninfo{__u32xres;

/*visibleresolution*/__u32yres;可見解析度,即分辨率__u32xres_virtual;/*virtualresolution*/__u32yres_virtual;

虛擬解析度__u32xoffset;/*offsetfromvirtualtovisible*/__u32yoffset;/*resolution*/虛擬到可見之間的偏移__u32bits_per_pixel;/*guesswhat*/

每像素位數(shù),BPP__u32grayscale;/*!=0Graylevelsinsteadofcolors*/

非0時指灰度structfb_bitfieldred;/*bitfieldinfbmemiftruecolor,*/structfb_bitfieldgreen;/*elseonlylengthissignificant*/structfb_bitfieldblue;fb緩存的R\G\B位域structfb_bitfieldtransp;/*transparency*/透明度__u32nonstd;

/*!=0Nonstandardpixelformat*/!=0非標(biāo)準(zhǔn)像素格式__u32activate;/*seeFB_ACTIVATE_**/

__u32height;

/*heightofpictureinmm

*/

屏幕的高度__u32width;

/*widthofpictureinmm

*/屏幕的寬度__u32accel_flags;/*(OBSOLETE)seefb_info.flags*/fb_info的標(biāo)志/*Timing:Allvaluesinpixclocks,exceptpixclock(ofcourse)*/__u32pixclock;/*pixelclockinps(picoseconds)*//*像素時鐘(皮秒)*/__u32left_margin;/*timefromsynctopicture*/

行切換:從同步到繪圖之間的延遲__u32right_margin;/*timefrompicturetosync*/

行切換:從繪圖到同步之間的延遲__u32upper_margin;/*timefromsynctopicture*/

幀切換:從同步到繪圖之間的延遲__u32lower_margin;

幀切換:從繪圖到同步之間的延遲__u32hsync_len;/*lengthofhorizontalsync*/

水平同步的長度__u32vsync_len;/*lengthofverticalsync*/

垂直同步的長度__u32sync;

/*seeFB_SYNC_**/__u32vmode;

/*seeFB_VMODE_**/__u32rotate;

/*anglewerotatecounterclockwise*/

順時鐘旋轉(zhuǎn)的角度__u32reserved[5];/*Reservedforfuturecompatibility*/};(5)、structfb_cmap結(jié)構(gòu)體介紹fb_cmap結(jié)構(gòu)體中記錄了顏色板信息,即調(diào)色板信息。,用戶空間可以通過ioctl()的FBIOGETCMAP和FBIOPUTCMAP命令讀取或設(shè)定顏色表。structfb_cmap{__u32start;

/*Firstentry*/第一個元素的入口__u32len;

/*Numberofentries*/元素個數(shù)__u16*red;

/*Redvalues*/紅色、綠色、藍色__u16*green;

__u16*blue;__u16*transp;/*transparency,canbeNULL*/透明度};上面這些結(jié)構(gòu)體之間有什么關(guān)系呢?看下圖:(6)、fb_bitfield結(jié)構(gòu)體描述每一像素顯示緩沖區(qū)的組織方式,包含位域偏移、位域長度和MSB指示,structfb_bitfield{__u32offset;

/*beginningofbitfield*/

位域偏移__u32length;

/*lengthofbitfield*/

位域長度__u32msb_right;/*!=0:Mostsignificantbitis*/

/*right*/

MSB};上一篇說了framebuffer幀緩沖的有關(guān)知識,這一篇具體的說下LCD驅(qū)動的實現(xiàn)。1、LCD設(shè)備驅(qū)動在linux內(nèi)核中是作為平臺設(shè)備存在,所以又要說那些已經(jīng)說過很多遍的東西。int__devinits3cfb_init(void){returnplatform_driver_register(&s3cfb_driver);}staticvoid__exits3cfb_cleanup(void){platform_driver_unregister(&s3cfb_driver);}module_init(s3cfb_init);module_exit(s3cfb_cleanup);對應(yīng)的platform_driver結(jié)構(gòu)體為:staticstructplatform_drivers3cfb_driver={.probe

=s3cfb_probe,.remove

=s3cfb_remove,.suspend

=s3cfb_suspend,.resume

=s3cfb_resume,

.driver={.name="s3c-lcd",.owner

=THIS_MODULE,},};那么平臺設(shè)備的資源呢?/*LCDController*/staticu64s3c_device_lcd_dmamask=0xffffffffUL;structplatform_devices3c_device_lcd={.name

="s3c-lcd",.id

=-1,設(shè)備編號,-1表示只有這樣一個設(shè)備.num_resources

=ARRAY_SIZE(s3c_lcd_resource),.resource

=s3c_lcd_resource,.dev

={.dma_mask

=&s3c_device_lcd_dmamask,.coherent_dma_mask=0xffffffffUL}};staticstructresources3c_lcd_resource[]={[0]={.start=S3C64XX_PA_LCD,

//LCD的I/O內(nèi)存的開始位置.end

=S3C64XX_PA_LCD+SZ_1M-1,.flags=IORESOURCE_MEM,},[1]={.start=IRQ_LCD_VSYNC,

//LCD的開始中斷號.end

=IRQ_LCD_SYSTEM,

//LCD的結(jié)束中斷號.flags=IORESOURCE_IRQ,}};2、分析其probe函數(shù),源碼如下:/*

*

Probe

*/staticint__inits3cfb_probe(structplatform_device*pdev){structresource*res;structfb_info*fbinfo;s3cfb_info_t*info;chardriver_name[]="s3cfb";intindex=0,ret,size;fbinfo=framebuffer_alloc(sizeof(s3cfb_info_t),&pdev->dev);申請一個s3cfb_info_t結(jié)構(gòu)體的空間if(!fbinfo)return-ENOMEM;platform_set_drvdata(pdev,fbinfo);info=fbinfo->par;info->dev=&pdev->dev;

填充info結(jié)構(gòu)體變量的相應(yīng)信息res=platform_get_resource(pdev,IORESOURCE_MEM,0);獲取LCD平臺設(shè)備所使用的I/O端口資源。if(res==NULL){dev_err(&pdev->dev,"failedtogetmemoryregisters\n");ret=-ENXIO;gotodealloc_fb;}size=(res->end-res->start)+1;info->mem=request_mem_region(res->start,size,pdev->name);申請LCD設(shè)備所占的I/O空間if(info->mem==NULL){dev_err(&pdev->dev,"failedtogetmemoryregion\n");ret=-ENOENT;gotodealloc_fb;}info->io=ioremap(res->start,size);將LCD的I/O端口所占用的這段I/O空間映射到內(nèi)存的虛擬地址。if(info->io==NULL){dev_err(&pdev->dev,"ioremap()ofregistersfailed\n");ret=-ENXIO;gotorelease_mem;}s3cfb_pre_init();這個函數(shù)的源碼在S3cfb_fimd4x.c(linux2.6.28\drivers\video\samsung)文件中,如下所示:voids3cfb_pre_init(void){/*initializethefimdspecific*/s3cfb_fimd.vidintcon0&=~S3C_VIDINTCON0_FRAMESEL0_MASK;s3cfb_fimd.vidintcon0|=S3C_VIDINTCON0_FRAMESEL0_VSYNC;s3cfb_fimd.vidintcon0|=S3C_VIDINTCON0_INTFRMEN_ENABLE;writel(s3cfb_fimd.vidintcon0,S3C_VIDINTCON0);}這個函數(shù)中涉及到一個結(jié)構(gòu)體s3cfb_fimd_info_ts3cfb_fimd,和這個函數(shù)在同一個文件中定義,列出部分源碼:s3cfb_fimd_info_ts3cfb_fimd={.vidcon0=S3C_VIDCON0_INTERLACE_F_PROGRESSIVE|S3C_VIDCON0_VIDOUT_RGB_IF|S3C_VIDCON0_L1_DATA16_SUB_16_MODE|\S3C_VIDCON0_L0_DATA16_MAIN_16_MODE|S3C_VIDCON0_PNRMODE_RGB_P|\S3C_VIDCON0_CLKVALUP_ALWAYS|S3C_VIDCON0_CLKDIR_DIVIDED|S3C_VIDCON0_CLKSEL_F_HCLK|\S3C_VIDCON0_ENVID_DISABLE|S3C_VIDCON0_ENVID_F_DISABLE,.dithmode=(S3C_DITHMODE_RDITHPOS_5BIT|S3C_DITHMODE_GDITHPOS_6BIT|S3C_DITHMODE_BDITHPOS_5BIT)&S3C_DITHMODE_DITHERING_DISABLE,#ifdefined(CONFIG_FB_S3C_BPP_8).wincon0=

S3C_WINCONx_BYTSWP_ENABLE|S3C_WINCONx_BURSTLEN_4WORD|S3C_WINCONx_BPPMODE_F_8BPP_PAL,.wincon1=

S3C_WINCONx_HAWSWP_ENABLE|S3C_WINCONx_BURSTLEN_4WORD|S3C_WINCONx_BPPMODE_F_16BPP_565|S3C_WINCONx_BLD_PIX_PLANE|S3C_WINCONx_ALPHA_SEL_1,.bpp=S3CFB_PIXEL_BPP_8,.bytes_per_pixel=1,.wpalcon=S3C_WPALCON_W0PAL_16BIT,vidosd1c=S3C_VIDOSDxC_ALPHA1_B(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_G(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_R(S3CFB_MAX_ALPHA_LEVEL),.vidosd2c=S3C_VIDOSDxC_ALPHA1_B(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_G(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_R(S3CFB_MAX_ALPHA_LEVEL),.vidosd3c=S3C_VIDOSDxC_ALPHA1_B(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_G(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_R(S3CFB_MAX_ALPHA_LEVEL),.vidosd4c=S3C_VIDOSDxC_ALPHA1_B(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_G(S3CFB_MAX_ALPHA_LEVEL)|S3C_VIDOSDxC_ALPHA1_R(S3CFB_MAX_ALPHA_LEVEL),.vidintcon0=S3C_VIDINTCON0_FRAMESEL0_VSYNC|S3C_VIDINTCON0_FRAMESEL1_NONE|S3C_VIDINTCON0_INTFRMEN_DISABLE|\S3C_VIDINTCON0_FIFOSEL_WIN0|S3C_VIDINTCON0_FIFOLEVEL_25|S3C_VIDINTCON0_INTFIFOEN_DISABLE|S3C_VIDINTCON0_INTEN_ENABLE,.vidintcon1=0,.xoffset=0,.yoffset=0,.w1keycon0=S3C_WxKEYCON0_KEYBLEN_DISABLE|S3C_WxKEYCON0_KEYEN_F_DISABLE|S3C_WxKEYCON0_DIRCON_MATCH_FG_IMAGE|S3C_WxKEYCON0_COMPKEY(0x0),w4keycon1=S3C_WxKEYCON1_COLVAL(0xffffff),.sync=0,.cmap_static=1,.vs_offset=S3CFB_DEFAULT_DISPLAY_OFFSET,.brightness=S3CFB_DEFAULT_BRIGHTNESS,.backlight_level=S3CFB_DEFAULT_BACKLIGHT_LEVEL,.backlight_power=1,.lcd_power=1,};那么對應(yīng)的結(jié)構(gòu)體原型在哪呢?在S3cfb.h(linux2.6.28\drivers\video\samsung)文件中,如下所示:看那些對應(yīng)的注釋,也應(yīng)該大致明白這個結(jié)構(gòu)體的作用,存儲與顯示控制器有關(guān)的信息,還有顯示屏幕的信息。不知道大家對s3cfb_fimd_info_t這個結(jié)構(gòu)體的命名有何看法?名字往往代表了這個結(jié)構(gòu)體的作用。其實這個結(jié)構(gòu)體的名字給我們的信息是:fimd—

——

——FIMD:

FullyInteractiveMobileDisplay(完全交互式移動顯示設(shè)備)這是第一個概念,另一個概念是

OSD,我查了下資料,有這樣的含義:OSD是on-screendisplay的簡稱,即屏幕菜單式調(diào)節(jié)方式。一般是按Menu鍵后屏幕彈出的顯示器各項調(diào)節(jié)項目信息的矩形菜單,可通過該菜單對顯示器各項工作指標(biāo)包括色彩、模式、幾何形狀等進行調(diào)整,從而達到最佳的使用狀態(tài)?,F(xiàn)在對這個結(jié)構(gòu)體的認識是不是深刻多了?typedefstruct{/*Screensize*/intwidth;intheight;/*Screeninfo*/intxres;intyres;/*VirtualScreeninfo*/intxres_virtual;intyres_virtual;intxoffset;intyoffset;/*OSDScreensize*/intosd_width;intosd_height;/*OSDScreeninfo*/intosd_xres;intosd_yres;/*OSDScreeninfo*/intosd_xres_virtual;intosd_yres_virtual;intbpp;intbytes_per_pixel;unsignedlongpixclock;inthsync_len;intleft_margin;intright_margin;intvsync_len;intupper_margin;intlower_margin;intsync;intcmap_grayscale:1;intcmap_inverse:1;intcmap_static:1;intunused:29;/*backlightinfo*/intbacklight_min;intbacklight_max;intbacklight_default;intvs_offset;intbrightness;intpalette_win;intbacklight_level;intbacklight_power;intlcd_power;s3cfb_vsync_info_tvsync_info;s3cfb_vs_info_tvs_info;/*lcdconfigurationregisters*/unsignedlonglcdcon1;unsignedlonglcdcon2;

unsignedlonglcdcon3;unsignedlonglcdcon4;unsignedlonglcdcon5;/*GPIOs*/unsignedlonggpcup;unsignedlonggpcup_mask;unsignedlonggpccon;unsignedlonggpccon_mask;unsignedlonggpdup;unsignedlonggpdup_mask;unsignedlonggpdcon;unsignedlonggpdcon_mask;/*lpc3600controlregister*/unsignedlonglpcsel;unsignedlonglcdtcon1;unsignedlonglcdtcon2;unsignedlonglcdtcon3;unsignedlonglcdosd1;unsignedlonglcdosd2;unsignedlonglcdosd3;unsignedlonglcdsaddrb1;unsignedlonglcdsaddrb2;unsignedlonglcdsaddrf1;unsignedlonglcdsaddrf2;unsignedlonglcdeaddrb1;unsignedlonglcdeaddrb2;unsignedlonglcdeaddrf1;unsignedlonglcdeaddrf2;unsignedlonglcdvscrb1;unsignedlonglcdvscrb2;unsignedlonglcdvscrf1;unsignedlonglcdvscrf2;unsignedlonglcdintcon;unsignedlonglcdkeycon;unsignedlonglcdkeyval;unsignedlonglcdbgcon;unsignedlonglcdfgcon;unsignedlonglcddithcon;unsignedlongvidcon0;unsignedlongvidcon1;unsignedlongvidtcon0;unsignedlongvidtcon1;unsignedlongvidtcon2;unsignedlongvidtcon3;unsignedlongwincon0;unsignedlongwincon2;unsignedlongwincon1;unsignedlongwincon3;unsignedlongwincon4;unsignedlongvidosd0a;unsignedlongvidosd0b;unsignedlongvidosd0c;unsignedlongvidosd1a;unsignedlongvidosd1b;unsignedlongvidosd1c;unsignedlongvidosd1d;unsignedlongvidosd2a;unsignedlongvidosd2b;unsignedlongvidosd2c;unsignedlongvidosd2d;unsignedlongvidosd3a;unsignedlongvidosd3b;unsignedlongvidosd3c;unsignedlongvidosd4a;unsignedlongvidosd4b;unsignedlongvidosd4c;unsignedlongvidw00add0b0;unsignedlongvidw00add0b1;unsignedlongvidw01add0;unsignedlongvidw01add0b0;unsignedlongvidw01add0b1;unsignedlongvidw00add1b0;unsignedlongvidw00add1b1;unsignedlongvidw01add1;unsignedlongvidw01add1b0;unsignedlongvidw01add1b1;unsignedlongvidw00add2b0;unsignedlongvidw00add2b1;unsignedlongvidw02add0;unsignedlongvidw03add0;unsignedlongvidw04add0;unsignedlongvidw02add1;unsignedlongvidw03add1;unsignedlongvidw04add1;unsignedlongvidw00add2;unsignedlongvidw01add2;unsignedlongvidw02add2;unsignedlongvidw03add2;unsignedlongvidw04add2;unsignedlongvidintcon;unsignedlongvidintcon0;unsignedlongvidintcon1;unsignedlongw1keycon0;unsignedlongw1keycon1;unsignedlongw2keycon0;unsignedlongw2keycon1;unsignedlongw3keycon0;unsignedlongw3keycon1;unsignedlongw4keycon0;unsignedlongw4keycon1;unsignedlongwin0map;unsignedlongwin1map;unsignedlongwin2map;unsignedlongwin3map;unsignedlongwin4map;unsignedlongwpalcon;unsignedlongdithmode;unsignedlongintclr0;unsignedlongintclr1;unsignedlongintclr2;unsignedlongwin0pal;unsignedlongwin1pal;/*utilityfunctions*/void(*set_backlight_power)(int);void(*set_lcd_power)(int);void(*set_brightness)(int);int(*map_video_memory)(s3cfb_info_t*);int(*unmap_video_memory)(s3cfb_info_t*);}s3cfb_fimd_info_t;下一篇接著從這里分析:s3cfb_set_backlight_power(1);s3cfb_set_lcd_power(1);s3cfb_set_backlight_level(S3CFB_DEFAULT_BACKLIGHT_LEVEL);info->clk=clk_get(NULL,"lcd");if(!info->clk||IS_ERR(info->clk)){printk(KERN_INFO"failedtogetlcdclocksource\n");ret=

-ENOENT;gotorelease_io;}clk_enable(info->clk);printk("S3C_LCDclockgotenabled::%ld.%03ldMhz\n",PRINT_MHZ(clk_get_rate(info->clk)));s3cfb_fimd.vsync_info.count=0;init_waitqueue_head(&s3cfb_fimd.vsync_info.wait_queue);res=platform_get_resource(pdev,IORESOURCE_IRQ,0);if(res==NULL){dev_err(&pdev->dev,"failedtogetirq\n");ret=-ENXIO;gotorelease_clock;}ret=request_irq(res->start,s3cfb_irq,0,"s3c-lcd",pdev);if(ret!=0){printk("Failedtoinstallirq(%d)\n",ret);gotorelease_clock;}msleep(5);for(index=0;index<S3CFB_NUM;index++){s3cfb_info[index].mem=info->mem;s3cfb_info[index].io=info->io;s3cfb_info[index].clk=info->clk;s3cfb_init_fbinfo(&s3cfb_info[index],driver_name,index);/*Initializevideomemory*/ret=s3cfb_map_video_memory(&s3cfb_info[index]);if(ret){printk("FailedtoallocatevideoRAM:%d\n",ret);ret=-ENOMEM;gotorelease_irq;}ret=s3cfb_init_registers(&s3cfb_info[index]);ret=s3cfb_check_var(&s3cfb_info[index].fb.var,&s3cfb_info[index].fb);if(index<2){if(fb_alloc_cmap(&s3cfb_info[index].fb.cmap,256,0)<0)gotodealloc_fb;}else{if(fb_alloc_cmap(&s3cfb_info[index].fb.cmap,16,0)<0)gotodealloc_fb;}ret=register_framebuffer(&s3cfb_info[index].fb);if(ret<0){printk(KERN_ERR"Failedtoregisterframebufferdevice:%d\n",ret);gotofree_video_memory;}printk(KERN_INFO"fb%d:%sframebufferdevice\n",s3cfb_info[index].fb.node,s3cfb_info[index].fb.fix.id);}/*createdevicefiles*/ret=device_create_file(&(pdev->dev),&dev_attr_backlight_power);if(ret<0)printk(KERN_WARNING"s3cfb:failedtoaddentries\n");ret=device_create_file(&(pdev->dev),&dev_attr_backlight_level);if(ret<0)printk(KERN_WARNING"s3cfb:failedtoaddentries\n");ret=device_create_file(&(pdev->dev),&dev_attr_lcd_power);if(ret<0)printk(KERN_WARNING"s3cfb:failedtoaddentries\n");return0;free_video_memory:s3cfb_unmap_video_memory(&s3cfb_info[index]);release_irq:free_irq(res->start,&info);release_clock:clk_disable(info->clk);clk_put(info->clk);release_io:iounmap(info->io);release_mem:release_resource(info->mem);kfree(info->mem);dealloc_fb:framebuffer_release(fbinfo);returnret;}上一篇在說LCD設(shè)備驅(qū)動對應(yīng)的probe函數(shù)時,沒有說完,這一篇接著繼續(xù)說probe函數(shù)。s3cfb_pre_init();上一次說到了這個函數(shù),而且還講到了一個結(jié)構(gòu)體s3cfb_fimd_info_t,并說了它的大致作用。s3cfb_set_backlight_power(1);看名字就只到它的大致作用,與背光燈有關(guān),源碼如下:staticvoids3cfb_set_backlight_power(intto){s3cfb_fimd.backlight_power=to;if(s3cfb_fimd.set_backlight_power)(s3cfb_fimd.set_backlight_power)(to);

函數(shù)指針}s3cfb_set_lcd_power(1);和上的類似,列出其源碼:staticvoids3cfb_set_lcd_power(intto){s3cfb_fimd.lcd_power=to;if(s3cfb_fimd.set_lcd_power)(s3cfb_fimd.set_lcd_power)(to);也是函數(shù)指針}s3cfb_set_backlight_level(S3CFB_DEFAULT_BACKLIGHT_LEVEL);也和上面差不多,就不說了。info->clk=clk_get(NULL,"lcd");得到LCD對應(yīng)的時鐘if(!info->clk||IS_ERR(info->clk)){printk(KERN_INFO"failedtogetlcdclocksource\n");ret=

-ENOENT;gotorelease_io;}clk_enable(info->clk);

使能時鐘printk("S3C_LCDclockgotenabled::%ld.%03ldMhz\n",PRINT_MHZ(clk_get_rate(info->clk)));s3cfb_fimd.vsync_info.count=0;init_waitqueue_head(&s3cfb_fimd.vsync_info.wait_queue);

//初始化幀同步信號的等待隊列頭res=platform_get_resource(pdev,IORESOURCE_IRQ,0);獲取LCD平臺設(shè)備所使用的中斷號if(res==NULL){dev_err(&pdev->dev,"failedtogetirq\n");ret=-ENXIO;gotorelease_clock;}ret=request_irq(res->start,s3cfb_irq,0,"s3c-lcd",pdev);

//申請中斷,中斷處理函數(shù)為s3cfb_irqif(ret!=0){printk("Failedtoinstallirq(%d)\n",ret);gotorelease_clock;}msleep(5);for(index=0;index<S3CFB_NUM;index++){

這一點不是很理解,不明白S3CFB_NUM的含義?查看了2410的代碼,發(fā)現(xiàn)沒有這個循環(huán)。我猜測與6410的多層窗口顯示有關(guān)。我在s3c6410的硬件LCD顯示控制器那篇博客中,有過這么一句話:“顯示控制器支持5層圖像窗口?!彼晕也抛鲞@樣的猜測。如果你知道了話,請告訴我,謝謝!#defineS3CFB_NUMFB_MIN_NUM(S3CFB_MAX_NUM,CONFIG_FB_S3C_NUM)#defineFB_MIN_NUM(x,y)((x)<(y)?(x):(y))

其實就是x,y中的最小值,也就是S3CFB_MAX_NUM和CONFIG_FB_S3C_NUM中的最小值。又有如下定義:#elifdefined(CONFIG_CPU_S3C6400)||defined(CONFIG_CPU_S3C6410)||defined(CONFIG_CPU_S5PC100)#defineS3CFB_MAX_NUM5#defineCONFIG_FB_S3C_NUM

4s3cfb_info[index].mem=info->mem;s3cfb_info[index].io=info->io;s3cfb_info[index].clk=info->clk;s3cfb_init_fbinfo(&s3cfb_info[index],driver_name,index);填充fb_info中的可變參數(shù)結(jié)構(gòu)的成員和不可變參數(shù)結(jié)構(gòu)的成員,fb_info結(jié)構(gòu)體中個成員的含義我在第一篇中說過了,你可以去查看。源碼如下:staticvoids3cfb_init_fbinfo(s3cfb_info_t*finfo,char*drv_name,intindex){inti=0;if(index==0)s3cfb_init_hw();strcpy(finfo->fb.fix.id,drv_name);finfo->win_id=index;finfo->fb.fix.type=FB_TYPE_PACKED_PIXELS;finfo->fb.fix.type_aux=0;finfo->fb.fix.xpanstep=0;finfo->fb.fix.ypanstep=1;finfo->fb.fix.ywrapstep=0;finfo->fb.fix.accel=FB_ACCEL_NONE;finfo->fb.fbops=&s3cfb_ops;finfo->fb.flags=FBINFO_FLAG_DEFAULT;finfo->fb.pseudo_palette=&finfo->pseudo_pal;finfo->fb.var.nonstd=0;finfo->fb.var.activate=FB_ACTIVATE_NOW;finfo->fb.var.accel_flags=0;finfo->fb.var.vmode=FB_VMODE_NONINTERLACED;finfo->fb.var.xoffset=s3cfb_fimd.xoffset;finfo->fb.var.yoffset=s3cfb_fimd.yoffset;if(index==0){finfo->fb.var.height=s3cfb_fimd.height;finfo->fb.var.width=s3cfb_fimd.width;finfo->fb.var.xres=s3cfb_fimd.xres;finfo->fb.var.yres=s3cfb_fimd.yres;finfo->fb.var.xres_virtual=s3cfb_fimd.xres_virtual;finfo->fb.var.yres_virtual=s3cfb_fimd.yres_virtual;}else{finfo->fb.var.height=s3cfb_fimd.osd_height;finfo->fb.var.width=s3cfb_fimd.osd_width;finfo->fb.var.xres=s3cfb_fimd.osd_xres;finfo->fb.var.yres=s3cfb_fimd.osd_yres;finfo->fb.var.xres_virtual=s3cfb_fimd.osd_xres_virtual;finfo->fb.var.yres_virtual=s3cfb_fimd.osd_yres_virtual;}finfo->fb.var.bits_per_pixel=s3cfb_fimd.bpp;

finfo->fb.var.pixclock=s3cfb_fimd.pixclock;finfo->fb.var.hsync_len=s3cfb_fimd.hsync_len;finfo->fb.var.left_margin=s3cfb_fimd.left_margin;finfo->fb.var.right_margin=s3cfb_fimd.right_margin;finfo->fb.var.vsync_len=s3cfb_fimd.vsync_len;finfo->fb.var.upper_margin=s3cfb_fimd.upper_margin;finfo->fb.var.lower_margin=s3cfb_fimd.lower_margin;finfo->fb.var.sync=s3cfb_fimd.sync;finfo->fb.var.grayscale=s3cfb_fimd.cmap_grayscale;finfo->fb.fix.smem_len=finfo->fb.var.xres_virtual*finfo->fb.var.yres_virtual*s3cfb_fimd.bytes_per_pixel;finfo->fb.fix.line_length=finfo->fb.var.width*s3cfb_fimd.bytes_per_pixel;#if!defined(CONFIG_FB_S3C_VIRTUAL_SCREEN)#ifdefined(CONFIG_FB_S3C_DOUBLE_BUFFERING)if(index<2)finfo->fb.fix.smem_len*=2;#else/**Somesystems(ex.DirectFB)useFB0memoryasavideomemory.*Youcanmodifythesizeofmultiple.*/if(index==0)finfo->fb.fix.smem_len*=5;#endif#endiffor(i=0;i<256;i++)finfo->palette_buffer[i]=S3CFB_PALETTE_BUFF_CLEAR;}/*Initializevideomemory*/

幀緩沖設(shè)備顯示緩沖區(qū)的內(nèi)存分配ret=s3cfb_map_video_memory(&s3cfb_info[index]);if(ret){printk("FailedtoallocatevideoRAM:%d\n",ret);ret=-ENOMEM;gotorelease_irq;}ret=s3cfb_init_registers(&s3cfb_info[index]);

對LCD各寄存器進行初始化,列出部分源碼:ints3cfb_init_registers(s3cfb_info_t*fbi){

writel(s3cfb_fimd.wincon0,S3C_WINCON0);writel(s3cfb_fimd.vidcon0,S3C_VIDCON0);writel(s3cfb_fimd.vidcon1,S3C_VIDCON1);writel(s3cfb_fimd.vidtcon0,S3C_VIDTCON0);writel(s3cfb_fimd.vidtcon1,S3C_VIDTCON1);writel(s3cfb_fimd.vidtcon2,S3C_VIDTCON2);writel(s3cfb_fimd.dithmode,S3C_DITHMODE);

}ret=s3cfb_check_var(&s3cfb_info[index].fb.var,&s3cfb_info[index].fb);此函數(shù)檢查fb的相關(guān)參數(shù),如果傳遞的參數(shù)不合法,則進行修改。列出其函數(shù)開頭的注釋:/*

*s3cfb_check_var():

*Getthevideoparamsoutof'var'.Ifavaluedoesn'tfit,rounditup,

*ifit'stoobig,return-EINVAL.

*

*/if(index<2){if(fb_alloc_cmap(&s3cfb_info[index].fb.cmap,256,0)<0)這個函數(shù)和調(diào)色板有關(guān),同樣列出其注釋:/**

*fb_alloc_cmap-allocateacolormap

*@cmap:framebuffercolormapstructure

*@len:lengthof@cmap

*@transp:boolean,1ifthereistransparency,0otherwise

*

*Allocatesmemoryforacolormap@cmap.

@lenisthe

*numberofentriesinthepalette.

*

*Returnsnegativeerrnoonerror,orzeroonsuccess.

*

*/gotodealloc_fb;}else{if(fb_alloc_cmap(&s3cfb_info[index].fb.cmap,16,0)<0)gotodealloc_fb;}ret=register_framebuffer(&s3cfb_info[index].fb);

注冊這個幀緩沖設(shè)備(FrameBuffer)fb_info到系統(tǒng)當(dāng)中,函數(shù)源碼如下:這個函數(shù)的主要作用其實就是把fb_info結(jié)構(gòu)體加入到全局量structfb_info*registered_fb[FB_MAX]數(shù)組中,還有進行一些其他的初始化。/**

*register_framebuffer-registersaframebufferdevice

*@fb_info:framebufferinfostructure

*

*Registersaframebufferdevice@fb_info.

*

*Returnsnegativeerrnoonerror,orzeroforsuccess.

*

*/intregister_framebuffer(structfb_info*fb_info){inti;structfb_eventevent;sif(num_registered_fb==FB_MAX)return-ENXIO;if(fb_check_foreignness(fb_info))return-ENOSYS;num_registered_fb++;for(i=0;i<FB_MAX;i++)if(!registered_fb[i])break;fb_info->node=i;mutex_init(&fb_info->lock);fb_info->dev=device_create(fb_class,fb_info->device,

MKDEV(FB_MAJOR,i),NULL,"fb%d",i);if(IS_ERR(fb_info->dev)){/*Notfatal*/printk(KERN_WARNING"Unabletocreatedeviceforframebuffer%d;errno=%ld\n",i,PTR_ERR(fb_info->dev));fb_info->dev=NULL;}elsefb_init_device(fb_info);if(fb_info->pixmap.addr==NULL){fb_info->pixmap.addr=kmalloc(FBPIXMAPSIZE,GFP_KERNEL);if(fb_info->pixmap.addr){f

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論