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

    說時遲,那時快,馬上進入I2C驅動的最後一個小節了,在這個小節裏,我們主要探討i2c_algorithm 數據結構和i2c-core.c 的一些主要函數及其作用。有鑑於i2c-core.c 代碼達2000行,所以本文僅對導出的函數(EXPORT_SYMBOL)進行簡單註釋,其它函數想必也是爲前者服務的啦。好,馬上進入正題:

 

i2c_algorithm 結構體

 

一個 i2c 適配器上的i2c 總線通信方法由其驅動程序提供的i2c_algorithm 數據結構描述,由algo 指針指向。i2c_algorithm 數據結構即爲i2c_adapter 數據結構與具體i2c 適配器的總線通信方法的中間層,正是這個中間層使得上層的i2c 框架代碼與與具體i2c 適配器的總線通信方法無關,從而實現了i2c 框架的
可移植性和重用性。當安裝具體i2c 適配器的驅動程序時由相應驅動程序實現具體的i2c_algorithm 數據結構,其中的函數指針指向操作具體i2c 適配器的代碼。

 

master_xfer/smbus_xfer 指針指向i2c 適配器驅動程序模塊實現的i2c 通信協議或者smbus 通信協議。在用戶進程通過i2c-dev 提供的/dev/i2c/%d 設備節點訪問i2c 設備時,最終是通過調用
master_xfer 或者smbus_xfer 指向的方法完成的。

 

 

i2c-core.c

i2c.h 和i2c-core.c 爲i2c 框架的主體,提供了核心數據結構的定義、i2c 適配器驅動和設備驅
動的註冊、註銷管理,i2c 通信方法上層的、與具體適配器無關的代碼、檢測設備地址的上層代碼等;
i2c-dev.c 用於創建i2c 適配器的/dev/i2c/%d 設備節點,提供i2c 設備訪問方法等。

 

下面介紹其主要的函數

函數i2c_init

主要做了以下幾件事情:

1.i2c_add_driver(&dummy_driver);
   註冊i2c總線

2.class_compat_register("i2c-adapter");

   註冊一個可兼容的類

3.i2c_add_driver(&dummy_driver);
   加載驅動

 

函數i2c_exit

這個就不解釋了呀~~

 

結構體i2c_bus_type

 

本結構體被導出,其裏面包含了6個函數,其作用看名字就能猜到個大概。下面貼出以上6個函數的代碼。

 

函數i2c_add_adapter

函數主要作用是添加一個適配器

1.idr_get_new_above(&i2c_adapter_idr, adapter,
                               __i2c_first_dynamic_bus_num, &id);

   確認是否還能分配得到適配器id,該操作不能被打斷。

2.i2c_register_adapter(adapter);
   註冊一個適配器

 

函數i2c_del_adapter

對應於i2c_add_adapter,此函數刪除一個適配器。

 

函數 i2c_register_driver

 

註冊一個設備

1.driver_register(&driver->driver);
   開始先註冊一個設備

2.bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);
   調用相對應的__attach_adapter 函數,並傳遞參數driver 給它。完成設備綁定適配器的動作。至於__attach_adapter 的代碼粘貼如下

  

  

函數i2c_del_driver

相對應i2c_register_driver,本函數執行卸載設備的動作。

1.bus_for_each_dev(&i2c_bus_type, NULL, driver, __detach_adapter);
   調用__detach_adapter 函數,並傳遞函數driver 給它,完成分離設備和適配器的功能。

2.driver_unregister(&driver->driver);
   卸載設備。

   __detach_adapter 代碼如下

  

 

最後來看3個重要的i2c總線操作函數

函數 i2c_transfer

該函數幾乎與 i2c_master_recv 和i2c_master_send (接下來馬上敘述)函數一模一樣,都是在持有i2c_adapter 的lock 信號量的情況下利用i2c 適配器的algo 所指的i2c_algorithm 數據結構的master_xfer 方法執行實際的i2c 操作。

整個函數最重要的,當數for 循環裏面的內容,而for 循環裏面的內容,最最重要的,肯定就是

ret = adap->algo->master_xfer(adap, msgs, num);  經過前文提及的內容,master_xfer用於產生I2C訪問週期需要的信號,以I2C消息爲單位。

 

函數 i2c_master_send

把需要發送的數據以及其信息保存到msg 結構體,通過i2c_transfer 函數發送。

 

函數 i2c_master_recv

跟發送函數i2c_master_send 對應的一個接收函數,具體不作解釋啦。

 

由於篇幅問題,故不能肆意展開全部代碼,但我還是在這裏羅列一下關於smbus協議需要注意的函數:

s32 i2c_smbus_read_byte(struct i2c_client *client);

s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);

s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command);

s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value);

s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);

s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value);

s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command,
                                              u8 *values);

s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
                                              u8 length, const u8 *values);

static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
                                                   unsigned short flags,
                                                   char read_write, u8 command, int size,
                                                   union i2c_smbus_data * data);

以上一系列的函數,都是在i2c_smbus_xfer 函數的基礎上建立起來的,只要理解了基石,其上的函數就不足爲懼了。最後的最後,看一下這個藏在代碼最後的基石吧!

 

函數 i2c_smbus_xfer

該函數通過適配器驅動提供的總線訪問方法(i2c_algorithm 的smbus_xfer 方法)嘗試訪問處於addr 地址上的設備。其實函數裏面最核心的一句是:

res = adapter->algo->smbus_xfer(adapter, addr, flags,
                                                read_write, command,
                                                protocol, data);

哈哈,這豈不妙哉,到最後我們還是回到結構體i2c_algorithm 的smbus_xfef 成員函數(見本文起始部分)。真是衆裏尋他千百度,驀然回首,此函數卻在燈火闌珊處。

 

 

經過這一個i2c系列4個小節的學習,自己對代碼的分析,特別是驅動代碼的分析有了一定的提高,起碼在心理上不會感到畏懼。希望各位初學的朋友能夠跟我一起堅持下去,踏踏實實地走好每一步!

 

 

本系列博文鏈接:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章