Lazy loaded image
🥳嵌入式Linux开发
IIC 驱动专题01 - 控制器驱动 i2c-imx.c 源码分析
Words 2955Read Time 8 min
2025-4-15
2025-4-16
type
date
slug
category
icon
password
drivers/i2c/busses 文件夹包含了各种 I2C 总线控制器的驱动程序。主要作用如下:
  1. 总线控制器驱动
      • 实现具体硬件平台上的 I2C 控制器驱动
      • 负责 I2C 总线的底层操作,如启动、停止、数据传输等
      • 处理时序、时钟等硬件相关的细节
  1. 支持多种平台 从当前代码可以看到支持多种平台的 I2C 控制器:
      • i2c-imx.c - Freescale i.MX 系列处理器
      • i2c-bcm2835.c - 树莓派使用的 BCM2835
      • i2c-mv64xxx.c - Marvell 处理器
      • i2c-st.c - ST 微电子的处理器
  1. 功能实现 每个驱动通常实现:
      • I2C 适配器注册
      • 中断处理
      • DMA 传输支持
      • 时钟配置
      • 电源管理
      • 错误处理和恢复机制
  1. 与上层接口
      • 实现标准的 I2C 总线接口
      • 向上提供统一的 API 供 I2C 核心层调用
      • 使得上层应用可以透明地访问不同的 I2C 控制器
 
本节对 drivers\i2c\busses\i2c-imx.c 文件进行源码分析。

数据结构

结构体 imx_i2c_hwdata

imx_i2c_hwdata 结构体则包含了每种处理器特定的I2C控制器配置信息,使驱动程序能够适应不同硬件平台的特性。

结构体 imx_i2c_struct

i.MX 系列处理器 I2C 控制器驱动的核心数据结构,包含了驱动运行所需的所有状态信息和配置数据。每个 I2C 控制器实例都会创建一个此结构体的实例,并通过 i2c_set_adapdata() 函数与 I2C 适配器关联。
 

函数接口

函数接口文档

i2c_imx_xfer

功能描述

核心传输函数,实现I2C适配器的master_xfer回调,处理I2C消息的传输。

函数原型

参数说明

  • adapter: I2C适配器结构体指针
  • msgs: I2C消息数组指针,包含要传输的数据
  • num: 消息数组中的消息数量

返回值

  • 成功: 传输的消息数量
  • 失败: 负的错误码

功能流程

  1. 启用电源管理
  1. 启动I2C总线传输
  1. 循环处理每个I2C消息
  1. 根据消息类型(读/写)调用相应的处理函数
  1. 停止I2C总线传输
  1. 处理电源管理
  1. 返回结果

i2c_imx_start

功能描述

控制I2C总线的启动操作,配置I2C控制器并生成START信号。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针

返回值

  • 成功: 0
  • 失败: 负的错误码

功能流程

  1. 设置I2C时钟频率
  1. 配置I2C控制器寄存器
  1. 生成START信号
  1. 等待总线变为忙状态
  1. 配置传输模式

i2c_imx_stop

功能描述

控制I2C总线的停止操作,生成STOP信号并禁用I2C控制器。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针

返回值

功能流程

  1. 清除MSTA位生成STOP信号
  1. 对于IMX1处理器,添加延迟以解决硬件bug
  1. 等待总线变为空闲状态
  1. 禁用I2C控制器

i2c_imx_read

功能描述

实现I2C读操作,从从设备读取数据。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针
  • msgs: I2C消息结构体指针,包含要读取的数据信息
  • is_lastmsg: 是否为最后一个消息的标志

返回值

  • 成功: 0
  • 失败: 负的错误码

功能流程

  1. 发送从设备地址(读模式)
  1. 配置控制器为接收模式
  1. 如果支持DMA且数据长度足够,使用DMA读取
  1. 否则,循环读取每个字节数据
  1. 在最后一个字节前设置TXAK位
  1. 对于最后一个消息,生成STOP信号

i2c_imx_write

功能描述

实现I2C写操作,向从设备写入数据。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针
  • msgs: I2C消息结构体指针,包含要写入的数据

返回值

  • 成功: 0
  • 失败: 负的错误码

功能流程

  1. 发送从设备地址(写模式)
  1. 检查ACK响应
  1. 循环发送每个字节数据
  1. 每发送一个字节后检查ACK响应

i2c_imx_dma_read

功能描述

使用DMA方式实现I2C读操作,提高数据传输效率。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针
  • msgs: I2C消息结构体指针,包含要读取的数据信息
  • is_lastmsg: 是否为最后一个消息的标志

返回值

  • 成功: 0
  • 失败: 负的错误码

功能流程

  1. 启用DMA模式
  1. 配置DMA通道和传输方向
  1. 启动DMA传输
  1. 等待DMA传输完成
  1. 禁用DMA模式
  1. CPU读取最后两个字节
  1. 对于最后一个消息,生成STOP信号

i2c_imx_dma_write

功能描述

使用DMA方式实现I2C写操作,提高数据传输效率。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针
  • msgs: I2C消息结构体指针,包含要写入的数据

返回值

  • 成功: 0
  • 失败: 负的错误码

功能流程

  1. 配置DMA通道和传输方向
  1. CPU发送第一个字节(从设备地址)
  1. 启用DMA模式
  1. 启动DMA传输
  1. 等待DMA传输完成
  1. 禁用DMA模式
  1. CPU发送最后一个字节
  1. 检查ACK响应

i2c_imx_bus_busy

功能描述

检查I2C总线状态,等待总线变为忙或空闲状态。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针
  • for_busy: 等待标志,1表示等待总线变忙,0表示等待总线变空闲

返回值

  • 成功: 0
  • 失败: 负的错误码(-EAGAIN表示仲裁丢失,-ETIMEDOUT表示超时)

功能流程

  1. 循环检查I2SR寄存器的IBB位
  1. 检查仲裁丢失标志(IAL)
  1. 根据for_busy参数等待总线状态变化
  1. 如果超时则返回错误

i2c_imx_trx_complete

功能描述

等待I2C传输完成,监控中断标志。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针

返回值

  • 成功: 0
  • 失败: -ETIMEDOUT(超时错误)

功能流程

  1. 等待中断标志(I2SR_IIF)被设置
  1. 如果超时则返回错误
  1. 清除状态标志

i2c_imx_acked

功能描述

检查是否收到ACK信号,验证从设备响应。

函数原型

参数说明

  • i2c_imx: i.MX I2C控制器结构体指针

返回值

  • 成功(收到ACK): 0
  • 失败(收到NACK): -ENXIO

功能流程

  1. 检查I2SR寄存器的RXAK位
  1. 如果RXAK位为1(表示收到NACK),返回错误
  1. 否则返回成功

工作流程

1. 驱动初始化流程

2. I2C传输核心流程

 

3. DMA相关流程

4. 电源管理和总线恢复

5. 模块间关系图

 
上一篇
模板设计模式:让你的代码结构更清晰
下一篇
Guide to Linux System

Comments
Loading...