diff options
author | Jean Delvare <khali@linux-fr.org> | 2008-10-14 11:30:05 -0400 |
---|---|---|
committer | Jean Delvare <khali@mahadeva.delvare> | 2008-10-14 11:30:05 -0400 |
commit | 7c15fd1249658e203b2ac8661e48da6c2102e563 (patch) | |
tree | 273d569997d69d5606be0d76baff1354376b9c96 | |
parent | fceb2d06800ddae53095f63843d85fcff4f701ac (diff) |
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>
-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 689a79ea5ce7..3e742ba25536 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 | |||
167 | the i2c_smbus_access function, that on its turn calls a specific ioctl | 167 | the i2c_smbus_access function, that on its turn calls a specific ioctl |
168 | with the data in a specific format. Read the source code if you | 168 | with the data in a specific format. Read the source code if you |
169 | want to know what happens behind the screens. | 169 | want to know what happens behind the screens. |
170 | |||
171 | |||
172 | Implementation details | ||
173 | ====================== | ||
174 | |||
175 | For the interested, here's the code flow which happens inside the kernel | ||
176 | when you use the /dev interface to I2C: | ||
177 | |||
178 | 1* Your program opens /dev/i2c-N and calls ioctl() on it, as described in | ||
179 | section "C example" above. | ||
180 | |||
181 | 2* These open() and ioctl() calls are handled by the i2c-dev kernel | ||
182 | driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(), | ||
183 | respectively. You can think of i2c-dev as a generic I2C chip driver | ||
184 | that can be programmed from user-space. | ||
185 | |||
186 | 3* Some ioctl() calls are for administrative tasks and are handled by | ||
187 | i2c-dev directly. Examples include I2C_SLAVE (set the address of the | ||
188 | device you want to access) and I2C_PEC (enable or disable SMBus error | ||
189 | checking on future transactions.) | ||
190 | |||
191 | 4* Other ioctl() calls are converted to in-kernel function calls by | ||
192 | i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter | ||
193 | functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which | ||
194 | performs an SMBus transaction using i2c-core.c:i2c_smbus_xfer(). | ||
195 | |||
196 | The i2c-dev driver is responsible for checking all the parameters that | ||
197 | come from user-space for validity. After this point, there is no | ||
198 | difference between these calls that came from user-space through i2c-dev | ||
199 | and calls that would have been performed by kernel I2C chip drivers | ||
200 | directly. This means that I2C bus drivers don't need to implement | ||
201 | anything special to support access from user-space. | ||
202 | |||
203 | 5* These i2c-core.c/i2c.h functions are wrappers to the actual | ||
204 | implementation of your I2C bus driver. Each adapter must declare | ||
205 | callback functions implementing these standard calls. | ||
206 | i2c.h:i2c_get_functionality() calls i2c_adapter.algo->functionality(), | ||
207 | while i2c-core.c:i2c_smbus_xfer() calls either | ||
208 | adapter.algo->smbus_xfer() if it is implemented, or if not, | ||
209 | i2c-core.c:i2c_smbus_xfer_emulated() which in turn calls | ||
210 | i2c_adapter.algo->master_xfer(). | ||
211 | |||
212 | After your I2C bus driver has processed these requests, execution runs | ||
213 | up the call chain, with almost no processing done, except by i2c-dev to | ||
214 | package the returned data, if any, in suitable format for the ioctl. | ||