Linux I2C bus (a) I2C drive frame

copy from:https://blog.csdn.net/weixin_42462202/article/details/100083025

Article directories
Linux I2C bus (a) I2C driver framework
a main target Linux I2C driven
1.1 I2C bus
1.2 I2C device
1.3 I2C driver
1.4 I2C adapter
two, Linux I2C driver framework
three, I2C driver framework source code analysis
3.1 registered I2C devices
3.2 Registration I2C driver
Construction I2C adapter 3.3
3.4 I2C data transmission
one, the main object of the Linux I2C driver
1.1 I2C bus
I2C bus I2C device for managing and I2C driver, maintain a list and device driver list, and defines the drive device matching rule, It defines the behavior after the match is successful, which is defined in the kernel are as follows

the bus_type i2c_bus_type = {struct
.name = "I2C",
.match = i2c_device_match, // matching rule
.probe = i2c_device_probe, // behavior after matching
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = & i2c_device_pm_ops,
};

1.2 I2C device
I2C device described I2C device hardware information, such as the address of the I2C device, connected to the I2C device in which an I2C controller, which structure is defined as follows

i2c_client {struct
unsigned Short addr; // device address
char name [I2C_NAME_SIZE]; // device name
struct i2c_adapter * adapter; // adapter means I2C controller
struct i2c_driver * driver; // device driver corresponding
struct device dev; / / indicates that this is a device
int irq; // interrupt number
struct the list_head Detected;
};

1.3 I2C driver
I2C driver is the driver I2C device for matching I2C device, its structure is defined as follows

i2c_driver {struct
int (* Probe) (struct i2c_client *, const struct i2c_device_id *); // Probe function
struct device_driver driver; // that this is a driving
const struct i2c_device_id * id_table; // to be matched from the device information (name )
int (* detect) (struct i2c_client *, struct i2c_board_info *); // apparatus detection function
const unsigned short * address_list; // device address
struct list_head clients; // device list
...
};

1.4 I2C adapter
I2C adapter is I2C controller software abstraction on the SOC, the hardware device can transmit data to the algorithm defined by its structure is defined as follows

i2c_adapter {struct
unsigned int ID;
unsigned int class;
const struct * i2c_algorithm Algo; // algorithm
void * algo_data;
...
struct Device dev; / * * The Device Adapter /
...
};

wherein i2c_algorithm algorithm expressed by to the hardware device to transmit data, defined as follows

struct i2c_algorithm {
int (* master_xfer) (struct i2c_adapter * ADAP, struct i2c_msg * Msgs,
int NUM);
int (* smbus_xfer) (struct i2c_adapter * ADAP, U16 addr,
unsigned Short the flags, char READ_WRITE,
U8 Command, int size, * Data i2c_smbus_data Union);
U32 (Functionality *) (* struct i2c_adapter);
};
. 1
2
. 3
. 4
. 5
. 6
. 7
. 8
summarize: the main object is driven I2C I2C bus, I2C device, I2C driver, I2C adapter

I2C bus and I2C device for managing I2C driver

I2C device description of the hardware I2C devices information

I2C driver is I2C device driver corresponding

I2C I2C controller adapter is on the SOC, which defines the algorithms, data may be transmitted to the I2C hardware

Wherein the developer to write directly to the device driver is I2C I2C device and I2C driver, I2C bus and I2C adapter is behind the scenes

Two, the Linux drive frame I2C
I2C drive frame can be divided into four parts, I2C core, I2C device, I2C driver, I2C adapter, wherein the core within the I2C bus I2C

It can be summarized by the following diagram to

 

I2C core maintains a I2C bus, I2C device provides registration, driver I2C interface I2C adapter

I2C bus maintains an equipment list and drive list, when registering the device to the I2C core layer, it is added to the device list bus, and then traverse the drive chain on the bus to see if the two match, if the match is called drive the probe function

When registering I2C driver, will be added to the drive list I2C bus, the bus then traverse device list, see both matches, if the match is called a function-driven probe

In the I2C driver, the data transmission device to the I2C hardware adapter via I2C Algorithm

Three, frame driving source analysis I2C
3.1 I2C device Register
Register I2C adaptation can i2c_new_device, this function generates a i2c_client, corresponding to the designated bus I2C bus, then the bus device to register

i2c_client * struct
i2c_new_device (ADAP struct i2c_adapter *, const struct i2c_board_info info *)
{
struct i2c_client * Client;
Client kzalloc = (the sizeof * Client, GFP_KERNEL);

Client-> dev.bus = & i2c_bus_type; // specified I2C bus

device_register (& client -> dev); // register the device to the bus
}

look at them i2c_bus_type objects, which represent the I2C bus, and device drivers defined matching rules as well as matching behavior after the success of

the bus_type i2c_bus_type = {struct
.name = "I2C",
.match = i2c_device_match, // matching rule
.probe = i2c_device_probe, // matching behavior after successful
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = & i2c_device_pm_ops,
};

the following look at what happens to the bus device_register registration process equipment

device_register will first bus unit to the unit list, and then traversing the linked list drive bus, and the device driver determines whether the system matches the drive probe function is called, the following source code analysis to look

device_register int (* struct Device dev)
{
device_add (dev);
}

int device_add (struct Device * dev)
{
bus_add_device (dev); // add devices to the device list in the bus

driver // Loop bus; bus_probe_device (dev)
}

wherein the function will bus_add_device unit to the unit bus in the list, the following

bus_add_device int (* struct Device dev)
{
klist_add_tail (& the dev-> p-> knode_bus, & BUS-> p-> klist_devices);
}
. 1
2
. 3
. 4
bus_probe_device simply iterates through the list bus driver, as follows

bus_probe_device void (* struct Device dev)
{
device_attach (dev);
}
. 1

int device_attach (struct Device * dev)
{
/ * list traverse driving bus * /
bus_for_each_drv (the dev-> Bus, NULL, dev, __device_attach);
}

bus_for_each_drv (dev-> bus, NULL, dev , __device_attach); traverses each of the bus driver list, then call __device_attach

static int __device_attach (struct the device_driver * DRV, void * Data)
{
IF (driver_match_device (DRV, dev)!)
return 0;

return driver_probe_device (DRV, dev);
}

driver_match_device function determination device and a driving match, if a match is called driver_probe_device

First, let's look at the definition of the function driver_match_device

int driver_match_device inline static (struct the device_driver DRV *,
struct Device * dev)
{
return Drv-> BUS-> match Drv-> BUS-> match (dev, DRV):?. 1;
}

found to match function calls bus, here bus I2C device at the time of registration has been set to the I2C bus, as defined below

the bus_type i2c_bus_type = {struct
.name = "I2C",
.match = i2c_device_match, // matching rule
.probe = i2c_device_probe, // behavior after matching
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = & i2c_device_pm_ops,
};

so here the name i2c_device_match function calls, i2c_device_match be driven by each id_table I2C I2C device name and matching

static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
const struct i2c_client *client)
{
while (id->name[0]) {
if (strcmp(client->name, id->name) == 0) //字符串匹配
return id;
id++;
}
return NULL;
}

int i2c_device_match static (struct Device dev *, struct the device_driver * DRV)
{
i2c_match_id (driver-> id_table, Client);
}

If a match calls driver_probe_device, following look driver_probe_device

driver_probe_device function will eventually call the first function to probe the I2C bus, I2C driver and then call a function of probe

int driver_probe_device (struct the device_driver * DRV, struct Device * dev)
{
really_probe (dev, DRV);
}

static int really_probe (struct Device * dev, struct the device_driver * DRV)
{

}


Probe function of bus lines is i2c_device_probe, this function calls the driver the probe function

int i2c_device_probe static (struct Device * dev)
{
/ * calls on the driver's probe function * /
driver-> probe (Client, i2c_match_id (driver-> id_table, Client));
}

3.2 registered I2C driver
can be driven by I2C register i2c_add_driver, the function corresponding to the specified drive bus I2C bus, and then driven to the bus register,

i2c_register_driver int (* struct Module1 owner, struct i2c_driver * Driver)
{
driver-> driver.bus = & i2c_bus_type; // specified I2C bus

driver_register (& driver-> driver); // Register the bus driver
}

i2c_bus_type defined as follows

the bus_type i2c_bus_type = {struct
.name = "I2C",
.match = i2c_device_match, // matching rule
.probe = i2c_device_probe, // behavior after matching
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = & i2c_device_pm_ops,
};

driver_register function list traverse device bus operation, and then add the drive to the drive chain of the bus

driver_register int (* struct the device_driver DRV)
{
bus_add_driver (DRV);
}

int bus_add_driver (struct the device_driver * DRV)
{
driver_attach (DRV); // This function will traverse the list bus device operating

klist_add_tail (& priv-> knode_bus, & bus-> p-> klist_drivers); // add to the bus driver the list
}

int driver_attach (struct the device_driver * DRV)
{
/ * list traverse device bus, * call __driver_attach /
bus_for_each_dev (Drv-> bus, NULL, DRV, __driver_attach );
}

Let's look __driver_attach function, this function determines whether the device driver and the system matches the probe function is called driving

int __driver_attach static (struct Device dev *, void * Data)
{
IF (driver_match_device (DRV, dev)!)
return 0;

driver_probe_device (DRV, dev);
}

procedure of this registration process and apparatus is the same, there is no longer analysis

Construction of 3.3 I2C adapter
for I2C adapter, we do not discuss the details of its registration, we see how it is built

For Samsung platform, built and registered I2C adapter drivers \ i2c \ busses \ i2c-s3c2410.c file, which is driving the Samsung platform I2C controller

static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
.master_xfer = s3c24xx_i2c_xfer,
.functionality = s3c24xx_i2c_func,
};

int s3c24xx_i2c_probe static (struct * platform_device PDEV)
{
I2C-> adap.algo = & s3c24xx_i2c_algorithm; // Construction algorithm

i2c_add_numbered_adapter (& i2c-> adap); // Register the adapter
}

s3c24xx_i2c_algorithm s3c24xx_i2c_xfer wherein in operation is through register by I2C controller transfers data

3.4 I2C data transfer
introduced above I2C data transfer is done via the I2C adapter, to analyze the following source

In the I2C driver using i2c_transfer I2C data to transmit, this function must be operated by I2C adapter algorithm, as follows

i2c_transfer int (* struct i2c_adapter ADAP, struct i2c_msg Msgs *, int NUM)
{
adap-> algo-> master_xfer (ADAP, Msgs, NUM); // call algorithm adapter
}

----------- -----
Disclaimer: this article is the original article CSDN bloggers "programmer JT", and follow CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
Original link: https: //blog.csdn.net/weixin_42462202/article/details/100083025

Guess you like

Origin www.cnblogs.com/Oude/p/12441068.html
I2C