linux设备模型之i2c子系统

来源:互联网 发布:淘宝定时上下架软件 编辑:程序博客网 时间:2024/05/16 07:13

===============================
本文系本站原创,欢迎转载!
转载请注明出处:http://blog.csdn.net/gdt_a20
===============================

      I2c子系统将i2c控制器(i2c寄存器所在的那块电路)抽象出来,用adapter(适配器)这个结构来描述,可以说一个适配器就代表一条i2c总线,而挂接在i2c总线上的设备是用client这个结构体来表述,另外i2c_bus上的设备链表挂接的不单单是连接的这条i2c上的client,同样adapter也作为一个设备挂在其所在的i2c_bus,也就是说控制器和设备都作为i2c_bus上的设备连接在设备链表,他们用内嵌的device的type这个成员来区分,适配器的类型为i2c_adapter_type,client的类型为i2c_client_type。

一、i2c相关的描述结构

     首先看一下i2c子系统给adapter定义的描述结构:

   再来看一下client的描述结构:


    下面是driver的表述结构i2c_driver:

      另外client端有一条全局链表,用于串联所有i2c的client设备,为__i2c_board_list,也就是说client可以静态注册亦可动态
被探测,静态注册挂接在该链表上的结构为:

    i2c_devinfo结构静态注册的信息最后都会被整合集成到client中,形成一个标准的i2c_client设备并注册。

二、i2c核心初始化代码分析

    首先看一下i2c平台无关的核心初始化,代码位于drivers/i2c/i2c-core.c下:

三、i2c_add_driver分析

    驱动端的统一接口为i2c_add_driver:

     以上就是i2c通用driver添加的流程,下面看一下设备端,适配器的流程
四、i2c_add_adapter分析

  依据以上的分析画出流程图如下:

 2


      i2c_driver依据内部成员的设定,会走不同的分支,产生不同的作用,下面根据流程前后顺序总结一下:
当发现的是i2c_bus上的一个client时(发生在标准driver注册的匹配):
 1、首先会进入到bus定义的匹配函数i2c_device_match如果定义了CONFIG_OF_DEVICE宏并且内部的标准
    driver结构定义了of_match_table成员,则利用其进行匹配;
 2、否则如果driver->id_table成员设定,则利用其进行匹配,否则匹配失败。
 3、如果匹配成功会调用i2c_bus的i2c_device_probe函数,该函数会判断,如果该i2c_driver的probe成员
    或者id_table成员为NULL,则返回,否则利用i2c_driver->probe初始化这个client。
当发现的是代表该i2c_bus的上的adapter时(发生在bus的遍历):
 1、如果该driver的driver->detect或者address_list为NULL退出
 2、如果该adapter->class和driver->class不匹配也退出
 3、如果以上都成立最终会调用driver->detect函数,实例化支持的client
 4、如果driver->attach_adapter也被设定,含会走旧式的路线,直接利用driver->attach_adapter进行探测
      不过,一般不会让3&&4这种结果出现
  可见,i2c_driver的设置非常灵活,抓住关键成员就不难掌握其流程。

五、i2c关于dev下节点的产生及其操作

  该部分的代码位于rivers/i2c/i2c-dev.c下,我们从头看起:

 

     由于没有关于client的支持表的定义,因此匹配client时就会直接返回, 由于存在成员attach_adapter,因此当匹配adapter时会进入该函数。

    通过以上分析可以看到i2c-dev层,找到一个adapter就会自动为其创建设备节点,形式类似于i2c-*,那么当应用层open对应的设备节点的时候,内核会自动调用刚才注册的字符设备的操作函数, 我们先来看一下刚才注册的字符设备的操作集:

    按照用户层的流程先看一下open函数i2cdev_open:

      由open可见,我们要操作i2c下的设备,始终是需要通过adapter,物理上也是如此,操作设备都是通过控制器进行读写的,因此我们打开的始终是adapter而open过程中会创建client,来表述我们主观上是要操作设备。下面在看一下read函数:

    i2c_transfer函数上面已经分析过了,其会最终调用client所在adapter的adap->algo->master_xfer函数发送。

六、总结

    分析了linux下i2c子系统模型及其关键点,针对核心的平台无关代码进行了描述,以上为个人观点,如有不妥,还望指正 ^_^

 

原创粉丝点击