예제 #1
0
/**
  Read EDID information from I2C Bus on CirrusLogic.

  @param  Private             Pointer to VBOX_VGA_PRIVATE_DATA.
  @param  EdidDataBlock       Pointer to EDID data block.
  @param  EdidSize            Returned EDID block size.

  @retval EFI_UNSUPPORTED
  @retval EFI_SUCCESS

**/
EFI_STATUS
ReadEdidData (
  VBOX_VGA_PRIVATE_DATA     *Private,
  UINT8                              **EdidDataBlock,
  UINTN                              *EdidSize
  )
{
  UINTN             Index;
  UINT8             EdidData[EDID_BLOCK_SIZE * 2];
  UINT8             *ValidEdid;
  UINT64            Signature;

  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++) {
    I2cReadByte (Private->PciIo, 0xa0, (UINT8)Index, &EdidData[Index]);
  }

  //
  // Search for the EDID signature
  //
  ValidEdid = &EdidData[0];
  Signature = 0x00ffffffffffff00ull;
  for (Index = 0; Index < EDID_BLOCK_SIZE * 2; Index ++, ValidEdid ++) {
    if (CompareMem (ValidEdid, &Signature, 8) == 0) {
      break;
    }
  }

  if (Index == 256) {
    //
    // No EDID signature found
    //
    return EFI_UNSUPPORTED;
  }

  *EdidDataBlock = AllocateCopyPool (
                     sizeof (EDID_BLOCK_SIZE),
                     ValidEdid
                     );
  if (*EdidDataBlock == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Currently only support EDID 1.x
  //
  *EdidSize = EDID_BLOCK_SIZE;

  return EFI_SUCCESS;
}
예제 #2
0
파일: i2c.c 프로젝트: cyysu/AliOS-Things
/**
  * @brief  This function receive multiple bytes to I2C slave.
  * @param  Buf: Buffer pointer to hold the received data.
  * @param  Len: Data Length to be received
  * @return None
  */
void I2cReadBytes(void* I2cMasterHandle, uint8_t* Buf, uint8_t Len)
{
	while(Len--)
	{
		*(Buf++) = I2cReadByte(I2cMasterHandle);
		if(Len == 0)
		{
			I2cSendNoAck(I2cMasterHandle);
		}
		else
		{
			I2cSendAck(I2cMasterHandle);
		}
	}
}
예제 #3
0
파일: TisPc.c 프로젝트: EvanLloyd/tianocore
/**
  Reads single byte data from TPM specified by I2C register address.

  Due to stability issues when using I2C combined write/read transfers (with
  RESTART) to TPM (specifically read from status register), a single write is
  performed followed by single read (with STOP condition in between).

  @param[in] TpmAddress  Address of register  to read.

  @return  The value register read.

**/
UINT8
TpmReadByte (
    IN UINTN  TpmAddress
)
{
    UINT8                   Data[1];
    UINT8                   ReadData;
    UINT8                   ReadCount;

    EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
    EFI_I2C_ADDR_MODE       I2CAddrMode;

    EFI_STATUS              Status;

    Status = EFI_SUCCESS;
    ReadData  = 0xFF;
    ReadCount = 0;

    //
    // Locate I2C protocol for TPM I2C access.
    //
    I2CDeviceAddr.I2CDeviceAddress = TPM_I2C_SLAVE_DEVICE_ADDRESS;
    I2CAddrMode = EfiI2CSevenBitAddrMode;

    //
    // As recommended by Infineon (SLB9645 I2C Communication protocol application
    // note revision 1.0) retry up to 3 times if TPM status, access or burst count
    // registers return 0xFF.
    //
    while ((ReadData == 0xFF) && (ReadCount < READ_RETRY)) {
        //
        // As recommended by Infineon (SLB9645 I2C Communication protocol application
        // note revision 1.0) wait 250 microseconds between a read and a write transfer.
        //
        if (mI2CPrevReadTransfer) {
            MicroSecondDelay (GUARD_TIME);
        }

        //
        // Write address to TPM.
        //
        Data[0] = (UINT8)TpmAddress;
        Status = I2cWriteByte (
                     I2CDeviceAddr,
                     I2CAddrMode,
                     &Data
                 );

        if (EFI_ERROR(Status)) {
            DEBUG ((EFI_D_INFO, "TpmReadByte(): write to TPM address %0x failed (%r)\n", TpmAddress, Status));
        }

        mI2CPrevReadTransfer = FALSE;

        //
        // Read data from TPM.
        //
        Data[0] = (UINT8)TpmAddress;
        Status = I2cReadByte (
                     I2CDeviceAddr,
                     I2CAddrMode,
                     &Data
                 );

        if (EFI_ERROR(Status)) {
            DEBUG ((EFI_D_INFO, "TpmReadByte(): read from TPM address %0x failed (%r)\n", TpmAddress, Status));
            ReadData = 0xFF;
        } else {
            ReadData = Data[0];
        }

        //
        // Only need to retry 3 times for TPM status, access, and burst count registers.
        // If read transfer is to TPM Data FIFO, do not retry, exit loop.
        //
        if (TpmAddress == INFINEON_TPM_DATA_FIFO_0_ADDRESS_DEFAULT) {
            ReadCount = READ_RETRY;
        } else {
            ReadCount++;
        }

        mI2CPrevReadTransfer = TRUE;
    }

    if (EFI_ERROR(Status)) {
        //
        //  Only reads to access register allowed to fail.
        //
        if (TpmAddress != INFINEON_TPM_ACCESS_0_ADDRESS_DEFAULT) {
            DEBUG ((EFI_D_ERROR, "TpmReadByte(): read from TPM address %0x failed\n", TpmAddress));
            ASSERT_EFI_ERROR (Status);
        }
    }
    return ReadData;
}
예제 #4
0
SDWORD I2cReadTest(BYTE byIicPort, BYTE bySlave, DWORD dwAddr)
{
	BYTE byData = 0;
    volatile BYTE i2c_bw_ctrl; /* I2C write control */
    volatile BYTE i2c_br_ctrl; /* I2C read control */
    volatile BYTE i2c_addr_00; /* I2C address (0) */

    STATUS semStatus;                           /*i2c同步信号量*/

    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/
    
    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }
    
    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

#ifdef I2C_DEBUG    
	printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_bw_ctrl = bySlave | I2C_WRITE;
    i2c_br_ctrl = bySlave | I2C_READ;
    /*i2c_addr_01 = I2C_W1_ADDR(addr);*/
    i2c_addr_00 = I2C_W0_ADDR(dwAddr);

	if(1)
    {
		i2cStart();
		I2cWriteByte(i2c_bw_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x1; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		/*I2cWriteByte(i2c_addr_01);*/
		/*ack1=I2cReadBit();*/ /*read ack from slave*/
		/*if(ack1!=0)
			i2c_ack_stat |= 0x2; */
		I2cWriteByte(i2c_addr_00);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x2; 
		i2cStart();
        I2C_DELAY(CLOCK_LOW_TIME*3);
		I2cWriteByte(i2c_br_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x3; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		byData = I2cReadByte();

		I2cStop();
    }

#ifdef I2C_DEBUG 
	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
#endif
	printf("byData: %x \n", byData);
    semGive(semI2cLock);    /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
예제 #5
0
SDWORD TestCpld(void)
{
    BYTE byData[5] = {0};
    BYTE bySlave = 0xca;
    BYTE i2c_br_ctrl = 0; /* I2C read control */
    BYTE byIicPort = 0;
    
    STATUS semStatus;                           /*i2c同步信号量*/

	if (0==I2Cisinit)
	{
		dev_I2cInit( );
	}
    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/
    
    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }
    
    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

#ifdef I2C_DEBUG    
/*	printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);*/
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_br_ctrl = bySlave | I2C_READ;
 
	if(1)/*0 == I2cDeviceBusy(bySlave))*/
    {
		i2cStart();
		I2cWriteByte(i2c_br_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x3; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		byData[0] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        byData[1] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        byData[2] = I2cReadByte();
        I2cWriteBit(0x00); /*send ack*/
        I2cData(HIGH);
        byData[3] = I2cReadByte();
        I2cWriteBit(0x00); /*send ack*/
        I2cData(HIGH);
        byData[4] = I2cReadByte();
        I2cWriteBit(0x80); /*send ack*/
        I2cData(HIGH);
		I2cStop();
    }

#ifdef I2C_DEBUG 
	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
#endif
    printf("\Data[0] = 0x%2x, Data[1] = 0x%2x, Data[2] = 0x%2d, Data[3] = 0x%2d, Data[4] = 0x%2d\n", byData[0], byData[1], byData[2], byData[3], byData[4]);

    semGive(semI2cLock);    /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
예제 #6
0
SDWORD I2cReadCpld(BYTE *pbyData, BYTE byDataNum)
{
    BYTE bySlave = I2C_CPLDID;
    BYTE i2c_br_ctrl = 0; /* I2C read control */
    BYTE byIicPort = I2C_CPLDPORT;

    static BYTE *pCpldData = (BYTE *)0x20000020;
    
    STATUS semStatus;                           /*i2c同步信号量*/
	if (0==I2Cisinit)
	{
		dev_I2cInit( );
	}

    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/
    
    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }
    
    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }

#ifdef I2C_DEBUG    
/*	printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);*/
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_br_ctrl = bySlave | I2C_READ;
 
	if(1)
    {
		i2cStart();
		I2cWriteByte(i2c_br_ctrl);
		ack1=I2cReadBit(); /*read ack from slave*/
		if(ack1!=0)
			i2c_ack_stat |= 0x3; 
        I2C_DELAY(CLOCK_LOW_TIME*3);
		pbyData[0] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        pbyData[1] = I2cReadByte();
        I2cWriteBit(0x0); /*send ack*/
        I2cData(HIGH);
        pbyData[2] = I2cReadByte();
        I2cWriteBit(0x80); /*send ack*/
        I2cData(HIGH);
		I2cStop();
    }

#ifdef I2C_DEBUG 
	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);
#endif
/*    printf("\nbyData[0] =%d, byData[1] =%d,byData[2] =%d\n",pbyData[0], pbyData[1], pbyData[2]);*/

    if (0x20000030 > pCpldData)
    {        
        *pCpldData++ = pbyData[0];
        *pCpldData++ = pbyData[1];
        *pCpldData++ = pbyData[2];
    }
    
    semGive(semI2cLock);    /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}
예제 #7
0
/*I2C读字符串   功能暂时不提供
//input :  byIicPort     I2C端口号为 0 ~ 1
//         bySlave       设备号
//         dwAddr        命令地址
//         dwCount       命令长度
//output:  pbyData       命令值
  return:  SYS_OK
           SYS_ERR
*/
SDWORD I2cReadSeq(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE *pbyData, DWORD dwCount)
{
    volatile BYTE i2c_bw_ctrl; /* I2C write control */
    volatile BYTE i2c_br_ctrl; /* I2C read control */
    volatile BYTE i2c_addr_00; /* I2C address (0) */
	int i;

    STATUS semStatus;                           /*i2c同步信号量*/

    if (0 == dwCount)
    {
        return SYS_ERROR;
    }
    
    semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/

    if(ERROR == semStatus)
    {
        logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0);
        return;
    }

    if(0 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK0;
        sCurI2cPort.byDataPin = IICDATA0;
    }
    else if(1 == byIicPort)
    {
        sCurI2cPort.byClkPin = IICCLK1;
        sCurI2cPort.byDataPin = IICDATA1;
    }
    
#ifdef I2C_DEBUG    
	printf("\n i2cReadSeq() slave address is 0x%x", bySlave);
#endif /* I2C_DEBUG */
	i2c_ack_stat=0x0;
    i2c_bw_ctrl = bySlave | I2C_WRITE;
    i2c_br_ctrl = bySlave | I2C_READ;
    /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/
    i2c_addr_00 = I2C_W0_ADDR(dwAddr);

	if(1)
	{
        i2cStart();
        I2cWriteByte(i2c_bw_ctrl);
        ack1=I2cReadBit(); /*read ack from slave*/
        if(ack1!=0)
            i2c_ack_stat |= 0x1; 
       
        I2cWriteByte(i2c_addr_00);
        ack1=I2cReadBit(); /*read ack from slave*/
        if(ack1!=0)
            i2c_ack_stat |= 0x2; 
        i2cStart();
        
        I2cWriteByte(i2c_br_ctrl);
        ack1=I2cReadBit(); /*read ack from slave*/
        if(ack1!=0)
            i2c_ack_stat |= 0x3; 
        for(i=0;i<dwCount;i++)
        {
            pbyData[i] = I2cReadByte();
            if(i != (dwCount-1))
                I2cWriteBit(0x0); /*send ack*/
            else
                I2cWriteBit(0x80); /*send nack after reading the last byte*/
            I2cData(HIGH);
        }
        
        I2cStop();
    }

	if(i2c_ack_stat!=0)
		printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat);

    semGive(semI2cLock);       /*释放信号量*/

    if(0 != i2c_ack_stat)
    {
	    return SYS_ERROR;
    }
    return SYS_OK;
}