Skip to content

Commit

Permalink
Add 16 bit addressing EEPROM handling
Browse files Browse the repository at this point in the history
Adding 16 bit eeprom addressing for reading data. First checking if
device is 8 bit or 16 bit by reading first 8 byte header and comparing
each byte. If all bytes are same then it is 8 bit or if address is auto
incremented then it is 16 bit.

Tested: Build Facebook TiogaPass board and load on the
target hardware. Ensure that Fru information are updated.

Change-Id: I1ec848764afb012562c1231f45e42f37e22334b8
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
  • Loading branch information
vijaykhemka authored and feistjj committed Nov 14, 2018
1 parent 5d5de44 commit 2d681f6
Showing 1 changed file with 65 additions and 7 deletions.
72 changes: 65 additions & 7 deletions src/FruDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,62 @@ static bool isMuxBus(size_t bus)
"/sys/bus/i2c/devices/i2c-" + std::to_string(bus) + "/mux_device"));
}

static int isDevice16Bit(int file)
{
/* Get first byte */
int byte1 = i2c_smbus_read_byte_data(file, 0);
if (byte1 < 0)
{
return byte1;
}
/* Read 7 more bytes, it will read same first byte in case of
* 8 bit but it will read next byte in case of 16 bit
*/
for (int i = 0; i < 7; i++)
{
int byte2 = i2c_smbus_read_byte_data(file, 0);
if (byte2 < 0)
{
return byte2;
}
if (byte2 != byte1)
{
return 1;
}
}
return 0;
}

static int read_block_data(int flag, int file, uint16_t offset, uint8_t len,
uint8_t *buf)
{
uint8_t low_addr = offset & 0xFF;
uint8_t high_addr = (offset >> 8) & 0xFF;

if (flag == 0)
{
return i2c_smbus_read_i2c_block_data(file, low_addr, len, buf);
}

/* This is for 16 bit addressing EEPROM device. First an offset
* needs to be written before read data from a offset
*/
int ret = i2c_smbus_write_byte_data(file, 0, low_addr);
if (ret < 0)
{
return ret;
}

return i2c_smbus_read_i2c_block_data(file, high_addr, len, buf);
}

int get_bus_frus(int file, int first, int last, int bus,
std::shared_ptr<DeviceMap> devices)
{

std::future<int> future = std::async(std::launch::async, [&]() {
std::array<uint8_t, I2C_SMBUS_BLOCK_MAX> block_data;

for (int ii = first; ii <= last; ii++)
{

Expand All @@ -90,8 +140,17 @@ int get_bus_frus(int file, int first, int last, int bus,
std::cout << "something at bus " << bus << "addr " << ii
<< "\n";
}
if (i2c_smbus_read_i2c_block_data(file, 0x0, 0x8,
block_data.data()) < 0)

/* Check for Device type if it is 8 bit or 16 bit */
int flag = isDevice16Bit(file);
if (flag < 0)
{
std::cerr << "failed to read bus " << bus << " address " << ii
<< "\n";
continue;
}

if (read_block_data(flag, file, 0x0, 0x8, block_data.data()) < 0)
{
std::cerr << "failed to read bus " << bus << " address " << ii
<< "\n";
Expand All @@ -117,8 +176,8 @@ int get_bus_frus(int file, int first, int last, int bus,
if (area_offset != 0)
{
area_offset *= 8;
if (i2c_smbus_read_i2c_block_data(
file, area_offset, 0x8, block_data.data()) < 0)
if (read_block_data(flag, file, area_offset, 0x8,
block_data.data()) < 0)
{
std::cerr << "failed to read bus " << bus
<< " address " << ii << "\n";
Expand All @@ -133,9 +192,8 @@ int get_bus_frus(int file, int first, int last, int bus,
while (length > 0)
{
auto to_get = std::min(0x20, length);
if (i2c_smbus_read_i2c_block_data(
file, area_offset, to_get,
block_data.data()) < 0)
if (read_block_data(flag, file, area_offset, to_get,
block_data.data()) < 0)
{
std::cerr << "failed to read bus " << bus
<< " address " << ii << "\n";
Expand Down

0 comments on commit 2d681f6

Please sign in to comment.