您的位置:首页 > 运维架构 > Linux

一、概览linux i2c驱动子系统

2015-12-26 21:10 696 查看

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
中的数据交换的接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux i2c-driver