s3c6410LCDframe buffer 驱动分析一.docx
- 文档编号:4955713
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:11
- 大小:20.89KB
s3c6410LCDframe buffer 驱动分析一.docx
《s3c6410LCDframe buffer 驱动分析一.docx》由会员分享,可在线阅读,更多相关《s3c6410LCDframe buffer 驱动分析一.docx(11页珍藏版)》请在冰豆网上搜索。
s3c6410LCDframebuffer驱动分析一
s3c6410_LCD&framebuffer驱动分析
fb_info结构体中的成员变量fops直接指向底层操作函数指针
structfb_opss3cfb_ops={
.owner =THIS_MODULE,
.fb_check_var =s3cfb_check_var,//检测可变参数,并调整到支持的值
.fb_set_par =s3cfb_set_par, //设置video的模式
.fb_blank =s3cfb_blank, //显示空白区域
.fb_pan_display =s3cfb_pan_display,//pan显示
.fb_setcolreg =s3cfb_setcolreg,//设置color寄存器,设置颜色表
.fb_fillrect =cfb_fillrect, //矩形填充
.fb_copyarea =cfb_copyarea, //数据复制
.fb_imageblit =cfb_imageblit, //图形填充
.fb_cursor =soft_cursor, //绘制光标
.fb_ioctl =s3cfb_ioctl, //fb特定的ioctl
};
//上面这些操作函数指针需要驱动开发人员自己编写的,如果没赋值则默认调用系统中的
staticstructplatform_drivers3cfb_driver={
.probe =s3cfb_probe,
.remove =s3cfb_remove,
.suspend =s3cfb_suspend,
.resume =s3cfb_resume,
.driver ={
.name ="s3c-fb",
.owner =THIS_MODULE,
},
};
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);
//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;
* if(!
dev->p){
* error=device_private_init(dev);
* if(error)
* return;
* }
* dev->p->driver_data=data;
*}
**********************************************************/
/**fb_info中似有成员赋值给 s3cfb_info_t**/
info=fbinfo->par;
info->dev=&pdev->dev;
/**获取LCD平台设备所使用的IO端口资源**/
res=platform_get_resource(pdev,IORESOURCE_MEM,0);
if(res==NULL){
dev_err(&pdev->dev,"failedtogetmemoryregisters\n");
ret=-ENXIO;
gotodealloc_fb;
}
size=(res->end-res->start)+1;//计算IO端口所需要的空间
/*为上面LCDIO端口申请IO内存*/
info->mem=request_mem_region(res->start,size,pdev->name);
if(info->mem==NULL){
dev_err(&pdev->dev,"failedtogetmemoryregion\n");
ret=-ENOENT;
gotodealloc_fb;
}
/**将LCD的此段IO地址空间映射成虚拟地址空间,这样才能操作**/
info->io=ioremap(res->start,size);
if(info->io==NULL){
dev_err(&pdev->dev,"ioremap()ofregistersfailed\n");
ret=-ENXIO;
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时钟**/
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);
/**获取LCD平台设备所使用的中断号*/
res=platform_get_resource(pdev,IORESOURCE_IRQ,0);
if(res==NULL){
dev_err(&pdev->dev,"failedtogetirq\n");
ret=-ENXIO;
gotorelease_clock;
}
//申请中断,中断处理函数为s3cfb_irq
ret=request_irq(res->start,s3cfb_irq,0,"s3c-lcd",pdev);
if(ret!
=0){
printk("Failedtoinstallirq(%d)\n",ret);
gotorelease_clock;
}
msleep(5);
/**6410支持多种屏幕**/
for(index=0;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){ printk("FailedtoallocatevideoRAM: %d\n",ret); ret=-ENOMEM; gotorelease_irq; } /*初始化完fb_info后,开始对LCD各寄存器进行初始化,这个寄存器的配置还真没怎么搞懂啊。 感觉好难。 。 */ 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; } /**注册帧缓冲设备(FrameBuffer)fb_info到系统当中*/ 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"); printk("jkqdebugVIDCON0is%x\n",readl(S3C_VIDCON0)); 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视频中断控制寄存器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 s3cfb_init_hw_43(); } strcpy(finfo->fb.fix.id,drv_name);//初始化不可变参数结构中的charid[16]数组 //填充不可变参数结构 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;//指向frambuffer函数操作集 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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- s3c6410LCD frame buffer 驱动分析一 驱动 分析