From 6341d629d889336408fed3ff878e219df4263787 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Thu, 29 Sep 2022 16:37:49 -0500 Subject: [PATCH] AMD ADL SMBus improvements * Allow word (2 byte) transfers * Fix block writes not sending data size --- i2c_smbus/i2c_smbus_amdadl.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/i2c_smbus/i2c_smbus_amdadl.cpp b/i2c_smbus/i2c_smbus_amdadl.cpp index 39f2ec27..e67d3a6f 100644 --- a/i2c_smbus/i2c_smbus_amdadl.cpp +++ b/i2c_smbus/i2c_smbus_amdadl.cpp @@ -128,16 +128,20 @@ s32 i2c_smbus_amdadl::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int s { int PrimaryDisplay; int ret; + int data_size = 0; + char* data_ptr; ADLI2C* pI2C; ADLI2C I2Cstore; pI2C = &I2Cstore; + char i2c_buf[I2C_SMBUS_BLOCK_MAX + 8]; + pI2C->iSize = sizeof(ADLI2C); pI2C->iSpeed = 100; pI2C->iLine = 1; //location of the Aura chip pI2C->iAddress = addr << 1; - pI2C->iOffset = command; + pI2C->iOffset = 0; pI2C->pcData = (char*)data; if (ADL_OK != ADL2_Adapter_Primary_Get(context, &PrimaryDisplay)) @@ -159,16 +163,18 @@ s32 i2c_smbus_amdadl::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int s //break; case I2C_SMBUS_BYTE_DATA: - pI2C->iDataSize = 1; + data_size = 1; + data_ptr = (char*)data; break; case I2C_SMBUS_WORD_DATA: - return -1; + data_size = 2; + data_ptr = (char*)data; break; case I2C_SMBUS_BLOCK_DATA: - pI2C->iDataSize = data->block[0]; - pI2C->pcData = (char*)&data->block[1]; + data_size = data->block[0] + 1; + data_ptr = (char*)&data->block[0]; break; default: @@ -177,12 +183,24 @@ s32 i2c_smbus_amdadl::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int s if (read_write == I2C_SMBUS_READ) { + /* An SMBus read can be achieved by setting the offset to the command (register address) */ + pI2C->iOffset = command; pI2C->iAction = ADL_DL_I2C_ACTIONREAD; + pI2C->iDataSize = data_size; + pI2C->pcData = (char *)data_ptr; + ret = ADL2_Display_WriteAndReadI2C(context, PrimaryDisplay, pI2C); } else { + /* An SMBus write has one extra byte, the register address, before the data */ pI2C->iAction = ADL_DL_I2C_ACTIONWRITE; + pI2C->iDataSize = data_size + 1; + pI2C->pcData = i2c_buf; + + i2c_buf[0] = command; + memcpy(&i2c_buf[1], data_ptr, data_size); + ret = ADL2_Display_WriteAndReadI2C(context, PrimaryDisplay, pI2C); }