一、概览linux i2c驱动子系统

来源:互联网 发布:淘宝客服招聘简历 编辑:程序博客网 时间:2024/05/27 00:37

1、概要


i2c是由PHILIPS推出的串行总线。无论是电气特性和总线协议都比较简单。关于i2c的电气特性和协议请参考i2c的规格说明说。
后来intel推出了另一种总线规范SMBus(system management bus)。不过SMBus基本上是基于i2c规范的。关于他们之间的相同和差异,请自行百度。
和spi驱动框架类似,i2c驱动子系统中也有i2c控制器和i2c设备的概念。不过在i2c驱动子系统中,我们称之为i2c adapter和i2c client。只有i2c adapter和i2c client配合起来,连接在i2c总线上的器件才能工作起来。

2、i2c_bus_type


i2c_bus_type 所代表的是i2c总线类型。这数据是在”drivers/i2c/i2c-core.c”中被定义的。它的原型如下:

struct bus_type i2c_bus_type = {        .name           = "i2c",        .match          = i2c_device_match,        .probe          = i2c_device_probe,        .remove         = i2c_device_remove,        .shutdown       = i2c_device_shutdown,        .pm             = &i2c_device_pm_ops,};EXPORT_SYMBOL_GPL(i2c_bus_type);

<1> i2c_device_match

在注册i2c_adapter,i2c_clienti2c_driver时,都会被调用来匹配设备和驱动,不过这个函数在开始的时候就判断设备是不是i2c_client,所以这个函数只能用来匹配struct i2c_clientstruct i2c_driver

<2> i2c_device_probe

这个函数是在struct i2c_clientstruct i2c_driver通过i2c_device_match的匹配规则匹配后被调用。这个函数用来探测i2c设备和驱动。在这个函数中会回调struct i2c_driver中的probe()函数来注册相应的设备。

<3> i2c_device_remove

这个函数在删除struct i2c_client会被调用,该函数会回调struct i2c_driver中的remove()函数。

<4> i2c_device_shutdown

在关机过程中会被调用来禁止操作设备。这个函数会回调struct i2c_driver中的shutdown()函数。

<5> i2c_device_pm_ops

电源管理相关操作。基本上都会回调struct i2c_driver.driver.pm中的对应的函数。

3、i2c adapter


一个struct i2c_adapter代表的是一个i2c总线控制器。这个结构体在”include/linux/i2c.h”中被定义。它的原型如下:

struct i2c_adapter {             struct module *owner;             unsigned int class;               /* classes to allow probing for */        const struct i2c_algorithm *algo; /* the algorithm to access the bus */        void *algo_data;        /* data fields that are valid for all devices   */        struct rt_mutex bus_lock;         int timeout;                    /* in jiffies */                  int retries;        struct device dev;              /* the adapter device */          int nr;        char name[48];        struct completion dev_released;        struct mutex userspace_clients_lock;        struct list_head userspace_clients;        struct i2c_bus_recovery_info *bus_recovery_info;}; 

这里面比较重要的一个字段就是algo,所有i2c总线相关的数据交换都是调用这个结构中的函数完成的。关于其他的字段,在后面详细讲解。

4、i2c client


一个struct i2c_client代表的是一个连接在i2c总线上的一个设备。它的原型在”include/linux/i2c.h”中被定义的,原型如下:

struct i2c_client {        unsigned short flags;           /* div., see below              */        unsigned short addr;            /* chip address - NOTE: 7bit    */                                        /* addresses are stored in the  */                                        /* _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;};

关于各个字段的含义,后面会详细讲解。

5、i2c driver


一个struct i2c_driver代表的就是一类i2c_client的驱动。它的原型如下,在”include/linux/i2c.h”中定义:

struct i2c_driver {        unsigned int class;        /* Notifies the driver that a new bus has appeared. You should avoid         * using this, it will be removed in a near future.         */        int (*attach_adapter)(struct i2c_adapter *) __deprecated;        /* 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 *);        /* 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 is 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 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 *, struct i2c_board_info *);        const unsigned short *address_list;        struct list_head clients;};

关于各个字段,后面会详细讲解。

6、总结


上述提到的struct i2c_adapterstruct i2c_clientstruct i2c_driver是i2c子系统工作的核心。注册的struct i2c_clientstruct i2c_driver匹配,struct i2c_driver才能驱动struct i2c_client所代表的硬件设备;cpu和i2c_client通信又必须调用struct i2c_adapter中的数据交换的接口。

0 0
原创粉丝点击