Commit c918194f authored by 陳永達's avatar 陳永達

Fix HDCP handshake process on line plug auth & allow reauthentication.

parent d3e36282
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
* 3) system ioctl support. ----------------------------- 2008-06-30 JChen * 3) system ioctl support. ----------------------------- 2008-06-30 JChen
* 3) 1080i support. ------------------------------------ 2008-06-30 JChen * 3) 1080i support. ------------------------------------ 2008-06-30 JChen
* 4) hdcp support. ------------------------------------ 2008-07-09 JChen * 4) hdcp support. ------------------------------------ 2008-07-09 JChen
* 5) fix hdcp auth. ------------------------------------ 2008-08-11 JChen
* 6) support line auth. -------------------------------- 2008-08-11 JChen
* 7) fix var mode into struct. ------------------------- 2008-08-12 JChen
* *
*/ */
...@@ -69,23 +72,16 @@ ...@@ -69,23 +72,16 @@
#define SIL9034_HDMI_NAME "sil9034hdmi" #define SIL9034_HDMI_NAME "sil9034hdmi"
/* Si9034 use 2 i2c to control the chip 0x39 & 0x3A */ /* Si9034 use 2 i2c to control the chip 0x39 & 0x3A */
#define SLAVE_SIZE 2 #define SLAVE_SIZE 2
#define TIMER_JIFFIES (1 * HZ) #define TIMER_JIFFIES (3 * HZ)
/* Timer only could cause the kernel busy, we push it into schedule */ /* Timer only could cause the kernel busy, we push it into schedule */
#define SIL9034_TIMER 1 #define SIL9034_TIMER 1
#define SIL9034_SCHED 1 #define SIL9034_SCHED 1
/* YCBCR MODE */
#define YCBCR_480I 0
#define YCBCR_480P 0
#define YCBCR_720P 0
#define YCBCR_1080I 1
/* Silicon Image provide 2 slave address to control. */ /* Silicon Image provide 2 slave address to control. */
static int slave_num = 0 ; static int slave_num = 0 ;
static int sil9034_attach_adapter(struct i2c_adapter * adapter); static int sil9034_attach_adapter(struct i2c_adapter * adapter);
static int sil9034_detach_client(struct i2c_client * client); static int sil9034_detach_client(struct i2c_client * client);
static struct input_dev *sil9034_hdmi_dev;
static unsigned short normal_i2c[] = { static unsigned short normal_i2c[] = {
/* Jchen: should probe this address if real physical device is mount */ /* Jchen: should probe this address if real physical device is mount */
...@@ -97,54 +93,58 @@ static unsigned short normal_i2c[] = { ...@@ -97,54 +93,58 @@ static unsigned short normal_i2c[] = {
/* Macro need by addr_data */ /* Macro need by addr_data */
I2C_CLIENT_INSMOD; I2C_CLIENT_INSMOD;
/* bus mapping struct */ /* video mapping struct */
typedef struct bus_mapping_sil9034 typedef struct sil9034_video_mapping
{ {
u8 bus_reg ; u8 video_reg ;
u16 value ; u16 value ;
} bus_mapping_sil9034 ; } sil9034_video_mapping ;
/* bus mapping for 480p YCbCr 4:2:2 Separate Sync Input*/ /* video mapping for 480p YCbCr 4:2:2 Separate Sync Input*/
bus_mapping_sil9034 sil9034_480p_setting[] = sil9034_video_mapping sil9034_480p_setting[] =
{ {
{DE_CTRL_ADDR,0x41}, {DE_CTRL_ADDR,(DE_GEN_ENABLE|0x70)},
{DE_DELAY_ADDR,0x04}, {DE_DELAY_ADDR,0x7A},
{DE_TOP_ADDR,0x19}, {DE_TOP_ADDR,0x24},
{DE_CNTH_ADDR,0x5}, {DE_CNTH_ADDR,0x2},
{DE_CNTL_ADDR,0x00}, {DE_CNTL_ADDR,0xD0},
{DEL_H_ADDR,0x2}, {DEL_H_ADDR,0x1},
{DEL_L_ADDR,0xD0}, {DEL_L_ADDR,0xE0},
{TX_VID_CTRL_ADDR,0x20}, {TX_VID_CTRL_ADDR,CSCSEL_BT709|SET_EXTN_12BIT},
{TX_VID_MODE_ADDR,0x00} {TX_VID_MODE_ADDR,UPSMP_ENABLE|CSC_ENABLE},
{0,0}
}; };
/* bus mapping for 720p YCbCr 4:2:2 Separate Sync Input*/ /* video mapping for 720p YCbCr 4:2:2 Separate Sync Input*/
bus_mapping_sil9034 sil9034_720p_setting[] = sil9034_video_mapping sil9034_720p_setting[] =
{ {
{DE_CTRL_ADDR,0x41}, {DE_CTRL_ADDR,(DE_GEN_ENABLE|0x1)},
{DE_DELAY_ADDR,0x2B}, {DE_DELAY_ADDR,0x04},
{DE_TOP_ADDR,0x19}, {DE_TOP_ADDR,0x19},
{DE_CNTH_ADDR,0x5}, {DE_CNTH_ADDR,0x5},
{DE_CNTL_ADDR,0x00}, {DE_CNTL_ADDR,0x00},
{DEL_H_ADDR,0x2}, {DEL_H_ADDR,0x2},
{DEL_L_ADDR,0xD0}, {DEL_L_ADDR,0xD0},
{TX_VID_CTRL_ADDR,0x30}, {TX_VID_CTRL_ADDR,CSCSEL_BT709|SET_EXTN_12BIT},
{TX_VID_MODE_ADDR,0x3C} {TX_VID_MODE_ADDR,UPSMP_ENABLE|CSC_ENABLE},
{0,0}
}; };
/* bus mapping for 1080i YCbCr 4:2:2 Separate Sync Input*/ /* video mapping for 1080i YCbCr 4:2:2 Separate Sync Input*/
bus_mapping_sil9034 sil9034_1080i_setting[] = sil9034_video_mapping sil9034_1080i_setting[] =
{ {
{DE_CTRL_ADDR,0x40}, {DE_CTRL_ADDR,(DE_GEN_ENABLE|0x0)},
{DE_DELAY_ADDR,0xC0}, {DE_DELAY_ADDR,0xC0},
{DE_TOP_ADDR,0x14}, {DE_TOP_ADDR,0x14},
{DE_CNTH_ADDR,0x07}, {DE_CNTH_ADDR,0x07},
{DE_CNTL_ADDR,0x80}, {DE_CNTL_ADDR,0x80},
{DEL_H_ADDR,0x2}, {DEL_H_ADDR,0x2},
{DEL_L_ADDR,0x1C}, {DEL_L_ADDR,0x1C},
{TX_VID_CTRL_ADDR,0x30}, {TX_VID_CTRL_ADDR,CSCSEL_BT709|SET_EXTN_12BIT},
{TX_VID_MODE_ADDR,0x3C} {TX_VID_MODE_ADDR,UPSMP_ENABLE|CSC_ENABLE},
{0,0}
}; };
/* i2c private data */ /* i2c private data */
typedef struct davinci6446_sil9034 typedef struct davinci6446_sil9034
{ {
...@@ -157,9 +157,12 @@ typedef struct davinci6446_sil9034 ...@@ -157,9 +157,12 @@ typedef struct davinci6446_sil9034
#endif #endif
spinlock_t lock; spinlock_t lock;
/* pointer to different setting according to system */ /* pointer to different setting according to system */
bus_mapping_sil9034 *sil9034_setting ; sil9034_video_mapping *sil9034_setting ;
unsigned char sil9034_setting_num ;
unsigned char work_flag ; unsigned char work_flag ;
unsigned char auth_state ;
u8 an_ksv_data[8] ;
char r0rx[2] ;
char r0tx[2] ;
} davinci6446_sil9034 ; } davinci6446_sil9034 ;
static davinci6446_sil9034 ds ; static davinci6446_sil9034 ds ;
...@@ -331,6 +334,7 @@ out: ...@@ -331,6 +334,7 @@ out:
return ret; return ret;
} }
static int sil9034_write(davinci6446_sil9034 *priv,u8 slave,u8 reg, u16 value) static int sil9034_write(davinci6446_sil9034 *priv,u8 slave,u8 reg, u16 value)
{ {
int retry = I2C_RETRY_COUNT; int retry = I2C_RETRY_COUNT;
...@@ -371,10 +375,66 @@ static int sil9034_read(davinci6446_sil9034 *priv,u8 slave,u8 reg) ...@@ -371,10 +375,66 @@ static int sil9034_read(davinci6446_sil9034 *priv,u8 slave,u8 reg)
return 0xff; return 0xff;
} }
static char *sil9034_ddc_write(davinci6446_sil9034 *priv,u8 *value,u8 reg, u8 length)
{
u8 count = 0 ;
while(sil9034_read(priv,SLAVE0,DDC_STATUS_ADDR)&BIT_MDDC_ST_IN_PROGR)
mdelay(10) ;
sil9034_write(priv,SLAVE0,DDC_ADDR,HDCP_RX_SLAVE) ;
sil9034_write(priv,SLAVE0,DDC_OFFSET_ADDR,reg) ;
sil9034_write(priv,SLAVE0,DDC_CNT1_ADDR,length) ;
sil9034_write(priv,SLAVE0,DDC_CNT2_ADDR,0) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_CLEAR_FIFO) ;
for(count=0 ;count < length ; count++)
{
sil9034_write(priv,SLAVE0,DDC_DATA_ADDR,value[count]) ;
}
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_SEQ_WR) ;
while(sil9034_read(priv,SLAVE0,DDC_STATUS_ADDR)&BIT_MDDC_ST_IN_PROGR)
mdelay(10) ;
sil9034_dbg("DDC WRITE FIFO is %d\n",sil9034_read(priv,SLAVE0,DDC_FIFOCNT_ADDR)) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_ABORT) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_CLOCK) ;
sil9034_write(priv,SLAVE0,DDC_MAN_ADDR,0) ;
return NULL ;
}
static char *sil9034_ddc_read(davinci6446_sil9034 *priv,u8 *value,u8 reg, u8 length)
{
u8 count = 0 ;
sil9034_write(priv,SLAVE0,DDC_ADDR,HDCP_RX_SLAVE) ;
sil9034_write(priv,SLAVE0,DDC_OFFSET_ADDR,reg) ;
sil9034_write(priv,SLAVE0,DDC_CNT1_ADDR,length) ;
sil9034_write(priv,SLAVE0,DDC_CNT2_ADDR,0) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_CLEAR_FIFO) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_SEQ_RD) ;
while(sil9034_read(priv,SLAVE0,DDC_STATUS_ADDR)&BIT_MDDC_ST_IN_PROGR)
mdelay(10) ;
sil9034_dbg("DDC READ FIFO is %d\n",sil9034_read(priv,SLAVE0,DDC_FIFOCNT_ADDR)) ;
for(count=0 ;count < length ; count++)
{
value[count] = sil9034_read(priv,SLAVE0,DDC_DATA_ADDR) ;
}
while(sil9034_read(priv,SLAVE0,DDC_STATUS_ADDR)&BIT_MDDC_ST_IN_PROGR)
mdelay(10) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_ABORT) ;
sil9034_write(priv,SLAVE0,DDC_CMD_ADDR,MASTER_CMD_CLOCK) ;
sil9034_write(priv,SLAVE0,DDC_MAN_ADDR,0) ;
return NULL ;
}
//-------------------------- INIT / EXIT --------------------------------------------------------- //-------------------------- INIT / EXIT ---------------------------------------------------------
static int sil9034_chipInfo(davinci6446_sil9034 *priv) static int sil9034_chipInfo(davinci6446_sil9034 *priv)
{ {
u8 device_info[3] = {255,255,255} ; u8 device_info[3] = {255,255,255} ;
device_info[1] = sil9034_read(priv,SLAVE0,DEV_IDL) ; device_info[1] = sil9034_read(priv,SLAVE0,DEV_IDL) ;
device_info[0] = sil9034_read(priv,SLAVE0,DEV_IDH) ; device_info[0] = sil9034_read(priv,SLAVE0,DEV_IDH) ;
...@@ -384,6 +444,134 @@ static int sil9034_chipInfo(davinci6446_sil9034 *priv) ...@@ -384,6 +444,134 @@ static int sil9034_chipInfo(davinci6446_sil9034 *priv)
return 0 ; return 0 ;
} }
static int sil9034_powerDown(davinci6446_sil9034 *priv,u8 enable)
{
/* power down internal oscillator
* disable internal read of HDCP keys and KSV
* disable master DDC block
* page 4,50,113
*/
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,TX_SYS_CTRL1_ADDR) ;
if(enable)
{
sil9034_write(priv,SLAVE1,DIAG_PD_ADDR,PDIDCK_NORMAL|PDOSC_NORMAL|PDTOT_NORMAL) ;
sil9034_write(priv,SLAVE0,TX_SYS_CTRL1_ADDR,reg_value & ~(SET_PD)) ;
}
else
{
sil9034_write(priv,SLAVE1,DIAG_PD_ADDR,~(PDIDCK_NORMAL|PDOSC_NORMAL|PDTOT_NORMAL)) ;
sil9034_write(priv,SLAVE0,TX_SYS_CTRL1_ADDR,(reg_value | SET_PD)) ;
}
reg_value = sil9034_read(priv,SLAVE0,TX_SYS_CTRL1_ADDR) ;
sil9034_dbg("System control register #1 0x%x = 0x%x\n",TX_SYS_CTRL1_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE1,DIAG_PD_ADDR) ;
sil9034_dbg("Diagnostic power down register 0x%x = 0x%x\n",DIAG_PD_ADDR,reg_value) ;
return 0 ;
}
static int sil9034_hdmiTmdsConfig(davinci6446_sil9034 *priv)
{
u8 reg_value ;
/* TMDS control register
* FPLL is 1.0*IDCK.
* Internal source termination enabled.
* Driver level shifter bias enabled.
* page 27
*/
reg_value = sil9034_read(priv,SLAVE0,TX_TMDS_CTRL_ADDR) ;
sil9034_write(priv,SLAVE0,TX_TMDS_CTRL_ADDR,reg_value|(LVBIAS_ENABLE|STERM_ENABLE)) ;
reg_value = sil9034_read(priv,SLAVE0,TX_TMDS_CTRL_ADDR) ;
sil9034_dbg("TMDS control register 0x%x = 0x%x\n",TX_TMDS_CTRL_ADDR,reg_value) ;
}
static int sil9034_audioInputConfig(davinci6446_sil9034 *priv)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/* Audio mode register */
sil9034_write(priv,SLAVE1,AUD_MODE_ADDR,SPDIF_ENABLE|AUD_ENABLE) ;
reg_value = sil9034_read(priv,SLAVE1,AUD_MODE_ADDR) ;
sil9034_dbg("Audio in mode register 0x%x = 0x%x\n",AUD_MODE_ADDR,reg_value) ;
/* ACR N software value */
sil9034_write(priv,SLAVE1,N_SVAL1_ADDR,0) ;
sil9034_write(priv,SLAVE1,N_SVAL2_ADDR,0x18) ;
sil9034_write(priv,SLAVE1,N_SVAL3_ADDR,0) ;
/* ACR ctrl */
sil9034_write(priv,SLAVE1,ACR_CTRL_ADDR,NCTSPKT_ENABLE) ;
/* ACR audio frequency register: * MCLK=128 Fs */
sil9034_write(priv,SLAVE1,FREQ_SVAL_ADDR,0x4) ;
reg_value = sil9034_read(priv,SLAVE1,FREQ_SVAL_ADDR) ;
sil9034_dbg("Audio frequency register 0x%x = 0x%x\n",FREQ_SVAL_ADDR,reg_value) ;
return 0 ;
}
static int sil9034_videoInputConfig(davinci6446_sil9034 *priv)
{
u8 count = 0 ;
/* Auto setting by the sil9034_video_mapping struct */
while(priv->sil9034_setting[count++].video_reg != 0)
{
sil9034_dbg("setting count %d 0x%x-0x%x\n",count,\
priv->sil9034_setting[count].video_reg,\
priv->sil9034_setting[count].value) ;
sil9034_write(priv,SLAVE0,priv->sil9034_setting[count].video_reg,\
priv->sil9034_setting[count].value) ;
}
return 0 ;
}
static int sil9034_swReset(davinci6446_sil9034 *priv)
{
/* use to temporary save inf_ctrl */
u8 temp1 ;
u8 temp2 ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
temp1 = sil9034_read(priv,SLAVE1,INF_CTRL1) ;
temp2 = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
/*
* audio fifo reset enable
* software reset enable
*/
while(!sil9034_read(priv,SLAVE0,TX_STAT_ADDR)&P_STABLE)
mdelay(10) ;
sil9034_write(priv,SLAVE0,TX_SWRST_ADDR,(BIT_TX_SW_RST|BIT_TX_FIFO_RST)) ;
mdelay(10) ;
sil9034_write(priv,SLAVE0,TX_SWRST_ADDR,0) ;
mdelay(64) ; // allow TCLK (sent to Rx across the HDMS link) to stabilize
/* restore */
sil9034_write(priv,SLAVE1,INF_CTRL1,temp1) ;
sil9034_write(priv,SLAVE1,INF_CTRL2,temp2) ;
return 0 ;
}
static int sil9034_triggerRom(davinci6446_sil9034 *priv)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,KEY_COMMAND_ADDR) ;
sil9034_write(priv,SLAVE0,KEY_COMMAND_ADDR,reg_value & ~LD_KSV) ;
mdelay(10) ;
sil9034_write(priv,SLAVE0,KEY_COMMAND_ADDR,reg_value |LD_KSV) ;
mdelay(10) ;
sil9034_write(priv,SLAVE0,KEY_COMMAND_ADDR,reg_value & ~LD_KSV) ;
return 0 ;
}
static int sil9034_audioInfoFrameSetting(davinci6446_sil9034 *priv) static int sil9034_audioInfoFrameSetting(davinci6446_sil9034 *priv)
{ {
u8 aud_info_addr ; u8 aud_info_addr ;
...@@ -427,53 +615,26 @@ static int sil9034_audioInfoFrameSetting(davinci6446_sil9034 *priv) ...@@ -427,53 +615,26 @@ static int sil9034_audioInfoFrameSetting(davinci6446_sil9034 *priv)
return 0 ; return 0 ;
} }
static int sil9034_cea861InfoFrameSetting(davinci6446_sil9034 *priv)
static int sil9034_cea861InfoFrameControl1(davinci6446_sil9034 *priv,u8 enable)
{ {
u8 avi_info_addr ;
u8 reg_value ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/* enable the avi repeat transmission */
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL1) ; reg_value = sil9034_read(priv,SLAVE1,INF_CTRL1) ;
if(enable) sil9034_write(priv,SLAVE1,INF_CTRL1,reg_value & (~BIT_AVI_REPEAT)) ;
sil9034_write(priv,SLAVE1,INF_CTRL1,(reg_value | (BIT_AVI_REPEAT |BIT_AUD_ENABLE |BIT_AUD_REPEAT))) ; mdelay(64) ; // Delay VSync for unlock DATA buffer
if(sil9034_read(priv,SLAVE1,INF_CTRL1)&BIT_AVI_ENABLE)
sil9034_dbg("Sent AVI error\n") ;
else else
sil9034_write(priv,SLAVE1,INF_CTRL1,0) ; sil9034_dbg("Silicon Image sending AVI success.\n") ;
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL1) ;
sil9034_dbg("InfoFrame control#1 register 0x%x = 0x%x\n",INF_CTRL1,reg_value) ;
return 0 ; if(sil9034_read(priv,SLAVE1,INF_CTRL1)&BIT_AUD_ENABLE)
} sil9034_dbg("Sent AUD error\n") ;
static int sil9034_cea861InfoFrameControl2(davinci6446_sil9034 *priv,u8 enable)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/* Generic packet transmittion & repeat mode enable */
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
if(enable)
{
/* enable GCP_RPT , GCP_EN */
sil9034_write(priv,SLAVE1,INF_CTRL2,(GCP_EN|GCP_RPT)) ;
}
else else
{ sil9034_dbg("Silicon Image sending AUD success.\n") ;
sil9034_write(priv,SLAVE1,INF_CTRL2,reg_value & ~(GCP_EN|GCP_RPT)) ;
}
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
sil9034_dbg("InfoFrame control#2 register 0x%x = 0x%x\n",INF_CTRL2,reg_value) ;
return 0 ;
}
static int sil9034_cea861InfoFrameSetting(davinci6446_sil9034 *priv)
{
u8 avi_info_addr ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/* set the info frame type according to CEA-861 datasheet */ /* set the info frame type according to CEA-861 datasheet */
avi_info_addr = AVI_IF_ADDR ; avi_info_addr = AVI_IF_ADDR ;
...@@ -485,16 +646,16 @@ static int sil9034_cea861InfoFrameSetting(davinci6446_sil9034 *priv) ...@@ -485,16 +646,16 @@ static int sil9034_cea861InfoFrameSetting(davinci6446_sil9034 *priv)
sil9034_write(priv,SLAVE1,avi_info_addr++,0x02) ; sil9034_write(priv,SLAVE1,avi_info_addr++,0x02) ;
/* AVI length */ /* AVI length */
sil9034_write(priv,SLAVE1,avi_info_addr++,0x0D) ; sil9034_write(priv,SLAVE1,avi_info_addr++,0x13) ;
/* AVI CRC */ /* AVI CRC */
sil9034_write(priv,SLAVE1,avi_info_addr++,(0x82 + 0x02 + 0x0D + 0x3D)) ; sil9034_write(priv,SLAVE1,avi_info_addr++,(0x82 + 0x02 + 0x13 + 0x1D)) ;
/* AVI DATA BYTE , according to Sil FAE, 3 byte is enought. /* AVI DATA BYTE , according to Sil FAE, 3 byte is enought.
* page 102 * page 102
*/ */
/* 0 | Y1 | Y0 | A0 | B1 | B0 | S1 | S0 */ /* 0 | Y1 | Y0 | A0 | B1 | B0 | S1 | S0 */
sil9034_write(priv,SLAVE1,avi_info_addr++,0x3D) ; sil9034_write(priv,SLAVE1,avi_info_addr++,0x1D) ;
/* C1 | C0 | M1 | M0 | R3 | R2 | R1 | R0 */ /* C1 | C0 | M1 | M0 | R3 | R2 | R1 | R0 */
sil9034_write(priv,SLAVE1,avi_info_addr++,0x68) ; sil9034_write(priv,SLAVE1,avi_info_addr++,0x68) ;
...@@ -502,111 +663,55 @@ static int sil9034_cea861InfoFrameSetting(davinci6446_sil9034 *priv) ...@@ -502,111 +663,55 @@ static int sil9034_cea861InfoFrameSetting(davinci6446_sil9034 *priv)
/* 0 | 0 | 0 | 0 | 0 | 0 | SC1 | SC0 */ /* 0 | 0 | 0 | 0 | 0 | 0 | SC1 | SC0 */
sil9034_write(priv,SLAVE1,avi_info_addr++,0x3) ; sil9034_write(priv,SLAVE1,avi_info_addr++,0x3) ;
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL1) ;
sil9034_write(priv,SLAVE1,INF_CTRL1,reg_value | (BIT_AVI_ENABLE|BIT_AVI_REPEAT)) ;
return 0 ; return 0 ;
} }
static int sil9034_wakeupHdmiTx(davinci6446_sil9034 *priv)
static int sil9034_ddcSetting(davinci6446_sil9034 *priv)
{
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
return 0 ;
}
static int sil9034_powerDown(davinci6446_sil9034 *priv,u8 enable)
{ {
/* power down internal oscillator
* disable internal read of HDCP keys and KSV
* disable master DDC block
* page 4,50,113
*/
u8 reg_value ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,TX_SYS_CTRL1_ADDR) ;
if(enable)
{
sil9034_write(priv,SLAVE1,DIAG_PD_ADDR,~(PDIDCK_NORMAL|PDOSC_NORMAL|PDTOT_NORMAL)) ;
sil9034_write(priv,SLAVE0,TX_SYS_CTRL1_ADDR,reg_value & ~(SET_PD)) ;
}
else
{
sil9034_write(priv,SLAVE1,DIAG_PD_ADDR,PDIDCK_NORMAL|PDOSC_NORMAL|PDTOT_NORMAL) ;
sil9034_write(priv,SLAVE0,TX_SYS_CTRL1_ADDR,(reg_value | SET_PD)) ;
}
reg_value = sil9034_read(priv,SLAVE0,TX_SYS_CTRL1_ADDR) ; reg_value = sil9034_read(priv,SLAVE0,TX_SYS_CTRL1_ADDR) ;
sil9034_dbg("System control register #1 0x%x = 0x%x\n",TX_SYS_CTRL1_ADDR,reg_value) ; sil9034_write(priv,SLAVE0,TX_SYS_CTRL1_ADDR,reg_value|SET_PD) ;
sil9034_write(priv,SLAVE0,INT_CNTRL_ADDR,0) ;
reg_value = sil9034_read(priv,SLAVE1,DIAG_PD_ADDR) ; reg_value = sil9034_read(priv,SLAVE1,INF_CTRL1) ;
sil9034_dbg("Diagnostic power down register 0x%x = 0x%x\n",DIAG_PD_ADDR,reg_value) ; sil9034_write(priv,SLAVE1,INF_CTRL1,reg_value |BIT_AVI_REPEAT|BIT_AUD_REPEAT) ;
return 0 ;
}
static int sil9034_swReset(davinci6446_sil9034 *priv)
{
/*
* audio fifo reset enable
* software reset enable
*/
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
sil9034_write(priv,SLAVE0,TX_SWRST_ADDR,(BIT_TX_SW_RST|BIT_TX_FIFO_RST)) ;
udelay(100) ;
sil9034_write(priv,SLAVE0,TX_SWRST_ADDR,~(BIT_TX_SW_RST|BIT_TX_FIFO_RST)) ;
return 0 ; return 0 ;
} }
static int sil9034_sentCPPackage(davinci6446_sil9034 *priv,u8 enable)
static int sil9034_generalControlPacket(davinci6446_sil9034 *priv,u8 enable)
{ {
u8 reg_value ; u8 reg_value ;
/* u8 timeout = 64 ;
* mute the video & audio
*/ reg_value = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_write(priv,SLAVE1,INF_CTRL2,reg_value &~BIT_CP_REPEAT) ;
reg_value = sil9034_read(priv,SLAVE1,GCP_BYTE1) ;
if(enable) if(enable)
{ sil9034_write(priv,SLAVE1,CP_IF_ADDR,BIT_CP_AVI_MUTE_SET) ;
/* set avmute flag */
sil9034_write(priv,SLAVE1,GCP_BYTE1,(reg_value | SET_AVMUTE)) ;
}
else else
sil9034_write(priv,SLAVE1,CP_IF_ADDR,BIT_CP_AVI_MUTE_CLEAR) ;
while(timeout--)
{ {
/* clear avmute flag */ if(!sil9034_read(priv,SLAVE1,INF_CTRL2)&BIT_CP_REPEAT)
sil9034_write(priv,SLAVE1,GCP_BYTE1,(reg_value | CLR_AVMUTE)) ; break ;
} }
reg_value = sil9034_read(priv,SLAVE1,GCP_BYTE1) ;
sil9034_dbg("General control packet register 0x%x = 0x%x\n",GCP_BYTE1,reg_value) ;
return 0 ;
}
static int sil9034_audioInputConfig(davinci6446_sil9034 *priv)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; if(timeout)
/* Audio mode register */ sil9034_write(priv,SLAVE1,INF_CTRL2,reg_value |(BIT_CP_REPEAT|BIT_CP_ENABLE)) ;
sil9034_write(priv,SLAVE1,AUD_MODE_ADDR,0xF9) ;
reg_value = sil9034_read(priv,SLAVE1,AUD_MODE_ADDR) ;
sil9034_dbg("Audio in mode register 0x%x = 0x%x\n",AUD_MODE_ADDR,reg_value) ;
/* ACR audio frequency register: * MCLK=128 Fs */
sil9034_write(priv,SLAVE1,FREQ_SVAL_ADDR,0) ;
reg_value = sil9034_read(priv,SLAVE1,FREQ_SVAL_ADDR) ;
sil9034_dbg("Audio frequency register 0x%x = 0x%x\n",FREQ_SVAL_ADDR,reg_value) ;
return 0 ; return 0 ;
} }
int sil9034_unmaskInterruptStatus(davinci6446_sil9034 *priv)
static int sil9034_hdmiVideoEmbSyncDec(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 reg_value = 0xFF ;
sil9034_write(priv,SLAVE0,HDMI_INT1_MASK,reg_value) ;
sil9034_write(priv,SLAVE0,HDMI_INT2_MASK,reg_value) ;
sil9034_write(priv,SLAVE0,HDMI_INT3_MASK,reg_value) ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,INTERLACE_ADJ_MODE) ;
sil9034_write(priv,SLAVE0,INTERLACE_ADJ_MODE,(reg_value & ~(AVI_RPT_ENABLE|AVI_ENABLE|SPD_RPT_ENABLE))) ;
reg_value = sil9034_read(priv,SLAVE0,INTERLACE_ADJ_MODE) ;
sil9034_dbg("Interlace Adjustment register 0x%x = 0x%x\n",INTERLACE_ADJ_MODE,reg_value) ;
return 0 ; return 0 ;
} }
static int sil9034_hdmiOutputConfig(davinci6446_sil9034 *priv) static int sil9034_hdmiOutputConfig(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 reg_value ;
...@@ -621,42 +726,47 @@ static int sil9034_hdmiOutputConfig(davinci6446_sil9034 *priv) ...@@ -621,42 +726,47 @@ static int sil9034_hdmiOutputConfig(davinci6446_sil9034 *priv)
return 0 ; return 0 ;
} }
static int sil9034_hdmiTmdsConfig(davinci6446_sil9034 *priv) static int sil9034_ddcSetting(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; sil9034_write(priv,SLAVE0,DDC_ADDR,HDCP_RX_SLAVE) ;
return 0 ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/* TMDS control register
* FPLL is 1.0*IDCK.
* Internal source termination enabled.
* Driver level shifter bias enabled.
* page 27
*/
reg_value = sil9034_read(priv,SLAVE0,TX_TMDS_CTRL_ADDR) ;
sil9034_write(priv,SLAVE0,TX_TMDS_CTRL_ADDR,reg_value|(LVBIAS_ENABLE|STERM_ENABLE)) ;
reg_value = sil9034_read(priv,SLAVE0,TX_TMDS_CTRL_ADDR) ;
sil9034_dbg("TMDS control register 0x%x = 0x%x\n",TX_TMDS_CTRL_ADDR,reg_value) ;
} }
static int sil9034_cea861InfoFrameControl2(davinci6446_sil9034 *priv,u8 enable)
static int sil9034_hdmiHdcpConfig(davinci6446_sil9034 *priv,u8 enable)
{ {
u8 reg_value ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; /* Generic packet transmittion & repeat mode enable */
/* HDMI HDCP configuration */ reg_value = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
if(enable) if(enable)
{ {
sil9034_write(priv,SLAVE0,DDC_ADDR,0x74) ; /* enable GCP_RPT , GCP_EN */
sil9034_write(priv,SLAVE0,DDC_CNT1_ADDR,0x1) ; sil9034_write(priv,SLAVE1,INF_CTRL2,(reg_value |(GCP_EN|GCP_RPT))) ;
sil9034_write(priv,SLAVE0,DDC_OFFSET_ADDR,0x40) ; }
sil9034_write(priv,SLAVE0,RI_CMD_ADDR,SET_RI_ENABLE) ; else
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,(reg_value | (SET_ENC_EN|SET_CP_RESTN|TX_ANSTOP_ENABLE))) ; {
sil9034_write(priv,SLAVE1,INF_CTRL2,reg_value & ~(GCP_EN|GCP_RPT)) ;
}
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
sil9034_dbg("InfoFrame control#2 register 0x%x = 0x%x\n",INF_CTRL2,reg_value) ;
return 0 ;
}
static int sil9034_hdmiHdcpConfig(davinci6446_sil9034 *priv,u8 enable)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/* HDMI HDCP configuration */
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
if(enable)
{
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,(reg_value | SET_ENC_EN)) ;
priv->auth_state = AUTH_NEED ;
} }
else else
{ {
sil9034_write(priv,SLAVE0,RI_CMD_ADDR,~SET_RI_ENABLE) ; sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,(reg_value & ~(SET_ENC_EN))) ;
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,(reg_value & ~((SET_ENC_EN)|RX_RPTR_ENABLE))) ; priv->auth_state = AUTH_DONE ;
} }
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ; reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
...@@ -664,360 +774,223 @@ static int sil9034_hdmiHdcpConfig(davinci6446_sil9034 *priv,u8 enable) ...@@ -664,360 +774,223 @@ static int sil9034_hdmiHdcpConfig(davinci6446_sil9034 *priv,u8 enable)
return 0 ; return 0 ;
} }
char sil9034_hotplugEvent(davinci6446_sil9034 *priv)
{
u8 reg_value ;
static int sil9034_480i_VideoInputConfig(davinci6446_sil9034 *priv) reg_value = sil9034_read(priv,SLAVE0,TX_STAT_ADDR) ;
if(reg_value&SET_HPD)
return 1 ;
else
return 0 ;
}
static int sil9034_checkHdcpDevice(davinci6446_sil9034 *priv)
{ {
/* Output Mode YcbCr 4:2:2 */ u8 total = 0 ;
u8 reg_value = 0 ; u8 bits = 0 ;
u8 count = 0 ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; /* read 5 byte from ddc */
sil9034_ddc_read(priv,&priv->an_ksv_data[0],DDC_BKSV_ADDR,5) ;
/* 480i YCbCr 4:2:2 Mux YC Separate Sync Input */ /* calculate bits */
/* Video DE control register : DE_DLY 3:0=0x0 for(count=0 ;count<5 ; count++)
* HS_POL 4 = 1 {
* VS_POL 5 = 1 sil9034_dbg("bksv %d,0x%x\n",count,priv->an_ksv_data[count]) ;
* DE_GEN 6 = 1 for(bits=0 ;bits<8 ; bits++)
* Note: DM320 input diverse, so change below: if(priv->an_ksv_data[count] & (1<<bits))
* HS_POL 4 = 0 total++ ;
* VS_POL 5 = 0 }
* DE_GEN 6 = 1
*/
sil9034_write(priv,SLAVE0,DE_CTRL_ADDR,0x30) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CTRL_ADDR) ;
sil9034_dbg("Video DE control register 0x%x = 0x%x\n",DE_CTRL_ADDR,reg_value) ;
/* Video DE delay register */
sil9034_write(priv,SLAVE0,DE_DELAY_ADDR,0x77) ;
reg_value = sil9034_read(priv,SLAVE0,DE_DELAY_ADDR) ;
sil9034_dbg("Video DE delay register 0x%x = 0x%x\n",DE_DELAY_ADDR,reg_value) ;
/* Video DE top register, DE_TOP 6:0=0x12*/
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_write(priv,SLAVE0,DE_TOP_ADDR,reg_value|0x12) ;
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_dbg("Video DE top register 0x%x = 0x%x\n",DE_TOP_ADDR,reg_value) ;
/* Video DE cnt high byte register, DE_CNT 3:0=0x2*/
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_write(priv,SLAVE0,DE_CNTH_ADDR,(reg_value | 0x2)) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_dbg("Video DE cnt high register 0x%x = 0x%x\n",DE_CNTH_ADDR,reg_value) ;
/* Video DE cnt low byte register, DE_CNT 7:0=0xD0*/
sil9034_write(priv,SLAVE0,DE_CNTL_ADDR,0xD0) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTL_ADDR) ;
sil9034_dbg("Video DE cnt low register 0x%x = 0x%x\n",DE_CNTL_ADDR,reg_value) ;
/* Video DE line high byte register, DE_LIN 2:0=0x0*/
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_write(priv,SLAVE0,DEL_H_ADDR,(reg_value & ~(0x7))) ;
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_H_ADDR,reg_value) ;
/* Video DE line low byte register, DE_LIN 7:0=0xF0*/ if(total == HDCP_ACC)
sil9034_write(priv,SLAVE0,DEL_L_ADDR,0xF0) ; return TRUE ;
reg_value = sil9034_read(priv,SLAVE0,DEL_L_ADDR) ; else
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_L_ADDR,reg_value) ; return FALSE ;
}
/* Video control register , ICLK = 00 EXTN = 1*/ static int sil9034_toggleRepeatBit(davinci6446_sil9034 *priv)
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ; {
sil9034_write(priv,SLAVE0,TX_VID_CTRL_ADDR,(reg_value|0x20)) ; u8 reg_value ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ;
sil9034_dbg("Video control register 0x%x = 0x%x\n",TX_VID_CTRL_ADDR,reg_value) ;
/* Video mode register , SYNCEXT=0 DEMUX=1 UPSMP=0 CSC=0 DITHER = 0*/ sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
sil9034_write(priv,SLAVE0,TX_VID_MODE_ADDR,0x2) ; reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_MODE_ADDR) ; if(reg_value & RX_RPTR_ENABLE)
sil9034_dbg("Video mode register 0x%x = 0x%x\n",TX_VID_MODE_ADDR,reg_value) ; sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,reg_value&~RX_RPTR_ENABLE) ;
else
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,reg_value|RX_RPTR_ENABLE) ;
return 0 ; return 0 ;
} }
static int sil9034_720p_VideoInputConfig(davinci6446_sil9034 *priv) static int sil9034_releaseCPReset(davinci6446_sil9034 *priv)
{ {
/* Output Mode YcbCr 4:2:2 */ u8 reg_value ;
u8 reg_value = 0 ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CTRL_ADDR) ; sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,reg_value|SET_CP_RESTN) ;
sil9034_write(priv,SLAVE0,DE_CTRL_ADDR,(reg_value|(DE_GEN_ENABLE|0x1))) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CTRL_ADDR) ;
sil9034_dbg("Video DE control register 0x%x = 0x%x\n",DE_CTRL_ADDR,reg_value) ;
/* Video DE delay register */
sil9034_write(priv,SLAVE0,DE_DELAY_ADDR,0x04) ;
reg_value = sil9034_read(priv,SLAVE0,DE_DELAY_ADDR) ;
sil9034_dbg("Video DE delay register 0x%x = 0x%x\n",DE_DELAY_ADDR,reg_value) ;
/* Video DE top register */
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_write(priv,SLAVE0,DE_TOP_ADDR,reg_value|0x19) ;
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_dbg("Video DE top register 0x%x = 0x%x\n",DE_TOP_ADDR,reg_value) ;
/* Video DE cnt high byte register */
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_write(priv,SLAVE0,DE_CNTH_ADDR,(reg_value | 0x5)) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_dbg("Video DE cnt high register 0x%x = 0x%x\n",DE_CNTH_ADDR,reg_value) ;
/* Video DE cnt low byte register */
sil9034_write(priv,SLAVE0,DE_CNTL_ADDR,0x00) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTL_ADDR) ;
sil9034_dbg("Video DE cnt low register 0x%x = 0x%x\n",DE_CNTL_ADDR,reg_value) ;
/* Video DE line high byte register */
sil9034_write(priv,SLAVE0,DEL_H_ADDR,0x2) ;
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_H_ADDR,reg_value) ;
/* Video DE line low byte register */
sil9034_write(priv,SLAVE0,DEL_L_ADDR,0xD0) ;
reg_value = sil9034_read(priv,SLAVE0,DEL_L_ADDR) ;
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_L_ADDR,reg_value) ;
/* Video control register , ICLK = 00 EXTN = 1*/
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ;
sil9034_write(priv,SLAVE0,TX_VID_CTRL_ADDR,(reg_value|(CSCSEL_BT709|SET_EXTN_12BIT))) ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ;
sil9034_dbg("Video control register 0x%x = 0x%x\n",TX_VID_CTRL_ADDR,reg_value) ;
/* Video mode register , SYNCEXT=0 DEMUX=0 UPSMP=1 CSC=1 DITHER = 0*/
sil9034_write(priv,SLAVE0,TX_VID_MODE_ADDR,(UPSMP_ENABLE|CSC_ENABLE)) ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_MODE_ADDR) ;
sil9034_dbg("Video mode register 0x%x = 0x%x\n",TX_VID_MODE_ADDR,reg_value) ;
return 0 ; return 0 ;
} }
static int sil9034_1080i_VideoInputConfig(davinci6446_sil9034 *priv) static int sil9034_StopRepeatBit(davinci6446_sil9034 *priv)
{ {
/* Output Mode YcbCr 4:2:2 */ u8 reg_value ;
u8 reg_value = 0 ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,reg_value&~RX_RPTR_ENABLE) ;
return 0 ;
}
reg_value = sil9034_read(priv,SLAVE0,DE_CTRL_ADDR) ; static int sil9034_writeAnHdcpRx(davinci6446_sil9034 *priv)
sil9034_write(priv,SLAVE0,DE_CTRL_ADDR,(reg_value|DE_GEN_ENABLE)) ; {
reg_value = sil9034_read(priv,SLAVE0,DE_CTRL_ADDR) ; /* write 8 byte to ddc hdcp rx*/
sil9034_dbg("Video DE control register 0x%x = 0x%x\n",DE_CTRL_ADDR,reg_value) ; sil9034_ddc_write(priv,&priv->an_ksv_data[0],DDC_AN_ADDR,8) ;
/* Video DE delay register */
sil9034_write(priv,SLAVE0,DE_DELAY_ADDR,0xC0) ;
reg_value = sil9034_read(priv,SLAVE0,DE_DELAY_ADDR) ;
sil9034_dbg("Video DE delay register 0x%x = 0x%x\n",DE_DELAY_ADDR,reg_value) ;
/* Video DE top register */
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_write(priv,SLAVE0,DE_TOP_ADDR,reg_value|0x14) ;
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_dbg("Video DE top register 0x%x = 0x%x\n",DE_TOP_ADDR,reg_value) ;
/* Video DE cnt high byte register */
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_write(priv,SLAVE0,DE_CNTH_ADDR,(reg_value | 0x7)) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_dbg("Video DE cnt high register 0x%x = 0x%x\n",DE_CNTH_ADDR,reg_value) ;
/* Video DE cnt low byte register */
sil9034_write(priv,SLAVE0,DE_CNTL_ADDR,0x80) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTL_ADDR) ;
sil9034_dbg("Video DE cnt low register 0x%x = 0x%x\n",DE_CNTL_ADDR,reg_value) ;
/* Video DE line high byte register */
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_write(priv,SLAVE0,DEL_H_ADDR,(reg_value)|0x2) ;
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_H_ADDR,reg_value) ;
/* Video DE line low byte register */ return 0 ;
sil9034_write(priv,SLAVE0,DEL_L_ADDR,0x1C) ; }
reg_value = sil9034_read(priv,SLAVE0,DEL_L_ADDR) ; static int sil9034_writeBksvHdcpTx(davinci6446_sil9034 *priv)
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_L_ADDR,reg_value) ; {
u8 count = 0 ;
/* Video control register , ICLK = 00 EXTN = 1*/ sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ;
sil9034_write(priv,SLAVE0,TX_VID_CTRL_ADDR,(reg_value|SET_EXTN_12BIT)) ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ;
sil9034_dbg("Video control register 0x%x = 0x%x\n",TX_VID_CTRL_ADDR,reg_value) ;
/* Video mode register , SYNCEXT=0 DEMUX=0 UPSMP=1 CSC=1 DITHER = 0*/ for(count=0; count<5; count++)
sil9034_write(priv,SLAVE0,TX_VID_MODE_ADDR,(UPSMP_ENABLE|CSC_ENABLE)) ; {
reg_value = sil9034_read(priv,SLAVE0,TX_VID_MODE_ADDR) ; sil9034_write(priv,SLAVE0,HDCP_BKSV1_ADDR+count,priv->an_ksv_data[count]) ;
sil9034_dbg("Video mode register 0x%x = 0x%x\n",TX_VID_MODE_ADDR,reg_value) ; sil9034_dbg("write bksv to tx 0x%x\n",priv->an_ksv_data[count]) ;
}
return 0 ; return 0 ;
} }
static int sil9034_Auto_VideoInputConfig(davinci6446_sil9034 *priv) static int sil9034_readBksvHdcpRx(davinci6446_sil9034 *priv)
{ {
u8 reg_value = 0 ;
u8 count = 0 ; u8 count = 0 ;
/* Auto setting by the bus_mapping_sil9034 struct */ sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
for(count=0 ;count<(priv->sil9034_setting_num) ;count++)
/* read 5 byte from ddc */
sil9034_ddc_read(priv,&priv->an_ksv_data[0],DDC_BKSV_ADDR,5) ;
for(count=0; count<5; count++)
{ {
reg_value = sil9034_read(priv,SLAVE0,\ sil9034_dbg("bksv data %d 0x%x\n",count,priv->an_ksv_data[count]) ;
priv->sil9034_setting[count].bus_reg) ;
sil9034_write(priv,SLAVE0,priv->sil9034_setting[count].bus_reg,\
(reg_value|priv->sil9034_setting[count].value)) ;
reg_value = sil9034_read(priv,SLAVE0,\
priv->sil9034_setting[count].bus_reg) ;
sil9034_dbg("bus mapping regster 0x%x = 0x%x\n",\
priv->sil9034_setting[count].bus_reg,reg_value) ;
} }
return 0 ; return 0 ;
} }
static int sil9034_480p_VideoInputConfig(davinci6446_sil9034 *priv) static int sil9034_writeAksvHdcpRx(davinci6446_sil9034 *priv)
{ {
/* Output Mode YcbCr 4:2:2 */ sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
u8 reg_value = 0 ; /* write 5 byte to ddc hdcp rx*/
sil9034_ddc_write(priv,&priv->an_ksv_data[0],DDC_AKSV_ADDR,5) ;
sil9034_write(priv,SLAVE0,DE_CTRL_ADDR,0x70) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CTRL_ADDR) ;
sil9034_dbg("Video DE control register 0x%x = 0x%x\n",DE_CTRL_ADDR,reg_value) ;
/* Video DE delay register */
sil9034_write(priv,SLAVE0,DE_DELAY_ADDR,0x7A) ;
reg_value = sil9034_read(priv,SLAVE0,DE_DELAY_ADDR) ;
sil9034_dbg("Video DE delay register 0x%x = 0x%x\n",DE_DELAY_ADDR,reg_value) ;
/* Video DE top register */
sil9034_write(priv,SLAVE0,DE_TOP_ADDR,0x24) ;
reg_value = sil9034_read(priv,SLAVE0,DE_TOP_ADDR) ;
sil9034_dbg("Video DE top register 0x%x = 0x%x\n",DE_TOP_ADDR,reg_value) ;
/* Video DE cnt high byte register */
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_write(priv,SLAVE0,DE_CNTH_ADDR,(reg_value|0x2)) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTH_ADDR) ;
sil9034_dbg("Video DE cnt high register 0x%x = 0x%x\n",DE_CNTH_ADDR,reg_value) ;
/* Video DE cnt low byte register */
sil9034_write(priv,SLAVE0,DE_CNTL_ADDR,0xD0) ;
reg_value = sil9034_read(priv,SLAVE0,DE_CNTL_ADDR) ;
sil9034_dbg("Video DE cnt low register 0x%x = 0x%x\n",DE_CNTL_ADDR,reg_value) ;
/* Video DE line high byte register */
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_write(priv,SLAVE0,DEL_H_ADDR,(reg_value|0x1)) ;
reg_value = sil9034_read(priv,SLAVE0,DEL_H_ADDR) ;
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_H_ADDR,reg_value) ;
/* Video DE line low byte register */ return 0 ;
sil9034_write(priv,SLAVE0,DEL_L_ADDR,0xE0) ; }
reg_value = sil9034_read(priv,SLAVE0,DEL_L_ADDR) ;
sil9034_dbg("Video DE line high register 0x%x = 0x%x\n",DEL_L_ADDR,reg_value) ;
/* Video control register , ICLK = 00 EXTN = 1*/ static int sil9034_readAksvHdcpTx(davinci6446_sil9034 *priv)
sil9034_write(priv,SLAVE0,TX_VID_CTRL_ADDR,0x20) ; {
reg_value = sil9034_read(priv,SLAVE0,TX_VID_CTRL_ADDR) ; u8 count = 0 ;
sil9034_dbg("Video control register 0x%x = 0x%x\n",TX_VID_CTRL_ADDR,reg_value) ;
/* Video mode register , SYNCEXT=0 DEMUX=0 UPSMP=0 CSC=0 DITHER = 0*/ sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
sil9034_write(priv,SLAVE0,TX_VID_MODE_ADDR,0x0) ;
reg_value = sil9034_read(priv,SLAVE0,TX_VID_MODE_ADDR) ; for(count=0; count<5; count++)
sil9034_dbg("Video mode register 0x%x = 0x%x\n",TX_VID_MODE_ADDR,reg_value) ; {
priv->an_ksv_data[count] = sil9034_read(priv,SLAVE0,HDCP_AKSV1_ADDR+count) ;
sil9034_dbg("aksv data %d 0x%x\n",count,priv->an_ksv_data[count]) ;
}
return 0 ; return 0 ;
} }
int sil9034_dumpHdcpRiStatus(davinci6446_sil9034 *priv) static int sil9034_readAnHdcpTx(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 count = 0 ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
printk(KERN_INFO "Hdcp register is %x,%s\n",reg_value,(reg_value&SET_ENC_EN)?"Enable":"Disable") ; for(count=0; count<8; count++)
reg_value = sil9034_read(priv,SLAVE0,HDCP_RI1) ; {
printk(KERN_INFO "Hdcp ri 1 status register 0x%x = 0x%x\n",HDCP_RI1,reg_value) ; priv->an_ksv_data[count] = sil9034_read(priv,SLAVE0,HDCP_AN1_ADDR+count) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_RI2) ; sil9034_dbg("an data %d 0x%x\n",count,priv->an_ksv_data[count]) ;
printk(KERN_INFO "Hdcp ri 2 status register 0x%x = 0x%x\n",HDCP_RI2,reg_value) ; }
reg_value = sil9034_read(priv,SLAVE0,HDCP_RI128_COMP) ;
printk(KERN_INFO "Hdcp ri 128 status register 0x%x = 0x%x\n",HDCP_RI128_COMP,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_CMD_ADDR) ;
printk(KERN_INFO "ri cmd status register 0x%x = 0x%x\n",RI_CMD_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,DDC_MAN_ADDR) ;
printk(KERN_INFO "ddc man status register 0x%x = 0x%x\n",DDC_MAN_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_STAT_ADDR) ;
printk(KERN_INFO "ri start status register 0x%x = 0x%x\n",RI_STAT_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_RX_L_ADDR) ;
printk(KERN_INFO "ri rx low status register 0x%x = 0x%x\n",RI_RX_L_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_RX_H_ADDR) ;
printk(KERN_INFO "ri rx hight status register 0x%x = 0x%x\n",RI_RX_H_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,DDC_ADDR) ;
printk(KERN_INFO "ddc status register 0x%x = 0x%x\n",DDC_ADDR,reg_value) ;
return 0 ; return 0 ;
} }
int sil9034_dumpSystemStatus(davinci6446_sil9034 *priv) static int sil9034_generateAn(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,TX_STAT_ADDR) ;
printk(KERN_INFO "System status register 0x%x = 0x%x\n",TX_STAT_ADDR,reg_value) ; reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,reg_value&~TX_ANSTOP) ;
mdelay(10) ;
sil9034_write(priv,SLAVE0,HDCP_CTRL_ADDR,reg_value|TX_ANSTOP) ;
return 0 ; return 0 ;
} }
static int sil9034_isRepeater(davinci6446_sil9034 *priv)
int sil9034_dumpDataCtrlStatus(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,DCTL_ADDR) ; /* read 1 byte from ddc */
printk(KERN_INFO "Data control register 0x%x = 0x%x\n",DCTL_ADDR,reg_value) ; sil9034_ddc_read(priv,&reg_value,DDC_BCAPS_ADDR,1) ;
return 0 ; if(reg_value&DDC_BIT_REPEATER)
} return TRUE ;
int sil9034_unmaskInterruptStatus(davinci6446_sil9034 *priv) return FALSE ;
}
static int sil9034_compareR0(davinci6446_sil9034 *priv)
{ {
u8 reg_value = 0xFF ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
sil9034_write(priv,SLAVE0,HDMI_INT1_MASK,reg_value) ;
sil9034_write(priv,SLAVE0,HDMI_INT2_MASK,reg_value) ;
sil9034_write(priv,SLAVE0,HDMI_INT3_MASK,reg_value) ;
return 0 ; /* read 2 byte from ddc */
sil9034_ddc_read(priv,&priv->r0rx[0],DDC_RI_ADDR,2) ;
priv->r0tx[0] = sil9034_read(priv,SLAVE0,HDCP_RI1) ;
priv->r0tx[1] = sil9034_read(priv,SLAVE0,HDCP_RI2) ;
if((priv->r0rx[0]==priv->r0tx[0])&&(priv->r0rx[1]==priv->r0tx[1]))
{
printk(KERN_INFO "HDCP handshake complete match.\n") ;
return TRUE ;
}
return FALSE ;
} }
int sil9034_clearInterruptStatus(davinci6446_sil9034 *priv) static int sil9034_autoRiCheck(davinci6446_sil9034 *priv,u8 enable)
{ {
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/*
u8 reg_value ; u8 reg_value ;
reg_value = sil9034_read(priv,SLAVE0,INT_CNTRL_ADDR) ; reg_value = sil9034_read(priv,SLAVE0,RI_CMD_ADDR) ;
sil9034_write(priv,SLAVE0,INT_CNTRL_ADDR,reg_value) ; if(enable)
reg_value = sil9034_read(priv,SLAVE0,INT_CNTRL_ADDR) ; sil9034_write(priv,SLAVE0,RI_CMD_ADDR, reg_value|SET_RI_ENABLE);
sil9034_dbg("Interrupt control register 0x%x = 0x%x\n",INT_CNTRL_ADDR,reg_value) ; else
*/ sil9034_write(priv,SLAVE0,RI_CMD_ADDR, reg_value&~SET_RI_ENABLE);
return 0 ;
}
sil9034_write(priv,SLAVE0,INT_SOURCE1_ADDR,0xFF) ; int sil9034_dumpSystemStatus(davinci6446_sil9034 *priv)
sil9034_write(priv,SLAVE0,INT_SOURCE2_ADDR,0xFF) ; {
sil9034_write(priv,SLAVE0,INT_SOURCE3_ADDR,0xFF) ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,TX_STAT_ADDR) ;
printk(KERN_INFO "System status register 0x%x = 0x%x\n",TX_STAT_ADDR,reg_value) ;
return 0 ; return 0 ;
} }
int sil9034_dumpInterruptSourceStatus(davinci6446_sil9034 *priv) int sil9034_dumpDataCtrlStatus(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ; sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,INT_SOURCE1_ADDR) ; reg_value = sil9034_read(priv,SLAVE0,DCTL_ADDR) ;
printk(KERN_INFO "Interrupt source 1 register 0x%x = 0x%x\n",INT_SOURCE1_ADDR,reg_value) ; printk(KERN_INFO "Data control register 0x%x = 0x%x\n",DCTL_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,INT_SOURCE2_ADDR) ;
printk(KERN_INFO "Interrupt source 2 register 0x%x = 0x%x\n",INT_SOURCE2_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,INT_SOURCE3_ADDR) ;
printk(KERN_INFO "Interrupt source 3 register 0x%x = 0x%x\n",INT_SOURCE3_ADDR,reg_value) ;
/* Interrupt register will auto clean after read ?*/
sil9034_clearInterruptStatus(priv) ;
return 0 ; return 0 ;
} }
...@@ -1079,7 +1052,41 @@ int sil9034_dumpVideoConfigureStatus(davinci6446_sil9034 *priv) ...@@ -1079,7 +1052,41 @@ int sil9034_dumpVideoConfigureStatus(davinci6446_sil9034 *priv)
return 0 ; return 0 ;
} }
int sil9034_clearInterruptStatus(davinci6446_sil9034 *priv)
{
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
/*
u8 reg_value ;
reg_value = sil9034_read(priv,SLAVE0,INT_CNTRL_ADDR) ;
sil9034_write(priv,SLAVE0,INT_CNTRL_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,INT_CNTRL_ADDR) ;
sil9034_dbg("Interrupt control register 0x%x = 0x%x\n",INT_CNTRL_ADDR,reg_value) ;
*/
sil9034_write(priv,SLAVE0,INT_SOURCE1_ADDR,0xFF) ;
sil9034_write(priv,SLAVE0,INT_SOURCE2_ADDR,0xFF) ;
sil9034_write(priv,SLAVE0,INT_SOURCE3_ADDR,0xFF) ;
return 0 ;
}
int sil9034_dumpInterruptSourceStatus(davinci6446_sil9034 *priv)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,INT_SOURCE1_ADDR) ;
printk(KERN_INFO "Interrupt source 1 register 0x%x = 0x%x\n",INT_SOURCE1_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,INT_SOURCE2_ADDR) ;
printk(KERN_INFO "Interrupt source 2 register 0x%x = 0x%x\n",INT_SOURCE2_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,INT_SOURCE3_ADDR) ;
printk(KERN_INFO "Interrupt source 3 register 0x%x = 0x%x\n",INT_SOURCE3_ADDR,reg_value) ;
/* Interrupt register will auto clean after read ?*/
sil9034_clearInterruptStatus(priv) ;
return 0 ;
}
int sil9034_dumpInterruptStateStatus(davinci6446_sil9034 *priv) int sil9034_dumpInterruptStateStatus(davinci6446_sil9034 *priv)
{ {
u8 reg_value ; u8 reg_value ;
...@@ -1094,6 +1101,88 @@ int sil9034_dumpInterruptStateStatus(davinci6446_sil9034 *priv) ...@@ -1094,6 +1101,88 @@ int sil9034_dumpInterruptStateStatus(davinci6446_sil9034 *priv)
return 0 ; return 0 ;
} }
int sil9034_dumpHdcpRiStatus(davinci6446_sil9034 *priv)
{
u8 reg_value ;
sil9034_dbg("----------%s----------\n",__FUNCTION__) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_CTRL_ADDR) ;
printk(KERN_INFO "Hdcp register is %x,%s\n",reg_value,(reg_value&SET_ENC_EN)?"Enable":"Disable") ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_RI1) ;
printk(KERN_INFO "Hdcp ri 1 status register 0x%x = 0x%x\n",HDCP_RI1,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_RI2) ;
printk(KERN_INFO "Hdcp ri 2 status register 0x%x = 0x%x\n",HDCP_RI2,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,HDCP_RI128_COMP) ;
printk(KERN_INFO "Hdcp ri 128 status register 0x%x = 0x%x\n",HDCP_RI128_COMP,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_CMD_ADDR) ;
printk(KERN_INFO "ri cmd status register 0x%x = 0x%x\n",RI_CMD_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,DDC_MAN_ADDR) ;
printk(KERN_INFO "ddc man status register 0x%x = 0x%x\n",DDC_MAN_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_STAT_ADDR) ;
printk(KERN_INFO "ri start status register 0x%x = 0x%x\n",RI_STAT_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_RX_L_ADDR) ;
printk(KERN_INFO "ri rx low status register 0x%x = 0x%x\n",RI_RX_L_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,RI_RX_H_ADDR) ;
printk(KERN_INFO "ri rx hight status register 0x%x = 0x%x\n",RI_RX_H_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE0,DDC_ADDR) ;
printk(KERN_INFO "ddc status register 0x%x = 0x%x\n",DDC_ADDR,reg_value) ;
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL2) ;
printk(KERN_INFO "InfoFrame ctrl2 register 0x%x = 0x%x\n",INF_CTRL2,reg_value) ;
reg_value = sil9034_read(priv,SLAVE1,INF_CTRL1) ;
printk(KERN_INFO "InfoFrame ctrl1 register 0x%x = 0x%x\n",INF_CTRL1,reg_value) ;
return 0 ;
}
int sil9034_hdcpAuthentication(davinci6446_sil9034 *priv)
{
sil9034_autoRiCheck(priv,DISABLE) ;
if(sil9034_hotplugEvent(priv))
{
sil9034_sentCPPackage(priv,ENABLE) ;
if(sil9034_checkHdcpDevice(priv) == TRUE)
{
sil9034_dbg("got 20's 1\n") ;
/* Random key */
sil9034_toggleRepeatBit(priv) ;
sil9034_releaseCPReset(priv) ;
sil9034_StopRepeatBit(priv) ;
sil9034_generateAn(priv) ;
/* Handshake start */
sil9034_readAnHdcpTx(priv) ;
sil9034_writeAnHdcpRx(priv) ;
sil9034_readAksvHdcpTx(priv) ;
sil9034_writeAksvHdcpRx(priv) ;
sil9034_readBksvHdcpRx(priv) ;
sil9034_writeBksvHdcpTx(priv) ;
if(sil9034_isRepeater(priv)==TRUE)
printk(KERN_ERR "This is repeater,not support.\n") ;
/* Finally, compare key */
mdelay(100) ; //delay for R0 calculation
if(sil9034_compareR0(priv)==FALSE)
{
priv->auth_state = REAUTH_NEED ;
}
else
{
/* unmute */
sil9034_sentCPPackage(priv,DISABLE) ;
sil9034_autoRiCheck(priv,ENABLE) ;
priv->auth_state = AUTH_DONE ;
}
}
else // no 20 ones and zeros
{
/* mute */
sil9034_sentCPPackage(priv,ENABLE) ;
printk(KERN_ERR "TV not send 20's 1,retry!!\n") ;
}
}
return 0 ;
}
/* HDCP key exchange for hdmi */ /* HDCP key exchange for hdmi */
static void sil9034_timer(unsigned long data) static void sil9034_timer(unsigned long data)
{ {
...@@ -1105,6 +1194,7 @@ static void sil9034_timer(unsigned long data) ...@@ -1105,6 +1194,7 @@ static void sil9034_timer(unsigned long data)
if(priv) if(priv)
{ {
#if SIL9034_SCHED #if SIL9034_SCHED
priv->work_flag = EVENT_NOTIFY ;
status = schedule_work(&priv->work); status = schedule_work(&priv->work);
if(!status) if(!status)
printk(KERN_ERR "scheduling work error\n") ; printk(KERN_ERR "scheduling work error\n") ;
...@@ -1114,19 +1204,28 @@ static void sil9034_timer(unsigned long data) ...@@ -1114,19 +1204,28 @@ static void sil9034_timer(unsigned long data)
} }
return ; return ;
} }
#if SIL9034_SCHED #if SIL9034_SCHED
static void sil9034_sched(void *data) static void sil9034_sched(void *data)
{ {
/* This is important, get out of the interrupt context switch trouble */ /* This is important, get out of the interrupt context switch trouble */
davinci6446_sil9034 *priv = container_of(data, davinci6446_sil9034, work); davinci6446_sil9034 *priv = container_of(data, davinci6446_sil9034, work);
u8 intr1_isr ;
u8 intr3_isr ;
switch(priv->work_flag) switch(priv->work_flag)
{ {
case SWITCH_480P: case SWITCH_480P:
priv->sil9034_setting = sil9034_480p_setting ;
priv->work_flag = VIDEO_CHANGE ;
break ; break ;
case SWITCH_720P: case SWITCH_720P:
priv->sil9034_setting = sil9034_720p_setting ;
priv->work_flag = VIDEO_CHANGE ;
break ; break ;
case SWITCH_1080I: case SWITCH_1080I:
priv->sil9034_setting = sil9034_1080i_setting ;
priv->work_flag = VIDEO_CHANGE ;
break ; break ;
case HDCP_ENABLE: case HDCP_ENABLE:
sil9034_hdmiHdcpConfig(priv,ENABLE) ; sil9034_hdmiHdcpConfig(priv,ENABLE) ;
...@@ -1142,22 +1241,49 @@ static void sil9034_sched(void *data) ...@@ -1142,22 +1241,49 @@ static void sil9034_sched(void *data)
break ; break ;
case HDCP_RI_STATUS: case HDCP_RI_STATUS:
sil9034_dumpHdcpRiStatus(priv) ; sil9034_dumpHdcpRiStatus(priv) ;
break ;
case EVENT_NOTIFY:
intr3_isr = sil9034_read(priv,SLAVE0,INT_SOURCE3_ADDR) ;
intr1_isr = sil9034_read(priv,SLAVE0,INT_SOURCE1_ADDR) ;
/* ri frame error occur */
if(intr3_isr & (INTR3_STAT7|INTR3_STAT5|INTR3_STAT4))
{
printk(KERN_INFO "Ri frame error 0x%x\n",intr3_isr) ;
priv->auth_state = REAUTH_NEED ;
}
/* line plug */
if(intr1_isr & (INTR1_HPD|INTR1_RSEN))
{
printk(KERN_INFO "line plug 0x%x\n",intr1_isr) ;
priv->auth_state = REAUTH_NEED ;
}
break ; break ;
default: default:
break ; break ;
} }
/* Check if video setting change */
if((priv->work_flag==VIDEO_CHANGE))
sil9034_videoInputConfig(priv) ;
/* Check if hdcp authentication need */
if((priv->auth_state == AUTH_NEED) || (priv->auth_state == REAUTH_NEED))
{
sil9034_hdcpAuthentication(priv) ;
}
/* clean the work flag */ /* clean the work flag */
priv->work_flag = DO_NOTHING ; priv->work_flag = DO_NOTHING ;
#if SIL9034_TIMER #if SIL9034_TIMER
mod_timer(&ds.timer, jiffies + TIMER_JIFFIES); mod_timer(&ds.timer, jiffies + TIMER_JIFFIES);
#endif #endif
sil9034_clearInterruptStatus(priv) ;
return ; return ;
} }
#endif #endif
static int __init sil9034_init(void) static int __init sil9034_init(void)
{ {
int status = 0 ; int status = 0 ;
...@@ -1170,57 +1296,73 @@ static int __init sil9034_init(void) ...@@ -1170,57 +1296,73 @@ static int __init sil9034_init(void)
goto out; goto out;
} }
/* Initial */ /* Initial default as 720p */
ds.work_flag = DO_NOTHING ; ds.sil9034_setting = sil9034_720p_setting ;
/* read chip id & revision */ /* read chip id & revision */
sil9034_chipInfo(&ds) ; sil9034_chipInfo(&ds) ;
/* power down occilator */ /* power down occilator */
sil9034_powerDown(&ds,ENABLE) ; sil9034_powerDown(&ds,ENABLE) ;
/* Tune the video input table according to DM320 hardware spec */ /* TMDS control register */
sil9034_720p_VideoInputConfig(&ds) ; sil9034_hdmiTmdsConfig(&ds) ;
/* Tune the audio input table according to DM320 hardware spec */ /* Tune the audio input table according to DM320 hardware spec */
sil9034_audioInputConfig(&ds) ;
/* read flag from env and tune the video input table
* according to DM320 hardware spec */
sil9034_videoInputConfig(&ds) ;
/* software reset */
sil9034_swReset(&ds) ;
/* Trigger ROM */
sil9034_triggerRom(&ds) ;
/* Audio Info Frame control setting */
sil9034_audioInfoFrameSetting(&ds) ;
sil9034_audioInputConfig(&ds) ; sil9034_audioInputConfig(&ds) ;
/* software reset */ /* software reset */
sil9034_swReset(&ds) ; sil9034_swReset(&ds) ;
/* CEA-861 Info Frame control setting */
sil9034_cea861InfoFrameSetting(&ds) ;
/* Wake up HDMI TX */
sil9034_wakeupHdmiTx(&ds) ;
/* power up occilator */ /* Sent CP package */
sil9034_powerDown(&ds,DISABLE) ; sil9034_sentCPPackage(&ds,ENABLE) ;
/* unmask the interrupt status */ /* unmask the interrupt status */
sil9034_unmaskInterruptStatus(&ds) ; sil9034_unmaskInterruptStatus(&ds) ;
/* Hdmi output setting */ /* Hdmi output setting */
sil9034_hdmiOutputConfig(&ds) ; sil9034_hdmiOutputConfig(&ds) ;
/* TMDS control register */
sil9034_hdmiTmdsConfig(&ds) ;
/* ddc master config */ /* ddc master config */
sil9034_ddcSetting(&ds) ; sil9034_ddcSetting(&ds) ;
/* HDCP control handshaking */
sil9034_hdmiHdcpConfig(&ds,DISABLE) ;
/* General control packet */ /* General control packet */
sil9034_generalControlPacket(&ds,DISABLE) ; sil9034_sentCPPackage(&ds,DISABLE) ;
/* enable the avi repeat transmission */ sil9034_cea861InfoFrameControl2(&ds,ENABLE) ;
sil9034_cea861InfoFrameControl1(&ds,ENABLE) ;
//sil9034_cea861InfoFrameControl2(&ds,ENABLE) ;
/* CEA-861 Info Frame control setting */ /* HDCP control handshaking */
sil9034_cea861InfoFrameSetting(&ds) ; sil9034_hdmiHdcpConfig(&ds,ENABLE) ;
/* Audio Info Frame control setting */ /* Disable Auto RI check here, enable it until hdcp complete. */
sil9034_audioInfoFrameSetting(&ds) ; sil9034_autoRiCheck(&ds,DISABLE) ;
sil9034_clearInterruptStatus(&ds) ;
#if SIL9034_SCHED #if SIL9034_SCHED
INIT_WORK(&ds.work, sil9034_sched); INIT_WORK(&ds.work, sil9034_sched);
ds.work_flag = EVENT_NOTIFY ;
schedule_work(&ds.work);
#endif #endif
#if SIL9034_TIMER #if SIL9034_TIMER
......
...@@ -54,8 +54,25 @@ ...@@ -54,8 +54,25 @@
/* System contorl register */ /* System contorl register */
#define TX_SYS_CTRL4_ADDR (0x0C) #define TX_SYS_CTRL4_ADDR (0x0C)
/* BKSV register : 5 bytes, Read only (RO), receiver KSV */
#define DDC_BKSV_ADDR (0x00)
/* AN register : 8 bytes, write only (WO) */
#define DDC_AN_ADDR (0x18)
/* AKSV register : 5 bytes, write only (WO) */
#define DDC_AKSV_ADDR (0x10)
/* RI register : 2 bytes, read only (R0) ,Ack from receiver R) */
#define DDC_RI_ADDR (0x08)
/* DDC fifo register : 1 bytes */
#define DDC_BCAPS_ADDR (0x40)
/* HDCP control register */ /* HDCP control register */
#define HDCP_CTRL_ADDR (0x0F) #define HDCP_CTRL_ADDR (0x0F)
#define HDCP_RX_SLAVE (0x74)
/* Data control register */ /* Data control register */
#define DCTL_ADDR (0x0D) #define DCTL_ADDR (0x0D)
...@@ -72,6 +89,16 @@ ...@@ -72,6 +89,16 @@
#define HDCP_BKSV4_ADDR (0x13) #define HDCP_BKSV4_ADDR (0x13)
#define HDCP_BKSV5_ADDR (0x14) #define HDCP_BKSV5_ADDR (0x14)
/* Hdcp AN register */
#define HDCP_AN1_ADDR (0x15)
#define HDCP_AN2_ADDR (0x16)
#define HDCP_AN3_ADDR (0x17)
#define HDCP_AN4_ADDR (0x18)
#define HDCP_AN5_ADDR (0x19)
#define HDCP_AN6_ADDR (0x1A)
#define HDCP_AN7_ADDR (0x1B)
#define HDCP_AN8_ADDR (0x1C)
/* Hdcp AKSV register */ /* Hdcp AKSV register */
#define HDCP_AKSV1_ADDR (0x1D) #define HDCP_AKSV1_ADDR (0x1D)
#define HDCP_AKSV2_ADDR (0x1E) #define HDCP_AKSV2_ADDR (0x1E)
...@@ -79,6 +106,31 @@ ...@@ -79,6 +106,31 @@
#define HDCP_AKSV4_ADDR (0x20) #define HDCP_AKSV4_ADDR (0x20)
#define HDCP_AKSV5_ADDR (0x21) #define HDCP_AKSV5_ADDR (0x21)
/* Rom command */
#define KEY_COMMAND_ADDR (0xFA)
/* Hdcp master command */
#define MASTER_CMD_ABORT (0x0f) // Command Codes
#define MASTER_CMD_CLEAR_FIFO (0x09)
#define MASTER_CMD_CLOCK (0x0a)
#define MASTER_CMD_CUR_RD (0x00)
#define MASTER_CMD_SEQ_RD (0x02)
#define MASTER_CMD_ENH_RD (0x04)
#define MASTER_CMD_SEQ_WR (0x06)
#define MASTER_FIFO_WR_USE (0x01)
#define MASTER_FIFO_RD_USE (0x02)
#define MASTER_FIFO_EMPTY (0x04)
#define MASTER_FIFO_FULL (0x08)
#define MASTER_DDC_BUSY (0x10)
#define MASTER_DDC_NOACK (0x20)
#define MASTER_DDC_STUCK (0x40)
#define MASTER_DDC_RSVD (0x80)
#define BIT_MDDC_ST_IN_PROGR (0x10)
#define BIT_MDDC_ST_I2C_LOW (0x40)
#define BIT_MDDC_ST_NO_ACK (0x20)
/* Video Hbit to HSYNC register */ /* Video Hbit to HSYNC register */
#define HBIT_2HSYNC1 (0x40) #define HBIT_2HSYNC1 (0x40)
#define HBIT_2HSYNC2 (0x41) #define HBIT_2HSYNC2 (0x41)
...@@ -180,6 +232,10 @@ ...@@ -180,6 +232,10 @@
#define DDC_OFFSET_ADDR (0xEF) #define DDC_OFFSET_ADDR (0xEF)
#define DDC_CNT1_ADDR (0xF0) #define DDC_CNT1_ADDR (0xF0)
#define DDC_CNT2_ADDR (0xF1) #define DDC_CNT2_ADDR (0xF1)
#define DDC_STATUS_ADDR (0xF2)
#define DDC_CMD_ADDR (0xF3)
#define DDC_DATA_ADDR (0xF4)
#define DDC_FIFOCNT_ADDR (0xF5)
...@@ -244,10 +300,15 @@ ...@@ -244,10 +300,15 @@
#define GENERIC1_IF_ADDR 0xC0 #define GENERIC1_IF_ADDR 0xC0
#define GENERIC2_IF_ADDR 0xE0 #define GENERIC2_IF_ADDR 0xE0
#define CP_IF_ADDR 0xDF // Contain Protect 1- byte Frame Info Frame #define CP_IF_ADDR 0xDF // Contain Protect 1- byte Frame Info Frame
#define BIT_CP_AVI_MUTE_SET 0x01
#define BIT_CP_AVI_MUTE_CLEAR 0x10
#define GEN_RPT (1<<0) #define GEN_RPT (1<<0)
#define EN_EN (1<<1) #define EN_EN (1<<1)
#define GCP_RPT (1<<2) #define GCP_RPT (1<<2)
#define GCP_EN (1<<3) #define GCP_EN (1<<3)
#define GEN2_RPT (1<<4)
#define GEN2_EN (1<<5)
#define CLR_AVMUTE 0x10 #define CLR_AVMUTE 0x10
#define SET_AVMUTE 0x01 #define SET_AVMUTE 0x01
...@@ -257,7 +318,9 @@ ...@@ -257,7 +318,9 @@
/* value defined */ /* value defined */
#define ENABLE 1 #define ENABLE 1
#define TRUE 1
#define DISABLE 0 #define DISABLE 0
#define FALSE 0
#define INT_ENABLE (0x1) #define INT_ENABLE (0x1)
#define BIT_TX_SW_RST (0x01) #define BIT_TX_SW_RST (0x01)
#define BIT_TX_FIFO_RST (0x02) #define BIT_TX_FIFO_RST (0x02)
...@@ -288,6 +351,12 @@ ...@@ -288,6 +351,12 @@
#define HDCP_ENABLE 6 #define HDCP_ENABLE 6
#define HDCP_DISABLE 7 #define HDCP_DISABLE 7
#define HDCP_RI_STATUS 8 #define HDCP_RI_STATUS 8
#define EVENT_NOTIFY 9
#define VIDEO_CHANGE 10
/*******************************AUTH STATE *************************/
#define AUTH_NEED 0
#define AUTH_DONE 1
#define REAUTH_NEED 2
/******************************* BIT FIELD *********************/ /******************************* BIT FIELD *********************/
#define SET_FIFORTS (1<<1) #define SET_FIFORTS (1<<1)
#define SET_SWRST (1<<0) #define SET_SWRST (1<<0)
...@@ -300,7 +369,7 @@ ...@@ -300,7 +369,7 @@
#define SET_VLOW (1<<7) #define SET_VLOW (1<<7)
#define SET_RSEN (1<<2) #define SET_RSEN (1<<2)
#define SET_HPD (1<<1) #define SET_HPD (1<<1)
#define SET_P_STABLE (1<<0) #define P_STABLE (1<<0)
#define SET_PLLF_80UA (0xf<<1) #define SET_PLLF_80UA (0xf<<1)
#define SET_PLLF_45UA (0x8<<1) #define SET_PLLF_45UA (0x8<<1)
#define SET_PLLF_40UA (0x7<<1) #define SET_PLLF_40UA (0x7<<1)
...@@ -311,8 +380,9 @@ ...@@ -311,8 +380,9 @@
#define PFEN_ENABLE (0x1) #define PFEN_ENABLE (0x1)
#define SET_VID_BLANK (1<<2) #define SET_VID_BLANK (1<<2)
#define SET_AUD_MUTE (1<<1) #define SET_AUD_MUTE (1<<1)
#define BKSV_ERR (1<<5)
#define RX_RPTR_ENABLE (1<<4) #define RX_RPTR_ENABLE (1<<4)
#define TX_ANSTOP_ENABLE (1<<3) #define TX_ANSTOP (1<<3)
#define SET_CP_RESTN (1<<2) #define SET_CP_RESTN (1<<2)
#define SET_ENC_EN (1<<0) #define SET_ENC_EN (1<<0)
#define BCAP_ENABLE (1<<1) #define BCAP_ENABLE (1<<1)
...@@ -361,6 +431,10 @@ ...@@ -361,6 +431,10 @@
#define INTR2_ACR_OVR (1<<2) #define INTR2_ACR_OVR (1<<2)
#define INTR2_TCLK_STBL (1<<1) #define INTR2_TCLK_STBL (1<<1)
#define INTR2_VSYNC_REC (1<<0) #define INTR2_VSYNC_REC (1<<0)
#define INTR3_STAT7 (1<<7)
#define INTR3_STAT5 (1<<5)
#define INTR3_STAT4 (1<<4)
#define INTR3_STAT3 (1<<3)
#define SOFT_INTR_CLEAR ~(1<<3) #define SOFT_INTR_CLEAR ~(1<<3)
#define SET_SOFT_INTR (1<<3) #define SET_SOFT_INTR (1<<3)
#define OPEN_DRAIN_ENABLE (1<<2) #define OPEN_DRAIN_ENABLE (1<<2)
...@@ -395,6 +469,19 @@ ...@@ -395,6 +469,19 @@
#define SET_MAN_OVR (1<<7) #define SET_MAN_OVR (1<<7)
#define SET_MAN_SDA (1<<5) #define SET_MAN_SDA (1<<5)
#define SET_MAN_SCL (1<<4) #define SET_MAN_SCL (1<<4)
#define HDCP_ACC 20
#define SET_CP_RESTN (1<<2)
#define NCTSPKT_ENABLE (1<<1)
#define CTS_SEL (1<<0)
#define BIT_AVI_EN_REPEAT 0x0003
#define LD_KSV (1<<5)
#define DDC_BIT_REPEATER (0x40)
#define DDC_BIT_FIFO_READY (0x20)
#define DDC_BIT_FAST_I2C (0x10)
#define DDC_BSTATUS_ADDR (0x41)
#define DDC_BSTATUS_1_ADDR (0x41)
#define DDC_BSTATUS_2_ADDR (0x42)
#define DDC_BIT_HDMI_MODE (0x10)
#define DDC_KSV_FIFO_ADDR (0x43)
#endif /* NEUROS_SIL9034__H */ #endif /* NEUROS_SIL9034__H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment