"Turn" Linux i²c device driver write (i)

Source: Internet
Author: User
Tags int size

Original URL: http://www.cnblogs.com/biglucky/p/4059576.html

In the Linux drive, the following members are mainly included in the I²C system:

I2C adapter 即I2C适配器I2C driver 某个I2C设备的设备驱动,可以以driver理解。I2C client  某个I2C设备的设备声明,可以以device理解。
I²C Adapter

is a CPU integrated or external I²C adapter, used to control a variety of i²c slave devices, the driver needs to complete a complete description of the adapter, the most important task is to complete the I2C_ALGORITHM structure. This structure contains the implementation of the data transmission of this I²C controller, as well as the external reporting of the type of functionality supported by this device. The I2C_ALGORITHM structure is 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 flags, char read_write,               u8 command, int size, union i2c_smbus_data *data);    u32 (*functionality) (struct i2c_adapter *);};

If an I²C adapter does not support the I²c channel, then the Master_xfer member is set to NULL. If the adapter supports the SMBus protocol, it is necessary to implement Smbus_xfer, and if the Smbus_xfer pointer is set to NULL, then the SMBus protocol will be emulated via the I²c channel. The return value of the function that the master_xfer points to should be the number of messages that have been successfully processed, or the return negative indicates an error. The functionality pointer is simple enough to tell you what features the I²c master supports.

An example of an I²C adapter is implemented in the kernel's DRIVERS/I2C/I2C-STUB.C, which implements a more complex smbus.

The difference between SMBus and i²c

Normally, I²c and SMBus are compatible, but there are some subtle differences.

Clock speed comparison:

i²c SMBus
Minimum No 10kHz
Biggest 100kHZ (Standard) 400kHz (fast mode) 2MHz (high speed mode) 100kHz
Timeout No 35ms

They also differ in electrical characteristics, and the SMBus requires a lower voltage range.

I²c Driver

Specific i²c device drivers, such as cameras, sensors, touch screen, backlight controller, most of the common hardware devices are or are through the I²C protocol and the host for data transmission, control. The structure is as follows:

struct I2c_driver {unsigned int class; /* Notifies the driver that a new bus have appeared or is on to be * removed.     You should avoid using this, it'll be is removed in a * near the future.  */INT (*attach_adapter) (struct i2c_adapter *) __deprecated;  The old interface function int (*detach_adapter) (struct i2c_adapter *) bound to the device is __deprecated;  Old interface function to unbind the device/* Standard driver Model interfaces */INT (*probe) (struct i2c_client *, const struct I2C_DEVICE_ID *);  The current generic interface function int (*remove) (struct i2c_client *) that binds to the corresponding device; Interface functions that are currently unbound by the current generic and corresponding devices/* Driver Model interfaces that don ' t relate to enumeration */void (*shutdown) (struct I2C_CLI  ENT *); Turn off device int (*suspend) (struct i2c_client *, pm_message_t MESG); Suspend the device, which is related to power management, is an energy-saving int (*resume) (struct i2c_client *);     Recover from suspended state/* Alert callback, for example for the SMBus alert protocol.     * The format and meaning of the data value depends on the protocol. * For the SMBus alert protocol, there are a single bit of Data passed * As the alert response ' s low bit ("event flag").    */void (*alert) (struct i2c_client *, unsigned int data);     /* A ioctl like command so 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;  The drive model of the I²C device is const struct I2C_DEVICE_ID *id_table; Matching device list/* Device detection callback for automatic device creation */INT (*detect) (struct i2c_client *, struct-i²c    _board_info *);    const unsigned short *address_list; struct list_head clients;}; #define To_i2c_driver (d) container_of (d, struct i2c_driver, driver)//General writing driver The object is usually driver type and can be to_i2c_ Driver find its parent type I2c_driver

Just as the driver of a common device can drive multiple devices, an I²C driver can also correspond to multiple I²C clients.

Taking the gravity sensor axll34x as an example, its implementation of the I²c drive is:

static const struct i2c_device_id adxl34x_id[] = {      { "adxl34x", 0 },  //匹配i2c client名为adxl34x的设备     { }  }; MODULE_DEVICE_TABLE(i2c, adxl34x_id); static struct i2c_driver adxl34x_driver = {      .driver = {          .name = "adxl34x",         .owner = THIS_MODULE,         .pm = &adxl34x_i2c_pm,  //指定设备驱动的电源管理接口,包含suspend、resume     },       .probe    = adxl34x_i2c_probe,  //组装设备匹配时候的匹配动作     .remove   = adxl34x_i2c_remove,  //组装设备移除接口     .id_table = adxl34x_id,  //制定匹配设备列表 }; module_i2c_driver(adxl34x_driver);

Here's a description of the Module_i2c_driver macro definition (i2c.h):

#define module_i2c_driver(__i2c_driver)     module_driver(__i2c_driver, i2c_add_driver,                      i2c_del_driver)#define i2c_add_driver(driver)         i2c_register_driver(THIS_MODULE, driver)

Module_driver ():

#define module_driver(__driver, __register, __unregister, ...) static int __init __driver##_init(void) {         return __register(&(__driver) , ##__VA_ARGS__); } module_init(__driver##_init); static void __exit __driver##_exit(void) {         __unregister(&(__driver) , ##__VA_ARGS__); } module_exit(__driver##_exit);

After understanding the macro definition above, Module_i2c_driver (Adxl34x_driver) is expanded to get:

static int __int adxl34x_driver_init(void){    return i2c_register_driver(&adxl34x_driver);}module_init(adxl34x_driver_init);static void __exit adxl34x_driver_exit(void){    return i2c_del_driver(&adxl34x_driver);}module_exit(adxl34x_driver_exit);

This macro solves the complex code of module modules ' loading and unloading. This allows the driver to implement the I²c drive as long as the i2c_driver structure is filled in, no need to care about the device registration and anti-registration process.

I²c Client

That is, the I²C device. The registration of an I²C device is generally in the board level code, before parsing the instance or familiar with several definitions:

struct I2c_client {unsigned short flags;        I2c_client_ten indicates that the device uses 10bit from the address, I2c_client_pec indicates that the device uses SMBus to check the unsigned short addr; Device from address, 7bit. Here is why the 7-bit, because the last thought 0 means write, 1 is read, by the 7bit address shift processing can be. Addr<<1 & 0x0 Write, addr<<1 |    0X01 is read.  Char Name[i2c_name_size];    From the device name struct I2c_adapter *adapter;    This from the device attached to which adapter on the struct i2c_driver *driver;        This device corresponds to the I²C drive pointer to the struct device dev;            device model int IRQ;  The device uses the interrupt number struct list_head detected; Used for list operation}; #define To_i2c_client (d) container_of (d, struct i2c_client, dev)//usually operates using the device equipment model and can be to_i2c_  Client found corresponding client pointer struct I2c_board_info {char type[i2c_name_size];  The device name, up to 20 characters, is eventually installed on the client's name unsigned short flags;  Final installation to client.flags unsigned short addr;  Device from address slave, final installation to client.addr on void *platform_data;    Device data, eventually stored to i2c_client.dev.platform_data on the struct dev_archdata *archdata;  struct Device_node *of_node;    OpenFirmware Device Node pointersstruct Acpi_dev_node acpi_node;  int IRQ; The device uses the interrupt number, finally stored to the I2C_CLIENT.IRQ};//can see, i2c_board_info basically is corresponding with i2c_client.  #define I2C_BOARD_INFO (Dev_type, dev_addr). Type = Dev_type,. Addr = (DEV_ADDR)//Through this macro definition can easily define the name of the i²c device and the slave address (don't forget 7bit)

Let's take adxl34x as an example:

static struct i2c_board_info i2c0_devices[] = {     {           I2C_BOARD_INFO("ak4648", 0x12),    },      {           I2C_BOARD_INFO("r2025sd", 0x32),    },      {           I2C_BOARD_INFO("ak8975", 0x0c),        .irq = intcs_evt2irq(0x3380), /* IRQ28 */    },      {           I2C_BOARD_INFO("adxl34x", 0x1d),        .irq = intcs_evt2irq(0x3340), /* IRQ26 */    },  };...i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));

In this way, the adxl34x i²c device is registered in the system, and when the name matches the members of the id_table in the I2c_driver, it is able to set off the probe matching function.

"Turn" Linux i²c device driver write (i)

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.