NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-arm/48933: Raspberry Pi i2c ioctl() does not allow just READ operation on the i2c bus



>Number:         48933
>Category:       port-arm
>Synopsis:       Raspberry Pi i2c ioctl() does not allow just READ operation on 
>the i2c bus
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-arm-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jun 21 01:45:00 +0000 2014
>Originator:     Yunis Mustafa
>Release:        evbarm-earmhf/201405181900Z
>Organization:
>Environment:
NetBSD rpi 6.99.42 NetBSD 6.99.42 (RPI) #0: Sun May 18 20:34:46 UTC 2014  
builds%b44.netbsd.org@localhost:/home/builds/ab/HEAD/evbarm-earmhf/201405181900Z-obj/home/builds/ab/HEAD/src/sys/arch/evbarm/compile/RPI
 evbarm
>Description:
i2c ioctl(I2C_IOCTL_EXEC, I2C_OP_READ) call always does an i2c write operation 
to the slave device before the i2c read operation. 

The i2c slave device I am working with NACKs read requests if it is busy. And 
the recommended recovery mechanism is to retry the read i2c operation again. 
But I am unable to because of this. And I couldn't find another mechanism to do 
just a read i2c operation without a leading write i2c operation. 

i2c bus protocal capture screenshots available for more information. However 
unsure how to upload that with this PR.

>How-To-Repeat:
- Compile sample code below
- Setup the i2c bus capture (I used a saleae product)
- run "a.out /dev/iic[01]"
- Notice the write i2c operation before read i2c operation in the bus capture.



#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <dev/i2c/i2c_io.h>

int
main(int argc, char *argv[])
{
        int                 fd;
        i2c_ioctl_exec_t    iie;


        if (argc != 2) printf("Error: %s <i2cdev>\n", argv[0]);

        fd = open(argv[1], O_RDWR);
        if (fd == -1)
    {
                printf("couldn't open %s", argv[1]);
        exit(1);
    }



    // Read
        iie.iie_op = I2C_OP_READ;
        iie.iie_addr = 0x11;
        iie.iie_cmd = NULL;
        iie.iie_cmdlen = 0;
        iie.iie_buf = dataBuf;
        iie.iie_buflen = 2;

        if (ioctl(fd, I2C_IOCTL_EXEC, &iie) == -1)
        perror("ioctl READ ");
    else
        printf("ioctl READ Success %02x:%02x\n", dataBuf[0], dataBuf[1]);


        close(fd);

        exit(0);
}

>Fix:



Home | Main Index | Thread Index | Old Index