s3c6410_LCD & frame buffer 驅動分析(三)

幀緩衝設備的參數設置和gpio配置

#include <linux/wait.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
#include "s3cfb.h"
#define S3CFB_HFP        2    /* front porch */
#define S3CFB_HSW        41    /* hsync width */
#define S3CFB_HBP        2    /* back porch */
#define S3CFB_VFP        2    /* front porch */
#define S3CFB_VSW        10    /* vsync width */
#define S3CFB_VBP        2    /* back porch */
#define S3CFB_HRES        480    /* horizon pixel  x resolition */
#define S3CFB_VRES        272    /* line cnt       y resolution */
#define S3CFB_HRES_VIRTUAL    480    /* horizon pixel  x resolition */
#define S3CFB_VRES_VIRTUAL    544    /* line cnt       y resolution */
#define S3CFB_HRES_OSD        480    /* horizon pixel  x resolition */
#define S3CFB_VRES_OSD        272    /* line cnt       y resolution */
#define S3CFB_VFRAME_FREQ         60    /* frame rate freq */

#define S3CFB_PIXEL_CLOCK    (S3CFB_VFRAME_FREQ * (S3CFB_HFP + S3CFB_HSW + S3CFB_HBP + S3CFB_HRES) * (S3CFB_VFP + S3CFB_VSW + S3CFB_VBP + S3CFB_VRES))

//設置LCD各信號之間的時間參數需要參考LCD技術手冊


static void s3cfb_set_fimd_info(void)
{
    //設置HSYNC和SYNC高電平有效,VDEN低電平有效(極性)
    s3cfb_fimd.vidcon1 = S3C_VIDCON1_IHSYNC_INVERT | S3C_VIDCON1_IVSYNC_INVERT | S3C_VIDCON1_IVDEN_NORMAL;
    //設置各信號之間的時間參數需要參考LCD數據手冊
    s3cfb_fimd.vidtcon0 = S3C_VIDTCON0_VBPD(S3CFB_VBP - 1) | S3C_VIDTCON0_VFPD(S3CFB_VFP - 1) | S3C_VIDTCON0_VSPW(S3CFB_VSW - 1);
    s3cfb_fimd.vidtcon1 = S3C_VIDTCON1_HBPD(S3CFB_HBP - 1) | S3C_VIDTCON1_HFPD(S3CFB_HFP - 1) | S3C_VIDTCON1_HSPW(S3CFB_HSW - 1);
    s3cfb_fimd.vidtcon2 = S3C_VIDTCON2_LINEVAL(S3CFB_VRES - 1) | S3C_VIDTCON2_HOZVAL(S3CFB_HRES - 1);
    //配置窗口位置寄存器A 和 B
    //win0左上角的X、Y座標(0,0)
    s3cfb_fimd.vidosd0a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0);
    //win0右下角角的X、Y座標(479,271)
    s3cfb_fimd.vidosd0b = S3C_VIDOSDxB_OSD_RBX_F(S3CFB_HRES - 1) | S3C_VIDOSDxB_OSD_RBY_F(S3CFB_VRES - 1);
    //win1左上角的X、Y座標(0,0)
    s3cfb_fimd.vidosd1a = S3C_VIDOSDxA_OSD_LTX_F(0) | S3C_VIDOSDxA_OSD_LTY_F(0);
    //win1右下角角的X、Y座標(479,271)
    s3cfb_fimd.vidosd1b = S3C_VIDOSDxB_OSD_RBX_F(S3CFB_HRES_OSD - 1) | S3C_VIDOSDxB_OSD_RBY_F(S3CFB_VRES_OSD - 1);
//設置LCD真實分辨率
    s3cfb_fimd.width = S3CFB_HRES;//圖像寬度480
    s3cfb_fimd.height = S3CFB_VRES;//圖像高度272
    s3cfb_fimd.xres = S3CFB_HRES;//水平可見解析度480
    s3cfb_fimd.yres = S3CFB_VRES;//垂直可見解析度272
//如果設置了虛擬屏
#if defined(CONFIG_FB_S3C_EXT_VIRTUAL_SCREEN)
    s3cfb_fimd.xres_virtual = S3CFB_HRES_VIRTUAL;//480
    s3cfb_fimd.yres_virtual = S3CFB_VRES_VIRTUAL;//544
#else
    s3cfb_fimd.xres_virtual = S3CFB_HRES;//640
    s3cfb_fimd.yres_virtual = S3CFB_VRES;//480
#endif
//填充s3cfb_fimd_info_t結構中的成員
    s3cfb_fimd.osd_width = S3CFB_HRES_OSD;
    s3cfb_fimd.osd_height = S3CFB_VRES_OSD;
    s3cfb_fimd.osd_xres = S3CFB_HRES_OSD;
    s3cfb_fimd.osd_yres = S3CFB_VRES_OSD;

    s3cfb_fimd.osd_xres_virtual = S3CFB_HRES_OSD;
    s3cfb_fimd.osd_yres_virtual = S3CFB_VRES_OSD;

    s3cfb_fimd.pixclock = S3CFB_PIXEL_CLOCK;

    s3cfb_fimd.hsync_len = S3CFB_HSW;
    s3cfb_fimd.vsync_len = S3CFB_VSW;
    s3cfb_fimd.left_margin = S3CFB_HFP;
    s3cfb_fimd.upper_margin = S3CFB_VFP;
    s3cfb_fimd.right_margin = S3CFB_HBP;
    s3cfb_fimd.lower_margin = S3CFB_VBP;
}
//初始化4.3寸LCD
void s3cfb_init_hw_43(void)
{
    printk(KERN_INFO "LCD TYPE :: LTE480WV will be initialized\n");

    s3cfb_set_fimd_info();
    s3cfb_set_gpio();
}

//對於QT6410使用的LCD是4.3寸屏,根據原理圖可知 LCD接在s3c6410的GPI和GPJ上,背光信號接在GPF14上。

int s3cfb_set_gpio(void)
{
    unsigned long val;
    int i, err;
   //使能LCD時鐘
    /* enable clock to LCD */
    val = readl(S3C_HCLK_GATE);//LCD使用HCLK
    val |= S3C_CLKCON_HCLK_LCD;
    writel(val, S3C_HCLK_GATE);

    /*設置LCD爲普通的RGB接口 */
    val = readl(S3C64XX_SPCON);
    val &= ~0x3;
    val |= (1 << 0);
    writel(val, S3C64XX_SPCON);

    //設置GPI(i)爲LCD接口
    for (i = 0; i < 16; i++)
        s3c_gpio_cfgpin(S3C64XX_GPI(i), S3C_GPIO_SFN(2));
    //設置GPJ(i)爲LCD接口
    for (i = 0; i < 12; i++)
        s3c_gpio_cfgpin(S3C64XX_GPJ(i), S3C_GPIO_SFN(2));
    /* backlight ON */
    //GPF14用作背光信號
    //printk("oPEN LCD BACKLIGHT1.\n");
    if (gpio_is_valid(S3C64XX_GPF(14))) {              //NOTE: orign GPF15 here
        err = gpio_request(S3C64XX_GPF(14), "GPF");
        if (err) {
            printk(KERN_ERR "failed to request GPF for "
                "lcd backlight control\n");
            return err;
        }
        gpio_direction_output(S3C64XX_GPF(14), 1);//配置成輸出引腳
        gpio_set_value(S3C64XX_GPF(14), 1);//設置成高電平
    }
    //QT6410接S3C64XX_GPE(0)電源使能引腳
    printk("oPEN LCD Power on.\n");
         if (gpio_is_valid(S3C64XX_GPE(0))) {
        err = gpio_request(S3C64XX_GPE(0), "GPE");
        if (err) {
            printk(KERN_ERR "failed to request GPE for "
                "lcd reset control\n");
            return err;
        }
        gpio_direction_output(S3C64XX_GPE(0), 1);
    }
    gpio_set_value(S3C64XX_GPE(0), 1);
    gpio_free(S3C64XX_GPE(0));
#ifndef CONFIG_BACKLIGHT_PWM
    gpio_free(S3C64XX_GPF(14));
#endif
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章