s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx

上传人:b****5 文档编号:17909075 上传时间:2022-12-12 格式:DOCX 页数:11 大小:20.89KB
下载 相关 举报
s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx_第1页
第1页 / 共11页
s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx_第2页
第2页 / 共11页
s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx_第3页
第3页 / 共11页
s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx_第4页
第4页 / 共11页
s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx

《s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。

s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx

//fb特定的ioctl

};

//上面这些操作函数指针需要驱动开发人员自己编写的,如果没赋值则默认调用系统中的

staticstructplatform_drivers3cfb_driver={

.probe 

=s3cfb_probe,

.remove 

=s3cfb_remove,

.suspend 

=s3cfb_suspend,

.resume 

=s3cfb_resume,

.driver 

={

.name 

="

s3c-fb"

},

int__devinits3cfb_init(void)

{

/**模块加载函数实现平台驱动的注册**/

returnplatform_driver_register(&

s3cfb_driver);

}

staticvoid__exits3cfb_cleanup(void)

platform_driver_unregister(&

module_init(s3cfb_init);

module_exit(s3cfb_cleanup);

//s3cfb_probe平台驱动的探测函数,主要初始化fb_info结构体中的可变参数和不可变参数结构体,LCD硬件控制器的初始化,获取时钟来源,显示缓存空间的申请,注册帧缓冲设备等工作。

staticint__inits3cfb_probe(structplatform_device*pdev)

//定义局部变量

structresource*res;

//保存平台资源的局部变量

structfb_info*fbinfo;

//帧缓冲结构

s3cfb_info_t*info;

//对于特定的bsp封装了驱动中所需要的一些信息

chardriver_name[]="

s3cfb"

;

/*驱动名称*/

intindex=0,ret,size;

//用来临时保存信息

/**分配fb_info结构体**/

fbinfo=framebuffer_alloc(sizeof(s3cfb_info_t),&

pdev->

dev);

if(!

fbinfo)

return-ENOMEM;

/*将fbinfo传递给内核中总线设备结构所对应的驱动数据信息*/

platform_set_drvdata(pdev,fbinfo);

//方便后面用到

/*********************************************************

platform_set_drvdata(pdev,fbinfo)的具体实现函数:

*voiddev_set_drvdata(structdevice*dev,void*data)

*{

interror;

if(!

dev)

return;

dev->

p){

error=device_private_init(dev);

if(error)

}

dev->

p->

driver_data=data;

*}

**********************************************************/

/**fb_info中似有成员赋值给 

s3cfb_info_t**/

info=fbinfo->

par;

info->

dev=&

dev;

/**获取LCD平台设备所使用的IO端口资源**/

res=platform_get_resource(pdev,IORESOURCE_MEM,0);

if(res==NULL){

dev_err(&

dev,"

failedtogetmemoryregisters\n"

);

ret=-ENXIO;

gotodealloc_fb;

size=(res->

end-res->

start)+1;

//计算IO端口所需要的空间

/*为上面LCDIO端口申请IO内存*/

mem=request_mem_region(res->

start,size,pdev->

name);

if(info->

mem==NULL){

failedtogetmemoryregion\n"

ret=-ENOENT;

/**将LCD的此段IO地址空间映射成虚拟地址空间,这样才能操作**/

io=ioremap(res->

start,size);

io==NULL){

ioremap()ofregistersfailed\n"

gotorelease_mem;

/*初始化LCD视频中断控制寄存器0**/

s3cfb_pre_init();

/**TFT背光设置**/

s3cfb_set_backlight_power

(1);

/**电源设置**/

s3cfb_set_lcd_power

(1);

s3cfb_set_backlight_level(S3CFB_DEFAULT_BACKLIGHT_LEVEL);

/**获取LCD时钟**/

clk=clk_get(NULL,"

lcd"

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);

/**获取LCD平台设备所使用的中断号*/

res=platform_get_resource(pdev,IORESOURCE_IRQ,0);

failedtogetirq\n"

gotorelease_clock;

//申请中断,中断处理函数为s3cfb_irq

ret=request_irq(res->

start,s3cfb_irq,0,"

s3c-lcd"

pdev);

if(ret!

=0){

Failedtoinstallirq(%d)\n"

ret);

msleep(5);

/**6410支持多种屏幕**/

for(index=0;

index<

S3CFB_NUM;

index++){

/**这个s3cfb_info就是一个 

s3cfb_info_t类型的数组,每一款LCD对应着一个索引*/

/**上面获取了IO内存,映射了IO,获取到了时钟等,这里用他们来填充这个s3cfb_info结构**/

s3cfb_info[index].mem=info->

mem;

s3cfb_info[index].io=info->

io;

s3cfb_info[index].clk=info->

clk;

/**填充各种结构体中的参数,比如填充fb_info中的可变参数结构的成员和不可变参数结构的成员等**/

s3cfb_init_fbinfo(&

s3cfb_info[index],driver_name,index);

/*Initializevideomemory*/帧缓冲设备显示缓冲区的内存分配**/

ret=s3cfb_map_video_memory(&

s3cfb_info[index]);

if(ret){

FailedtoallocatevideoRAM:

%d\n"

ret=-ENOMEM;

gotorelease_irq;

/*初始化完fb_info后,开始对LCD各寄存器进行初始化,这个寄存器的配置还真没怎么搞懂啊。

感觉好难。

*/

ret=s3cfb_init_registers(&

/**检查可变参数**/

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)

}else{

s3cfb_info[index].fb.cmap,16,0)<

/**注册帧缓冲设备(FrameBuffer)fb_info到系统当中*/

ret=register_framebuffer(&

if(ret<

0){

printk(KERN_ERR"

Failedtoregisterframebufferdevice:

gotofree_video_memory;

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);

printk(KERN_WARNING"

s3cfb:

failedtoaddentries\n"

ret=device_create_file(&

dev_attr_backlight_level);

dev_attr_lcd_power);

jkqdebugVIDCON0is%x\n"

readl(S3C_VIDCON0));

return0;

/********下面这些是各错误函数**/

free_video_memory:

s3cfb_unmap_video_memory(&

release_irq:

free_irq(res->

start,&

info);

release_clock:

clk_disable(info->

clk_put(info->

release_io:

iounmap(info->

io);

release_mem:

release_resource(info->

mem);

kfree(info->

dealloc_fb:

framebuffer_release(fbinfo);

returnret;

/*初始化LCD视频中断控制寄存器0**/

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;

/**详情请看S3C6410数据手册第14章482页。

初始化视频中断以VSYNS开始并使能该寄存器*/

writel(s3cfb_fimd.vidintcon0,S3C_VIDINTCON0);

/******下面这三个是控制LCD电源以及背光控制的**/

staticvoids3cfb_set_lcd_power(intto)

s3cfb_fimd.lcd_power=to;

if(s3cfb_fimd.set_lcd_power)

(s3cfb_fimd.set_lcd_power)(to);

staticvoids3cfb_set_backlight_power(intto)

s3cfb_fimd.backlight_power=to;

if(s3cfb_fimd.set_backlight_power)

(s3cfb_fimd.set_backlight_power)(to);

staticvoids3cfb_set_backlight_level(intto)

s3cfb_fimd.backlight_level=to;

if(s3cfb_fimd.set_brightness)

(s3cfb_fimd.set_brightness)(to);

/*********************************************************************************************/

/***该函数在probe中被调用(初始化s3cfb_info_t结构体,其中每一个fb_info结构都会对应一个s3cfb_info_t结构体)*/

//初始化就是填充s3cfb_info_t结构中的成员变量和成员函数

staticvoids3cfb_init_fbinfo(s3cfb_info_t*finfo,char*drv_name,intindex)

inti=0;

if(index==0)

{//lcdsize是一全局变量用来标记LCD所使用的尺寸。

if(lcdsize==0)

s3cfb_init_hw_35();

elseif(lcdsize==1)

s3cfb_init_hw_43();

//本开发板所使用的

elseif(lcdsize==2)

s3cfb_init_hw_56();

elseif(lcdsize==3)

s3cfb_init_hw_70();

elseif(lcdsize==4)

s3cfb_init_hw_vga800();

else

strcpy(finfo->

fb.fix.id,drv_name);

//初始化不可变参数结构中的charid[16]数组

//填充不可变参数结构

finfo->

win_id=index;

fb.fix.type=FB_TYPE_PACKED_PIXELS;

fb.fix.type_aux=0;

fb.fix.xpanstep=0;

fb.fix.ypanstep=1;

fb.fix.ywrapstep=0;

fb.fix.accel=FB_ACCEL_NONE;

//无硬件加速

fb.fbops=&

s3cfb_ops;

//指向frambuffer函数操作集

fb.flags 

=FBINFO_FLAG_DEFAULT;

fb.pseudo_palette=&

pseudo_pal;

//填充可变参数结构

fb.var.nonstd=0;

fb.var.activate=FB_ACTIVATE_NOW;

fb.var.accel_flags=0;

fb.var.vmode=FB_VMODE_NONINTERLACED;

fb.var.xoffset=s3cfb_fimd.xoffset;

//水平方向虚拟到可见之间的偏移

fb.var.yoffset=s3cfb_fimd.yoffset;

//垂直方向虚拟到可见之间的偏移

if(index==0){

fb.var.height=s3cfb_fimd.height;

fb.var.width=s3cfb_fimd.width;

fb.var.xres=s3cfb_fimd.xres;

fb.var.yres=s3cfb_fimd.yres;

fb.var.xres_virtual=s3cfb_fimd.xres_virtual;

fb.var.yres_virtual=s3cfb_fimd.yres_virtual;

fb.var.height=s3cfb_fimd.osd_height;

//图像高度

fb.var.width=s3cfb_fimd.osd_width;

//图像宽度

fb.var.xres=s3cfb_fimd.osd_xres;

//水平方向真实可见的解析度

fb.var

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1