S3C2440驅動簡析——I2C驅動(1)

來源:互聯網
上載者:User

      這次來研究核心內建I2C驅動的代碼,在深入代碼之前,首先簡單瞭解一下I2C核心資料結構的相互關係。由此來展開,也許能夠對驅動代碼有更好地理解。軟體資料結構的設計、資料結構之間的關係就至少應該描述硬體物理串連的這種組織關係。Linux的i2c 架構中各個部分的關係如所示:

 

 

 

核心中 i2c 相關代碼可以分為三個層次:
1. i2c 架構:i2c.h 和i2c-core.c 為i2c 架構的主體,提供了核心資料結構的定義、i2c 適配器驅動和裝置驅動的註冊、登出管理,i2c 通訊方法上層的、與具體適配器無關的代碼、檢測裝置地址的上層代碼等;i2c-dev.c 用於建立i2c 適配器的/dev/i2c/%d 裝置節點,提供i2c 裝置存取方法等。
2. i2c 匯流排適配器驅動:定義描述具體i2c 匯流排適配器的i2c_adapter 資料結構、實現在具體i2c 適配器上的i2c 匯流排通訊方法,並由i2c_algorithm 資料結構進行描述。
3. i2c 裝置驅動:定義描述具體裝置的i2c_client 和可能的私人資料結構、藉助i2c 架構的i2c_probe 函數實現註冊裝置的attach_adapter 方法、提供裝置可能使用的位址範圍、以及裝置地址檢測成功後建立i2c_client 資料結構的回呼函數。

 

 

I2C主要資料結構如下:

 

1. 一個 i2c 裝置的驅動程式由i2c_driver 資料結構描述,定義於include/linux/i2c.h:

struct i2c_driver {<br />char name[32]; //最大32位元組的字串<br />int id; //id 可選0xf000 到0xffff 中的任一數值<br />unsigned int flags; //一般直接設定為I2C_DF_NOTIFY<br />int (*attach_adapter)(struct i2c_adapter *);<br />int (*detach_client)(struct i2c_client *);<br />int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);<br />void (*inc_use)(struct i2c_client *client);<br />void (*dec_use)(struct i2c_client *client);<br />};<br />

 

attach_adapter 回呼函數在安裝i2c 裝置驅動程式模組時、或者在安裝i2c 適配器驅動
程式模組時被調用,用於檢測、認領裝置並為裝置分配i2c_client 資料結構。

 

detach_client 方法在卸載適配器或裝置驅動程式模組時被調用,用於從匯流排上登出裝置、並釋放i2c_client 及相應的私人資料結構。

 

inc_use 和dec_use 所指向的函數用於改變i2c 裝置驅動程式模組的引用計數。注意不要直接調用i2c_driver資料結構中的這兩個方法,而要通過如下函數調用路徑:
i2c_use_client > i2c_inc_use_client > inc_use
i2c_release_client > i2c_dec_use_client > dec_use

 

 

2. 一個 i2c 裝置由i2c_client 資料結構進行描述:
struct i2c_client {<br />char name[32];<br />int id;<br />unsigned int flags; /* div., see below */<br />unsigned int addr; /* chip address - NOTE: 7bit addresses are stored in the */<br />/* _LOWER_ 7 bits of this char */<br />struct i2c_adapter *adapter; /* the adapter we sit on */<br />struct i2c_driver *driver; /* and our access routines */<br />void *data; /* for the clients */<br />int usage_count; /* How many accesses currently to the client */<br />};<br />

在安裝適配器或者裝置的驅動程式時通過裝置驅動程式 i2c_driver 中的attach_adapter 函數檢測裝置地址。如果檢測成功則調用裝置驅動程式提供的回呼函數建立描述裝置的i2c_client 資料結構,並將其中的driver指標指向裝置驅動程式的i2c_driver 資料結構。這樣將來就可以使用i2c_driver 中的登出裝置和控制引用計數的方法了。

 

 

3. 一個 i2c 適配器由i2c_adapter 資料結構描述:
struct i2c_adapter {<br />char name[32];<br />unsigned int id; /* == is algo->id | hwdep.struct->id, for registered values see below */<br />struct i2c_algorithm *algo; /* the algorithm to access the bus */<br />void *algo_data;<br />void (*inc_use)(struct i2c_adapter *);<br />void (*dec_use)(struct i2c_adapter *);<br />int (*client_register)(struct i2c_client *);<br />int (*client_unregister)(struct i2c_client *);<br />void *data; /* private data for the adapter */<br />struct semaphore lock;<br />unsigned int flags; /* flags specifying div. data */<br />struct i2c_client *clients[I2C_CLIENT_MAX];<br />int client_count;<br />int timeout;<br />int retries;<br />#ifdef CONFIG_PROC_FS<br />/* No need to set this when you initialize the adapter */<br />int inode;<br />#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)<br />struct proc_dir_entry *proc_entry;<br />#endif<br />#endif /* def CONFIG_PROC_FS */<br />};

 

在 i2c_adapter 資料結構中設計了clients 指標數組,指向該匯流排上每個裝置的i2c_client 資料結構。由於一條i2c 匯流排上最多隻有I2C_CLENT_MAX 個裝置,所以可以使用靜態數組(題外話,如果相關資料結構的個數是未知的,鏈表顯然是更好的選擇)。lock 訊號量用於實現對i2c 匯流排的互斥訪問:在訪問i2c 匯流排上的任一裝置期間當前進程必須首先獲得該訊號量,並且在阻塞等待i2c 操作完成期間不釋放。

 

 

4.具體 i2c 適配器的通訊方法由i2c_algorithm 資料結構進行描述:

struct i2c_algorithm {<br />char name[32]; /* textual description */<br />unsigned int id;<br />int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);<br />int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,<br />unsigned short flags, char read_write,<br />u8 command, int size, union i2c_smbus_data * data);<br />int (*slave_send)(struct i2c_adapter *,char*,int);<br />int (*slave_recv)(struct i2c_adapter *,char*,int);<br />int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long);<br />u32 (*functionality) (struct i2c_adapter *);<br />};

 

master_xfer/smbus_xfer 指標指向i2c 適配器驅動程式模組實現的i2c 通訊協定或者smbus 通訊協定。由下文分析可見在使用者進程通過i2c-dev 提供的/dev/i2c/%d 裝置節點訪問i2c 裝置時,最終是通過調用master_xfer 或者smbus_xfer 指向的方法完成的。

 

slave_send/recv 函數用於實現當i2c 適配器扮演slave 角色時的傳輸方法。 

 

 

由於內容統一的關係,在一篇文章裡又記錄資料結構,又貼出驅動代碼,這樣個人感覺比較亂。所以我還是選擇把I2C驅動這一塊內容分成三部分,本文討論資料結構為第一部分,在接下來的I2C驅動文章《S3C2440驅動簡析——I2C驅動(2)》裡,將會深入i2c-dev.c驅動代碼。第三部分是深入i2c-core.c,以瞭解實際底層操作的過程。

 

欲知後事如何,請聽下回分解~

 

 

本系列博文連結:

I2C驅動(1)http://blog.csdn.net/jarvis_xian/archive/2011/05/27/6449939.aspx
I2C驅動(2)http://blog.csdn.net/jarvis_xian/archive/2011/05/27/6451168.aspx
I2C驅動(3)http://blog.csdn.net/jarvis_xian/archive/2011/05/28/6452431.aspx
I2C驅動(4)http://blog.csdn.net/jarvis_xian/archive/2011/05/30/6455697.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.