Hi,
I am working with 4.19 imx-warrior distro and with i.mx8mm evk hw.
I am able to access the IO expander gpios using /sys/class/gpio interface.
at a time we can access one gpio value using /sys/class/gpio interface. but
I intended to read all values of IO expander PCA6416 using i2c device interface
(I followed the kernel documentation dev-interface)
I have succesfully opened the device and detected the slave,
but when i tried to read the port values (16-bit). I am getting -6 (0xfffffffa)
Please find my code below:
/**************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
extern "C" {
#include <linux/i2c-dev.h>
#include "smbus.h"
}
int main()
{
int ret = 0;
int fd;
int adapter_nr = 2;
short u201_val = 0;
char filename[20];
snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
fd = open(filename, O_RDWR);
if (fd < 0) {
fprintf(stderr," i2c dev interface opened \n");
return 1;
} else {
fprintf(stdout," i2c dev interface opened \n");
}
int addr = 0x40; /* The I2C address 0x20 << 1*/
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr," i2c slave not detected \n");
return 1;
} else {
fprintf(stdout," i2c slave is detected \n");
}
if (ioctl(fd, I2C_FUNCS, &funcs) < 0) {
fprintf(stderr," i2c funcs not detected \n");
return 1;
}
if (!(funcs & I2C_FUNC_SMBUS_READ_WORD_DATA)) {
fprintf(stderr," Oops, the needed functionality \n");
return (1);
} else {
fprintf(stdout," the needed functionality supported \n");
}
fprintf(stdout," i2c slave read start \n");
u201_val = i2c_smbus_read_word_data(fd,0x00);
fprintf(stdout," u201_val : 0x%04x \n", u201_val);
if ( u201_val < 0) {
fprintf(stderr," i2c read failed, u201_val : %d \n", u201_val);
} else {
fprintf(stdout," i2c read success, u201_val: 0x%04x \n", u201_val);
}
return 0;
}
/************************************************************************************/
As per the read protocol timing diagram of the pca6416 datasheet
i have identified the appropriate API for smbus read.
i2c_smbus_read_word_data
command value = 0x00, for input port reading.
I have checked the functionality of I2C_FUNC_SMBUS_READ_WORD_DATA
it is supported.
ps: I have installed the following package:
sudo apt-get install libi2c-dev
I have linked the the library -L ./libs/libi2c.so.0 ./libs/libi2c.so.0.1.0 in makefile.
i2c_smbus_read_word_data call is failing to get the input port values of IO expander. it is returning -6.
instead of smbus, i tried plain read call, it also returned the same.
Please let me know your inputs. where i am doing wrong.
Thank you, Sreedhar
Is the I2C address correct?
Hi Jimmychan,
Yes address is correct, It is passing the below function.
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr," i2c slave not detected \n");
return 1;
} else {
fprintf(stdout," i2c slave is detected \n");
You can check running the code, i have posted. please let me know the solution.
Thank you, Sreedhar
Could you check the I2C signals when you do the SMBUS read/write?
Hi,
Thank you, I will do when i visit office, due to this pandemic we are doing WFH.
-Sreedhar