本文針對的核心為友善提供的linux-3.0.31版本,從linux驅動模型的角度分析i2C驅動。
一、linux的i2c驅動介紹。
Linux下編寫I2C裝置驅動有兩種方法,一種是利用系統給我們提供的i2c-dev.c來實作一個i2c擴充卡的裝置檔案。然後通過在應用層操作i2c擴充卡來控制i2c裝置。另一種是利用I2C驅動體系結構為i2c裝置,獨立編寫一個裝置驅動。
1、利用i2c-dev.c操作擴充卡,進而控制i2c裝置
i2c-dev.c并沒有針對特定的裝置而設計,隻是提供了通用的read()、write()和ioctl()等接口,應用層可以借用這些接口通路挂接在擴充卡上的i2c裝置的存儲空間或寄存器,并控制I2C裝置的工作方式。
2、利用I2C驅動體系結構,在核心裡直接為i2c裝置編寫驅動
目前linux提供兩種編寫i2c裝置驅動,分别為“Adapter方式(LEGACY)”和“Probe方式(new style)”,其核心資料結構為“structi2c_driver”即i2c裝置驅動,核心函數為“i2c_add_driver”即添加i2c裝置驅動。
● Probe方式(newstyle),如:
staticstruct i2c_driver pca953x_driver = {
.driver= {
.name= "pca953x",
},
.probe= pca953x_probe,
.remove= pca953x_remove,
.id_table= pca953x_id,
};
● Adapter方式(LEGACY),如:
staticstruct i2c_driver pcf8575_driver = {
.driver= {
.owner= THIS_MODULE,
.name= "pcf8575",
},
.attach_adapter= pcf8575_attach_adapter,
.detach_client= pcf8575_detach_client,
};
一、linux的i2c驅動實作流程
本文選擇以mma7660三軸重力加速度傳感器I2C驅動作為學習對象,來幫助學習i2c裝置驅動的編寫。其驅動實作流程如下圖所示:
其中關鍵資料結構邏輯關系圖如下所示:
三、i2c與sys檔案系統
與i2c有關的sys檔案系統有這麼幾個目錄:
“/sys/class/i2c-adapter”:i2c-adapter”類是由“i2c-core.c”中的“i2c-init”函數建立,每個i2c擴充卡的注冊都會在該目錄下建立自己的目錄,該目錄僅提供使用者觀察i2c擴充卡的視角,沒有讀寫操作意義。
“/sys/class/i2c-dev”:“i2c-dev”類是由2c-dev.c檔案中“i2c_dev_init”函數建立,每個i2c擴充卡的注冊都會在該目錄下建立自己的目錄,該目錄不僅提供使用者觀察i2c擴充卡的視角,而且建立了具體i2c擴充卡裝置,具備讀寫操作意義。
“/sys/bus/i2c”:i2c總線是由“i2c-core.c”中的“i2c-init”函數建立,向使用者提供i2c總線視角。