Recently, I am working on a capacitive touch screen driver and using I2C bus interfaces to transmit data. So let's take a look at the I2C bus principles.
The I2C bus is a character transmission bus between chips launched by Philips. It adopts two-wire system, which consists of the serial clock line SCL and serial data line SDA. In the circuit design, the I2C bus interface is open or open collector output, and the pull-up resistance is required.
I2C bus communication mode:
(1) I2C uses the Master/Slave Mode for bidirectional communication.
(2) The Clock line of the I2C bus and the data line SDA are both bidirectional transmission lines.
(3) In standard I2C mode, the data transmission rate can reach 100 kbps, 400 kbps, and 3.4 Mbit/s in high-speed (HS) mode.
(4) During the High-level period of the clock line, the SDA of the data line starts I2C when the signal S starts when the SDA changes from the high-level to the low-level. If the signal P is stopped when the SDA of the data line changes from low to high during the high-level period of the clock line SCL, the I2C bus data transmission is terminated.
(5) I2C bus Transmission Format: After the start bit, the master device sends 8-bit control bytes to select the direction from the device and control the bus transmission, and then transmit data.
The Linux I2C architecture consists of three parts:
(1) I2C Core
File Path: Linux/driver/I2C/i2c-core.c this file implements I2C core functions and/proc/bus/i2c-xxx interfaces.
(2) I2C bus driver
File Path: Linux/driver/I2C/busses/i2c-xxx.c this file contains I2C bus drivers for various arm processors. The I2C bus driver mainly includes the i2c_adapter data structure of the I2C adapter, the algorithm Data Structure i2c_algorithm of the I2C adapter, and the function that controls the communication signal generated by the I2C adapter.
(3) I2C Device Driver
The I2C Device Driver mainly includes the data structure i2c_driver and i2c_client. We need to implement the member functions based on the specific device.
Four important data structures in I2C bus drivers.
I2C adapter struct:
The i2c_adapter corresponds to a physical adapter.
/* I2c_adapter is the structure used to identify a physical I2C bus along with the access algorithms necessary to access it .*/
Struct i2c_adapter {
Struct module * owner;
Unsigned int ID;
Unsigned int class;/* classes to allow probing */
Const struct i2c_algorithm * algo;/* the algorithm to access the bus */
Void * algo_data;
/* Data fields that are valid for all devices */
U8 level;/* nesting level for lockdep */
Struct mutex bus_lock;
Int timeout;/* In jiffies */
Int retries;
Struct device dev;/* the adapter device */
Int NR;
Char name [48];
Struct completion dev_released;
};
I2C communication method structure:
I2c_algorithm corresponds to a set of communication methods. The key function master_xfer () in I2C -- algorithm is used to generate signals required for I2C access periods.
Struct i2c_algorithm {
/* If an adapter algorithm can't do I2C-level access, set master_xfer
To null. If an adapter algorithm can do SMBus access, Set
Smbus_xfer. If set to null, The SMBus protocol is simulated
Using common I2C messages */
/* Master_xfer shoshould return the number of messages successfully
Processed, or a negative value on Error */
INT (* master_xfer) (struct i2c_adapter * ADAP, struct i2c_msg * msgs,
Int num );
INT (* smbus_xfer) (struct i2c_adapter * ADAP, 2010addr,
Unsigned short flags, char read_write,
U8 command, int size, Union i2c_smbus_data * data );
/* To determine what the adapter supports */
U32 (* functionality) (struct i2c_adapter *);
};
I2C device driver structure:
I2c_driver corresponds to a set of driver methods.
/* The i2c_client structure which is handed to the @ detect callback is
* Not a real i2c_client. It is initialized just enough so that you can
* Call i2c_smbus_read_byte_data and friends on it. Don't do anything
* Else with it. In particle, calling dev_dbg and friends on it is
* Not allowed.
*/
Struct i2c_driver {
Int ID;
Unsigned int class;
/* Notifies the driver that a new bus has appeared or is about to be
* Removed. You shoshould avoid using this if you can, it will probably
* Be removed in a near future.
*/
INT (* attach_adapter) (struct i2c_adapter *);
INT (* detach_adapter) (struct i2c_adapter *);
/* Standard driver model interfaces */
INT (* probe) (struct i2c_client *, const struct i2c_device_id *);
INT (* remove) (struct i2c_client *);
/* Driver Model interfaces that don't relate to enumeration */
Void (* shutdown) (struct i2c_client *);
INT (* suspend) (struct i2c_client *, pm_message_t mesg );
INT (* resume) (struct i2c_client *);
/* A ioctl like command that can be used to perform specific functions
* With the device.
*/
INT (* command) (struct i2c_client * client, unsigned int cmd, void * Arg );
Struct device_driver driver;
Const struct i2c_device_id * id_table;
/* Device Detection callback for automatic device creation */
INT (* detect) (struct i2c_client *, int kind, struct i2c_board_info *);
Const struct i2c_client_address_data * address_data;
Struct list_head clients;
};
I2C client structure:
The i2c_client corresponds to a real physical device. Each I2C device must be described by an i2c_client.
Struct i2c_client {
Unsigned short flags;/* Div., see below */
Unsigned short ADDR;/* chip address-Note: 7bit */
/* Addresses are stored in */
/* _ Lower _ 7 bits */
Char name [i2c_name_size];
Struct i2c_adapter * adapter;/* the adapter we sit on */
Struct i2c_driver * driver;/* and our access routines */
Struct device dev;/* The device structure */
Int IRQ;
/* IRQ issued by device */
Struct list_head detected;
};
These four data structures are closely related. An I2C adapter requires the communication function provided in i2c_algorithm to control the generation of a specific access cycle on the adapter. The i2c_adapter without i2c_algorithm cannot do anything. Therefore, the i2c_adapter contains the i2c_algorithm pointer. The relationship between i2c_driver and i2c_client is one-to-multiple. One i2c_driver can support multiple i2c_clients of the same type.