diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-10-14 17:30:05 +0200 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-10-14 17:30:05 +0200 |
commit | 7c15fd1249658e203b2ac8661e48da6c2102e563 (patch) | |
tree | 273d569997d69d5606be0d76baff1354376b9c96 /Documentation/i2c | |
parent | fceb2d06800ddae53095f63843d85fcff4f701ac (diff) | |
download | linux-3.10-7c15fd1249658e203b2ac8661e48da6c2102e563.tar.gz linux-3.10-7c15fd1249658e203b2ac8661e48da6c2102e563.tar.bz2 linux-3.10-7c15fd1249658e203b2ac8661e48da6c2102e563.zip |
i2c: Document the implementation details of the /dev interface
I wrote this explanation to answer a question on the i2c mailing list,
and thought it would be good to have in the kernel documentation.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'Documentation/i2c')
-rw-r--r-- | Documentation/i2c/dev-interface | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/Documentation/i2c/dev-interface b/Documentation/i2c/dev-interface index 689a79ea5ce..3e742ba2553 100644 --- a/Documentation/i2c/dev-interface +++ b/Documentation/i2c/dev-interface @@ -167,3 +167,48 @@ The above functions are all inline functions, that resolve to calls to the i2c_smbus_access function, that on its turn calls a specific ioctl with the data in a specific format. Read the source code if you want to know what happens behind the screens. + + +Implementation details +====================== + +For the interested, here's the code flow which happens inside the kernel +when you use the /dev interface to I2C: + +1* Your program opens /dev/i2c-N and calls ioctl() on it, as described in +section "C example" above. + +2* These open() and ioctl() calls are handled by the i2c-dev kernel +driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(), +respectively. You can think of i2c-dev as a generic I2C chip driver +that can be programmed from user-space. + +3* Some ioctl() calls are for administrative tasks and are handled by +i2c-dev directly. Examples include I2C_SLAVE (set the address of the +device you want to access) and I2C_PEC (enable or disable SMBus error +checking on future transactions.) + +4* Other ioctl() calls are converted to in-kernel function calls by +i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter +functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which +performs an SMBus transaction using i2c-core.c:i2c_smbus_xfer(). + +The i2c-dev driver is responsible for checking all the parameters that +come from user-space for validity. After this point, there is no +difference between these calls that came from user-space through i2c-dev +and calls that would have been performed by kernel I2C chip drivers +directly. This means that I2C bus drivers don't need to implement +anything special to support access from user-space. + +5* These i2c-core.c/i2c.h functions are wrappers to the actual +implementation of your I2C bus driver. Each adapter must declare +callback functions implementing these standard calls. +i2c.h:i2c_get_functionality() calls i2c_adapter.algo->functionality(), +while i2c-core.c:i2c_smbus_xfer() calls either +adapter.algo->smbus_xfer() if it is implemented, or if not, +i2c-core.c:i2c_smbus_xfer_emulated() which in turn calls +i2c_adapter.algo->master_xfer(). + +After your I2C bus driver has processed these requests, execution runs +up the call chain, with almost no processing done, except by i2c-dev to +package the returned data, if any, in suitable format for the ioctl. |