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");