Linux的I2C子系统
目录
一、i2c_adapter、i2c_client等结构体分析
一、i2c_adapter、i2c_client等结构体分析
1.1 结构体之间的包含关系
1.2 i2c_adapter结构体
i2c_adapter的重要成员
struct i2c_algorithm *algo // 主控的数据传输的算法
struct device dev // 主控分配的device结构体,可以通过dev获得i2c_adapter等操作。
int nr // 适配器编号,即:i2c通道编号。驱动可以通过这个编号获得i2c_adapter
i2c_adapter的内存分配
在主控程序的probe函数中会分配i2c_adapter的内存
i2c_adapter的使用
驱动可以直接通过i2c_get_adapter函数,以adapter编号为参数获得i2c_adapter结构体,进而调用其相关函数完成数据传输。注意:
i2c_get_adapter函数会调用idr_find(&i2c_adapter_idr, nr);
i2c_add_numbered_adapter和i2c_add_adapter函数中都会调用idr_alloc向i2c_adapter添加adapter i2c_get_adapter;
调用后要使用i2c_put_adapter释放掉adapter。1.3 i2c_client结构体
i2c_client的重要成员
unsigned short addr // 外设的地址(7bit)
struct i2c_adapter *adapter // 本外设所关联的主控适配器
struct device dev // device结构体i2c_client的内存分配和使用
(1)i2c-dev.c
open函数中分配i2c_client结构体,设置adapter等成员,将file->private_data指向本结构体;
write,read,ioctl等函数中通过file->private_data获得i2c_client结构体,进行其他操作。
(2)外设驱动
分配i2c_client结构体,设置其adapter等成员,驱动中可以将i2c_client作为参数调用i2c_transfer、i2c_master_send、i2c_master_recv等函数。
(3)主控、mux驱动层
如果主控设备(i2c_add_adapter)和mux驱动(i2c_add_driver)都存在,则最终会分配i2c_client结构体,并将其挂到mux驱动(i2c_driver)的clients链表上边。二、I2C系统调用过程
2.1 整体调用过程
2.2 调用过程路径1
2.3调用过程路径2
三、I2C底层框架
3.1 底层调用流程例1
(i2c-hisilicon.c)
3.2 底层调用流程例2
(i2c-hisi-v110.c)
3.3底层调用流程例3
3.4 用到mux时的流程
(一般不用mux)
3.5 驱动程序使用流程
(ipc_stm8.c)
注意:
i2c_put_adapter最好在初始化或者打开时 进行,不能放在module_exit修饰的退出函数中。如果放在了module_exit函数修饰的
出函 数中,会导致rmmod时失败。
原因:i2c_get_adapter会调用 try_module_get函数使i2c_adapter使用计数加一, rmmod函数会先检查模块使用计数,再调用自己 定义的函数,如果i2c_put_adapter在退出函数中, 那么在rmmod检查时使用计数还是1,会导致 rmmod失败,无法卸载。3.6 mux驱动流程
(一般不用mux)
(pca9541.c)
四、ak4954操作流程