Linux operating system I2C driver architecture explanation

Source: Internet
Author: User

Linux operating system I2C driver architecture explanation ()

Recently, due to work requirements, the I2C bus has been involved. Although I used I2C in the past, I found that a layer can be perfected only after reading Linux kernel.

1. Linux I2C driver rack

In Linux, I2C bus drivers are divided into two parts: Bus and device ). The role of the bus driver is to add corresponding read/write methods for each I2C bus in the system. However, the bus driver does not communicate with each other. It only exists and waits for the device driver to call its function.

A device driver is a driver that communicates with a specific device mounted on the I2C bus. Using the functions provided by the I2C bus driver, device drivers can ignore the differences between different bus controllers and communicate with hardware devices without considering their implementation details.

1.1. Bus Driver

When the system is started, the I2C bus driver is first loaded. A bus driver is used to support reading and writing of a specific I2C bus. A bus driver usually requires two modules, a struct i2c_adapter and a struct i2c_algorithm to describe:

static struct i2c_adapter pb1550_board_adapter = 


name: "pb1550 adapter",

id: I2C_HW_AU1550_PSC,

algo: NULL,

algo_data: &pb1550_i2c_info,

inc_use: pb1550_inc_use,

dec_use: pb1550_dec_use,

client_register: pb1550_reg,

client_unregister: pb1550_unreg,

client_count: 0,


In this example, a driver named "pb1550 adapter" is attached. However, this module does not provide read/write functions. The specific read/write method is provided by the second module, struct i2c_algorithm.

static struct i2c_algorithm au1550_algo = 


 .name = "Au1550 algorithm",

 .id = I2C_ALGO_AU1550,

 .master_xfer = au1550_xfer,

 .functionality = au1550_func,


i2c_adap->algo = &au1550_algo;

This example adds a read/write "algorithm" to the above bus driver ". Generally, each I2C bus driver defines a read/write algorithm. However, some bus use the same algorithm, so they can share the same set of read/write functions. In this example, the driver defines its own read/write Algorithm Module named "au1550 algorithm ".

After completing all the information, call:


Register the two modules in the operating system, and the bus driver is installed. For amd au1550, this Part has been provided by AMD.

1.2 Device Drivers

As mentioned above, bus drivers only provide a read/write mechanism for a bus and do not communicate with each other. Communication is implemented by I2C device drivers. Device Drivers communicate with specific devices through I2C bus. A device driver consists of two modules, struct i2c_driver and struct i2c_client.

After the system is started and the I2C bus driver is loaded, the device driver can be loaded. First, load the following structure:

static struct i2c_driver driver = 


.name = "i2c TV tuner driver",


.flags = I2C_DF_NOTIFY,

.attach_adapter = tuner_probe,

.detach_client = tuner_detach,

.command = tuner_command,



Once the i2c_driver is loaded, the attach_adapter function will be called. You can traverse each I2C bus driver in the system to detect the devices you want to access:

static int tuner_probe(struct i2c_adapter *adap) 


 return i2c_probe(adap, &addr_data, tuner_attach);


Note that multiple devices may be found, so not only can one I2C bus be mounted to multiple devices of different types, a device driver can also serve devices mounted on multiple different I2C buses at the same time.

Whenever a device driver detects a device that it supports, it creates a struct i2c_client to identify the device:

new_client->addr = address;

new_client->adapter = adapter;

new_client->driver = &driver;

/* Tell the I2C layer a new client has arrived */

err = i2c_attach_client(new_client);

if (err)

goto error;

It can be seen that an i2c_client is located on the adapter bus and the address is address. A device is driven by a driver. It binds the bus driver with the device driver and the device address. An i2c_client represents an I2C device.

After obtaining the I2C device, you can directly read and write the device:


* The master routines are the ones normally used to transmit data to devices

* on a bus (or read from them). Apart from two basic transfer functions to

* transmit one message at a time, a more complex version can be used to

* transmit an arbitrary number of messages without interruption.


extern int i2c_master_send(struct i2c_client *,const char* ,int);

extern int i2c_master_recv(struct i2c_client *,char* ,int);

Generally, the Read and Write functions are the same. These two functions read and write int Char to the device specified by the i2c_client pointer. The returned value is the number of bytes read/write. For our existing SLIC drive
As long as the data to be read and written to the bus is transmitted to the two functions, the porting is completed, and we will get a Linux I2C device driver.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.