目录
1.I2C主设备:
其实主控这端的i2c驱动 也可以理解为适配器驱动,尽管I2C为别的设备提供了总线,但是它作为适配器时自己也被认为是platform总线上的一个客户。Linux总线,设备,驱动模型就是一个树形结构,每个节点可能成为别人的控制器,但是自己也被认为从上一级枚举出来的。
下面将以busses文件夹的I2c-tegra.c来描述整个适配器驱动的框架。
看一个驱动代码,从入口函数出发,adapter驱动还是遵循platform总线那一套框架,i2c总线框架其实与platform总线框架也十分类似。感兴趣可以去看下相关接口。
在设备树里添加了 与tegra_i2c_of_match 兼容的节点后。platform driver 与 device匹配成功后会调用到 tegra_i2c_probe。
在Linux 驱动的编程中特别喜欢利用struct结构体来抽象出来一对应不通设备的变量,也就是面向对象的思想,这在Linux驱动编程中十分的重要。下面就来看看tegra_i2c_dev结构体
probe中会初始化对应的一些数据
其中比较关键的是
i2c_dev->adapter.algo = &tegra_i2c_algo; 中tegra_i2c_algo会有tegra I2C总线通信的传输函数tegra_i2c_xfer
可以看到这个接口 使用到了上一节提到的adapter结构体 与 msg结构体 真正发的 是tegra_i2c_xfer_msg这个接口。
2.I2C client 与 driver是如何匹配的呢?
注册i2c_driver的时候 会调用到i2c_device_match这个函数 这个函数就是用来匹配client与driver的。
以下是I2c设备在设备树里的表现形式
3.I2C从设备
以at24.c举例子
还是从入口函数着手可以看到i2c从设备的驱动,就没有用到platform总线,而是直接挂在了i2c总线下,上面有提到其实可以把i2c总线抽象成platform总线的一个子设备,每一条i2c总线又会对应一个adapter。
at24_data这个私有数据结构体可以看到 有i2client ,并且是个动态数组,说明多个client是可以对应这一个driver的。
那么从设备的读写是如何实现的呢?
在probe函数中可以找到以下对应的代码,以at24_bin_read举例 大概的调用关系
at24_bin_read
at24_read
at24_eeprom_read
i2c_transfer
其实就跟我上一节讲到的东西是对的上的 本质就会调用到i2c_transfer这个接口,这个接口本质就是使用client对应的adapter上所注册的x_fer接口来进行传输数据。