i2c_driver结构体

 

驱动程序的主要工作就是定义并初始化一个i2c_driver结构体。i2c_driver的成员参考上面。
 
i2c_driver中的driver成员至少应该初始化它的name成员。

Legacy model的驱动i2c_driver的函数指针至少应该初始化attach_adapter和detach_ client,另外attach_adapter会使用example_attach函数,这个函数主要是将我们的client注册到系统中。这两个函数指针对应的函数实现比较固定。

Standard driver model的驱动需要注册板级信息。板级信息必须要有driver的id name还有设备的7位从机地址。驱动中不再需要创建i2c_client结构体,它是由i2c内核创建的。驱动中不需要定义设备的地址,取而代之的是i2c_device_id,用来保存支持的设备类型。这里面保存的设备名将会和板级信息中注册的i2c_board_info的名字进行比较,在i2c_device_id中存在的名字才能依附于本驱动。i2c_driver函数指针成员只需要初始化probe和remove就就够了。其它的函数都是可选的。特别需要注意的是,如果同时初始化两种模式需要用到的i2c_driver的成员,那么会报错,因为i2c内核无法判断是哪种模式的驱动。i2c_driver中的probe、remove、detect任何一个被初始化意味着这是一个Standard driver model模式的驱动,attach_adapter和detach_adapter绝对不可以初始化。

另外,i2c_driver的shutdown、suspend、resume这三个函数指针是否初始化是可选的。这三个函数指针分别对应关机、挂起、唤醒。

如果已经将i2c驱动正确的编译并插入内核,那么内核中提供了一些接口和设备通信:

extern int i2c_master_send(struct i2c_client *client, const char* buf, int len);

extern int i2c_master_recv(struct i2c_client * client,char* buf, int len);

这两个函数都是让client对应的适配器以主机的身份和client->addr地址的设备进行通信,返回值是实际读写的字节数。Linux下的i2c适配器不支持从机模式。

上面的两个函数有个弊端,那就是只能完成单方向的通信,如果通信的过程既有发送又有接收而且接收和发送不能分开,那就需要调用另一个函数:

extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num);

实际上,上面两个函数也是直接调用了i2c_transfer。

i2c_transfer中的参数有三个,第一个是适配器结构体的指针,第二个是消息数组的头指针,第三个是消息的数量。这个函数发送一系列的消息。每个消息可以是读,也可以是写,也可以混合。发送过程是连贯的,在发送中没有停止条件。它的返回值是成功执行的消息数目。

消息的格式定义如下。

struct i2c_msg {
         __u16 addr; // slave address
         __u16 flags;
#define I2C_M_TEN                                0x0010       //10bit地址
#define I2C_M_RD                                  0x0001       //读取数据标志,清零表示写
#define I2C_M_NOSTART                     x4000         //不发送起始位
#define I2C_M_REV_DIR_ADDR        0x2000       // 反转读写标志
#define I2C_M_IGNORE_NAK            x1000         //忽略I2C器件的ack和nack信号
#define I2C_M_NO_RD_ACK               0x0800       //读操作时不去ACK
#define I2C_M_RECV_LEN                   0x0400       //length will be first received byte
         __u16 len; // msg length
         __u8 *buf; // pointer to msg data
};
flags各位的含义已经用宏定义好了。如果连续多条消息的话,除了第一条之外,余下的都不需要发送起始条件。

你可能感兴趣的:(i2c_driver结构体)