通讯协议I2C子系统之I2C Driver
现在来写 I2C Driver 部分。
I2C driver 分四个部分来写:
文章以 MTK 平台为例,code 来源于小米开源项目,小米每做一个手机项目,都会将 kernel 部分开源,因为必须遵循 GPL 协议。

I2C driver 源码目录。

1、I2C SW Architecture

【driver 驱动层】由普通驱动工程师负责,【i2c 核心层】由 Linux 提供,【i2c 核心层】以下由芯片原厂负责。
I2C 子系统通过 i2c-core 将 i2c 设备驱动和 i2c 总线驱动进行了分离,从而使得 i2c 设备驱动中不用关心 i2c 总线传输细节,专注于 i2c 设备逻辑的实现。
抽象如下:
![]()

I2C 总线驱动重点是 I2C 适配器(控制器)驱动,这里用到两个重要的数据结构:i2c_adapter 和 i2c_algorithm。其中,Linux 内核将 SOC 的 I2C 适配器(控制器)抽象成 i2c_adapter,i2c_algorithm 只是一些 i2c 传输的实现函数合集。
在 Linux 系统中有如下节点:

2、I2C Data Structure
我们要搞懂一个 Linux 子系统,必须研究它的数据结构,搞懂每个结构体存储了什么东西,才能梳理清楚该子系统的架构。
I2C 子系统有几个主要的结构体:

i2c_adapter:i2c-core 层描述一个 I2C 控制器,假如一个芯片有 8 路 I2C bus,则有 8 个 i2c_adapter。请详细看博主对 code 的注释说明。

i2c_algorithm:I2C 传输函数合集,其中 master_xfer 是真正的传输函数,芯片原厂写 I2C 控制器驱动时必须实现。functionality 函数会返回该 I2C 控制器支持什么通信协议,也需要实现,其他的函数即便 Linux 规定了,芯片原厂也可以不实现,因为不常用。
MTK 只实现了其中两个。
i2c_client:描述设备信息:

i2c_driver:普通驱动工程师写驱动时,必须实现其中的 probe 函数和 remove 函数,其余的函数一般用不到。

mtk_i2c:MTK 平台用该结构体表示 I2C 控制器,定义在/kernel-5.10/drivers/i2c/busses/i2c-mt65xx.c。

i2c_msg:I2C 读写时,必须填充 i2c_msg。
标志位:写为 0 ,读为 I2C_M_RD,其他的 flag 大家可以参考。
I2C 单笔传输最大 64KB,len 的长度博主在注释中有说明。
