分层思想
首先iic是一个总线,所以强大的linux肯定会利用常见的分层思想把他分成两个部分,一个部分肯定是通用的,总线驱动模型,一个部分是我们做的,设备驱动模型。
总线驱动模型
linux 总线 都是在干一件事,就是把相同总线的设备扔在总线上,其中肯定有注册机制乱七八糟的,在这个驱动中,主要做一件事:“I2C 适配器”。
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;
const struct i2c_adapter_quirks *quirks;
};
其中比较重要的是 i2c_algorithm
struct i2c_algorithm {
/* 如果适配器算法无法执行I2C级访问,请设置master_xfer
为NULL。 如果适配器算法可以执行SMBus访问,请设置
smbus_xfer。 如果设置为NULL,则模拟SMBus协议
使用常见的I2C消息*/
/* master_xfer应该成功返回消息数
已处理,或错误值为负*/
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num);
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data);
/* To determine what the adapter supports */
u32 (*functionality) (struct i2c_adapter *);
#if IS_ENABLED(CONFIG_I2C_SLAVE)
int (*reg_slave)(struct i2c_client *client);
int (*unreg_slave)(struct i2c_client *client);
#endif
};