I2C、 SPI、 USB驅動架構類比
1 I2C、 SPI、 USB驅動架構
根據圖12.4, Linux傾向於將主機端的驅動與外設端的驅動分離,而通過一個核心層將某種匯流排的協議進行抽象,外設端的驅動呼叫核心層API間接過渡到對主機驅動傳輸函式的呼叫。對於I2C、 SPI這類不具備熱插拔能力的匯流排而言,一般在arch/arm/mach-xxx或者arch/arm/boot/dts中會有相應的板級描述資訊,描述外設與主機的連線情況。Linux的各個子系統都呈現為相同的特點,表17.1類比了
I2C、 SPI、 USB驅動架構,其他的PCI等都是類似的。
表17.1 I2C、 SPI、 USB驅動架構的類比
對於USB、 PCI等匯流排而言,由於它們具備熱插拔能力,所以實際上不存在類似I2C、 SPI這樣的板級描述資訊。換句話說,即便是有這類資訊,其實也沒有什麼用,因為如果寫了板子上有個U盤,但實際上沒有,其實反而是製造了麻煩;相反,如果沒有寫, U盤一旦插入, Linux USB子系統會自動探測到一個U盤。
同時我們注意到, I2C、 SPI、 USB控制器雖然給別人提供了匯流排,但是其實自己也是由它自身依附的匯流排枚舉出來的。比如,對於SoC而言,這些控制器一般是直接整合在晶片內部,通過記憶體訪問指令來訪問的,因此它們自身是通過platform_driver、 platform_device這種模型列舉進來的
2 I2C主機和外設眼裡的Linux世界
I2C控制器所在驅動的platform_driver與arch/arm/mach-xxx中的platform_device(或者裝置樹中的節點)通過platform匯流排的match()函式匹配導致platform_driver.probe()執行,從而完成I2C控制器的註冊;而I2C上面掛的觸控式螢幕依附的i2c_driver與arch/arm/mach-xxx中的i2c_board_info指向的裝置(或者裝置樹中的節點)通過I2C匯流排的match()函式匹配導致i2c_driver.probe()執行,從而使觸控式螢幕展開。
圖17.1虛線上方部分是i2c_adapater眼裡的Linux世界;下方部分是i2c_client眼裡的Linux世界。其實, Linux中的每一個裝置通過它依附的匯流排被枚舉出來,儘管它自身可能給別人提供匯流排。