1

我有一个支持 SMBus/I2C 的带有 EEPROM 的 PCI 设备。我想创建一个可以读取和写入目标 EEPROM 的用户空间应用程序 (Linux)。类似于 IPMI 在每个 SSD/NVME 设备上查询 VPD 信息时所做的事情。但是,我很难查询目标 i2c 总线和 i2c 设备。我正在使用 i2cdetect 查询 i2c 总线,但我无法定位是否检测到我的目标设备。问题,我还需要知道我的设备连接到的 i2c 总线/适配器吗?这是怎么做的?我一直在研究如何创建应用程序,甚至在考虑开发驱动程序。

我已经解决这个问题好几个星期了,希望有人可以帮助我解决这个问题。非常感谢!!!

4

1 回答 1

-1

显示如下:

$i2c检测-l

i2c-0 i2c i915 gmbus dpc I2C 适配器

i2c-1 i2c i915 gmbus vga I2C 适配器

i2c-6 smbus SMBus I801 适配器在 e000 SMBus 适配器

$i2cdetect -y 6 #EEPROM 主要位于0x54设备位置。

0 1 2 3 4 5 6 7 8 9 abcdef

00: -- -- -- -- -- 08 -- -- -- -- -- -- --

10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

20: -- -- -- -- -- -- -- -- -- -- -- -- -- 2d -- --

30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

50: 50 -- -- -- 54 55 56 57 -- -- -- -- -- -- -- --

60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

70: -- -- -- -- -- -- -- -- --

https://www.kernel.org/doc/Documentation/i2c/dev-interface对 API 使用有更好的解释。

要在 SMBus 上使用特定设备:

static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command, int size, union i2c_smbus_data *data)
{
          struct i2c_smbus_ioctl_data args;

          args.read_write = read_write;
          args.command = command;
          args.size = size;
          args.data = data;

        return ioctl(file,I2C_SMBUS,&args);
}

static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
        union i2c_smbus_data data;
        if (i2c_smbus_access(file, I2C_SMBUS_READ, command, I2C_SMBUS_WORD_DATA,&data))
                return -1;
        else
         {       printf("word before returning%x\n",data.word);
                return 0x0FFFF & data.word;
         }
}

int main( void)
{
        uint8_t data=0x55 , addr = 0x54, reg = 0x0d;
        const char *path = "/dev/i2c-6";  // SmBus
        int file;
        if ( (file=open( path , O_RDWR)) < 0)
                err(errno, "Tried to open but not working'%s'", path);

        if ( ioctl(file, I2C_SLAVE, addr ) < 0)
                err(errno, "Tried to set device address '0x%02x'", 0x01);
        data = i2c_smbus_read_byte_data(file, reg);
        printf("%s: device at address 0x%02x: date : 0x%02x\n", path, reg, data);

    return 0;
}
于 2018-04-26T20:36:14.123 回答