Linux device driver Subsystem first bullet-I2C __linux

Source: Internet
Author: User
Tags int size

1. Overview

2. Data Structure

3. Adapter

4. I2c-core

5. Slave Device

1. Overview

1.1 Definition I2C inter-integrated circuit SMBUS System Management Bus, the I2C subset

1.2 Characteristics  The amount of data exchanged is small. The required data transfer rate is low.

1.3 Speed Fast speed Kbps Full speed Kbps

1.4 Topology

2 Data Structure

Understanding the data structure is important to understanding the entire driver subsystem. There are two major data structures in I2C, struct i2c_client and struct i2c_adapter.

2.1 i2c_client

struct I2c_client {
unsigned short flags; /* Div., below *
unsigned short addr; /* Chip Address * *
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 (OR-1) * *
Char Driver_name[kobj_name_len];
struct List_head list; * Deprecated * *
struct completion released;
};

The struct i2c_client represents a I2C from the device that is mounted on the I2C bus, the data structure required by the device, including the I2C main device that the I2C attaches to the device struct I2c_adapter *adapter The I2C from the device driver struct I2c_driver *driver as a member variable that I2C from the device, such as addr, name, and so on, which is specific to the device driver, attached to I2C

2.2 I2c_adapter

struct I2c_adapter {
struct module *owner;
unsigned int id;
unsigned int class;
const struct I2C_ALGORITHM *algo; * * The algorithm to access the bus * *
void *algo_data;

... ...

};
struct I2c_adapter represents a I2C master device supported by the main chip, the data structure required by the device,

Among them, struct i2c_algorithm *algo is a kind of algorithm that transmits data to the I2C main equipment, or it is a kind of ability that completes the communication between master and slave devices on the I2C bus.

     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 flags, char Read_write,
                     u8 command, int size, Union i2c_smbus_data * data);
        u32 (*functionality) (struct i2c_adapter *);
    };

Next, to realize the whole I2C subsystem drive, then around the two data structures, the main steps can be summed up as the following three steps to achieve I2C main device driver (drivers/i2c/bus/*) registration I2C from the device i2c_client (drive Rs/i2c/i2c-core) implement I2C from device driver

3 Adapter

Kernel directory DRIVERS/I2C has two folders, algorithm and bus, where the bus storage I2C main device driver, the main device driver completes two major tasks, provides the I2C the main equipment and from the equipment to complete the communication between the ability to complete the i2c_ Adapter and the registration of all known I2c_client

Taking I2C-PXA.C as an example,

* DRIVERS/I2C/BUS/I2C-PXA.C * *

static int __init i2c_adap_pxa_init (void)
{
Return Platform_driver_register (&i2c_pxa_driver);
}

static struct Platform_driver I2c_pxa_driver = {
. Probe = I2c_pxa_probe,
... ...
. id_table = i2c_pxa_id_table,
};

static int i2c_pxa_probe (struct platform_device *dev)
{
struct PXA_I2C *i2c;
I2c->adap.algo = I2c_pxa_algorithm; Provides the ability of the I2C master device to complete data communication from the device

I2c_add_numbered_adapter (&I2C->ADAP); Call the interface function in I2C-CORE.C to complete the registration of the I2c_adapter and i2c_client

  ... ...
}

static const struct I2c_algorithm I2c_pxa_algorithm = {
. Master_xfer = I2c_pxa_xfer, complete I2C data transfer according to PXA specific chip requirements
. functionality = I2c_pxa_functionality,
};

4 I2c-core

Kernel directory drivers/i2c i2c-core.c, as the name suggests, is the kernel for the I2C provided by the unified system interface.

Look what I2c_add_numbered_adapter did,

int I2c_add_numbered_adapter (struct i2c_adapter *adap)
{
... ...
Status = I2c_register_adapter (ADAP);
return status;
}

static int i2c_register_adapter (struct i2c_adapter *adap)
{
... ...
Device_register (&adap->dev); Complete the registration of I2C Master device adapter, that is, register object and send Uevent etc.
I2c_scan_static_board_info (ADAP);

... ...
}
I2c_scan_static_board_info (ADAP), which is the core of the entire I2C subsystem, goes through a two-way circular list of I2C from the device and completes all I2C registration from the device i2c_client, as follows,

static void I2c_scan_static_board_info (struct i2c_adapter *adapter)
{
struct I2c_devinfo *devinfo; I2C has been set up from the equipment linked list


List_for_each_entry (DevInfo, &__i2c_board_list, list) {
I2c_new_device (Adapter,&devinfo->board_info);
... ...
}
}

struct i2c_client *i2c_new_device (struct i2c_adapter *adap, struct i2c_board_info const *info)
{
... ...
I2c_attach_client (client);
... ...

}
int i2c_attach_client (struct i2c_client *client)
{
... ...
Device_register (&client->dev); Complete registration of I2C from the device client
... ...
}

So, when did this I2C from the device to the two-way cycle of the list, when it was established by what way.

Take a gravity induction device for example,

*/ARCH/ARM/MACH-PXA/STARWOOD_P1.C * *

static void __init saar_init (void)

{

... ...

I2c_register_board_info (0, Array_and_size (saar_i2c_bma220_info));

... ...

}

static struct I2c_board_info saar_i2c_bma220_info[] = {
{
. driver_name = "bma220",
. addr = 0x0b,
. IRQ = Irq_gpio (Mfp_to_gpio (MFP_PIN_GPIO15)),
},
};

* DRIVERS/I2C/I2C-BOARDINFO.C * *

int __init i2c_register_board_info (int busnum, struct i2c_board_info const *info, unsigned len)
{

... ...

struct I2c_devinfo *devinfo;
Devinfo->board_info = *info;
List_add_tail (&devinfo->list, &__i2c_board_list); Add I2C from the device to the list
... ...
}

therefore, in the system initialization process, we can through I2c_register_board_info, will need I2C from the device to add a __i2c_board_list two-way cycle list, the system after the successful loading of I2C main device adapt, All the I2C in this chain will complete the i2c_client registration from the device.

5 Slave Driver

If the hardware, I2C main device has been integrated in the main chip, software, Linux also provides us with the appropriate driver, located under Drivers/i2c/bus, then the next I2C from the device driver becomes much easier. Since the system is loaded I2C the main device driver has been registered I2c_adapter and i2c_client, then I2C from the device mainly completes three major tasks, system initialization to add i2c_board_info as the structure of the I2C from the device information Using the algorithm provided in I2c_adapter in the I2C from the device driver, the I2C communication is realized. The I2C is hung from the device's unique data structure under I2c_client.dev->driver_data.

Take the gravitational induction device for example,

static int __init bma220_init (void)
{
Return I2c_add_driver (&bma220_driver);
}

static struct I2c_driver Bma220_driver = {
. Driver = {
. Owner = This_module,
. Name = "Bma220",
},
. class = I2c_class_hwmon,
. Probe = Bma220_probe,
. remove = Bma220_remove,
};

static int bma220_probe (struct i2c_client *client, const struct I2C_DEVICE_ID)
{
struct Bma220_data *data;
I2c_check_functionality (Client->adapter, I2C_FUNC_I2C)

I2c_smbus_read_word_data (client, 0x00); I2c-core provides the interface, using I2c_adapter algorithm to realize I2C communication
I2c_set_clientdata (bma220_client, data); To hang a device's data structure under I2c_client.dev->driver_data
Misc_register (&bma_device);
REQUEST_IRQ (CLIENT->IRQ, Bma220_irq_handler, irqf_trigger_rising, "bma220", &data->bma220);
BMA220_SET_EN_TT_XYZ (0);
Bma220_reset_int ();

... ...
}

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: info-contact@alibabacloud.com 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.