在Linux内核中I2C的体系结构分为3个部分:
① I2C核心:I2C核心提供了I2C总线驱动和设备驱动的注册、注销方法等。
② I2C总线驱动:I2C总线驱动是对I2C硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在CPU内部。
③ I2C设备驱动:I2C设备驱动是对I2C硬件体系结构中设备端的实现,设备一般挂接在受CPU控制的I2C适配器上,通过I2C适配器与CPU交换数据。
1 I2C总线驱动
I2C总线和platform总线差不多,只不过platform总线是虚拟出来的一条总线,而I2C总线是实际存在的。对于使用I2C通信的设备,在驱动中直接使用I2C总结即可。I2C总线驱动的重点是I2C适配器驱动,主要涉及到两个结构体:i2c_adapter 和 i2c_algorithm。在Linux内核中用i2c_adapter结构体来表示I2C适配器。i2c_adapter 结构体定义在include/linux/i2c.h 文件中,结构体内容如下:
498 struct i2c_adapter {
499 struct module *owner;
500 unsigned int class; /* classes to allow probing for */
501 const struct i2c_algorithm *algo; /* 总线访问算法 */
502 void *algo_data;
503
504 /* data fields that are valid for all devices */
505 struct rt_mutex bus_lock;
506
507 int timeout; /* in jiffies */
508 int retries;
509 struct device dev; /* the adapter device */
510
511 int nr;
512 char name[48];
513 struct completion dev_released;
514
515 struct mutex userspace_clients_lock;
516 struct list_head userspace_clients;
517
518 struct i2c_bus_recovery_info *bus_recovery_info;
519 const struct i2c_adapter_quirks *quirks;
520 };
第 501 行,i2c_algorithm 类型的指针变量 algo,对于一个 I2C 适配器,肯定要对外提供读写 API 函数,设备驱动程序可以使用这些 API 函数来完成读写操作。i2c_algorithm 就是 I2C 适配器与 IIC 设备进行通信的方法。
i2c_algorithm 结构体定义在 include/linux/i2c.h 文件中,部分内容如下:
391 struct i2c_algorithm {
......
398 int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
399 int num);
400 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
401 unsigned short flags, char read_write,
402 u8 command, int size, union i2c_smbus_data *data);
403
404 /* To determine what the adapter supports */
405 u32 (*functionality) (struct i2c_adapter *);
......
411 };
第 398 行,master_xfer 就是 I2C 适配器的传输函数,可以通过此函数来完成与 IIC 设备之