注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

时间记录器

记录我的Linux、Android学习之路

 
 
 

日志

 
 

sep0718_fb 分析(一)sep0718fb_driver  

2010-08-03 17:35:16|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
结构体一:sep0718fb_driver 
static struct platform_driver sep0718fb_driver = {
.probe = sep0718fb_probe,
.remove = sep0718fb_remove,
.suspend = sep0718fb_suspend,
.resume = sep0718fb_resume,
    .driver = {
           .name = "sep0718-lcd",
           .owner = THIS_MODULE,
              },
};
以它为中心的相关函数层次关系入下列表:
|__* platform_driver sep0718fb_driver
| |__**static int __init sep0718fb_probe(struct platform_device *pdev) 
| |   |__***void sep0718fb_init_hw(sep0718fb_info_t *fbi)
| |   |   |__****static void sep0718fb_set_lcdc_info(void)
| |   |   |__****void sep0718_init_backlight(void)
| |   |   |__****void sep0718_enable_backlight(void)
| |   |__***static void sep0718fb_init_fbinfo(sep0718fb_info_t *finfo, char *drv_name, int index)
| |   |   |__****//其中会初始化finfo->fb.fbops = &sep0718fb_ops;这里把ops接口挂接了
| |   |__***static int sep0718fb_map_video_memory(sep0718fb_info_t *fbi) 
| |   |__***static int sep0718fb_init_registers(sep0718fb_info_t *fbi)
| |   |__***static int sep0718fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
| |   |__***static void sep0718fb_unmap_video_memory(sep0718fb_info_t *fbi)
| |__**static int sep0718fb_remove(struct platform_device *pdev)
| |__**int sep0718fb_suspend(struct platform_device *dev, pm_message_t state)
| |   |__***void sep0718_disable_backlight(void)
| |__**int sep0718fb_resume(struct platform_device *dev)
分析:
1int __devinit sep0718fb_init(void)
{
printk("SEP0718 Framebuffer driver init\n");
return platform_driver_register(&sep0718fb_driver);
}
函数通过module_init(sep0718fb_init);被系统识别。当驱动被insmod的时候,该init函数被执行。其中platform_
driver_register(&sep0718fb_driver);动作时向系统注册驱动,这会导致static int __init sep0718fb_probe(struct platform_
device *pdev)的执行,因此可以认为probe函数是驱动实质性工作的开始。
在probe函数中将调用如下函数:
1***void sep0718fb_init_hw(sep0718fb_info_t *fbi)
   2***static void sep0718fb_init_fbinfo(sep0718fb_info_t *finfo, char *drv_name, int index)
   3***static int sep0718fb_map_video_memory(sep0718fb_info_t *fbi)
   4***static int sep0718fb_init_registers(sep0718fb_info_t *fbi)
   5***static int sep0718fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
   6***static void sep0718fb_unmap_video_memory(sep0718fb_info_t *fbi)
由于LCDC硬件上市四层的结构,所以1-5几个函数将被使用不同参数调用初始化4次。其中
if (index == 0)//只初始化一次hardware
sep0718fb_init_hw(&sepfb_info[index]);
使得他制备执行一次。sep0718fb_init_hw()中调用的函数有
****static void sep0718fb_set_lcdc_info(void)
     ****void sep0718_init_backlight(void)
     ****void sep0718_enable_backlight(void)
其中sep0718fb_set_lcdc_info(void) 设置了lcdc的基本信息,属于硬件部分。内部的sep0718_lcdc_info.regs.* 被其他部分多次使用。
   void sep0718fb_init_fbinfo 中初始化了fb的基本信息,相对于上面一个函数,它更偏向于软一点。里面设置的信息将在用到时具体分析,此处不谈。

   sep0718fb_map_video_memory 就是分配实际显存了。函数内部有如下实现: 
fbi->map_size_f1 = PAGE_ALIGN(fbi->fb.fix.smem_len); 
fbi->map_cpu_f1 = dma_alloc_writecombine(fbi->dev, fbi->map_size_f1, &fbi->map_dma_f1, GFP_KERNEL); 
fbi->map_size_f1 = fbi->fb.fix.smem_len; 

其中的fbi->fb.fix.smem_len 是在sep0718fb_init_fbinfo  中初始化的,其内容为 
finfo->fb.fix.smem_len = finfo->fb.var.xres_virtual * finfo->fb.var.yres_virtual * sep0718_lcdc_info.bytes_per_pixel; 
即smem_len的大小为虚拟x、y大小(所有的点数)乘以bpp,就是显存所占内存的字节数。可视区和虚拟区的关系入下图所示: 
sep0718_fb 分析(一)sep0718fb_driver - Goink - 时间记录器
 
该函数会分配 4 块内存区作为显存。  
  sep0718fb_init_registers 需要对上面设置好的参数写入LCDC各个寄存器中去。函数内部会根据fbi->win_id对不同硬件层进行设置。通过如sep0718_lcdc_info.regs.bbsar = start_address;这种操作给出显示起始内存地址。同样也有 4 次操作。4层对应4块由sep0718fb_map_video_memory分配的内存。 
  sep0718fb_check_var  中的操作起始并没有完成这个函数的本意,即检查参数是否在设定的有效范围内。有待完善。 
至此,probe的初始化工作基本完成。当然,还有一些必要的出错处理。 
  评论这张
 
阅读(264)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017