分类: LINUX
2008-10-31 18:59:03
Distribution Guide Device drivers Inter-IC (I2C) |
The I2C bus is a simple interconnect for low data rate communications in embedded applications. Only two signals are required, and multiple devices can be attached to a single bus as shown in Figure 2: Multiple devices on a single bus.
|
More recent variants support operation up to 2 MHz. It is now used by a large number of manufacturers, and parts are available for numerous monitoring, control and audio/visual applications. For more details on the bus and protocols, see the site.
A variant of I2C, called , is now frequently used in x86 based PC systems for system management and monitoring. It is frequently possible to mix and match I2C and SMBus devices, although there are some differences. The differences are discussed in a Maxim .
Linux support for I2C grew out of the project to support the hardware health monitors such as the LM78 and LM75, but has now been extended to other classes of hardware. The site has some documentation on how to use the various I2C software interfaces, both from user and kernel mode.
The ST distribution 2.0 supports two different methods for interfacing with I2C devices:
I2C devices communicate over the physical bus using a standard protocol. Each I2C operation (called a transaction) consists of a "Start Condition" followed by the bus master writing a "Slave Address" to select a device. The type of operation (read or write) is written and then, if the slave responds, the master writes/reads data byte-by-byte to/from the bus until the transaction is closed with a "Stop Condition".
Note: After a stop condition, it is mandatory for the bus to be idle for a number of microseconds.
An I2C operation is shown in .
|
When there are repeated transactions, the I2C standard supports a "Repeat Start Condition". This avoids too much time being spent on the "Stop Condition - Idle - Start Condition" phase.
This "RepStart" mode is shown in .
|
This mode is supported by the SSC driver in Linux.
By default, Linux kernel distributions 2.0 and later, include I2C "Bit-Banging" support. This support must be configured as before (see ). Bring up the Linux Kernel Configuration screen and enter the following sections in the order given:
Device Drivers --->
I2C Support ---> I2C Support
Device Drivers --->
I2C Support ---> I2C device interface
Either:
Device Drivers --->
I2C Hardware Bus Support ---> STMicroelectronics I2C Support ---> I2C bit-banging PIO driver
, or
Device Drivers --->
I2C Hardware Bus Support ---> STMicroelectronics I2C Support ---> I2C hardware SSC driver
.
The I2C based on the SSC is supported on the following platforms:
|
The I2C algorithm and adapter provide the low-level hardware control which drive the bus. It is these functions that are implemented by the ST Linux drivers in order to drive the I2C on ST hardware. For further technical details, see the at .
The I2C driver is a kernel driver which controls a particular type of device. Each instance of a device (for example, the same type of device on different buses) is handled as a separate client.
More information can be found in the linux kernel source code directory under Documentation/i2c/summary
.
The Linux kernel I2C "I2C device interface" provides an I2C driver where the clients are associated with all devices on a particular I2C bus. A standard character device interface for selecting a particular device on a particular bus, setting its properties and reading/writing to the bus and device from user-space is then provided.
Each STMicroelectronics' SoC can be equipped with a number of SSC devices, or a number of I2C buses can be set up on different sets of PIO pins. In both cases, the software drivers assume that the buses are independent.
Each I2C bus is assigned a device node of /dev/i2c-
n
(where n
is the number of the bus).
The device nodes are character devices with permission, device name, and major and minor numbers:
crw-rw-rw- /dev/i2c-
n
89
n
More information can be found in the Linux kernel source code directory under Documentation/i2c/dev-interface
. Example code for using this interface is given below.
I2C_RETRIES
1
.
I2C_TIMEOUT
4
seconds (for each I2C message).
I2C_SLAVE
I2C_RDWR
i2c_msg
object. This object generates a single I2C transaction (with stop bit). I2C_RDWR
ioctl. I2C_RDWR
ioctl the user application releases to the kernel, a struct i2c_rdwr_ioctl_data
object which holds a pointer to the struct i2c_msg
and the array size. When the user application uses the I2C_RDWR
ioctl it does not need the I2C_SLAVE
ioctl because it has to specify the following for each struct i2c_msg
object:
addr
field,
flags
field,
len
field,
buf
field.
The i2c_msg
and i2c_rdwr_ioctl_data
struct definitions are shown below:
|
I2C_STM_IOCTL_FAST
./drivers/i2c/algos/i2c-algo-stm.h
. The default value is 0
.
This simple example demonstrates how to use the I2C character device interface from user space. It reads size
bytes at the memory address mem_addr
from an eeprom (M24c64 with slave address 0x50) on the /dev/i2c-x
bus.
In this example, the user application does not manage an i2c_msg
struct and it sets the slave address with the I2C_SLAVE
ioctl.
|
The next example shows how to use the I2C_RDWR
ioctl.
|
Note: When the user application uses the I2C_RDWR
ioctl, the I2C kernel subsystem starts to send the I2C messages, but if during the transaction the kernel meets some problem (for example, a NOTACK) it will stop all the I2C transactions and return an error code to the user application.
Implementing an I2C driver is relatively straightforward. A good introduction is given in the Linux kernel source code directory under Documentation/i2c/writing-clients
.
For further technical details, see the at .