該篇不屬於原創,主要是最近解決了一個I2C的問題,期間看了很多大俠的博文,現在將這個子系統整理一下。
整個I2C framework, eric.xiao大俠做了很詳盡的敘述,給了我很大協助,在此表示感謝,好像也是成都的,有緣....
++++++++++++++++++++++++++++++++++++
這裡用稍微“粗俗”一點的語言稍微記錄一下,方便記憶即可,
i2c 驅動架構套件含三層:
1,i2c core:提供通用的一些方法和通訊演算法供i2c bus操作使用,這是與具體硬體無關的一層。
2,i2c bus: 這是與具體i2c模組相關的一層,不同的cpu會有不同的實現,主要實現i2c驅動並註冊。
3,i2c client:這是具體i2c裝置的驅動。
完整的i2c架構會產生兩個ko檔案(如果你選擇M模式的話),一個是bus的,一個是client裝置的。
i2c core裡面會向sys檔案系統註冊一個i2c匯流排並提供i2c匯流排方法。
i2c bus會使用platform的方式向核心註冊device和driver,來完成i2c模組的初始化:通常在板級代碼中arch/arm/mach-xxxx/devices.c中完成裝置註冊,platform_device_register(&xxx_i2c_device);drivers/i2c/busses/i2c-xxxx.c中完成驅動的註冊,platform_driver_register(&xxxx_i2c_driver)
i2c client中使用i2c core中提供的方法進行裝置和驅動的註冊:通常在板級代碼中進行裝置的註冊,這兒core提供的API比較特殊,是使用i2c_register_board_info來向系統註冊裝置資訊,當然如果深入看代碼的話,發現裡面並沒有構建i2c_client結構,但i2c core要使用i2c_client來和driver做匹配,從而綁定的,那它怎麼在裡面運作的呢?
當i2c bus platform裝置註冊時,bus的probe函數會被調用,緊接著i2c_add_numbered_adapter()->i2c_register_adapter()->i2c_scan_static_board_info()->i2c_new_device() 會構建i2c_client結構,i2c_attach_client()會將裝置註冊到系統。不知道為什麼設計者要繞這麼大一圈子,為了通用性?難道就沒有更優美一點的方案?:( 核心設計者的心思你別猜,別猜,猜來猜去就會!^&@¥$
然後在裝置的驅動代碼裡面註冊驅動:i2c_add_driver()->i2c_register_driver()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev()->__driver_attach()->driver_probe_device()-> 調用i2c匯流排的match函數進行driver和device 資訊的匹配(根據裝置的不同,比較的內容不相同,有時候是name,有時候是id),如果匹配,調用really_probe()->driver的probe。 如果人的經脈,2個小周天后發功......
這裡去除了很多核心其它的處理,為了方便理解,僅作為一個備忘錄。