1

So I have 2 PCA9555 (16 channel digital I/O) chips connected to a small embedded device running Linux over i2c. The PCA9555 devices have 7 bit addresses 0100000 and 0100001.

When I power up the board, I run:

# modprobe i2c-i801
# modprobe i2c-dev
# i2cdetect -l
i2c-0  smbus    SMBus I801 adapter at 0500    SMBus adapter
# i2cdump -y -r 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
... (Same for every line)
70: -- -- -- -- -- -- --
# dmesg|tail
i801_smbus 0000:00:1f.3 Transaction timeout
... (For every '--' in i2cdump, one of these errors outputted)
i801_smbus 0000:00:1f.3 Transaction timeout

So then I tried to write a simple program to set all pins on the first PCA9555 chip to output high:

char *file;
unsigned char buf[3];
int addr, fd;

file = "/dev/i2c-0";
addr = 0x20; /* 0100000 */

if((fd = open(file, O_RDWR)) < 0){
  err(1, "open()");
}

if(ioctl(fd, I2C_SLAVE, addr) < 0){ /* also tried I2C_SLAVE_FORCE */
  err(1, "ioctl()");
}

/* Set all digital I/Os to output */
buf[0] = 6;
buf[1] = 0x00;
buf[2] = 0x00;

if(write(fd, buf, 3) != 3){
  err(1, "write() 1");
}

/* Set all outputs high */
buf[0] = 2;
buf[1] = 0xFF;
buf[2] = 0xFF;

if(write(fd, buf, 3) != 3){
  err(1, "write() 2");
}

return 0;

Running this returns:

# ./i2c
./i2c: write() 1: Operation not supported

So I don't really understand what I'm doing wrong. Assuming the hardware is wired correctly where do I go from here?

Kristina
  • 883
  • 1
  • 9
  • 24

1 Answers1

2

The i801 adapter only supports SMBUS transfers, and the Linux i2c core doesn't support arbitrary write calls on SMBUS adapters. You'll need to use i2c_smbus_write_word_data. The kernel documentation doesn't go into detail on this, but that's the reason it recommends using SMBUS commands.

Adrian Cox
  • 6,204
  • 5
  • 41
  • 68
  • Since I have no experience writing kernel drivers, I was really hoping to make just a basic user program to talk to the i2c devices. Since I can't use `write()` and `i2c_smbus_write_word_data()` is a kernel function, am I stuck with writing a kernel driver? – Kristina Mar 06 '11 at 14:46
  • There is a user space version of the function available through the lmsensors project: http://www.lm-sensors.org/browser/i2c-tools/trunk/include/linux/i2c-dev.h – Adrian Cox Mar 06 '11 at 18:23
  • Just updated my code: `i2c_smbus_write_word_data()` returns -1 with the error "No such device or address". I take it this means the chip is not responding to the bus? – Kristina Mar 06 '11 at 20:31
  • That's right. No such device or address is `ENXIO` which indicates no response. Can you try using `i2cdump` to probe those addresses? If this is a custom board, double check the address select pins on the PCA9555 devices. – Adrian Cox Mar 06 '11 at 21:19
  • After probing the chips it looks like theres some hardware issue. Thanks for the help! – Kristina Mar 07 '11 at 05:05