///*****************************************
// Copyright (C) 2009-2014
// ITE Tech. Inc. All Rights Reserved
// Proprietary and Confidential
///*****************************************
// @file >cat6611_drv.c<
// @author Jau-Chih.Tseng@ite.com.tw
// @date 2009/08/24
// @fileversion: CAT6611_SAMPLEINTERFACE_1.12
//******************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/ioctl.h>
#include <linux/poll.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include "hdmitx.h"
#define TIMEOUT_WAIT_AUTH MS(2000)
#define CAT6611_DEBUG 1
BYTE I2CADR = 0x98 ;
BYTE I2CDEV = 0 ;
////////////////////////////////////////////////////////////////////////////////
// General global variables
////////////////////////////////////////////////////////////////////////////////
// #define ENABLE_EXTERNAL_MCLK_SAMPLING_SPDIFAUDIO
_XDATA BYTE VideoFormat ;
//_XDATA BYTE bVideoInputType = 0 /* | T_MODE_CCIR656 | T_MODE_SYNCEMB | T_MODE_INDDR */ ; // for Sync Embedded, CCIR656, InputDDR
// _XDATA ULONG AudioSampleFreq = 48000 ;
// _XDATA BYTE AudioSWL = 24 ;
// _XDATA BYTE AudioChannel = 2 ;
_XDATA BYTE bOutputAudioMode = 0x41 ; // use full packet as default
_XDATA BYTE bAudioChannelSwap = 0 ;
_XDATA BYTE bIntType = 0 ;
_XDATA BYTE bAudioEnableSetting = 0 ;
_XDATA BYTE bAudioPendingCounter = 0 ;
_XDATA ULONG currVideoPixelClock ;
// BOOL bHDMIMode = FALSE;
// BOOL bAudioEnable = FALSE ;
// BOOL bCheckHDCP = FALSE ;
// BOOL bEnableEncryption = FALSE ;
// BOOL bGetEDID = FALSE ;
static BOOL bNLPCM = FALSE ;
static BOOL bAuthenticated = FALSE ;
static BOOL bManualCheckRi = FALSE ;
static BOOL bPendingAudio = FALSE ;
static BOOL bPendingAudioAdjust = FALSE ;
_XDATA unsigned short ManualCheckRiCounter = 0 ;
_XDATA TXDEVINFO TXDev_Info[TXDEVCOUNT] ;
// Y,C,RGB offset
// for register 73~75
_CODE BYTE bCSCOffset_16_235[] =
{
0x00, 0x80, 0x00
};
_CODE BYTE bCSCOffset_0_255[] =
{
0x10, 0x80, 0x10
};
#ifdef SUPPORT_INPUTRGB
_CODE BYTE bCSCMtx_RGB2YUV_ITU601_16_235[] =
{
0xB2,0x04,0x64,0x02,0xE9,0x00,
0x93,0x3C,0x18,0x04,0x56,0x3F,
0x49,0x3D,0x9F,0x3E,0x18,0x04
} ;
_CODE BYTE bCSCMtx_RGB2YUV_ITU601_0_255[] =
{
0x09,0x04,0x0E,0x02,0xC8,0x00,
0x0E,0x3D,0x84,0x03,0x6E,0x3F,
0xAC,0x3D,0xD0,0x3E,0x84,0x03
} ;
_CODE BYTE bCSCMtx_RGB2YUV_ITU709_16_235[] =
{
0xB8,0x05,0xB4,0x01,0x93,0x00,
0x49,0x3C,0x18,0x04,0x9F,0x3F,
0xD9,0x3C,0x10,0x3F,0x18,0x04
} ;
_CODE BYTE bCSCMtx_RGB2YUV_ITU709_0_255[] =
{
0xE5,0x04,0x78,0x01,0x81,0x00,
0xCE,0x3C,0x84,0x03,0xAE,0x3F,
0x49,0x3D,0x33,0x3F,0x84,0x03
} ;
#endif
#ifdef SUPPORT_INPUTYUV
_CODE BYTE bCSCMtx_YUV2RGB_ITU601_16_235[] =
{
0x00,0x08,0x6A,0x3A,0x4F,0x3D,
0x00,0x08,0xF7,0x0A,0x00,0x00,
0x00,0x08,0x00,0x00,0xDB,0x0D
} ;
_CODE BYTE bCSCMtx_YUV2RGB_ITU601_0_255[] =
{
0x4F,0x09,0x81,0x39,0xDF,0x3C,
0x4F,0x09,0xC2,0x0C,0x00,0x00,
0x4F,0x09,0x00,0x00,0x1E,0x10
} ;
_CODE BYTE bCSCMtx_YUV2RGB_ITU709_16_235[] =
{
0x00,0x08,0x53,0x3C,0x89,0x3E,
0x00,0x08,0x51,0x0C,0x00,0x00,
0x00,0x08,0x00,0x00,0x87,0x0E
} ;
_CODE BYTE bCSCMtx_YUV2RGB_ITU709_0_255[] =
{
0x4F,0x09,0xBA,0x3B,0x4B,0x3E,
0x4F,0x09,0x56,0x0E,0x00,0x00,
0x4F,0x09,0x00,0x00,0xE7,0x10
} ;
#endif
////////////////////////////////////////////////////////////////////////////////
// Function Prototype
////////////////////////////////////////////////////////////////////////////////
void InitCAT6611(void);
BOOL EnableVideoOutput(BOOL HiFreq, unsigned char inputColorMode, unsigned char inputVideoType, unsigned char outputColorMode, BOOL bHDMI) ;
BOOL EnableAudioOutput(unsigned long VideoPixelClock, unsigned long AudioSampleClock, int ChannelNumber, BOOL bSPDIF);
void DisableVideoOutput(void) ;
void DisableAudioOutput(void) ;
BOOL GetEDIDData(int EDIDBlockID, unsigned char *pEDIDData);
BOOL CheckHDMITX(BYTE *pHPD, BYTE *pHPDChange) ;
BOOL EnableAVIInfoFrame(BOOL bEnable, unsigned char *pAVIInfoFrame);
BOOL EnableAudioInfoFrame(BOOL bEnable, unsigned char *pAudioInfoFrame);
void SetAVMute(BOOL bEnable) ;
BOOL ProgramSyncEmbeddedVideoMode(BYTE VIC, BYTE bVideoInputType) ;
///////////////////////////////////////////////////////////
// Video Function
///////////////////////////////////////////////////////////
static void SetInputMode(BYTE InputColorMode, BYTE InputSignalType);
static void SetCSCScale(BYTE bInputMode,BYTE bOutputMode);
static void SetupAFE(BOOL HighFreqMode);
static void FireAFE(void);
///////////////////////////////////////////////////////////
// Audio Function
///////////////////////////////////////////////////////////
static SYS_STATUS SetAudioFormat(BYTE NumChannel, BYTE AudioEnable, ULONG SampleFreq, BYTE AudSWL, BYTE AudioCatCode);
static SYS_STATUS SetNCTS(ULONG PCLK, ULONG Fs);
static void SetAudioChannel(void) ;
static void AdjustAudioSampleClock(void) ;
///////////////////////////////////////////////////////////
// DDC
///////////////////////////////////////////////////////////
static void ClearDDCFIFO(void);
static void GenerateDDCSCLK(void) ;
static void AbortDDC(void);
///////////////////////////////////////////////////////////
// EDID
///////////////////////////////////////////////////////////
static SYS_STATUS ReadEDID(BYTE *pData, BYTE bSegment, BYTE offset, SHORT Count);
///////////////////////////////////////////////////////////
// InfoFrame
///////////////////////////////////////////////////////////
static SYS_STATUS SetAVIInfoFrame(AVI_InfoFrame *pAVIInfoFrame);
static SYS_STATUS SetAudioInfoFrame(Audio_InfoFrame *pAudioInfoFrame);
///////////////////////////////////////////////////////////
// HDCP Authentication
///////////////////////////////////////////////////////////
static SYS_STATUS HDCP_EnableEncryption(void);
static void HDCP_Auth_Fire(void);
static void HDCP_StartAnCipher(void);
static void HDCP_GenerateAn(void);
static SYS_STATUS HDCP_GetBCaps(PBYTE pBCaps ,PUSHORT pBStatus);
static SYS_STATUS HDCP_GetBKSV(BYTE *pBKSV);
static SYS_STATUS HDCP_Authenticate(void);
static void HDCP_ResumeAuthentication(void);
static void HDCP_ReadRi(void) ;
static void HDCP_ResetAuthenticate(void) ;
static void HDCP_StartAnCipher(void) ;
static void HDCP_StopAnCipher(void) ;
static SYS_STATUS HDCP_GetVr(BYTE *pVr) ;
static SYS_STATUS HDCP_Authenticate_Repeater(void) ;
static SYS_STATUS HDCP_VerifyIntegration(void) ;
static SYS_STATUS HDCP_GetKSVList(BYTE *pKSVList,BYTE cDownStream) ;
static SYS_STATUS HDCP_CheckSHA(BYTE M0[],USHORT BStatus,BYTE KSVList[],int devno,BYTE Vr[]) ;
static void HDCP_Reset(void) ;
#ifdef CAT6611_DEBUG
static void DumpCat6611Reg(void) ;
#endif // CAT6611_DEBUG
void DumpCat6611Reg(void) ;
////////////////////////////////////////////////////////////////////////////////
// Function Body.
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// External Interface //
////////////////////////////////////////////////////////////////////////////////
#ifdef CAT6611_DEBUG
//#define ErrorF printk
void
DumpCat6611Reg(void)
{
int i