I2C总线驱动模型:
用户空间 应用程序
---------------------system_call-----------------
I2C 设备驱动(设备一般挂在i2c适配器上,通过i2c适配器与cpu交换数据)
I2C核心(i2c-core.c)
I2C总线驱动层(I2C适配器数据结构I2C_adapter,)
\\
内核空间 I2C适配器
-----------------------------------------------------
硬件 I2C适配器
// \\
I2C设备 I2C设备
Busses文件夹 i2c总线驱动。
注意:i2c_dev.c实现了i2c适配器设备文件的功能,每个i2c适配器都被分配一个设备。
/drivers/i2c/chips/ds1337.c (chips文件中包含i2c设备驱动)
i2c_add_driver(&ds1337_driver) //添加driver到i2c driver_list
i2c_register_driver(THIS_MODULE, driver);
driver->driver.bus = &i2c_bus_type;
list_add_tail(&driver->list,&drivers); //添加到list末尾
/**遍历adpaters_list,调用attach_adapter()进行匹配**/
list_for_each_entry(adapter, &adapters, list) {
driver->attach_adapter(adapter);
} \\
i2c_driver结构体中的attach_adapter()
//构造 i2cdriver结构体
static struct i2c_driver at24c02_driver = {
.driver = {
.name = "at24c02",
},
/*识别枚举i2c设备*/
.attach_adapter = at24c02_attach_adapter,
.detach_client = at24c02_detach_client,
};
at24c02_attach_adapter(struct i2c_adapter *adapter)
//调用i2c_probe,判断设备地址是否存在……
//若存在,则调用at24c02_detect()进一步处理(通过adapter发送设备地址)
i2c_probe(adapter, &at24c02_addr_data, at24c02_detect);
i2c_probe_address(); //匹配地址
i2c_smbus_xfer();//传递信息、地址
i2c_smbus_xfer_emulated(); //传递信息/地址
i2c_transfer(adapter, msg, num);//
i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
adap->algo->master_xfer(adap,msgs,num);
注意:i2c_transfer()不具备驱动适配器完成消息交互的能力;最终它会找到匹配i2c_adapter对应的i2c_algorithm的master_xfer的函数指针,调用相关总线驱动来发送数据。
master_xfer();传输数据
master_xfer()调用i2c_s3c2410.c 中的 .master_xfer
/driver/i2c/busses/i2c_s3c2410.c
static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
.master_xfer = s3c24xx_i2c_xfer,
.functionality = s3c24xx_i2c_func,
};
static struct s3c24xx_i2c s3c24xx_i2c = {
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock),
.wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
.tx_setup = 50,
.adap = {
.name = "s3c2410-i2c",
.owner = THIS_MODULE,
.algo = &s3c24xx_i2c_algorithm,
.retries = 2,
.class = I2C_CLASS_HWMON,
},
};
s3c24xx_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msgs, int num)
3c24xx_i2c_doxfer(i2c, msgs, num);
s3c24xx_i2c_message_start(i2c, msgs); //向底层硬件传递信息
底层硬件,操作相关的寄存器来完成数据的发送……