http://blog.csdn.net/sunweizhong1024/article/details/8447915
MTK_LCD_Driver
代码的路是在/mediatek/source/kernel/driver/vedio/mtkfb.c
module_init(mtkfb_init);模块初始化函数
int__init mtkfb_init(void)
{
int r = 0;
MSG_FUNC_ENTER();
/* Register the driver withLDM */
if(platform_driver_register(&mtkfb_driver)) {//以platform方式进行注册mtkfb driver
PRNERR("failed toregister mtkfb driver\n");
r = -ENODEV;
goto exit;
}
#ifdefCONFIG_HAS_EARLYSUSPEND
register_early_suspend(&mtkfb_early_suspend_handler);//LCD是以erly_suspend的方式注册的,这个涉及到power_management的内容
#endif
DBG_Init();
exit:
MSG_FUNC_LEAVE();
return r;
}
知道设备模型的人应该知道platformbus总线的match函数的规则是device和driver的名字必须相同,当name匹配一样的时候,我们就会调用driver里面的probe函数,这个函数是LCDdriver的核心入口函数。
进入LCDprobe世界。
staticint mtkfb_probe(struct device *dev)
{
struct platform_device *pdev;
struct mtkfb_device *fbdev= NULL;
struct fb_info *fbi;
int init_state;
int r = 0;
char*p = NULL;
MSG_FUNC_ENTER();
printk("%s,%s\n", __func__, saved_command_line);
p= strstr(saved_command_line, "fps=");
if(p== NULL){
lcd_fps= 6000;
printk("[FBdriver]can not get fps from uboot\n");
}
else{
p+= 4;
lcd_fps= simple_strtol(p, NULL, 10);
}
…........................
…........................
r = register_framebuffer(fbi);
if (r != 0) {
PRNERR("register_framebufferfailed\n");
goto cleanup;
}
fbdev->state =MTKFB_ACTIVE;
MSG(INFO, "MTKframebuffer initialized vram=%lu\n", fbdev->fb_size_in_byte);
MSG_FUNC_LEAVE();
return 0;
cleanup:
mtkfb_free_resources(fbdev,init_state);
MSG_FUNC_LEAVE();
return r;
}
这个函数比较长,下面我们一一对这个Probe函数进行讲解。
1、开始driver接受从uboot中传递过来的参数,saved_command_line变量,进行参数的取值。
2、DISP_IsContextInited这个函数判断lcm_params、disp_drv、lcm_drv是不是都进行初始化了,如果都初始化了,那么就返回TRUE如果有一个没有进行初始化的话,那么就返回FALSE。其实这里在uboot中已经进行了初始化了,我们这里假设这里还没有初始化,如果是FALSE的话,那么就会调用mtkfb_find_lcm_driver这个function函数。
mtkfb_find_lcm_driver:
BOOLmtkfb_find_lcm_driver(void)
{
BOOLret = FALSE;
char*p, *q;
p= strstr(saved_command_line,"lcm=");//这里我们会找出”lcm=”这个字符串在saved_command_line中第一次出现的位置,取出这个指针。
if(p== NULL)
{
//we can't find lcm string in the command line, the uboot should be oldversion
returnDISP_SelectDevice(NULL);
}
p+= 4;
if((p- saved_command_line) > strlen(saved_command_line+1))
{
ret= FALSE;
gotodone;
}
printk("%s,%s\n", __func__, p);
q= p;
while(*q!= ' ' && *q != '\0')
q++;
memset((void*)mtkfb_lcm_name,0, sizeof(mtkfb_lcm_name));
strncpy((char*)mtkfb_lcm_name,(const char*)p, (int)(q-p));//这里会找出lcm的名字,接下来会将这个Name股指给mtkfb_lcm_name这个变量,下面会将这个变量传递给mtkfb_lcm_name这个函数。
printk("%s,%s\n", __func__, mtkfb_lcm_name);
if(DISP_SelectDevice(mtkfb_lcm_name))
ret= TRUE;
done:
returnret;
}
continuetrace code:DISP_SelectDevice(mtkfb_lcm_name)
DISP_SelectDevice(mtkfb_lcm_name):
BOOLDISP_SelectDevice(const char* lcm_name)
{
LCD_STATUSret;
ret= LCD_Init();
printk("retof LCD_Init() = %d\n", ret);
lcm_drv= disp_drv_get_lcm_driver(lcm_name);
if(NULL == lcm_drv)
{
printk("%s,disp_drv_get_lcm_driver() returns NULL\n", __func__);
returnFALSE;
}
disp_dump_lcm_parameters(lcm_params);
returndisp_drv_init_context();
}
上面的函数还是比较复杂的,我们下面会进行一一的讲解:
2.1:LCD_Init
LCD_STATUSLCD_Init(void)
{
LCD_STATUS ret =LCD_STATUS_OK;
memset(&_lcdContext, 0,sizeof(_lcdContext));//我们可以发现-lcdContext这个变量是一个数组,而且是static类型的,C语言中我们定义了这种类型的变量的话,那么就会为这个变量分配一个地址
// LCD controller would NOTreset register as default values
// Do it by SW here
//
ResetBackupedLCDRegisterValues();这里我们会为上面的_lcdContext.