linux内核I2C子系统详解——看这一篇就够了

      最后更新:2022-07-05 02:35:44 手机定位技术交流文章

      1、I2C通信协议

      参考博客:I2C通信协议细节和通信过程分析;

      通过KXTF9-2050芯片分析I2C协议

      参考博客: 通过KXTF9-2050芯片分析I2C协议;

      I2C子系统框架

      图片:I2C子系统框架图

      (一)I2C子系统分为三个层:I2C核心层、I2C适配驱动器和I2C设备驱动器;
      (2)I2C核心层:管理I2C驱动器和I2C设备的注册和匹配,实现I2C通信方法,是I2C通信的抽象框架,与特定硬件无关;
      (三)I2C适配器驱动器:与SOC相对应的I2C控制器,将I2C控制器视为设备,实现I2C控制器的驱动程序代码,以及与SOC有关的特定程序;
      (4)I2C设备驱动程序:每个外部设备都有与特定I2C接口相关的特殊I2C驱动程序代码;

      I2C子系统初始化过程

      (1)内核首先在启动时注册I2C核心层,包括注册I2C总线,提供适配器驱动和设备驱动的注册和卸载接口;
      (二)内核将注册的I2C适配器驱动到I2C核心层;
      (三)内核驱动已注册的I2C设备进入I2C核心层;
      (4)I2C适配器驱动器和I2C设备驱动器在I2C总线上匹配,如果匹配,则调用I2C设备驱动器探测方法;
      (5)I2C适配器驱动器与I2C设备驱动器匹配的影响:I2C设备驱动器调用I2C适配器驱动器在I2C总线上实现主控SoC与外部I2C接口之间的通信,I2C适配器驱动器只提供最基本的数据传输功能,具体通信协议由I2C驱动的设备控制;

      实现I2C驱动的两种方法

      参考博客:I2C驱动实现两个想法(i2c -dev.c和i2c-core.(c));

      I2C子系统的重要数据结构

      6.1,i2c_adapter结构

      变量名 解释
      id 适配器ID包括/linux/i2c - 某些特定适配器的ID.h定义其ID。 这个字段在普通适配器驱动器中不常见
      class 检查某些I2C设备驱动程序中的成员的适配器类型,以确定该设备是否由适配器操作
      algo 指针描述组件的通信方法结构,是适配器I2C控制器的特定操作功能
      algo_data 指向通信方法数据,成员不会被I2C核心层修改,只用于特定i2c_algorithm使用
      timeout 传输超时时间
      retries 传输超时的重试次数
      name 通过 sys/bus/i2c/devices/i2c-x/name访问的适配器名称(x=0,1,2.. )
      nr 设备节点/dev/i2c-x中的x(x=0,1,2..)的总线代码(同样的适配器代码)

      6.2,i2c_algorithm结构

      适配器能力的宏定义 解释
      I2C_FUNC_I2C 支持I2C通信
      I2C_FUNC_SMBUS_EMUL 支持SMBus协议仿真
      I2C_FUNC_PROTOCOL_MANGLING 支持I2C协议修改,即支持非标准序列访问设备
      I2C_FUNC_10BIT_ADDR 支持数据传输的10位模式,通常是8位模式
      变量名 解释
      master_xfer 指向特定I2C传输功能的指示器,相应的传输通常通过适配器硬件的直接操作启动。
      这些功能由:使用传输方法的适配器,等待传输的消息 msgs,以及消息数
      返回值:返回成功发送的邮件数目,未能返回负值
      smbus_xfer 指向特定SMBus传输功能
      functionality 指向返回适配器支持函数的功能,以查看适配能力。 这些函数在 include/linux/i2c中定义的宏定义方式中表达

      (一)SMBus协议主要基于I2C总线规范,并基于I2C扩展,但访问序列也有一些差异;
      (2)如果I2C协议支持,则执行 master_xfer函数指针,如果SMBus协议支持,则执行 thembus_xfer函数指针;

      6.3,i2c_msg结构

      6.4,i2c_driver结构

      变量名 解释
      attach_adapter 与i2c_adapter连接的函数指针:(1)在将i2c_driver添加到系统时,驱动注册函数通过所有适配器类i2c_adapter_class的设备,将attache_adapter方法应用到驱动器上。
      (2)因此,在添加i2c_adapter时,适配器登记函数通过所有驱动器的总线i2c_bus_type。如果定义了attache_adapter方法,它也将被调用
      detach_adapter 功能指针关闭i2c_adapter
      probe 当设备在总线i2c_bus_type与设备驱动器相匹配时被调用
      driver 在注册i2c_driver对象时,i2c_driver->driver的总线类型被指定为i2c_bus_type
      id_table 保存由驱动器支持的设备列表,当驱动器匹配设备时将使用此列表
      detect 基于设备检测机制的12C设备驱动:设备检测调制功能
      address_list 设备探测的地址范围
      clients 探测到的设备列表

      6.i2c_client结构

      变量名 解释
      flags I2C_CLIENT_TEN:设备使用10bit地址;
      I2C_CLIENT_PEC:SMBus包设备错误检查
      addr 设备地址,在7位地址格式中,存储在会员的下位7位
      name 设备的名称
      adapter 依附的适配器
      driver 设备绑定的驱动
      irq 设备使用的中断号
      dev 内嵌的device结构体,在注册i2c_client对象时,i2c_client->dev的总线类型被指定为i2c_bus_type,其type成员被指定为i2c_client_type

      6.i2c_board_info结构

      结构之间的关系

      在这里插入图片描述

      (1)struct i2c_adapter结构:用于描述索克的I2C控制器;
      (二)结构i2c_algorithm结构:描述特定I2C控制器的数据通信方法,以及相关的硬件;
      (三)struct i2c_msg结构:I2C子系统数据传输的基本单元,通过I2C控制器传输数据是基本单元的信息,我们希望通信的数据是按照struct i2c_msg结构填充的;
      (4)结构i2c_driver结构:描述I2C驱动的结构,I2C设备驱动器是结构i2c_driver结构的结构,调用I2C核心层提供驱动器注册界面的注册;
      (5)struct i2c_client structure:描述了I2C设备的结构,它在匹配I2C总线和I2C驱动器后将设备信息发送给驱动器,这里是分开驱动器设计数据的操作方法的设想;
      (6)i2c_board_info结构:描述由I2C适配器驱动的支持I2C设备的信息,包括支持I2C设备的名称、I2C总线的地址、中断数据、私人数据等;

      7、I2C核心层

      核心层的功能

      (1)定义和登记I2C总线i2c_bus_type和适配器类i2c_adapter_class;
      (二)提供i2c_driver、i2c_adapter和i2c_client的分配、创建、登记、取消等服务;
      (三)执行I2C通信方法的高级代码;
      (四)为I2C设备的检测、添加和地址检查提供方法;

      7.2.核心层的注册

      I2C核心层的注册界面功能很简单:注册I2C总线和注册I2C设备驱动程序 dummy_driver;

      7.3、I2C总线

      7.3.I2C巴士描述

      (1)I2C总线有两个链表,一个用于连接驱动器,另一个用于连接设备;
      (2)有两个类型的设备连接到I2C:i2c_client_type和i2c_adapter_type;
      (3)i2c_adapter_type表示适配器,i2c_client_type是当dap注册时i2c_board_info结构的结构;
      (4)工作流程:设备在I2C总线上注册时,是否已经在I2C总线上注册的驱动器匹配,如果匹配,请调用驾驶员探测方法;当驾驶员登记到I2C巴士时,它还可以查看I2C总线上的设备是否匹配,如果匹配,请调用驱动探测方法;

      7.3.2,I2C巴士登记

      I2C总线在I2C核心层的注册界面i2c_init()中注册,负责匹配I2C设备和I2C驱动器;

      7.3.I2C总线的匹配功能

      在将I2C驱动器或I2C设备注册到I2C总线时,I2C驱动器名称和I2C设备名称将相匹配,如果相匹配,I2C总线的探测方法将被调用;

      7.3.I2C总线的探测功能

      I2C总线的探测方法没有实用功能,是匹配的I2C驱动器的探测方法;

      I2C适配器驱动

      介绍I2C适配器

      (1)I2C适配器与硬件上的SocI2C控制器相符,在内核中,I2C控制器被认为是设备,因为有相应的驱动器,即I2C设备驱动器;
      (二)I2C适配器驱动器是操作I2C控制器的基本方法,提供与I2C控制器连接的I2C设备在I2C总线上通信。
      (三)I2C适配器驱动主要通过操作Soc的I2C控制器相关注册表实现数据传输;

      8.2,I2C适配器驱动器注册表

      (一)首先在平台总线上登记I2C适配器驱动程序,并以平台设备方式将I2C适配器所要求的数据传递给I2C适配器驱动程序;
      (2)在S5PV210芯片中,三个I2C适配器操作方法相同,只是服务器地址和操作中断数不同,并且在平台设备中的适配器之间的差异已经转移到适配器驱动器中,因此,这些适配器通常用于i2c-s3c2410.c适配器驱动文件;
      s3c24xx_i2c_probe将被调用三次,因为它将在 platform_device.dev. platform_data中使用不同的适配器来区分,在平台总线上将被调用三次;

      8.i2c_board_info结构注册

      (1)为每个struct i2c_board_info建立相应的struct i2c-devinfo结构;
      (2)生成的结构i2c-devinfo结构与 __i2c_board_list链表相连;

      8.Adapter结构i2c_adapter注册

      (1)适配器适配器被视为内核中的设备,i2c_register_adapter()函数首先初始化内核内置的设备结构。
      (2)在向内核注册ap时,因为dap嵌入设备结构的总线总线类型设置为i2c_bus_type,事实上,它是注册到I2C总线的设备,I2C总线的匹配函数用于与I2C总线已经注册的司机匹配,如果匹配成功,请调用I2C总线的探测函数;
      (3)adap和已注册的结构i2c_board_info结构由适配器代码匹配,匹配生成结构客户端结构;
      (4)adap和已经注册的I2C驱动进行逐一匹配,如果I2C驱动定义了driver->attach_adapter方法就调用;

      8.生成i2c_client结构

      8.5.1.函数调用关系

      (1)结构i2c_client结构是适配器注册时在I2C总线上的设备,由适配器适配器和匹配的结构i2c_board_info结构组成;
      (2)struct i2c_client 在描述I2C设备时,I2C总线的设备类型为i2c_client_type。

      8.5.2,i2c_scan_static_board_info()函数

      (一)在 __i2c_board_list 链表上重复所有结构 i2c_devinfo 结构,并与新注册的适配器适配器的数目相匹配;
      (2)如果匹配,调用i2c_new_device()函数生成基于struct i2c_devinfo结构和 adapter adapter adapter adapter的结构客户端结构;

      8.5.3,i2c_new_device()函数

      8.5. bus_for_each_drv()函数的分析

      (1) bus_for_each_drv()函数是内核总线的驱动过渡函数,该函数是已经在总线总线上注册的驱动过渡,并且调用fn匹配函数与数据匹配驱动;
      (2)在i2c_register_adapter()注册函数中,公共汽车经过I2C公共汽车结构,数据是新注册的 adapter 结构 i2c_adapter 结构,匹配函数是 __process_new_adapter()函数;
      (3)功能:将I2C总线上已经注册的驱动逐一和新注册的适配器adap进行匹配,匹配函数是 __process_new_adapter()函数;

      8.5.5,__process_new_adapter()函数

      __process_new_adapter()函数的实际功能是检查在I2C总线上定义的I2C驱动器是否定义了attache_adapter方法,如果定义了调用驱动程序的attache_adapter方法,输入新注册的适配器适配器作为参数;
      (2)事实上,通用驱动器不是定义的attache_adapter方法,仅在i2cdev_driver驱动器中定义了attache_adapter方法,i2cdev_driver驱动器是i2c-dev.defined中的c的i2c_dev_init()函数,在博客: Device Interface Analysis of Adapters for I2C Subsystems ( i2c -dev."(c) Document Analysis)。 有详细的介绍;
      (3)实际效果:每件新注册的适配器适配器适配器,都会调用i2cdev_driver->attach_adapter方法,在sysfs中创建i2c-dev类"/sys/class/i2c-dev/i2c-n(n=0, 1,..⋯)",创建设备节点"/dev/i2c-n(n=0, 1,⋯⋯)"

      8.I2C适配器的设备接口分析(i2c-dev.(c文档分析)

      (1)i2c-dev.c是将I2C适配器暴露于上层应用程序的实现,表示为设备节点"/dev/i2c-n(n=0, 1, 2, ⋯⋯)",多少设备节点代表Soc的多少I2C控制器;
      (二)应用程序可直接通过设备节点操作I2C适配器,以与与I2C适配器连接的设备进行通信;
      (2)参考博客: Device Interface Analysis of Adapters for I2C Subsystems ( i2c -dev."(c) Document Analysis)。 ;

      8.7,I2C适配器驱动源分析(i2c-s3c2410)。(c)

      参考博客:S5PV210芯片I2C适配器驱动器分析(i2c-s3c2410.(c));

      9、I2设备驱动层

      9.介绍I2C设备驱动程序

      (一)I2C设备驱动器与特定硬件密切相关,即该设备是I2C接口,与SOC的I2C控制器连接,通过I2C总线和主控制SOC进行通信;
      (二)I2C设备驱动器将I2C设备驱动器注册到I2C核心层,然后核心层将I2C总线与I2C设备驱动器匹配,并将I2C适配器驱动器与I2C设备驱动器匹配;
      (3)I2C设备驱动器成功匹配I2C核心层后,设备可以直接调用I2C适配器进行数据通信;

      9.2,触摸屏幕驱动源代码分析(gslX680)。(c)

      参考博客: gslx680 Touchscreen Drive Source Code Analysis (gslX680.(c));

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/29258.html

          热门文章

          文章分类