SN65DSI83 support Allwinner A64 platform

Other Parts Discussed in Thread: SN65DSI83

Dear Sir,

我們使用的cpu是Allwinner A64, 螢幕採用天馬TM070DDHG03-40,螢幕解析度是1024 x 600,

參考datasheet 8.2.2.1 Example Script範例去修改程式,仍然沒有畫面輸出.

1.請問TI SN65DSI83有無支援Allwinner A64的sample code?

2.附件是我們的driver code,有哪邊需要修改?還請給予建議.

3.附件是天馬TM070DDHG03-40的datasheet.

Best regards,

Alan Hsu │ 徐仲達

R.D Engineer │

alanhsu@posiflex.com.tw  |  www.posiflex.com

TM070DDHG03-40_Final specification_V1.2.pdf

#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/gpio.h>
#ifdef CONFIG_OF
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#endif

//#undef CONFIG_FB

#ifdef CONFIG_FB
#include <linux/notifier.h>
#include <linux/fb.h>
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif

//define here(Maolung)
//#define _1080P_LVDS_Panel_

#define _1024_LVDS_Panel_

#define _Test_Pattern_
#define  MODULE_NAME             "dsi83_i2c_driver"
#define  MODULE_I2C_ADDR          0x2d
static u32 debug_mask = 0;

#define LVDS_CLK_FROM_DSI_CLK     1

//Reset and clock Registers
#define DSI83_SOFT_RESET		      0x09
#define DSI83_CORE_PLL			      0x0A
#define DSI83_PLL_DIV			        0x0B
#define DSI83_PLL_EN			        0x0D

//DSI Registers
#define DSI83_DSI_CFG			        0x10
#define DSI83_DSI_EQ			        0x11
#define DSI83_CHA_DSI_CLK_RNG     0x12
#define DSI83_CHB_DSI_CLK_RNG     0x13

//LVDS Registers
#define DSI83_LVDS_MODE			      0x18
#define DSI83_LVDS_SIGN			      0x19
#define DSI83_LVDS_TERM			      0x1A
#define DSI83_LVDS_CM_ADJUST      0x1B

//Video Registers
#define DSI83_CHA_LINE_LEN_LO		  0x20
#define DSI83_CHA_LINE_LEN_HI		  0x21
#define DSI83_CHB_LINE_LEN_LO		  0x22
#define DSI83_CHB_LINE_LEN_HI		  0x23
#define DSI83_CHA_VERT_LINES_LO		0x24
#define DSI83_CHA_VERT_LINES_HI		0x25
#define DSI83_CHB_VERT_LINES_LO		0x26
#define DSI83_CHB_VERT_LINES_HI		0x27
#define DSI83_CHA_SYNC_DELAY_LO		0x28
#define DSI83_CHA_SYNC_DELAY_HI		0x29
#define DSI83_CHB_SYNC_DELAY_LO		0x2A
#define DSI83_CHB_SYNC_DELAY_HI		0x2B
#define DSI83_CHA_HSYNC_WIDTH_LO	0x2C
#define DSI83_CHA_HSYNC_WIDTH_HI	0x2D
#define DSI83_CHB_HSYNC_WIDTH_LO	0x2E
#define DSI83_CHB_HSYNC_WIDTH_HI	0x2F
#define DSI83_CHA_VSYNC_WIDTH_LO	0x30
#define DSI83_CHA_VSYNC_WIDTH_HI	0x31
#define DSI83_CHB_VSYNC_WIDTH_LO	0x32
#define DSI83_CHB_VSYNC_WIDTH_HI	0x33
#define DSI83_CHA_HORZ_BACKPORCH	0x34
#define DSI83_CHB_HORZ_BACKPORCH	0x35
#define DSI83_CHA_VERT_BACKPORCH	0x36
#define DSI83_CHB_VERT_BACKPORCH	0x37
#define DSI83_CHA_HORZ_FRONTPORCH	0x38
#define DSI83_CHB_HORZ_FRONTPORCH	0x39
#define DSI83_CHA_VERT_FRONTPORCH	0x3A
#define DSI83_CHB_VERT_FRONTPORCH	0x3B

#define DSI83_TEST_PATTERN      	0x3C

/*******************************************************

dsi83 mipi��J�榡�B�n�D�G
1�Anon-burst mode�]continue mode�^
2�AVideo mode
3�Async event
4�AMIPI DSI

*********************************************************/

//#define _Test_Pattern_ // ��X�¥սݱ���test pattern

#define _MIPI_Lane_	4 // MIPI Lane 1,2,4

//******************************************************//
#ifdef _1024_LVDS_Panel_

// �ھګe��MIPI�H����Timing�A�ק�H�U�ѼơG
static int MIPI_Timing[] = 
//  H_act  V_act	H_total V_total H_BP	  H_sync	V_sync	V_BP
//	{1920,	1080,	2200,	  1125,	  192,	  44,	    5,	    41};;// 1080P  Vesa Timing
    {1024,	600,	1344,	  635,	  160,	  80,	    7,	    28};
    
    //HPW      136      //VPW   5
    //HBP      160      //VBP   28
    //HFP      24       //VFP   2
    //Hact     1024     //Vact  600

// #define _8_Bit_ColorDepth_ // LVDS panel Color Depth�A16.7M color
#define _6_Bit_ColorDepth_ // LVDS panel Color Depth�A262K color

#define _MIPI_X_RES_	1024
#define _MIPI_Y_RES_	600

#define _MIPI_HSW_	  136
#define _MIPI_VSW_	  5

#define _MIPI_HBP_	  160
#define _MIPI_VBP_	  28

#define _MIPI_HFP_	  24
#define _MIPI_VFP_	  2

#endif

//******************************************************//

enum
{
	H_act = 0,
	V_act,
	H_tol,
	V_tol,
	H_bp,
	H_sync,
	V_sync,
	V_bp
};

static u8 swing_req=0x00;
static int brigde_init = 0;

#define Swing_Level_Close	0x00

#define Swing_Level_0_H	0x00
#define Swing_Level_0_L	0xa0 

#define Swing_Level_1_H	0x00
#define Swing_Level_1_L	0xf0

#define Swing_Level_2_H	0x01
#define Swing_Level_2_L	0x40

#define Swing_Level_3_H	0x02
#define Swing_Level_3_L	0xb4

static u8 DPCD0000H;
static u8 DPCD0001H;
static u8 DPCD0002H;
static u8 DPCD0202H;
static u8 DPCD0204H;
static u8 DPCD0206H;

#define DSI83_I2C_NAME             "dsi83_i2c_driver"
#define DSI83_CONFIG_PROC_FILE     "dsi83_config"
#define DSI83_CTRL_PROC_FILE	     "dsi83_ctrl"

//#define GPIO_RESET	136 
//use PD24
#define GPIO_RESET	104 

#define GPIO_POWER	24

//use PH08
#define GPIO_BACKLIGHT	362

static void DSI83_bist_init(void);

static struct i2c_client * dsi83_i2c_client = NULL; 
static int rst_gpio = GPIO_RESET;
static int bl_gpio = GPIO_BACKLIGHT;
	
#define DSI83_ID_LOW	0x11
#define DSI83_ID_HIGH	0x89

#if  defined(CONFIG_FB)
static struct notifier_block *notifier;
#endif


static int HDMI_ReadI2C_Byte(unsigned char addr,unsigned char *value)
{
    struct i2c_msg msgs[2];
    int ret=-1;
    s32 retries = 0;

    msgs[0].flags = !I2C_M_RD;
    msgs[0].addr  = dsi83_i2c_client->addr;
    //msgs[0].addr  = addr;
    msgs[0].len   = 1;
    msgs[0].buf   = &addr;
    
    msgs[1].flags = I2C_M_RD;
    msgs[1].addr  = dsi83_i2c_client->addr;
    //msgs[1].addr  = addr;
    msgs[1].len   = 1;
    msgs[1].buf   = value;

    while(retries < 2)
    {
        ret = i2c_transfer(dsi83_i2c_client->adapter, msgs, 2);
        if(ret == 2)
        	break;
        retries++;
    }
    if((ret != 2))
    {    
        printk("LT8911: I2C Read: 0x%02x failed, errcode: %d! Process reset.", addr, ret);
    }
//    else
//    printk("LT8911: I2C Read: dev addr %x, reg 0x%02x=0x%02x\n", msgs[0].addr, addr, *value);
    	
    return ret;
}

static int HDMI_WriteI2C_Byte(unsigned char addr,unsigned char value)
{
    struct i2c_msg msg;
    s32 ret = -1;
    s32 retries = 0;
	  u8 temp[2];
	
	  temp[0] = addr;
	  temp[1] = value;
	
    msg.flags = !I2C_M_RD;
	  msg.addr = dsi83_i2c_client->addr;
	  //msg.addr = addr;

    msg.len = 2;
    msg.buf = temp;

    while(retries < 2)
    {
        ret = i2c_transfer(dsi83_i2c_client->adapter, &msg, 1);
        if (ret == 1)
        	break;
        retries++;
    }
    if((ret != 1))
    {
        printk("LT8911: I2C Write: 0x%02x failed, errcode: %d! Process reset.",addr,ret );
    }
    return ret;
}


static void DpcdWrite(u32 Address, u8 Data)
{
	u8 AddressH = 0x0f & (Address>>16);
	u8 AddressM = 0xff & (Address>>8);
	u8 AddressL = 0xff &  Address    ;

	HDMI_WriteI2C_Byte(0xff,0x80);
	HDMI_WriteI2C_Byte(0x62,0xbd);
	HDMI_WriteI2C_Byte(0x62,0xbf);	
	HDMI_WriteI2C_Byte(0x36,0x00);
	HDMI_WriteI2C_Byte(0x30,0x10);// 0x11
	HDMI_WriteI2C_Byte(0x33,AddressL);
	HDMI_WriteI2C_Byte(0x34,AddressM);
	HDMI_WriteI2C_Byte(0x35,AddressH);
	HDMI_WriteI2C_Byte(0x37,Data);	
	HDMI_WriteI2C_Byte(0x36,0x20);
}

static u8 DpcdRead(u32 Address)
{
	u8 read_cnt=0x03;
	u8 DpcdValue = 0x00;
	u8 AddressH = 0x0f & (Address>>16);
	u8 AddressM = 0xff & (Address>>8);
	u8 AddressL = 0xff &  Address    ;	
	u8 tempValue = 0x00;
	
	HDMI_WriteI2C_Byte(0xff,0x80);
	HDMI_WriteI2C_Byte(0x62,0xbd);
	HDMI_WriteI2C_Byte(0x62,0xbf);	
	HDMI_WriteI2C_Byte(0x36,0x00);
	HDMI_WriteI2C_Byte(0x30,0x90);// 0x91
	HDMI_WriteI2C_Byte(0x33,AddressL);
	HDMI_WriteI2C_Byte(0x34,AddressM);
	HDMI_WriteI2C_Byte(0x35,AddressH);
	HDMI_WriteI2C_Byte(0x36,0x20);

	msleep(2); //���n��

	HDMI_ReadI2C_Byte(0x39,&tempValue);

	while((tempValue != 0x01)&&(read_cnt>0))
	{
		HDMI_WriteI2C_Byte(0x62,0xbd);
	  HDMI_WriteI2C_Byte(0x62,0xbf);
		HDMI_WriteI2C_Byte(0x36,0x00);
		HDMI_WriteI2C_Byte(0x36,0x20);
		read_cnt--;
		msleep(2);
		HDMI_ReadI2C_Byte(0x39,&tempValue);
	}

	if(tempValue == 0x01)
	{
		HDMI_ReadI2C_Byte(0x38,&DpcdValue);
	}
	
	return DpcdValue;
}


static void adj_swing(void)
{
	swing_req=DPCD0206H&0x0f;      //lane 0
	HDMI_WriteI2C_Byte(0xff,0x81); 
	switch(swing_req)
	{
		case 0x00: 	
			HDMI_WriteI2C_Byte(0x18,Swing_Level_0_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_0_L);
			DpcdWrite(0x0103,0x00);  
			break;
			
		case 0x01:
			HDMI_WriteI2C_Byte(0x18,Swing_Level_1_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_1_L);
			DpcdWrite(0x0103,0x01); 
			break;

		case 0x02: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_2_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_2_L);
			DpcdWrite(0x0103,0x02);  
			break;
			
		case 0x03: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_3_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_3_L);
			DpcdWrite(0x0103,0x07);  
			break;
			
		case 0x04: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_0_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_0_L);
			DpcdWrite(0x0103,0x08);  
			break;
			
		case 0x05: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_1_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_1_L);
			DpcdWrite(0x0103,0x09);  
			break;
			
		case 0x06: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_2_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_2_L);
			DpcdWrite(0x0103,0x0a);  
			break;
			
		case 0x07: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_3_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_3_L);
			DpcdWrite(0x0103,0x0f);  
			break;
			
		case 0x08: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_0_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_0_L);
			DpcdWrite(0x0103,0x10);  
			break;
			
		case 0x09: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_1_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_1_L);
			DpcdWrite(0x0103,0x11);  
			break;
			
		case 0x0a: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_2_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_2_L);
			DpcdWrite(0x0103,0x12);  
			break;
			
		case 0x0b: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_3_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_3_L);
			DpcdWrite(0x0103,0x17);  
			break;
			
		case 0x0c: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_0_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_0_L);
			DpcdWrite(0x0103,0x38);  
			break;
			
		case 0x0d: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_1_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_1_L);
			DpcdWrite(0x0103,0x39);  
			break;
			
		case 0x0e: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_2_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_2_L);
			DpcdWrite(0x0103,0x3a);  
			break;
			
		case 0x0f: 
			HDMI_WriteI2C_Byte(0x18,Swing_Level_3_H);   
			HDMI_WriteI2C_Byte(0x19,Swing_Level_3_L);
			DpcdWrite(0x0103,0x3f);  
			break;

		default:   break;
	}
	
#ifdef _1024_LVDS_Panel_

	swing_req=DPCD0206H&0xf0;      //lane 1
	HDMI_WriteI2C_Byte(0xff,0x81); 
	switch(swing_req)
	{
	case 0x00: 	
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_0_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_0_L);
		DpcdWrite(0x0104,0x00);  
		break;
		
	case 0x10:
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_1_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_1_L);
		DpcdWrite(0x0104,0x01); 
		break;
		
	case 0x20: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_2_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_2_L);
		DpcdWrite(0x0104,0x02);  
		break;
		
	case 0x30: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_3_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_3_L);
		DpcdWrite(0x0104,0x07);  
		break;
		
	case 0x40: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_0_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_0_L);
		DpcdWrite(0x0104,0x08);  
		break;
		
	case 0x50: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_1_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_1_L);
		DpcdWrite(0x0104,0x09);  
		break;
		
	case 0x60: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_2_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_2_L);
		DpcdWrite(0x0104,0x0a);  
		break;
		
	case 0x70: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_3_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_3_L);
		DpcdWrite(0x0104,0x0f);  
		break;
		
	case 0x80: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_0_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_0_L);
		DpcdWrite(0x0104,0x10);  
		break;
		
	case 0x90: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_1_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_1_L);
		DpcdWrite(0x0104,0x11);  
		break;
		
	case 0xa0: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_2_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_2_L);
		DpcdWrite(0x0104,0x12);  
		break;
			
	case 0xb0: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_3_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_3_L);
		DpcdWrite(0x0104,0x17);  
		break;
		
	case 0xc0: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_0_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_0_L);
		DpcdWrite(0x0104,0x38);  
		break;
		
	case 0xd0: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_1_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_1_L);
		DpcdWrite(0x0104,0x39);  
		break;
		
	case 0xe0: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_2_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_2_L);
		DpcdWrite(0x0104,0x3a);  
		break;
		
	case 0xf0: 
		HDMI_WriteI2C_Byte(0x1a,Swing_Level_3_H);   
		HDMI_WriteI2C_Byte(0x1b,Swing_Level_3_L);
		DpcdWrite(0x0104,0x3f);  
		break;
	default:   
		break;
	}


#endif  //_1024_LVDS_Panel_
	
}

#ifdef _1024_LVDS_Panel_

static void LT8911_AUX_Training(void)
{
	u8 swing_adj_cnt=0x00;
	u8 tempValue = 0x0;
	
  DPCD0202H=0x00;
	DPCD0000H=DpcdRead(0x0000);
	DPCD0001H=DpcdRead(0x0001);
	DPCD0002H=DpcdRead(0x0002);

	HDMI_WriteI2C_Byte(0xff,0x80);//register bank               
	HDMI_WriteI2C_Byte(0x62,0x3f); //Reset dp video

	HDMI_WriteI2C_Byte(0x03,0x42); //41-1lane,42-2lane,44-4lane

	HDMI_WriteI2C_Byte(0x04,0x14); 	

	HDMI_WriteI2C_Byte(0xff,0x84);  //register bank
  //HDMI_WriteI2C_Byte(0x14,0x01);	
	HDMI_WriteI2C_Byte(0x14,0x81);
	HDMI_WriteI2C_Byte(0x14,0x82);
	
	DpcdWrite(0x0600,0x01); 
	
	if(DpcdRead(0x0600)!=0x01)
	{
		DpcdWrite(0x0600,0x01); 
	}
	
	DpcdWrite(0x0100,0x0a); 
	DpcdWrite(0x0101,0x82); //2 lane
	DpcdWrite(0x010a,0x00); 

	if(DpcdRead(0x0100)!=0x0a)
	{
		DpcdWrite(0x0100,0x0a); 
	}

	if(DpcdRead(0x0101)!=0x82) // 2 Lane
	{
		DpcdWrite(0x0101,0x82); 
	}
	
	if(DpcdRead(0x010a)!=0x00)
	{
		DpcdWrite(0x010a,0x00);
	}
	
	DpcdWrite(0x0102,0x00);
	DpcdWrite(0x0102,0x01); // sent TPS1
	DpcdWrite(0x0103,0x00); 
	DpcdWrite(0x0104,0x00); 

	if(DpcdRead(0x0102)!=0x01)
	{
		DpcdWrite(0x0102,0x01); 
	}
	
	msleep(16);
	DPCD0204H=DpcdRead(0x0204);
	DPCD0202H=DpcdRead(0x0202);
	
	swing_adj_cnt=0x05;
	DPCD0202H=DPCD0202H&0x11;// 2 Lane 0x11 ; 1 Lane 0x01
	while(((DPCD0202H&0x11)!=0x11)&&(swing_adj_cnt>0))// 1080P 0x11 ; 1366 0x01
	{
		DPCD0206H=DpcdRead(0x0206);
		adj_swing();
		swing_adj_cnt--;
		msleep(1);
		DPCD0202H=DpcdRead(0x0202);
		DPCD0202H=DPCD0202H&0x11;// 2 Lane 0x11 ; 1 Lane 0x01
	}
	
	if(DPCD0202H==0x11)// 2 Lane 0x11 ; 1 Lane 0x01
	{
		HDMI_WriteI2C_Byte(0xff,0x80);//register bank
		HDMI_WriteI2C_Byte(0x04,0x18); 	

		HDMI_WriteI2C_Byte(0xff,0x84);//register bank
    //HDMI_WriteI2C_Byte(0x14,0x04);			
		HDMI_WriteI2C_Byte(0x14,0x84);
		HDMI_WriteI2C_Byte(0x14,0x88); //0x88

		DpcdWrite(0x0102,0x02);      // sent TPS2
		if(DpcdRead(0x0102)!=0x02)
		{
			DpcdWrite(0x0102,0x02); 
		}
		
		msleep(16);
		DPCD0204H=DpcdRead(0x0204);
		DPCD0202H=DpcdRead(0x0202);
		
		swing_adj_cnt=0x05;

		while(((DPCD0202H&0x77)!=0x77)&&(swing_adj_cnt>0))// 2 Lane 0x77 ; 1 Lane 0x07
		{  
			DPCD0206H=DpcdRead(0x0206);
			HDMI_WriteI2C_Byte(0xff,0x84);//register bank
			HDMI_WriteI2C_Byte(0x14,0x08);			
			HDMI_WriteI2C_Byte(0x14,0x88);
			adj_swing();
			swing_adj_cnt--;
			msleep(1);
			DPCD0202H=DpcdRead(0x0202);
			DPCD0204H=DpcdRead(0x0204);
		}
  }
	
//	HDMI_WriteI2C_Byte(0xff,0x82);//register bank
//	HDMI_WriteI2C_Byte(0x1c,DPCD0202H); 
	
	HDMI_WriteI2C_Byte(0xff,0x80); //register bank
	HDMI_WriteI2C_Byte(0x04,0x10);

	HDMI_WriteI2C_Byte(0xff,0x84); //register bank
	HDMI_WriteI2C_Byte(0x14,0x80);	
	HDMI_WriteI2C_Byte(0x14,0xc0);

	HDMI_WriteI2C_Byte(0xff,0x80); //register bank
	HDMI_WriteI2C_Byte(0x62,0xbf);

	HDMI_WriteI2C_Byte(0xff,0x88);//register bank

//if(HDMI_ReadI2C_Byte(0x24)!=0xc0)
	HDMI_ReadI2C_Byte(0x24,&tempValue);
	if(tempValue != 0xc0)
	{
		HDMI_WriteI2C_Byte(0xff,0x80);//register bank
		HDMI_WriteI2C_Byte(0x62,0x3f);
		HDMI_WriteI2C_Byte(0x62,0xbf);
	}
	
	DpcdWrite(0x0102,0x00); // sent data
	if(DpcdRead(0x0102)!=0x00)
	{
		DpcdWrite(0x0102,0x00); 
	}
	
	if(DpcdRead(0x0600)!=0x01)
	{
		DpcdWrite(0x0600,0x01); //
	}
	
	if(DpcdRead(0x010a)!=0x00)
	{
		DpcdWrite(0x010a,0x00); //
	}

	DPCD0202H=DpcdRead(0x0202);
}

#endif //_1024_LVDS_Panel_


static int dsi83_check_id(void)
{
	unsigned char buf;
	unsigned char IdLow;
	unsigned char IdHigh;
	
	int ret=0;
	
	HDMI_WriteI2C_Byte(0xff,0x80);
	HDMI_ReadI2C_Byte(0x00,&buf);
	IdLow = buf;
	
	HDMI_ReadI2C_Byte(0x01,&buf);
	IdHigh = buf;

	//printk("\n%s: get id 0x%02x,0x%02x\n",__func__,(unsigned int)IdLow,(unsigned int)IdHigh);
	if(IdLow != DSI83_ID_LOW || IdHigh != DSI83_ID_HIGH)
		ret = -1;
		
	return ret;		
}

static void dsi83_bl_en(int value)
{
	
	if (gpio_is_valid(bl_gpio)) {
		gpio_direction_output(bl_gpio,value);
	}
	else
	{
		printk("%s: gpio [%d] is not valid\n",__func__,bl_gpio);
		return ;
	}
	
}

static void reset_dsi83(void)
{
	int ret;
	if (gpio_is_valid(rst_gpio)) {
		ret = gpio_request(rst_gpio, "dsi83_reset_gpio");
		if (ret) {
			printk("%s: Unable to request reset gpio [%d]\n",__func__,rst_gpio);
			return;
		}
	}
	else
	{
		printk("%s: gpio [%d] is not valid\n",__func__,rst_gpio);
		return ;
	}
	ret = gpio_direction_output(rst_gpio, 1);
	if (ret) {
		printk("%s: Unable to set direction for reset gpio [%d] High\n",__func__,rst_gpio);
	}
	msleep(150);
	ret = gpio_direction_output(rst_gpio, 0);
	if (ret) {
		printk("Unable to set direction for reset gpio [%d] low\n",
			rst_gpio);
	}

	msleep(150);

	ret = gpio_direction_output(rst_gpio, 1);
	if (ret) {
		printk("%s: Unable to set direction for reset gpio [%d] High\n",__func__,rst_gpio);
	}
	msleep(150);
}

//---------------------------------------------//

static void DSI83_bist_init(void)
{
	unsigned char tempValue;

	HDMI_WriteI2C_Byte(0xff,0x81);//register bank
	HDMI_WriteI2C_Byte(0x00,0x04);

	HDMI_WriteI2C_Byte(0xff,0x80);//register bank
	HDMI_WriteI2C_Byte(0x7a,0x07);
	HDMI_WriteI2C_Byte(0x71,0x36);
	HDMI_WriteI2C_Byte(0x72,0x00);
	HDMI_WriteI2C_Byte(0x73,0x00);

	HDMI_WriteI2C_Byte(0x63,0x7f);
	HDMI_WriteI2C_Byte(0x63,0xff);

	///////////txpll_analog///////
  HDMI_WriteI2C_Byte(0xff,0x81);//register bank
	HDMI_WriteI2C_Byte(0x0e,0x27);
	HDMI_WriteI2C_Byte(0x01,0x18);
	HDMI_WriteI2C_Byte(0x02,0x42);
	HDMI_WriteI2C_Byte(0x04,0x00);
	HDMI_WriteI2C_Byte(0x04,0x01);

	
	HDMI_WriteI2C_Byte(0xff,0x80);//register bank
	HDMI_WriteI2C_Byte(0x61,0x7f);
	HDMI_WriteI2C_Byte(0x61,0xff);
	
	HDMI_WriteI2C_Byte(0xff,0x81);//register bank
	HDMI_WriteI2C_Byte(0x05,0x13); 

	//////////txpll_digtal////////
	HDMI_WriteI2C_Byte(0xff,0x80);//register bank
	HDMI_WriteI2C_Byte(0x74,0x41); 
	HDMI_WriteI2C_Byte(0x75,0x03); 
	HDMI_WriteI2C_Byte(0x76,0x0a); 
	HDMI_WriteI2C_Byte(0x78,0x0a); 

//-------------------------------------------//
	HDMI_WriteI2C_Byte(0xff,0x81);//register bank
	HDMI_WriteI2C_Byte(0x0e,0x27); 

	// 2 Lane LVDS Output
	HDMI_WriteI2C_Byte(0x22,0x30);// ���� LANE2 / LANE3 SWING���q�y�}��
	HDMI_WriteI2C_Byte(0x23,0x3c);// ���� LANE2 / LANE3 pre-emphase���q�y�}��
	HDMI_WriteI2C_Byte(0x25,0x08);
		
	HDMI_WriteI2C_Byte(0x18,Swing_Level_0_H); 
	HDMI_WriteI2C_Byte(0x19,Swing_Level_0_L); 
		
	HDMI_WriteI2C_Byte(0x1a,Swing_Level_0_H); 
	HDMI_WriteI2C_Byte(0x1b,Swing_Level_0_L); 


//---------------DDS--------------- //	

	HDMI_WriteI2C_Byte(0xff,0x90);//register bank
	HDMI_WriteI2C_Byte(0x4a,0x33); // 148.5MHz
	HDMI_WriteI2C_Byte(0x4b,0x33); 
	HDMI_WriteI2C_Byte(0x4c,0x33); 
	HDMI_WriteI2C_Byte(0x4d,0x10);

//------------RX_PLL-----------------//

	HDMI_WriteI2C_Byte(0xff,0x81);//register bank
	HDMI_WriteI2C_Byte(0x09,0x01); 
	HDMI_WriteI2C_Byte(0x0b,0x0b);
	HDMI_WriteI2C_Byte(0x08,0x13);

//-----------------1080P_60Hz---------------------//

	HDMI_WriteI2C_Byte(0xff,0x88);//register bank
	HDMI_WriteI2C_Byte(0x00,0x6a);
	HDMI_WriteI2C_Byte(0x04,0xff);

	HDMI_WriteI2C_Byte(0x05,0x08);//RG_HTOTAL[15:0] 
	HDMI_WriteI2C_Byte(0x06,0x98);//RG_HTOTAL[7:0] 
	HDMI_WriteI2C_Byte(0x07,0x00);//RG_HSTART [15:8]
	HDMI_WriteI2C_Byte(0x08,0xc0);//RG_HSTART[7:0]=110
	HDMI_WriteI2C_Byte(0x09,0x00);//[7]RG_HSPOL;[6:0]RG_HSYNC_WIDTH[14:8]	0x80-->0x00
	HDMI_WriteI2C_Byte(0x0a,0x2c);//RG_HSYNC_WIDTH[7:0]=60
	HDMI_WriteI2C_Byte(0x0b,0x07);//RG_HWIDTH[15:8] 
	HDMI_WriteI2C_Byte(0x0c,0x80);//RG_HWIDTH[7:0] 
	HDMI_WriteI2C_Byte(0x0d,0x04);//RG_VTOTAL [15:8] 
	HDMI_WriteI2C_Byte(0x0e,0x65);//RG_VTOTAL[7:0] 
	
	HDMI_WriteI2C_Byte(0x0f,0x00);//RG_TOP_VTOTAL[15:8] //fiexd
	HDMI_WriteI2C_Byte(0x10,0x00);//RG_TOP_VTOTAL[7:0]	//fixed
	
	HDMI_WriteI2C_Byte(0x11,0x00);//RG_VSTART[15:8] 
	HDMI_WriteI2C_Byte(0x12,0x29);//RG_VSTART[7:0] 
	HDMI_WriteI2C_Byte(0x13,0x00);//RG_VSPOL;RG_VSYNC_WIDTH[14:8]  0x80-->0x00	
	HDMI_WriteI2C_Byte(0x14,0x05);//RG_VSYNC_WIDTH[7:0] 
	HDMI_WriteI2C_Byte(0x15,0x04);//RG_VHEIGTH[15:8] 
	HDMI_WriteI2C_Byte(0x16,0x38);//RG_VHEIGTH[7:0]

//#ifdef _6_Bit_ColorDepth_ 
	HDMI_WriteI2C_Byte(0x17,0x00);// LVDS Color Depth:   6 bit: 0x00 ;   8 bit: 0x08
	HDMI_WriteI2C_Byte(0x18,0x00);// LVDS Color Depth:   6 bit: 0x00 ;   8 bit: 0x20
//#endif

	HDMI_WriteI2C_Byte(0x19,0x00);
	HDMI_WriteI2C_Byte(0x1a,0x80);
	HDMI_WriteI2C_Byte(0x1e,0x30);
	HDMI_WriteI2C_Byte(0x21,0x00);
	HDMI_WriteI2C_Byte(0x2c,0xdf);
	HDMI_WriteI2C_Byte(0x2d,0x00);

	HDMI_WriteI2C_Byte(0x4b,0xfe);

	HDMI_WriteI2C_Byte(0x2e,0x29);//RG_GCM_DE_TOP[6:0]
	HDMI_WriteI2C_Byte(0x2f,0x00);//RG_GCM_DE_DLY[11:8]
	HDMI_WriteI2C_Byte(0x30,0xc0);//RG_GCM_DE_DLY[7:0]
	HDMI_WriteI2C_Byte(0x31,0x07);//RG_GCM_DE_CNT[11:8]
	HDMI_WriteI2C_Byte(0x32,0x80);//RG_GCM_DE_CNT[7:0]
	HDMI_WriteI2C_Byte(0x33,0x04);//RG_GCM_DE_LIN[10:8]
	HDMI_WriteI2C_Byte(0x34,0x38);//RG_GCM_DE_LIN[7:0]
	HDMI_WriteI2C_Byte(0x35,0x08);//RG_GCM_HTOTAL[11:8]
	HDMI_WriteI2C_Byte(0x36,0x98);//RG_GCM_HTOTAL[7:0]

#ifdef  _Test_Pattern_ // ��X�¥սݱ���test pattern
	HDMI_WriteI2C_Byte(0x37,0x1c);
#else
	HDMI_WriteI2C_Byte(0x37,0x0c);
#endif

	HDMI_WriteI2C_Byte(0x38,0x65);//RG_GCM_VTOTAL[7:0]
	HDMI_WriteI2C_Byte(0x39,0x00);//reseve
	HDMI_WriteI2C_Byte(0x3a,0x14);//RG_GCM_VWIDTH[5:0];RG_GCM_HWIDTH[9:8]
	HDMI_WriteI2C_Byte(0x3b,0x2c);//RG_GCM_HWIDTH[7:0]

	
  ////////////////////Nvid//////////////
	HDMI_WriteI2C_Byte(0xff,0x8c); //register bank
	HDMI_WriteI2C_Byte(0x00,0x00);
	HDMI_WriteI2C_Byte(0x01,0x80);
	HDMI_WriteI2C_Byte(0x02,0x00);

//-----------------Training-----------------------------//

	LT8911_AUX_Training(); 

	if(DPCD0202H!=0x77)

	LT8911_AUX_Training();
	       
//	HDMI_WriteI2C_Byte(0xff,0x88);//register bank      
//	HDMI_WriteI2C_Byte(0x1e,0x30);           
//	HDMI_WriteI2C_Byte(0x4b,0xfe);

//-----------------------------------------------//

	HDMI_WriteI2C_Byte(0xff,0x81);//register bank
	HDMI_WriteI2C_Byte(0x32,0x40);
	HDMI_WriteI2C_Byte(0x27,0x80); 
	HDMI_WriteI2C_Byte(0x28,0xa4);
	HDMI_WriteI2C_Byte(0x29,0xd2);
	HDMI_WriteI2C_Byte(0x2a,0x04);
	HDMI_WriteI2C_Byte(0x2b,0x7e); 
	HDMI_WriteI2C_Byte(0x2c,0x02);
	HDMI_WriteI2C_Byte(0x2d,0x02);
	HDMI_WriteI2C_Byte(0x2e,0xaa);
	HDMI_WriteI2C_Byte(0x2f,0x02); 
	HDMI_WriteI2C_Byte(0x30,0xaa);
	HDMI_WriteI2C_Byte(0x31,0x4b);
	HDMI_WriteI2C_Byte(0x32,0x43);
	HDMI_WriteI2C_Byte(0x33,0x20); 
	HDMI_WriteI2C_Byte(0x34,0x00);
	HDMI_WriteI2C_Byte(0x35,0x80);
	HDMI_WriteI2C_Byte(0x36,0xa4);
	HDMI_WriteI2C_Byte(0x37,0xd2); 
	HDMI_WriteI2C_Byte(0x38,0x00);
	HDMI_WriteI2C_Byte(0x39,0x36);
	HDMI_WriteI2C_Byte(0x3a,0x00);

//--------------------------------------------//

	HDMI_WriteI2C_Byte(0xff,0x90);//register bank
	HDMI_WriteI2C_Byte(0x01,0x04); 
	HDMI_WriteI2C_Byte(0x02,0x04);
	HDMI_WriteI2C_Byte(0x03,0x04);
	HDMI_WriteI2C_Byte(0x04,0xc8);
	HDMI_WriteI2C_Byte(0x05,0x00); 
	HDMI_WriteI2C_Byte(0x06,0x0b);
	HDMI_WriteI2C_Byte(0x0b,_MIPI_Lane_%0x04);// 00:4 Lane;01:1 Lane;02:2 Lane;03:3 Lane
	HDMI_WriteI2C_Byte(0x0c,0x00);// 3210
	HDMI_WriteI2C_Byte(0x10,0x03);
	HDMI_WriteI2C_Byte(0x11,0x03); 

	HDMI_WriteI2C_Byte(0x12,0x2c);
	HDMI_WriteI2C_Byte(0x13,0x05);
	HDMI_WriteI2C_Byte(0x14,0x80);
	HDMI_WriteI2C_Byte(0x15,0x07); 
	HDMI_WriteI2C_Byte(0x16,0x80);
	HDMI_WriteI2C_Byte(0x17,0x07);

	HDMI_WriteI2C_Byte(0x18,0x00);
	HDMI_WriteI2C_Byte(0x19,0x01); 
	HDMI_WriteI2C_Byte(0x1a,0x17);
	HDMI_WriteI2C_Byte(0x2b,0x0b);
	HDMI_WriteI2C_Byte(0x2c,0x0c);

	HDMI_WriteI2C_Byte(0x31,0x98); 
	HDMI_WriteI2C_Byte(0x32,0x08);
	HDMI_WriteI2C_Byte(0x33,0x65);
	HDMI_WriteI2C_Byte(0x34,0x04);
	HDMI_WriteI2C_Byte(0x35,0x24); 
	HDMI_WriteI2C_Byte(0x36,0x00);
	HDMI_WriteI2C_Byte(0x37,0x04);
	HDMI_WriteI2C_Byte(0x38,0x00);
	HDMI_WriteI2C_Byte(0x39,0x94); 
	HDMI_WriteI2C_Byte(0x3a,0x00);
	HDMI_WriteI2C_Byte(0x3b,0x58);
	HDMI_WriteI2C_Byte(0x3c,0x00);

	HDMI_WriteI2C_Byte(0x1b,0x90); 
	HDMI_WriteI2C_Byte(0x1c,0x01);
	HDMI_WriteI2C_Byte(0x1d,0x68);
	HDMI_WriteI2C_Byte(0x1e,0x01);
	HDMI_WriteI2C_Byte(0x1f,0x5e); 
	HDMI_WriteI2C_Byte(0x20,0x01);
	HDMI_WriteI2C_Byte(0x21,0x54);
	HDMI_WriteI2C_Byte(0x22,0x01);
	HDMI_WriteI2C_Byte(0x23,0x90); 
	HDMI_WriteI2C_Byte(0x24,0x01);
	HDMI_WriteI2C_Byte(0x25,0x68);
	HDMI_WriteI2C_Byte(0x26,0x01);
	HDMI_WriteI2C_Byte(0x27,0x5e); 
	HDMI_WriteI2C_Byte(0x28,0x01);
	HDMI_WriteI2C_Byte(0x29,0x54);
	HDMI_WriteI2C_Byte(0x2a,0x01);
	HDMI_WriteI2C_Byte(0x3d,0x64); 
	HDMI_WriteI2C_Byte(0x3f,0x00);
	HDMI_WriteI2C_Byte(0x40,0x04);
	HDMI_WriteI2C_Byte(0x41,0x00);
	HDMI_WriteI2C_Byte(0x42,0x59); 
	HDMI_WriteI2C_Byte(0x43,0x00);
	HDMI_WriteI2C_Byte(0x44,0xf2);
	HDMI_WriteI2C_Byte(0x45,0x06);
	HDMI_WriteI2C_Byte(0x46,0x00); 
	HDMI_WriteI2C_Byte(0x47,0x72);
	HDMI_WriteI2C_Byte(0x48,0x45);
	HDMI_WriteI2C_Byte(0x49,0x00);

	HDMI_WriteI2C_Byte(0x60,0x08); 
	HDMI_WriteI2C_Byte(0x61,0x00);
	HDMI_WriteI2C_Byte(0x62,0xb2);
	HDMI_WriteI2C_Byte(0x63,0x00);
	HDMI_WriteI2C_Byte(0x64,0xe4); 
	HDMI_WriteI2C_Byte(0x65,0x0d);
	HDMI_WriteI2C_Byte(0x66,0x00);
	HDMI_WriteI2C_Byte(0x67,0xe4);
	HDMI_WriteI2C_Byte(0x68,0x8a); 
	HDMI_WriteI2C_Byte(0x69,0x00);
	HDMI_WriteI2C_Byte(0x6a,0x0b);
	HDMI_WriteI2C_Byte(0x1a,0x4f);
	HDMI_WriteI2C_Byte(0x6b,0x04); 

#ifdef  _Test_Pattern_ 
	HDMI_WriteI2C_Byte(0x4d,0x10);// Enable DDS
#else
	HDMI_WriteI2C_Byte(0x4d,0x00);// Close DDS
#endif
//---------------------------------------//
	HDMI_WriteI2C_Byte(0xff,0x80);//register bank
	HDMI_WriteI2C_Byte(0x60,0xde); 
	HDMI_WriteI2C_Byte(0x60,0xff);

	HDMI_WriteI2C_Byte(0x63,0x7f);
	HDMI_WriteI2C_Byte(0x63,0xff);
//------------------------------------------//

	HDMI_WriteI2C_Byte(0xff,0x00);//register bank

	msleep(1000);
	HDMI_WriteI2C_Byte(0xff,0x90);//register bank
	HDMI_ReadI2C_Byte(0x4d,&tempValue);
	printk("%s: get 0x904d value 0x%02x\n",__func__, tempValue);		
}

#ifdef _1024_LVDS_Panel_

// MIPI��J�I024x600 LVDS�̪� DSI83 �H�s���]�m�G
// ��ij�b��DSI83 ����MIPI�H������A�A��l��DSI83�H�s���C

static void DSI83_Initial(void)
{
  u8 val = 0;

	/* Soft reset and disable PLL */
	HDMI_WriteI2C_Byte(DSI83_SOFT_RESET,0x01);
	HDMI_WriteI2C_Byte(DSI83_PLL_EN,0x00);

#if LVDS_CLK_FROM_DSI_CLK
       val = 0x1;
#endif

	/* user external clock reference with no muliplier */
    //if (dssdev->panel.timings.pixel_clock <= 37500)
    //{
        // Do nothing.
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 62500), 1024x600x60=36864000
    //{
    //    val |= (0x01 << 1);
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 87500)
    //{
    //    val |= (0x02 << 1);
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 112500)
    //{
    //    val |= (0x03 << 1);
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 137500)
    //{
    //    val |= (0x04 << 1);
    //}
    //else
    //{
        val |= (0x05 << 1);
    //}
  
  HDMI_WriteI2C_Byte(DSI83_CORE_PLL,val);
////
#if LVDS_CLK_FROM_DSI_CLK
  HDMI_WriteI2C_Byte(DSI83_PLL_DIV,0x10);   // Divide DSI_CLK by 3.
#else
  HDMI_WriteI2C_Byte(DSI83_PLL_DIV,0x00);   // Multiply REFCLK by 1.
#endif  

	/* four DSI lanes with single channel*/
	HDMI_WriteI2C_Byte(DSI83_DSI_CFG,0x20);
	HDMI_WriteI2C_Byte(DSI83_DSI_EQ,0x00);

    /* set DSI clock range */
  //  i2c_smbus_write_byte_data(dsi83_i2c_client, DSI83_CHA_DSI_CLK_RNG, (dssdev->panel.timings.pixel_clock * 3 / 5000));
  //  i2c_smbus_write_byte_data(dsi83_i2c_client, DSI83_CHB_DSI_CLK_RNG, (dssdev->panel.timings.pixel_clock * 3 / 5000));
  HDMI_WriteI2C_Byte(DSI83_CHA_DSI_CLK_RNG,(36864000 * 3 / 5000));
  HDMI_WriteI2C_Byte(DSI83_CHB_DSI_CLK_RNG,(36864000 * 3 / 5000));
  
	/* set LVDS for single channel, 24 bit mode, HS/VS low, DE high */
	HDMI_WriteI2C_Byte(DSI83_LVDS_MODE,0x7F);

	/* set LVDS 200 Ohm termination and max differential swing voltage */
	HDMI_WriteI2C_Byte(DSI83_LVDS_SIGN,0x00);
	HDMI_WriteI2C_Byte(DSI83_LVDS_TERM,0x00);


	/* x resolution high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_LINE_LEN_LO,(_MIPI_X_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHA_LINE_LEN_HI,(_MIPI_X_RES_ & 0xFF00)>>8);

	/* x resolution high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_LINE_LEN_LO,(_MIPI_X_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHB_LINE_LEN_HI,(_MIPI_X_RES_ & 0xFF00)>>8);
	
	/* y resolution high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_LINES_LO,(_MIPI_Y_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_LINES_HI,(_MIPI_Y_RES_ & 0xFF00)>>8);

	/* y resolution high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_LINES_LO,(_MIPI_Y_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_LINES_HI,(_MIPI_Y_RES_ & 0xFF00)>>8);

	/* SYNC delay high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_SYNC_DELAY_LO,0x00);
	HDMI_WriteI2C_Byte(DSI83_CHA_SYNC_DELAY_HI,0x02);

	/* SYNC delay high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_SYNC_DELAY_LO,0x00);
	HDMI_WriteI2C_Byte(DSI83_CHB_SYNC_DELAY_HI,0x02);


	/* HSYNC width high/low for channel A */
  HDMI_WriteI2C_Byte(DSI83_CHA_HSYNC_WIDTH_LO,(_MIPI_HSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHA_HSYNC_WIDTH_HI,(_MIPI_HSW_ & 0xFF00)>>8);
		
	/* HSYNC width high/low for channel B */
  HDMI_WriteI2C_Byte(DSI83_CHB_HSYNC_WIDTH_LO,(_MIPI_HSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHB_HSYNC_WIDTH_HI,(_MIPI_HSW_ & 0xFF00)>>8);	

	/* VSYNC width high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VSYNC_WIDTH_LO,(_MIPI_VSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHA_VSYNC_WIDTH_HI,(_MIPI_VSW_ & 0xFF00)>>8);	

	/* VSYNC width high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VSYNC_WIDTH_LO,(_MIPI_VSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHB_VSYNC_WIDTH_HI,(_MIPI_VSW_ & 0xFF00)>>8);	

	/* Horizontal BackPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_HORZ_BACKPORCH,(_MIPI_HBP_ & 0x00FF));

	/* Horizontal BackPorch for channel B */
  HDMI_WriteI2C_Byte(DSI83_CHB_HORZ_BACKPORCH,(_MIPI_HBP_ & 0x00FF));

	/* Vertical BackPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_BACKPORCH,(_MIPI_VBP_ & 0x00FF));

	/* Vertical BackPorch for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_BACKPORCH,(_MIPI_VBP_ & 0x00FF));
 
 	/* Horizontal FrontPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_HORZ_FRONTPORCH,(_MIPI_HFP_ & 0x00FF));

	/* Horizontal FrontPorch for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_HORZ_FRONTPORCH,(_MIPI_HFP_ & 0x00FF));

	/* Vertical FrontPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_FRONTPORCH,(_MIPI_VFP_ & 0x00FF));

	/* Vertical FrontPorch for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_FRONTPORCH,(_MIPI_VFP_ & 0x00FF));

	/* Soft reset and enable PLL */
	HDMI_WriteI2C_Byte(DSI83_SOFT_RESET,0x01);
	HDMI_WriteI2C_Byte(DSI83_PLL_EN,0x01);

	return;
  
}

static void DSI83_Test(void)
{
  u8 val = 0;

	/* Soft reset and disable PLL */
	HDMI_WriteI2C_Byte(DSI83_SOFT_RESET,0x01);
	HDMI_WriteI2C_Byte(DSI83_PLL_EN,0x00);

#if LVDS_CLK_FROM_DSI_CLK
       val = 0x1;
#endif

	/* user external clock reference with no muliplier */
    //if (dssdev->panel.timings.pixel_clock <= 37500)
    //{
        // Do nothing.
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 62500), 1024x600x60=36864000
    //{
    //    val |= (0x01 << 1);
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 87500)
    //{
    //    val |= (0x02 << 1);
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 112500)
    //{
    //    val |= (0x03 << 1);
    //}
    //else if (dssdev->panel.timings.pixel_clock <= 137500)
    //{
    //    val |= (0x04 << 1);
    //}
    //else
    //{
        val |= (0x05 << 1);
    //}

    //LADLDL
    printk(KERN_INFO "Mao: Pixel CLK value was %d\n",val);
  
  HDMI_WriteI2C_Byte(DSI83_CORE_PLL,val);
////
#if LVDS_CLK_FROM_DSI_CLK
  HDMI_WriteI2C_Byte(DSI83_PLL_DIV,0x10);   // Divide DSI_CLK by 3.
#else
  HDMI_WriteI2C_Byte(DSI83_PLL_DIV,0x00);   // Multiply REFCLK by 1.
#endif  

	//LADLDL PLL enable after address A and B configured
	HDMI_WriteI2C_Byte(DSI83_PLL_EN,0x01); 

	/* four DSI lanes with single channel*/
	HDMI_WriteI2C_Byte(DSI83_DSI_CFG,0x20);
	HDMI_WriteI2C_Byte(DSI83_DSI_EQ,0x00);



    /* set DSI clock range */
  //  i2c_smbus_write_byte_data(dsi83_i2c_client, DSI83_CHA_DSI_CLK_RNG, (dssdev->panel.timings.pixel_clock * 3 / 5000));
  //  i2c_smbus_write_byte_data(dsi83_i2c_client, DSI83_CHB_DSI_CLK_RNG, (dssdev->panel.timings.pixel_clock * 3 / 5000));
  HDMI_WriteI2C_Byte(DSI83_CHA_DSI_CLK_RNG,(36864000 * 3 / 5000));
  HDMI_WriteI2C_Byte(DSI83_CHB_DSI_CLK_RNG,(36864000 * 3 / 5000));

	/* set LVDS for single channel, 24 bit mode, HS/VS low, DE high */
	//i2c_smbus_write_byte_data(dsi83_i2c_client, DSI83_LVDS_MODE, 0x7F);
	/*LADLD set LVDS for single channel, 24 bit mode, HS/VS low, DE high */
	HDMI_WriteI2C_Byte(DSI83_LVDS_MODE,0x60);
  
	/* set LVDS 200 Ohm termination and max differential swing voltage */
	//HDMI_WriteI2C_Byte(DSI83_LVDS_SIGN,0x00);
	//HDMI_WriteI2C_Byte(DSI83_LVDS_TERM,0x00);


	/* x resolution high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_LINE_LEN_LO,(_MIPI_X_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHA_LINE_LEN_HI,(_MIPI_X_RES_ & 0xFF00)>>8);

	/* x resolution high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_LINE_LEN_LO,(_MIPI_X_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHB_LINE_LEN_HI,(_MIPI_X_RES_ & 0xFF00)>>8);
	
	/* y resolution high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_LINES_LO,(_MIPI_Y_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_LINES_HI,(_MIPI_Y_RES_ & 0xFF00)>>8);

	/* y resolution high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_LINES_LO,(_MIPI_Y_RES_ & 0x00FF));
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_LINES_HI,(_MIPI_Y_RES_ & 0xFF00)>>8);

	/* SYNC delay high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_SYNC_DELAY_LO,0x00);
	HDMI_WriteI2C_Byte(DSI83_CHA_SYNC_DELAY_HI,0x02);

	/* SYNC delay high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_SYNC_DELAY_LO,0x00);
	HDMI_WriteI2C_Byte(DSI83_CHB_SYNC_DELAY_HI,0x02);

	/* HSYNC width high/low for channel A */
  HDMI_WriteI2C_Byte(DSI83_CHA_HSYNC_WIDTH_LO,(_MIPI_HSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHA_HSYNC_WIDTH_HI,(_MIPI_HSW_ & 0xFF00)>>8);
		
	/* HSYNC width high/low for channel B */
  HDMI_WriteI2C_Byte(DSI83_CHB_HSYNC_WIDTH_LO,(_MIPI_HSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHB_HSYNC_WIDTH_HI,(_MIPI_HSW_ & 0xFF00)>>8);	

	/* VSYNC width high/low for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VSYNC_WIDTH_LO,(_MIPI_VSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHA_VSYNC_WIDTH_HI,(_MIPI_VSW_ & 0xFF00)>>8);	

	/* VSYNC width high/low for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VSYNC_WIDTH_LO,(_MIPI_VSW_ & 0x00FF));
  HDMI_WriteI2C_Byte(DSI83_CHB_VSYNC_WIDTH_HI,(_MIPI_VSW_ & 0xFF00)>>8);	

	/* Horizontal BackPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_HORZ_BACKPORCH,(_MIPI_HBP_ & 0x00FF));

	/* Horizontal BackPorch for channel B */
  HDMI_WriteI2C_Byte(DSI83_CHB_HORZ_BACKPORCH,(_MIPI_HBP_ & 0x00FF));

	/* Vertical BackPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_BACKPORCH,(_MIPI_VBP_ & 0x00FF));

	/* Vertical BackPorch for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_BACKPORCH,(_MIPI_VBP_ & 0x00FF));
 
 	/* Horizontal FrontPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_HORZ_FRONTPORCH,(_MIPI_HFP_ & 0x00FF));

	/* Horizontal FrontPorch for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_HORZ_FRONTPORCH,(_MIPI_HFP_ & 0x00FF));

	/* Vertical FrontPorch for channel A */
	HDMI_WriteI2C_Byte(DSI83_CHA_VERT_FRONTPORCH,(_MIPI_VFP_ & 0x00FF));

	/* Vertical FrontPorch for channel B */
	HDMI_WriteI2C_Byte(DSI83_CHB_VERT_FRONTPORCH,(_MIPI_VFP_ & 0x00FF));

	//Test Pattern
	HDMI_WriteI2C_Byte(DSI83_TEST_PATTERN,0x11);

  //LADLDL
	/* Soft reset and enable PLL */
	//HDMI_WriteI2C_Byte(DSI83_SOFT_RESET,0x01);
	//HDMI_WriteI2C_Byte(DSI83_PLL_EN,0x01);

	return;
  
}

#endif   //_1024_LVDS_Panel_


static ssize_t dsi83_ctrl_write_proc(struct file *filp, const char __user *buffer, size_t count, loff_t *off)
{
	int ret;	
	unsigned char buf[128]={0};
	unsigned char temp;
	

	ret = copy_from_user(buf, buffer, count-1);
	if(ret < 0){
		printk("%s, copy data from user space, failed\n", __func__);
		return -1;
	}

		DSI83_Initial(); 
		DSI83_Test(); //


    return count;
}

static struct proc_dir_entry *dsi83_ctrl_proc = NULL;
static const struct file_operations ctrl_proc_ops = {
    .owner = THIS_MODULE,
    .read = NULL,
    .write = dsi83_ctrl_write_proc,
};


#if  defined(CONFIG_FB)
static int dsi83_is_suspend = 0;

static void dsi83_ts_suspend(void)
{
	unsigned char  value;
	if(!dsi83_is_suspend){
		//printk("### %s\n",__func__);	

		//printk("### read value: %x \n",value);
	}
	else{	
			
		//printk("### %s: always in suspend\n",__func__);
	  dsi83_is_suspend = 1;
	  gpio_set_value(rst_gpio, 0);  //susu
	  msleep(20);
	  
	}
}

static void dsi83_ts_resume(void)
{
	unsigned char  value;
	s32 ret = -1;
	if(dsi83_is_suspend){
		//printk("### read value: %x \n",value);
	  gpio_set_value(rst_gpio, 1);   //susu
	  msleep(20);
	}
	dsi83_is_suspend = 0;
	//////////////////////////
	  //printk("### dsi83_resume_reset\n");
		reset_dsi83();
	
		//ret = dsi83_check_id();
		//if(ret <0)
		//{

		//	if (gpio_is_valid(rst_gpio)) {
		//		printk("### free gpio %d\n",rst_gpio);
		//		gpio_free(rst_gpio);
		//	}
			
		//}
    
		DSI83_Initial(); 

	
}

/* frame buffer notifier block control the suspend/resume procedure */
static int dsi83_fb_notifier_callback(struct notifier_block *noti, unsigned long event, void *data)
{
	struct fb_event *ev_data = data;
	int *blank;
	
	if (ev_data && ev_data->data && event == FB_EVENT_BLANK ) {
		blank = ev_data->data;
		if (*blank == FB_BLANK_UNBLANK) {
			printk("Resume by fb notifier.\n");
			dsi83_ts_resume();
				
		}
		else if (*blank == FB_BLANK_POWERDOWN) {
			printk("Suspend by fb notifier.\n");
			dsi83_ts_suspend();
		}
	}
	return 0;
}
#endif


static int dsi83_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    s32 ret = -1;

	  //printk("### %s\n",__func__);


	if (client->dev.of_node) {
		
		rst_gpio = of_get_named_gpio(client->dev.of_node,
			"reset-gpios", 0);
		
		if (!gpio_is_valid(rst_gpio))
		{
			rst_gpio = GPIO_RESET;
			pr_err("%s:%d, rst_gpio gpio not specified\n",
							__func__, __LINE__);
		}

		bl_gpio = of_get_named_gpio(client->dev.of_node,
			"backlight-gpios", 0);
		
		if (!gpio_is_valid(bl_gpio))
		{
			bl_gpio = GPIO_BACKLIGHT;
			pr_err("%s:%d, bl gpio not specified\n",
							__func__, __LINE__);
		}
	}
	
    dsi83_i2c_client = client;
    
    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
    {
        printk("I2C check functionality failed.");
        return -ENODEV;
    }

	// ��H�s�����e�A��Reset LT8911/B ,��GPIO ���ԧCLT8911/B���_��} 150ms���k�A�A�԰��A�O��150ms
	if(brigde_init == 0)
	{	
		reset_dsi83();
	
		//ret = dsi83_check_id();
		//if(ret <0)
		//{
			//printk("### dsi83_check_id failed\n");
			//if (gpio_is_valid(rst_gpio)) {
			//	printk("### free gpio %d\n",rst_gpio);
			//	gpio_free(rst_gpio);
			//}
			//return -1;	
		//}    
	
		DSI83_Initial(); 
		    brigde_init = 1;
		if(0)	
		dsi83_bl_en(0);
	}
    // Create proc file system
    dsi83_ctrl_proc = proc_create(DSI83_CTRL_PROC_FILE, 0666, NULL, &ctrl_proc_ops);
    if (dsi83_ctrl_proc == NULL)
    {
        printk("create_proc_entry %s failed\n", DSI83_CTRL_PROC_FILE);
    }
    else
    {
        ;
        //printk("create proc entry %s success\n", DSI83_CTRL_PROC_FILE);
    }

#if defined(CONFIG_FB)
	notifier = kzalloc(sizeof(*notifier), GFP_KERNEL);
	notifier->notifier_call = dsi83_fb_notifier_callback;
	fb_register_client(notifier);
#endif
	
	//lvds_ic_type_set("lt8911");

    return 0;	

}

static int dsi83_remove(struct i2c_client *client)
{
      
    i2c_set_clientdata(client, NULL);

    return 0;
}

static const struct of_device_id dsi83_match_table[] = {
		{.compatible = "dsi83,dsi83",},
		{ },
};

static const struct i2c_device_id dsi83_id[] = {
    { DSI83_I2C_NAME, 0 },
    { }
};


//struct i2c_driver dsi83_driver = {     /*--1--*/
//    .probe      = dsi83_probe,
//    .remove     = dsi83_remove,
//    .id_table   = dsi83_id,
//    .driver = {
//        .name     = DSI83_I2C_NAME,
//        .owner    = THIS_MODULE,
//        .of_match_table = dsi83_match_table,
//    },
//};

struct i2c_driver dsi83_i2c_driver = {     /*--2--*/
    .probe      = dsi83_probe,
    .remove     = dsi83_remove,
    .id_table   = dsi83_id,
    .driver = {
        .name     = DSI83_I2C_NAME,
        .owner    = THIS_MODULE,
        .of_match_table = dsi83_match_table,
    },
};



static struct i2c_board_info dsi83_board_info={
    .type = MODULE_NAME, 
    .addr = MODULE_I2C_ADDR,
};


static struct i2c_client *dsi83_client;

int __init dsi83_i2c_init(void)
{
    struct i2c_adapter *i2c_adap;
    unsigned int cfg_i2c_adap_id;
    
    //use i2c-1
    //cfg_i2c_adap_id = 1;
     
    //use i2c-0  
    cfg_i2c_adap_id = 0; 
    
    i2c_adap = i2c_get_adapter(cfg_i2c_adap_id);  
    dsi83_client = i2c_new_device(i2c_adap, &dsi83_board_info);  
    i2c_put_adapter(i2c_adap);
    
    //printk("dsi83_i2c_init\n");
    
    //return i2c_add_driver(&dsi83_driver);       /*--1--*/  
    return i2c_add_driver(&dsi83_i2c_driver);     /*--2--*/
    
}
fs_initcall(dsi83_i2c_init);


void __exit dsi83_i2c_exit(void)
{
        //del_dsi_ops(lt8911_ops);
        //lt8911_lcd_manager = NULL;
    printk("dsi83_i2c_exit\n");
    
    //i2c_del_driver(&dsi83_driver);             /*--1--*/
    i2c_del_driver(&dsi83_i2c_driver);           /*--2--*/
    
    //i2c_unregister_device(dsi83_client);
}
module_exit(dsi83_i2c_exit);


//module_i2c_driver(dsi83_driver);

module_param_named(debug_mask, debug_mask, int, 0644);
MODULE_AUTHOR("<Maolung.>");
MODULE_DESCRIPTION("Posiflex DSI83 MIPI to LVDS Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.1");

  • 下面这个帖子下有个基于OMAP 的代码例程,希望对您有帮助:
    e2e.ti.com/.../2328916
  • Dear Sir,

    我們使用SN65DSI83有遇到一些問題,

    當系統執行完bootload程序,按power button開機時有出現Android的log,一但進入到User 畫面2~3秒後,

    畫面會整個變白,必需系統整個restart重置,但系統重置進入到User 畫面2~3秒後畫面又變白.

    1.有確認提供給Panel的電壓(AVDD、VGH、VGL)都是正確的.

    2.有確認power on的時序Timming,參照datasheet Figure 5. Shutdown and RESET Timing Definition是正確的.

    能幫忙確認是那邊有問題嗎?

    如有需要我可以提供線路,請私下mail,不要上傳.

    Best regards,

    Alan Hsu │

    R.D Engineer │ 研發電子部工程師

    alanhsu@posiflex.com.tw