Linux的I2C子系统

目录

一、i2c_adapter、i2c_client等结构体分析 

1.1 结构体之间的包含关系

1.2 i2c_adapter结构体

1.3 i2c_client结构体

二、I2C系统调用过程

2.1 整体调用过程

2.2 调用过程路径1

2.3调用过程路径2

​ 三、I2C底层框架

3.1 底层调用流程例1

​3.2 底层调用流程例2

3.3底层调用流程例3

3.4 用到mux时的流程

3.5 驱动程序使用流程

3.6 mux驱动流程

四、ak4954操作流程


一、i2c_adapter、i2c_client等结构体分析 

1.1 结构体之间的包含关系

Linux的I2C子系统

 

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 整体调用过程

Linux的I2C子系统

2.2 调用过程路径1

Linux的I2C子系统

2.3调用过程路径2

Linux的I2C子系统 三、I2C底层框架

3.1 底层调用流程例1

(i2c-hisilicon.c)

Linux的I2C子系统3.2 底层调用流程例2

(i2c-hisi-v110.c)

Linux的I2C子系统

3.3底层调用流程例3

Linux的I2C子系统

3.4 用到mux时的流程

(一般不用mux)

Linux的I2C子系统

3.5 驱动程序使用流程

(ipc_stm8.c)

Linux的I2C子系统

注意:
 
  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)

Linux的I2C子系统

四、ak4954操作流程

Linux的I2C子系统