/** Receive a response to a command from Atmel I2c TPM breaking response into multiple I2C transfers if required. @param[out] Buffer Pointer to TPM response data. @param[in] Length Maximum number of bytes to receive. @retval EFI_SUCCESS TPM response received. @retval EFI_NOT_FOUND TPM chip doesn't exit. @retval EFI_TIMEOUT Can't get the TPM control in time. **/ EFI_STATUS ReadTpmBufferMultiple ( OUT UINT8 *Buffer, IN UINTN Length ) { EFI_STATUS Status; EFI_I2C_DEVICE_ADDRESS I2CDeviceAddr; UINTN WriteLength; UINTN Index; UINTN PartialLength; Status = EFI_SUCCESS; I2CDeviceAddr.I2CDeviceAddress = ATMEL_I2C_TPM_SLAVE_ADDRESS; WriteLength = 0; DEBUG ((EFI_D_VERBOSE, "ReadTpmBufferMultiple: Addr=%02x Length=%02x\n", I2CDeviceAddr.I2CDeviceAddress, Length)); for (PartialLength = 0; Length > 0; Length -= PartialLength, Buffer += PartialLength) { // // Read data from TPM. // PartialLength = MIN (Length, ATMEL_I2C_TPM_MAX_TRANSFER_SIZE); Status = I2cReadMultipleByte ( I2CDeviceAddr, EfiI2CSevenBitAddrMode, &WriteLength, &PartialLength, Buffer ); if (!EFI_ERROR (Status)) { DEBUG ((EFI_D_VERBOSE, " ")); for (Index = 0; Index < PartialLength; Index++) { DEBUG ((EFI_D_VERBOSE, "%02x ", Buffer[Index])); } DEBUG ((EFI_D_VERBOSE, "\n")); } if (EFI_ERROR (Status)) { DEBUG ((EFI_D_VERBOSE, " Status = %r\n", Status)); return Status; } } DEBUG ((EFI_D_VERBOSE, " Status = %r\n", Status)); return Status; }
/** Initialize state of I2C GPIO expanders. **/ EFI_STATUS EarlyPlatformConfigGpioExpanders ( VOID ) { EFI_STATUS Status; EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress; UINTN Length; UINTN ReadLength; UINT8 Buffer[2]; // // Configure GPIO expanders for Galileo // Set all GPIO expander pins connected to the Reset Button as inputs // Route I2C pins to Arduino header // // // Detect the I2C Slave Address of the GPIO Expander // if (PlatformLegacyGpioGetLevel(R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) { I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR; } else { I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR; } DEBUG((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress)); // // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector // // // Select GPIO Expander GPORT1 // Length = 2; Buffer[0] = 0x18; //sub-address Buffer[1] = 0x01; //data Status = I2cWriteMultipleByte( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &Buffer ); if (EFI_ERROR(Status)) { DEBUG((EFI_D_WARN, "Fail to select GPIO Expander\n")); return EFI_SUCCESS; } // // Read "Pin Direction" of GPIO Expander GPORT1 // Length = 1; ReadLength = 1; Buffer[1] = 0x1C; Status = I2cReadMultipleByte ( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &ReadLength, &Buffer[1] ); ASSERT_EFI_ERROR (Status); // // Configure GPIO Expander GPORT1_BIT5 as an output // Length = 2; Buffer[0] = 0x1C; //sub-address Buffer[1] = (UINT8)(Buffer[1] & (~BIT5)); //data Status = I2cWriteMultipleByte ( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &Buffer ); ASSERT_EFI_ERROR (Status); // // Set GPIO Expander GPORT1_BIT5 low // Length = 2; Buffer[0] = 0x09; //sub-address Buffer[1] = (UINT8)(~BIT5); //data Status = I2cWriteMultipleByte ( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &Buffer ); ASSERT_EFI_ERROR (Status); // // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs // // // Select GPIO Expander GPORT5 // Length = 2; Buffer[0] = 0x18; Buffer[1] = 0x05; Status = I2cWriteMultipleByte ( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &Buffer ); ASSERT_EFI_ERROR (Status); // // Read "Pin Direction" of GPIO Expander GPORT5 // Length = 1; ReadLength = 1; Buffer[1] = 0x1C; Status = I2cReadMultipleByte ( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &ReadLength, &Buffer[1] ); ASSERT_EFI_ERROR (Status); // // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs // Length = 2; Buffer[0] = 0x1C; Buffer[1] = Buffer[1] | BIT0 | BIT1; Status = I2cWriteMultipleByte ( I2CSlaveAddress, EfiI2CSevenBitAddrMode, &Length, &Buffer ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }