1. 程式人生 > >itop exynos4412 lcd驅動 詳細分析 (一)

itop exynos4412 lcd驅動 詳細分析 (一)

(若轉載,請註明出處,若有錯誤請指正,謝謝)
(以下分析皆基於:itop4412精英板裝置和程式碼資源)
(核心為:iTop4412_Kernel_3.0提供)

(看客需要一定的linux平臺驅動基礎,和lcd操作基礎)
(針對lcd基本操作,我準備寫一個lcd裸機程式設計來完善)

lcd的工作,在kernel 中有device 和driver兩個描述,這也是必然。

一.先看device

在 palt-s5p/dev-fimd-s5p.c
定義了一個 struct platform_device s3c_device_fb 平臺裝置

#ifdef CONFIG_FB_S5P   // 選擇開關
static struct resource s3cfb_resource[] = { [0] = { .start = S5P_PA_FIMD0, //資源地址 .end = S5P_PA_FIMD0 + SZ_32K - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_FIMD0_VSYNC, //同步中斷 .end = IRQ_FIMD0_VSYNC, .flags = IORESOURCE_IRQ, }, [2
] = { .start = IRQ_FIMD0_FIFO, //fifo中斷 .end = IRQ_FIMD0_FIFO, .flags = IORESOURCE_IRQ, }, }; static u64 fb_dma_mask = 0xffffffffUL; //dma 掩碼 struct platform_device s3c_device_fb = { //fb裝置定義和描述 .name = "s3cfb", //裝置名字 #if defined(CONFIG_ARCH_EXYNOS4) .id = 0
, #else .id = -1, #endif .num_resources = ARRAY_SIZE(s3cfb_resource),//指定上面的資源 .resource = s3cfb_resource, .dev = { .dma_mask = &fb_dma_mask, .coherent_dma_mask = 0xffffffffUL } }; 這上面是device 和exynos 相關的lcd暫存器資源和中斷, 除了這些還有一些其他的相關資訊如下(所以該檔案中還有如下:)
static struct s3c_platform_fb default_fb_data __initdata = {
#if defined(CONFIG_ARCH_EXYNOS4)
    .hw_ver = 0x70,
#else
    .hw_ver = 0x62,
#endif
    .nr_wins    = 5,  //支援的視窗數
#if defined(CONFIG_FB_S5P_DEFAULT_WINDOW) 
    .default_win    = CONFIG_FB_S5P_DEFAULT_WINDOW, //指定預設顯示視窗
#else
    .default_win    = 0,
#endif
    .swap       = FB_SWAP_WORD | FB_SWAP_HWORD, //資料字交換
};

struct s3c_platform_fb default_fb_data 該結構體是是裝置的 預設初始化,當然你還可以指定
,靠的就是下面的這個函式

    void __init s3cfb_set_platdata(struct s3c_platform_fb *pd)
{
    struct s3c_platform_fb *npd;
    int i;

    if (!pd) //是判斷使用預設配置。 確定因素在boardtiao呼叫該函式時,是否新增此引數
        pd = &default_fb_data;

    npd = kmemdup(pd, sizeof(struct s3c_platform_fb), GFP_KERNEL);
    if (!npd)
        printk(KERN_ERR "%s: no memory for platform data\n", __func__);
    else {
        for (i = 0; i < npd->nr_wins; i++) //初始化每個視窗的id
            npd->nr_buffers[i] = 1;

#if defined(CONFIG_FB_S5P_NR_BUFFERS)
        npd->nr_buffers[npd->default_win] = CONFIG_FB_S5P_NR_BUFFERS;
#else
        npd->nr_buffers[npd->default_win] = 1;
#endif
        //下面這些函式都是在 driver 匹配後,在裡面呼叫
        s3cfb_get_clk_name(npd->clk_name); //獲取時鐘
        npd->cfg_gpio = s3cfb_cfg_gpio; //獲取引腳操作函式
        npd->backlight_on = s3cfb_backlight_on; //開背光
        npd->backlight_off = s3cfb_backlight_off; //關背光
        npd->lcd_on = s3cfb_lcd_on;  //使能lcd裝置
        npd->lcd_off = s3cfb_lcd_off;//關閉lcd 裝置
        npd->clk_on = s3cfb_clk_on; // 時鐘開
        npd->clk_off = s3cfb_clk_off; 時鐘關

        s3c_device_fb.dev.platform_data = npd;//把初始化的驅動相關資訊放到dev的私有資料裡面
        // 供驅動使用,在驅動中我們將看到如何呼叫的
    }
}
#endif
   針對上面的s3cfb_set_platdata:
   board檔案中看到:是否確定引數,如下
是否需要新增取決於你的開關,我用的是普通屏,所以選擇的是s3cfb_set_platdata(NULL)
#ifdef CONFIG_FB_S5P
#ifdef CONFIG_FB_S5P_LMS501KF03
    spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
    s3cfb_set_platdata(&lms501kf03_data); //set_data
#else
    s3cfb_set_platdata(NULL);//set_data   
#endif

來看看時鐘:  s3cfb_get_clk_name(npd->clk_name); 是獲得裝置時鐘name,該函式在
setuo-fb-s5pc.c 中函式原型如下:


void s3cfb_get_clk_name(char *clk_name)
{
    strcpy(clk_name, "sclk_fimd"); //可以看出所用的clk
}

而下面是對裝置操作的初始化(都在setuo-fb-s5pc.c ,指定相關硬體 的操作):
  npd->cfg_gpio = s3cfb_cfg_gpio;
npd->backlight_on = s3cfb_backlight_on;
npd->backlight_off = s3cfb_backlight_off;
npd->lcd_on = s3cfb_lcd_on;
npd->lcd_off = s3cfb_lcd_off;
npd->clk_on = s3cfb_clk_on;
npd->clk_off = s3cfb_clk_off;
  在這裡不做介紹,在驅動呼叫時,分析

-----總上,有了裝置如何新增到核心中,board 檔案中有這樣一句:
static struct platform_device *smdk4x12_devices[] __initdata = {
。。。。。。。。
#ifdef CONFIG_FB_S5P
&s3c_device_fb
。。。。。。。。,
    有此可以看出。此項可以根據核心配置
         Device Drivers  --->  
                 Graphics support  --->
                       <*> Support for frame buffer devices  ---> 
                                     <*>   S5P Framebuffer support    

“`

好了裝置device我們就分析完了。
總結了一下:
先定義了一個struct platform_device s3c_device_fb 結構體
然後指定了一下io和中斷資源在static struct resource s3cfb_resource[] 中
之後定義了一個預設配置 struct s3c_platform_fb default_fb_data ,而是否使用取決於
s3cfb_set_platdata(struct s3c_platform_fb *pd) 函式,該函式做了一下時鐘 ,io,背光等操作集後,把這些操作都放在了s3c_device_fb.dev.platform_data = npd; 中供驅動匹配時呼叫

<接下來我們將要分析driver ,未完待續>