高通 android平台LCD驅動分析


目前手機芯片廠家提供的源碼里包含整個LCD驅動框架,一般廠家會定義一個xxx_fb.c的源文件,注冊一個平台設備和平台驅動,在驅動的probe函數中來調用register_framebuffer(),從而生成/dev/fbx的設備節點。這里最重要的數據結構是fb_ops,它包括fb打開、參數設置、畫圖、配置、內存映射等操作函數,芯片廠家通常提供了這部分的源碼,因為這些操作一般是跟芯片內部的DMP和MIPI DSI等部件打交道。

        當開發一款新的LCD驅動時往往需要關注的是LCD最底層的驅動,即是LCD屏的初始化、亮屏、熄屏以及背光操作。個人覺得以下幾個問題有必要弄清楚(參考Qualcomm芯片上的驅動代碼):

1、如何添加一款新屏驅動
        下面以東芝屏為例(參照源代碼mipi_toshiba_video_wvga_pt.c mipi_toshiba.c)
        模塊初始化:module_init(mipi_video_toshiba_wvga_pt_init);
        在mipi_video_toshiba_wvga_pt_init()中主要工作是設置LCD屏的參數,然后注冊一個名為mipi_toshiba的平台驅動和平台設備。在注冊平台設備時將LCD亮屏、熄屏以及背光操作添加到平台設備中。在mipi_toshiba的平台驅動中利用probe函數調用msm_fb_add_device()。當需要添加一款新屏的驅動時最主要的工作就是注冊一個相關的平台驅動和平台設備,可以參照上面的兩個源文件。這里需要說明一下:msm_fb_add_device()函數里定義了一個非常重要的數據結構msm_fb_data_type mfd,這個結構里包括了fb_info,還定義了panel有關的變量。

2、LCD驅動是如何依次打開MDP、MIPI DSI和LCD PANEL
        首先在驅動里注冊了三個平台設備msm_fb,mdp,mipi_dsi,然后再對應平台驅動probe的時候把各自設備的指針鏈接到一起,看下面的調用關系:

         mdp_probe(pdev)
                     |
                     |--->msm_fb_dev = platform_device_alloc('msm_fb', pdev->id)
                     |
                     |
                     |--->pdata = msm_fb_dev->dev.platform_data
                     |
                     |
                     |--->pdata->on = mdp_dsi_video_on
                     |
                     |
                     |--->pdata->off = mdp_dsi_video_off
                     |
                     |
                     |--->pdata->next = pdev


         mipi_dsi_probe(pdev)
                     |
                     |--->mdp_dev = platform_device_alloc('mdp', pdev->id)
                     |
                     |
                     |--->pdata = mdp_dev->dev.platform_data
                     |
                     |
                     |--->pdata->on = mipi_dsi_on
                     |
                     |
                     |--->pdata->off = mipi_dsi_off
                     |
                     |
                     |--->pdata->next = pdev


         mipi_toshiba_lcd_probe(pdev)
                     |
                     |
             msm_fb_add_device(pdev)
                     |
                     |
                     |--->pdata = pdev->dev.platform_data
                     |
                     |
                     |--->this_dev = msm_fb_device_alloc(pdata, type, id)
                                                                         |
                                                                         |
                                                                         |--->this_dev = platform_device_alloc()
                                                                         |
                                                                         |
                                                                         |--->platform_device_add_data(this_dev, pdata, ...)

 

        當pdata->next指向this_dev時,執行pdata->on,pdata->off時,即調用到mipi_toshiba_lcd_on和mipi_toshiba_lcd_off。

        從上面的分析來看,從MDP到panel的調用順序應該是:mdp_dsi_video_on-->mipi_dsi_on-->mipi_toshiba_lcd_on。msm_fb_blank_sub()是通過mfd->pdev->dev.platform_data來獲取pdata,再調用pdata->on(),從而完成上面的調用,在這里mfd->pdev->dev.platform_data指向的就是msm_fb設備的數據。

3、mfd是如何保存msm_fb設備的指針

         msm_fb_add_device(pdev)
                     |
                     |--->fbi=framebuffer_alloc(sizeof(struct msm_fb_data_type),NULL)
                     |
                     |
                     |--->mfd=(struct msm_fb_data_type *)fbi->par
                     |
                     |
                     |--->mfd->pdev=this_dev  (this_dev即mipi_dsi)
                     |
                     |
                     |--->platform_set_drvdata(this_dev,mfd)

 

         mipi_dsi_probe(pdev)
                     |
                     |--->mfd=platform_get_drvdata(pdev)
                     |
                     |
                     |--->mfd->pdev=mdp_dev
                     |
                     |
                     |--->platform_set_drvdata(mdp_dev,mfd)

 

         mdp_probe(pdev)
                     |
                     |--->mfd=platform_get_drvdata(pdev)
                     |
                     |
                     |--->mfd->pdev=msm_fb_dev
                     |
                     |
                     |--->platform_set_drvdata(msm_fb_dev,mfd)
               
        從上面的調用關系來看,mfd->pdev最終指向了平台設備msm_fb,值得一提的是,在這幾個函數中完成了mfd結構的填充。

 

int panel_next_on(struct platform_device *pdev)

每次執行完一個->on后執行panel_next_on,執行下一個->on


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM