I am writing code for implementing a simple i2c
read/write function using the general linux i2c
driver linux/i2c-dev.h
I am confused about the ioctl
: I2C_SLAVE
The kernel documentation states as follows :
You can do plain i2c transactions by using read(2) and write(2) calls. You do not need to pass the address byte; instead, set it through ioctl I2C_SLAVE before you try to access the device
However I am using the ioctl I2C_RDWR
where I again set the slave address using i2c_msg.addr
.
The kernel documentation also mentions the following :
Some ioctl() calls are for administrative tasks and are handled by i2c-dev directly. Examples include I2C_SLAVE
So is it must to use the ioctl I2C_SLAVE
? If so do I need to set it just once or every time I perform a read and write?
If I had an i2c
device I could have just tested the code on the device and would not have bothered you guys but unfortunately I don't have one right now.
Thanks for the help.
There are three major methods of communicating with i2c devices from userspace.
1. IOCTL I2C_RDWR
This method allows for simultaneous read/write and sending an uninterrupted sequence of message. Not all i2c devices support this method.
Before performing i/o with this method, you should check whether the device supports this method using an ioctl
I2C_FUNCS
operation.Using this method, you do not need to perform an ioctl
I2C_SLAVE
operation -- it is done behind the scenes using the information embedded in the messages.2. IOCTL SMBUS
This method of i/o is more powerful but the resulting code is more verbose. This method can be used if the device does not support the
I2C_RDWR
method.Using this method, you do need to perform an ioctl
I2C_SLAVE
operation (or, if the device is busy, anI2C_SLAVE_FORCE
operation).3. SYSFS I/O
This method uses the basic file i/o system calls
read()
andwrite()
. Uninterrupted sequential operations are not possible using this method. This method can be used if the device does not support theI2C_RDWR
method.Using this method, you do need to perform an ioctl
I2C_SLAVE
operation (or, if the device is busy, anI2C_SLAVE_FORCE
operation).I can't think of any situation when this method would be preferable to others, unless you need the chip to be treated like a file.
Full IOCTL Example
I haven't tested this example, but it shows the conceptual flow of writing to an i2c device.-- automatically detecting whether to use the ioctl
I2C_RDWR
or smbus technique.I'm not too sure if this helps because I don't use ioctl I2C_RDWR but I've been using the following code with success:
All I do is set I2C_SLAVE_FORCE once at the beginning and I can read and write as much as I want to after that.
PS - This is just a code sample and obviously you should check the returns of all of these functions. I'm using this code to communicate with a digital I/O chip. The two i2c_* functions are just wrappers that call ioctl(fd, I2C_SMBUS, &args); where args is a struct i2c_smbus_ioctl_data type.
If you use the
read()
andwrite()
methods, callingioctl
withI2C_SLAVE
once is enough. You can also useI2C_SLAVE_FORCE
if the device is already in use.However I haven't yet found a consistent way to read specific registers for every device using the
read()/write()
methods.