s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx
- 文档编号:17909075
- 上传时间:2022-12-12
- 格式:DOCX
- 页数:11
- 大小:20.89KB
s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx
《s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《s3c6410LCDframe buffer 驱动分析一Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。
//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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- s3c6410LCD frame buffer 驱动分析一 驱动 分析