一、Linux的I2C體系結構
主要由三部分組成:
(1) I2C核心
提供I2C控制器和設備驅動的注冊和注銷方法,I2C通信方法,與適配器無關的代碼以及探測設備等。
(2) I2C控制器驅動(適配器)
(3) I2C設備驅動

二、重要的結構體
- i2c_adapter
//i2c控制器(適配器)
- i2c_algorithm
//I2C傳輸方法
SMBus是基于I2C總線規范的,所以上面的傳輸函數要根據自己的總線來選擇,選擇其一就可以。
- i2c_driver
//I2C驅動,和platform_driver,spi_driver類似
- i2c_client
//I2C設備
- i2c_msg
//I2C傳輸數據結構體,代表一個消息數據
總結上面結構體關系:
1. i2c_adapter和i2c_algorithm
i2c_adapter對應物理上的一個適配器,而i2c_algorithm對應一套通信方法,適配器需要通過i2c_algorithm提供的通信函數來產生對應的訪問時序。所以i2c_adapter中包含i2c_algorithm的指針。
i2c_algorithm使用master_xfer()來產生I2C時序,以i2c_msg為單位,i2c_msg代表一次傳輸的數據。
2. i2c_driver和i2c_client
i2c_driver對應一套驅動方法,包含probe,remove等方法。i2c_clent對應真實的物理設備,每個i2c設備都需要一個i2c_client來描述。i2c_driver與i2c_client是一對多的關系,一個i2c_driver上可以支持多個同類型的i2c_client。
3. i2c_adapter和i2c_client
i2c_adapter與i2c_client的關系和硬件上適配器與設備的關系一致,即i2c_client依附于i2c_adapter。一個適配器可以連接多個設備,所以i2c_adapter中包含i2c_client的鏈表。
三、API函數
//增加/刪除i2c_adapter
i2c_transfer()函數本身不具備驅動適配器物理硬件以完成消息交互的能力,它只是尋找到與i2c_adapter對應的i2c_algorithm, 并使用i2c_algorithm的master_xfer()函數真正驅動硬件流程。
追蹤i2c_transfer()的源碼會發現下面的代碼
for
四、適配器(控制器)驅動
由于I2C控制器通常是在內存上的,所以它本身也連接在platform總線上的,通過platform_driver和platform_device的匹配還執行。
(1) probe()完成如下工作:
- 初始化I2C控制器所使用的硬件資源,如申請IO地址,中斷號,時鐘等。
- 為特定I2C控制器實現通信方法,主要是實現i2c_algorithm的master_xfer()和functionality()函數。
- 通過i2c_add_adapter()添加i2c_adapter的數據結構(i2c_adapter成員已被初始化)。
模板代碼:
static
xxx_adapter_hw_init實現和具體的CPU和I2C控制器硬件相關的初始化。
functionality() 函數比較簡單,返回支持的通信協議。
master_xfer() 函數在適配器上完成i2c_msg的數據傳輸。
五、設備(外設)驅動
i2c_dirver就是i2c標準總線設備驅動模型中的驅動部分,i2c_client可理解為i2c總線上掛的外設。
模板代碼:
static
