2 I2C子系統
2.1 LinuxI2C子系統架構
在核心中已經提供I2C子系統,所以在做I2C驅動之前,就必須要熟悉該子系統。
2.2 三大組成部分
1、I2C核心(i2c-core)
I2C核心提供了I2C匯流排驅動和裝置驅動的註冊、登出方法,I2C通訊方法(algorithm)上層的、與具體適配器無關的代碼以及探測裝置、檢測裝置地址的上層代碼等。
2、I2C匯流排驅動(I2Cadapter/Algo driver)
I2C匯流排驅動是I2C適配器的軟體實現,提供I2C適配器與從裝置間完成資料通訊的能力。
I2C匯流排驅動由i2c_adapter和i2c_algorithm來描述
3、I2C客戶驅動程式(I2Cclient driver)
I2C客戶驅動是對I2C從裝置的軟體實現,一個具體的I2C客戶驅動包括兩個部分:一部分是i2c_driver,用於將裝置掛接於i2c匯流排;另一部分是裝置本身的驅動。
I2C客戶驅動程式由i2c_driver和i2c_client來描述
2.3 所有的I2C驅動代碼位於drivers/i2c目錄下
I2c-core.c 實現I2C核心的功能
I2c-dev.c 通用的從裝置驅動
Chips 特定的I2C裝置驅動
Busses I2C適配器的驅動
Algos 實現了一些I2C匯流排適配器的algorithm
2.4 I2C驅動編寫的兩種方法
從上面的圖我們可以看到兩種編寫驅動方法,一種是利用系統提供的i2c-dev.c來實現一個i2c適配器的裝置檔案,然後通過在應用程式層操作I2C適配器來控制I2C裝置;另一種是為I2C從裝置獨立編寫一個裝置驅動,不需要i2c-dev.c檔案。
2.5 重要的資料結構
每次分析子系統免不了分析它的資料結構,OK我們先來分析一下。
I2c_adapter結構體代表I2C匯流排控制器
struct i2c_adapter { struct module *owner; unsigned int class; /*classes to allow probing for */ const struct i2c_algorithm*algo; /* 匯流排上資料轉送的演算法*/ void *algo_data; /* algorithm 資料 */ int timeout; /* injiffies */ int retries; /* 重試次數 */ struct device dev; /* the adapter device */ int nr; char name[48]; /* 適配器名字 */ struct completion dev_released; /* 用於同步 */ };
I2c_algorithm對應一套通訊方法 [cpp] view plaincopy struct i2c_algorithm { int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, intnum); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, unsigned short flags, charread_write, u8 command, int size, unioni2c_smbus_data *data); u32 (*functionality) (structi2c_adapter *); };
Functionality 函數用於返回algorithm所支援的通訊協定,比如I2C_FUNC_I2C,I2C_FUNC_10BIT_ADDR等。
Master_xfer 函數實現匯流排上資料轉送,與具體的適配器有關
Master_xfer函數實現模板 [cpp] view plaincopy static int i2c_adapter_xxx_xfer(structi2c_adapter *adap, struct i2c_msg *msgs, int num) { ...... for (i = 0; i < num; i++) { i2c_adapter_xxx_start(); /*產生起始位*/ if (msgs[i]->flags & I2C_M_RD) { /*讀取*/