I2C SMBUS read error PCA6416 IO Expander in i.MX8MM EVK

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C SMBUS read error PCA6416 IO Expander in i.MX8MM EVK

1,382 Views
sreedhar_appala
Contributor IV

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

0 Kudos
4 Replies

1,357 Views
jimmychan
NXP TechSupport
NXP TechSupport

Is the I2C address correct?

0 Kudos

1,349 Views
sreedhar_appala
Contributor IV

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

@Igor  @wigros_sun

0 Kudos

1,338 Views
jimmychan
NXP TechSupport
NXP TechSupport

Could you check the I2C signals when you do the SMBUS read/write?

0 Kudos

1,327 Views
sreedhar_appala
Contributor IV

Hi,

Thank you, I will do when i visit office, due to this pandemic we are doing WFH.

-Sreedhar

0 Kudos