红联Linux门户
Linux帮助

概览linux i2c驱动子系统

发布时间:2016-08-30 10:15:43来源:linux网站作者:stevin_liang
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_client和i2c_driver时,都会被调用来匹配设备和驱动,不过这个函数在开始的时候就判断设备是不是i2c_client,所以这个函数只能用来匹配struct i2c_client和struct i2c_driver。
<2> i2c_device_probe
这个函数是在struct i2c_client和struct 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_adapter,struct i2c_client和struct i2c_driver是i2c子系统工作的核心。注册的struct i2c_client和struct i2c_driver匹配,struct i2c_driver才能驱动struct i2c_client所代表的硬件设备;cpu和i2c_client通信又必须调用struct i2c_adapter中的数据交换的接口。
 
本文永久更新地址:http://www.linuxdiyf.com/linux/23735.html