mirror of
https://github.com/polyfractal/rustl8710.git
synced 2026-07-04 18:35:39 +00:00
539 lines
No EOL
18 KiB
C
539 lines
No EOL
18 KiB
C
/*
|
|
* Routines to access hardware
|
|
*
|
|
* Copyright (c) 2013 Realtek Semiconductor Corp.
|
|
*
|
|
* This module is a confidential and proprietary property of RealTek and
|
|
* possession or use of this module requires written permission of RealTek.
|
|
*/
|
|
|
|
#include "rtl8195a.h"
|
|
|
|
/* Used only for A~C Version */
|
|
#ifndef CONFIG_CHIP_E_CUT
|
|
//---------------------------------------------------------------------------------------------------
|
|
//Function Name:
|
|
// HalI2CSendRtl8195a
|
|
//
|
|
// Description:
|
|
// Send one byte to the I2C internal fifo, it will generate START and STOP bit
|
|
// automatically.
|
|
//
|
|
// Arguments:
|
|
// [in] VOID *Data -
|
|
// The I2C parameter data struct.
|
|
//
|
|
// Return:
|
|
// _EXIT_SUCCESS if the sending succeeded.
|
|
// _EXIT_FAILURE if the sending failed.
|
|
//
|
|
// Note:
|
|
// None
|
|
//
|
|
// See Also:
|
|
// NA
|
|
//
|
|
// Author:
|
|
// By Jason Deng, 2014-02-18.
|
|
//
|
|
//---------------------------------------------------------------------------------------------------
|
|
HAL_Status
|
|
HalI2CSendRtl8195a_Patch(
|
|
IN VOID *Data
|
|
){
|
|
PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data;
|
|
u8 I2CIdx = pHalI2CInitData->I2CIdx;
|
|
u8 *pDat = pHalI2CInitData->I2CRWData;
|
|
u8 I2CCmd = pHalI2CInitData->I2CCmd;
|
|
u8 I2CStop = pHalI2CInitData->I2CStop;
|
|
u8 I2CReSTR= pHalI2CInitData->I2CReSTR;
|
|
|
|
DBG_I2C_INFO("HalI2CSendRtl8195a\n");
|
|
DBG_I2C_INFO("I2C Index: %x\n",I2CIdx);
|
|
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DATA_CMD,
|
|
*(pDat) |
|
|
BIT_CTRL_IC_DATA_CMD_RESTART(I2CReSTR)|
|
|
BIT_CTRL_IC_DATA_CMD_CMD(I2CCmd) |
|
|
BIT_CTRL_IC_DATA_CMD_STOP(I2CStop));
|
|
|
|
return (HAL_OK);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
//Function Name:
|
|
// HalI2CInit8195a
|
|
//
|
|
// Description:
|
|
// To initialize I2C module by using the given data.
|
|
//
|
|
// Arguments:
|
|
// [in] VOID *Data -
|
|
// The I2C parameter data struct.
|
|
//
|
|
// Return:
|
|
// The status of the DeInit process.
|
|
// _EXIT_SUCCESS if the initialization succeeded.
|
|
// _EXIT_FAILURE if the initialization failed.
|
|
//
|
|
// Note:
|
|
// None
|
|
//
|
|
// See Also:
|
|
// NA
|
|
//
|
|
// Author:
|
|
// By Jason Deng, 2014-04-02.
|
|
//
|
|
//---------------------------------------------------------------------------------------------------
|
|
HAL_Status
|
|
HalI2CMassSendRtl8195a_Patch(
|
|
IN VOID *Data
|
|
){
|
|
PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data;
|
|
|
|
u8 I2CIdx = pHalI2CInitData->I2CIdx;
|
|
u8 I2CCmd = pHalI2CInitData->I2CCmd;
|
|
u8 I2CDatLen = pHalI2CInitData->I2CDataLen;
|
|
u8 *pDat = pHalI2CInitData->I2CRWData;
|
|
u8 I2CStopSet = pHalI2CInitData->I2CStop;
|
|
u8 I2CSTP;
|
|
u8 I2CReSRT = 0;
|
|
u8 DatCnt = 0;
|
|
|
|
/* Send I2C data one by one. The STOP bit is only used for the last byte.*/
|
|
for (DatCnt = 0; DatCnt < I2CDatLen; DatCnt++)
|
|
{
|
|
I2CSTP = 0;
|
|
if ((DatCnt == (I2CDatLen - 1)) && (I2CStopSet != 0)) {
|
|
I2CSTP = 1;
|
|
}
|
|
|
|
if ((DatCnt == 0) && ((pHalI2CInitData->RSVD0 & BIT0) != 0)) {
|
|
I2CReSRT = 1;
|
|
}
|
|
else {
|
|
I2CReSRT = 0;
|
|
}
|
|
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DATA_CMD,
|
|
*(pDat+DatCnt) |
|
|
BIT_CTRL_IC_DATA_CMD_CMD(I2CCmd) |
|
|
BIT_CTRL_IC_DATA_CMD_RESTART(I2CReSRT) |
|
|
BIT_CTRL_IC_DATA_CMD_STOP(I2CSTP));
|
|
}
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
//Function Name:
|
|
// HalI2CInit8195a
|
|
//
|
|
// Description:
|
|
// To initialize I2C module by using the given data.
|
|
//
|
|
// Arguments:
|
|
// [in] VOID *Data -
|
|
// The I2C parameter data struct.
|
|
//
|
|
// Return:
|
|
// The status of the DeInit process.
|
|
// _EXIT_SUCCESS if the initialization succeeded.
|
|
// _EXIT_FAILURE if the initialization failed.
|
|
//
|
|
// Note:
|
|
// None
|
|
//
|
|
// See Also:
|
|
// NA
|
|
//
|
|
// Author:
|
|
// By Jason Deng, 2014-04-02.
|
|
//
|
|
//---------------------------------------------------------------------------------------------------
|
|
HAL_Status
|
|
HalI2CInit8195a_Patch(
|
|
IN VOID *Data
|
|
)
|
|
{
|
|
PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data;
|
|
|
|
u8 Master;
|
|
u8 I2CIdx;
|
|
u8 SpdMd;
|
|
u8 AddrMd;
|
|
u8 ReSTR;
|
|
u8 StartByte;
|
|
u8 Specical;
|
|
u8 GC;
|
|
u16 I2CAckAddr;
|
|
u16 SdaHd;
|
|
u8 SdaSetup;
|
|
u8 RXTL;
|
|
u8 TXTL;
|
|
u8 SlvNoAck;
|
|
u32 INTRMsk;
|
|
u8 TxDMARqLv;
|
|
u8 RxDMARqLv;
|
|
u32 I2CTmp;
|
|
|
|
/* Get the I2C parameters*/
|
|
I2CIdx = pHalI2CInitData->I2CIdx;
|
|
SpdMd = pHalI2CInitData->I2CSpdMod;
|
|
AddrMd = pHalI2CInitData->I2CAddrMod;
|
|
I2CAckAddr = pHalI2CInitData->I2CAckAddr;
|
|
Master = pHalI2CInitData->I2CMaster;
|
|
SdaHd = pHalI2CInitData->I2CSdaHd;
|
|
SdaSetup = pHalI2CInitData->I2CSetup;
|
|
|
|
ReSTR = pHalI2CInitData->I2CReSTR;
|
|
GC = pHalI2CInitData->I2CGC;
|
|
StartByte = pHalI2CInitData->I2CStartB;
|
|
SlvNoAck = pHalI2CInitData->I2CSlvNoAck;
|
|
|
|
RXTL = pHalI2CInitData->I2CRXTL;
|
|
TXTL = pHalI2CInitData->I2CTXTL;
|
|
|
|
TxDMARqLv = pHalI2CInitData->I2CTxDMARqLv;
|
|
RxDMARqLv = pHalI2CInitData->I2CRxDMARqLv;
|
|
|
|
/* Disable the IC first */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_ENABLE,BIT_CTRL_IC_ENABLE(0));
|
|
|
|
/* Master case*/
|
|
if (Master) {
|
|
/*RESTART MUST be set in these condition in Master mode.
|
|
But it might be NOT compatible in old slaves.*/
|
|
if ((AddrMd == I2C_ADDR_10BIT) || (SpdMd == I2C_HS_MODE))
|
|
ReSTR = 1;
|
|
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_CON,
|
|
(BIT_CTRL_IC_CON_IC_SLAVE_DISABLE(1) |
|
|
BIT_CTRL_IC_CON_IC_RESTART_EN(ReSTR) |
|
|
BIT_CTRL_IC_CON_IC_10BITADDR_MASTER(AddrMd) |
|
|
BIT_CTRL_IC_CON_SPEED(SpdMd) |
|
|
BIT_CTRL_IC_CON_MASTER_MODE(Master)));
|
|
|
|
DBG_I2C_INFO("Init master, IC_CON%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_CON, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_CON));
|
|
|
|
|
|
/* To set target addr.*/
|
|
Specical = 0;
|
|
if ((GC!=0) || (StartByte!=0))
|
|
Specical = 1;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_TAR,
|
|
(BIT_CTRL_IC_TAR_IC_10BITADDR_MASTER(AddrMd) |
|
|
BIT_CTRL_IC_TAR_SPECIAL(Specical) |
|
|
BIT_CTRL_IC_TAR_GC_OR_START(StartByte) |
|
|
BIT_CTRL_IC_TAR(I2CAckAddr)));
|
|
|
|
/* To Set I2C clock*/
|
|
HalI2CSetCLKRtl8195a_Patch(pHalI2CInitData);
|
|
|
|
|
|
DBG_I2C_INFO("Init master, IC_TAR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_TAR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_TAR));
|
|
|
|
} /*if (Master)*/
|
|
else {
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_CON,
|
|
BIT_CTRL_IC_CON_IC_10BITADDR_SLAVE(AddrMd) |
|
|
BIT_CTRL_IC_CON_IC_SLAVE_DISABLE(Master) |
|
|
BIT_CTRL_IC_CON_SPEED(SpdMd)|
|
|
BIT_CTRL_IC_CON_MASTER_MODE(Master));
|
|
|
|
DBG_I2C_INFO("Init slave, IC_CON%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_CON, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_CON));
|
|
|
|
|
|
/* To set slave addr. */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SAR,BIT_CTRL_IC_SAR(I2CAckAddr));
|
|
|
|
DBG_I2C_INFO("Init slave, IC_SAR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_SAR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SAR));
|
|
|
|
|
|
/* To set slave no ack */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SLV_DATA_NACK_ONLY,BIT_CTRL_IC_SLV_DATA_NACK_ONLY(SlvNoAck));
|
|
|
|
/* Set ack general call. */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_ACK_GENERAL_CALL,BIT_CTRL_IC_ACK_GENERAL_CALL(pHalI2CInitData->I2CSlvAckGC));
|
|
|
|
|
|
|
|
DBG_I2C_INFO("Init slave, I2C_IC_ACK_GC%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_ACK_GENERAL_CALL, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_ACK_GENERAL_CALL));
|
|
|
|
/* to set SDA hold time */
|
|
//HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(SdaHd));
|
|
//4
|
|
/* to set SDA setup time */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_SETUP,BIT_CTRL_IC_SDA_SETUP(SdaSetup));
|
|
}
|
|
|
|
/* to set SDA hold time */
|
|
INTRMsk = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_CON);
|
|
if (BIT_GET_IC_CON_SPEED(INTRMsk) == I2C_SS_MODE) {
|
|
I2CTmp = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT);
|
|
} else if (BIT_GET_IC_CON_SPEED(INTRMsk) == I2C_FS_MODE) {
|
|
I2CTmp = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT);
|
|
} else {
|
|
I2CTmp = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_HS_SCL_LCNT);
|
|
}
|
|
|
|
if (Master) {
|
|
if (SdaHd > (I2CTmp -2)) {
|
|
I2CTmp = I2CTmp -2;
|
|
if (I2CTmp < 1) {
|
|
I2CTmp = 1 + 1;
|
|
}
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(I2CTmp));
|
|
} else {
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(SdaHd));
|
|
}
|
|
} else {
|
|
if (SdaHd > (I2CTmp -2)) {
|
|
I2CTmp = I2CTmp -2;
|
|
if (I2CTmp < 7) {
|
|
I2CTmp = 7 + 1;
|
|
}
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(I2CTmp));
|
|
} else {
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(SdaHd));
|
|
}
|
|
}
|
|
//DBG_8195A("SDA:%x\n", HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD));
|
|
|
|
/* To set TX_Empty Level */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_TX_TL,TXTL);
|
|
|
|
/* To set RX_Full Level */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_RX_TL,RXTL);
|
|
|
|
/* To set TX/RX FIFO level */
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DMA_TDLR,TxDMARqLv);
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DMA_RDLR,RxDMARqLv);
|
|
|
|
|
|
DBG_I2C_INFO("Init i2c dev, I2C_IC_DMA_TDLR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_DMA_TDLR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_DMA_TDLR));
|
|
DBG_I2C_INFO("Init i2c dev, I2C_IC_DMA_RDLR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_DMA_RDLR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_DMA_RDLR));
|
|
|
|
|
|
/*I2C Clear all interrupts first*/
|
|
HalI2CClrAllIntrRtl8195a(pHalI2CInitData);
|
|
|
|
/*I2C Disable all interrupts first*/
|
|
INTRMsk = pHalI2CInitData->I2CIntrMSK;
|
|
pHalI2CInitData->I2CIntrMSK = 0;
|
|
HalI2CIntrCtrl8195a(pHalI2CInitData);
|
|
pHalI2CInitData->I2CIntrMSK = INTRMsk;
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------
|
|
//Function Name:
|
|
// HalI2CSetCLKRtl8195a
|
|
//
|
|
// Description:
|
|
// To set I2C bus clock rate.
|
|
//
|
|
// Arguments:
|
|
// [in] VOID *Data -
|
|
// The I2C parameter data struct.
|
|
//
|
|
// Return:
|
|
// The status of the enable process.
|
|
// _EXIT_SUCCESS if the de-initialization succeeded.
|
|
// _EXIT_FAILURE if the de-initialization failed.
|
|
//
|
|
// Note:
|
|
// None
|
|
//
|
|
// See Also:
|
|
// NA
|
|
//
|
|
// Author:
|
|
// By Jason Deng, 2014-02-18.
|
|
//
|
|
//---------------------------------------------------------------------------------------------------
|
|
HAL_Status
|
|
HalI2CSetCLKRtl8195a_Patch(
|
|
IN VOID *Data
|
|
)
|
|
{
|
|
PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data;
|
|
u8 SpdMd = pHalI2CInitData->I2CSpdMod;
|
|
u32 I2CClk = pHalI2CInitData->I2CClk;
|
|
u8 I2CIdx = pHalI2CInitData->I2CIdx;
|
|
u32 ICHLcnt;
|
|
u32 ICHtime;
|
|
u32 ICLtime;
|
|
|
|
/* Get the IC-Clk setting first for the following process*/
|
|
#ifdef CONFIG_FPGA
|
|
u32 IcClk = SYSTEM_CLK/1000000;
|
|
#else
|
|
u32 IcClk;
|
|
u32 ClkSELTmp = 0;
|
|
u32 CpuClkTmp = 0;
|
|
|
|
#if defined(CONFIG_CHIP_A_CUT)
|
|
CpuClkTmp = StartupHalGetCpuClk();
|
|
#elif (defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT))
|
|
CpuClkTmp = HalGetCpuClk();
|
|
#endif
|
|
|
|
DBG_I2C_INFO("%s, CPU Clk:%x\n",__func__, CpuClkTmp);
|
|
|
|
ClkSELTmp = HAL_READ32(PERI_ON_BASE, REG_PESOC_CLK_SEL);
|
|
ClkSELTmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3)));
|
|
HAL_WRITE32(PERI_ON_BASE,REG_PESOC_CLK_SEL,ClkSELTmp);
|
|
IcClk = (CpuClkTmp/1000000)>>1;
|
|
|
|
#if 0
|
|
if ((I2CClk > 0) && (I2CClk <= 400)) {
|
|
ClkSELTmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3)));
|
|
HAL_WRITE32(PERI_ON_BASE,REG_PESOC_CLK_SEL,ClkSELTmp);
|
|
IcClk = ClkSELTmp/1000000; /*actually it's 12.5MHz*/
|
|
}
|
|
else {
|
|
ClkSELTmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3)));
|
|
HAL_WRITE32(PERI_ON_BASE,REG_PESOC_CLK_SEL,ClkSELTmp);
|
|
IcClk = 100;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
switch (SpdMd)
|
|
{
|
|
case I2C_SS_MODE:
|
|
{
|
|
ICHtime = ((1000000/I2CClk)*I2C_SS_MIN_SCL_HTIME)/(I2C_SS_MIN_SCL_HTIME+I2C_SS_MIN_SCL_LTIME);
|
|
ICLtime = ((1000000/I2CClk)*I2C_SS_MIN_SCL_LTIME)/(I2C_SS_MIN_SCL_HTIME+I2C_SS_MIN_SCL_LTIME);
|
|
|
|
ICHLcnt = (ICHtime * IcClk)/1000;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_HCNT,ICHLcnt);
|
|
|
|
|
|
DBG_I2C_INFO("IC_SS_SCL_HCNT%d[%2x]: %x\n", I2CIdx,
|
|
REG_DW_I2C_IC_SS_SCL_HCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SS_SCL_HCNT));
|
|
|
|
|
|
ICHLcnt = (ICLtime * IcClk)/1000;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT,ICHLcnt);
|
|
|
|
|
|
DBG_I2C_INFO("IC_SS_SCL_LCNT%d[%2x]: %x\n", I2CIdx,
|
|
REG_DW_I2C_IC_SS_SCL_LCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT));
|
|
|
|
break;
|
|
}
|
|
|
|
case I2C_FS_MODE:
|
|
{
|
|
ICHtime = ((1000000/I2CClk)*I2C_FS_MIN_SCL_HTIME)/(I2C_FS_MIN_SCL_HTIME+I2C_FS_MIN_SCL_LTIME);
|
|
ICLtime = ((1000000/I2CClk)*I2C_FS_MIN_SCL_LTIME)/(I2C_FS_MIN_SCL_HTIME+I2C_FS_MIN_SCL_LTIME);
|
|
|
|
ICHLcnt = (ICHtime * IcClk)/1000;
|
|
if (ICHLcnt>4)/*this part is according to the fine-tune result*/
|
|
ICHLcnt -= 4;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_HCNT,ICHLcnt);
|
|
|
|
|
|
DBG_I2C_INFO("IC_FS_SCL_HCNT%d[%2x]: %x\n", I2CIdx,
|
|
REG_DW_I2C_IC_FS_SCL_HCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_FS_SCL_HCNT));
|
|
|
|
|
|
ICHLcnt = (ICLtime * IcClk)/1000;
|
|
if (ICHLcnt>3)/*this part is according to the fine-tune result*/
|
|
ICHLcnt -= 3;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT,ICHLcnt);
|
|
|
|
|
|
DBG_I2C_INFO("IC_FS_SCL_LCNT%d[%2x]: %x\n", I2CIdx,
|
|
REG_DW_I2C_IC_FS_SCL_LCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT));
|
|
|
|
break;
|
|
}
|
|
|
|
case I2C_HS_MODE:
|
|
{
|
|
ICHLcnt = 400;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_HCNT,ICHLcnt);
|
|
|
|
ICHLcnt = 470;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT,ICHLcnt);
|
|
|
|
ICHLcnt = 60;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_HCNT,ICHLcnt);
|
|
|
|
ICHLcnt = 130;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT,ICHLcnt);
|
|
|
|
ICHtime = ((1000000/I2CClk)*I2C_HS_MIN_SCL_HTIME_100)/(I2C_HS_MIN_SCL_HTIME_100+I2C_HS_MIN_SCL_LTIME_100);
|
|
ICLtime = ((1000000/I2CClk)*I2C_HS_MIN_SCL_LTIME_100)/(I2C_HS_MIN_SCL_HTIME_100+I2C_HS_MIN_SCL_LTIME_100);
|
|
|
|
|
|
DBG_I2C_INFO("ICHtime:%x\n",ICHtime);
|
|
DBG_I2C_INFO("ICLtime:%x\n",ICLtime);
|
|
|
|
|
|
ICHLcnt = (ICHtime * IcClk)/1000;
|
|
if (ICHLcnt>8)/*this part is according to the fine-tune result*/
|
|
ICHLcnt -= 3;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_HS_SCL_HCNT,ICHLcnt);
|
|
|
|
|
|
DBG_I2C_INFO("IC_HS_SCL_HCNT%d[%2x]: %x\n", I2CIdx,
|
|
REG_DW_I2C_IC_HS_SCL_HCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_HS_SCL_HCNT));
|
|
|
|
|
|
ICHLcnt = (ICLtime * IcClk)/1000;
|
|
if (ICHLcnt>6)/*this part is according to the fine-tune result*/
|
|
ICHLcnt -= 6;
|
|
HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_HS_SCL_LCNT,ICHLcnt);
|
|
|
|
|
|
DBG_I2C_INFO("IC_HS_SCL_LCNT%d[%2x]: %x\n", I2CIdx,
|
|
REG_DW_I2C_IC_HS_SCL_LCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_HS_SCL_LCNT));
|
|
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
HAL_Status
|
|
HalI2CEnableRtl8195a_Patch(
|
|
IN VOID *Data
|
|
){
|
|
PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data;
|
|
u8 I2CIdx = pHalI2CInitData->I2CIdx;
|
|
u8 I2CICEn = pHalI2CInitData->I2CEn;
|
|
u32 I2CTimeoutCount;
|
|
u32 I2CStartCount;
|
|
/* Enable I2C module */
|
|
HAL_I2C_WRITE32(I2CIdx, REG_DW_I2C_IC_ENABLE, BIT_CTRL_IC_ENABLE(I2CICEn));
|
|
|
|
I2CTimeoutCount = ((10000/pHalI2CInitData->I2CClk) /TIMER_TICK_US) +1;
|
|
I2CStartCount = HalTimerOp.HalTimerReadCount(1);
|
|
|
|
if (!I2CICEn) {
|
|
while (HAL_I2C_READ32(I2CIdx, REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN) {
|
|
if (HAL_TIMEOUT == I2CIsTimeout(I2CStartCount, I2CTimeoutCount)) {
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
} else {
|
|
while (!(HAL_I2C_READ32(I2CIdx, REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN)) {
|
|
if (HAL_TIMEOUT == I2CIsTimeout(I2CStartCount, I2CTimeoutCount)) {
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
return HAL_OK;
|
|
}
|
|
#endif |