在系統開機時,首先裝載的是
i2c匯流排驅動。乙個匯流排驅動用於支援一條特定的
i2c匯流排的讀寫。乙個匯流排驅動通常需要兩個模組,乙個
struct i2c_adapter
和乙個struct i2c_algorithm
來描述:
static struct
i2c_adapter
pb1550_board_adapter =;
這個樣例掛接了乙個叫做
「pb1550 adapter」
的驅動。但這個模組並未提供讀寫函式,具體的讀寫方法由第二個模組,
struct i2c_algorithm
提供。
static struct
i2c_algorithm
au1550_algo =
;i2c_adap->algo = &au1550_algo;
這個樣例給上述匯流排驅動增加了讀寫「演算法
」。通常情況下每個
i2c匯流排驅動都定義乙個自己的讀寫演算法,但鑑於有些匯流排使用相同的演算法,因而可以共用同一套讀寫函式。本例中的驅動定義了自己的讀寫演算法模組,起名叫
「au1550 algorithm」。
全部填妥後,通過呼叫:
i2c_add_adapter(i2c_adap);
將這兩個模組註冊到作業系統裡,匯流排驅動就算裝上了。對於
amd au1550
,這部分已經由
amd提供了。
i2c的裝置驅動是通過
i2c_add_driver(&my_driver)
向i2c-core
註冊的,
my_driver
中的核心是
detach_client
和attach_adapter
函式,在
attach_adapter
中通過probe
探測到匯流排上的裝置並把裝置和驅動建立連線以完成裝置的初始化。
裝置驅動透過
i2c匯流排同具體的裝置進行通訊。乙個裝置驅動有兩個模組來描述,
struct i2c_driver
和struct i2c_client。
當系統開機、
i2c匯流排驅動裝入完成後,就可以裝入裝置驅動了。首先裝入如下結構:
static struct i2c_driver zlg7290_driver = ;
i2c_add_driver(&zlg7290_driver);
這個i2c_driver
一旦裝入完成,其中的
attach_adapter
函式就會被呼叫。
如何探測匯流排上的裝置、
linux
中i2c
裝置位址如何標識並引用?
i2c中,
典型的attach_adapter
如下所示:
static int my_attach(struct i2c_adapter *adapter)
static int
zlg7290_detect
(struct i2c_adapter *adapter, int address, int kind)
3.2.2.1
iic裝置探測
注意探測可能會找到多個裝置,因而不僅乙個
i2c匯流排可以掛多個不同型別的裝置,乙個裝置驅動也可以同時為掛在多個不同
i2c匯流排上的裝置服務。
每當裝置驅動探測到了乙個它能支援的裝置,它就建立乙個
struct i2c_client
來標識這個裝置:
struct i2c_client *new_client;
…… new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &zlg7290_driver;
new_client->flags = 0;
strlcpy(new_client->name, dev_name, i2c_name_size);
if ((err =
i2c_attach_client
(new_client)))
可見,乙個
i2c_client
代表著位於
adapter
匯流排上,位址為
address
,使用zlg7290_driver
來驅動的乙個裝置。它將匯流排驅動與裝置驅動,以及裝置位址繫結在了一起。乙個
i2c_client
就代表著乙個
i2c裝置。
當得到i2c裝置後,就可以直接對此裝置進行讀寫:
extern int i2c_master_send(struct i2c_client *,const char* ,int);
extern int i2c_master_recv(struct i2c_client *,char* ,int);
3.2.2.2
linux
下iic
裝置位址
addr_data
是在
include/linux/i2c.h
中定義的或自己在自己驅動程式中定義的乙個
i2c_client_address_data
結構:
static struct i2c_client_address_data addr_data =
若自己不定義,則用
i2c.h
中的預設定義。
struct i2c_client_address_data ;
根據作者自行定義裝置位址與否,有兩種情形:
a.採用預設定義,一般是不會
work,
畢竟大多數
i2c-core
中是不可能提前知道所接裝置位址的,這樣通過
i2c_probe()
探測肯定不可能找到,也不可能建立兩者之間的聯絡;況且,
i2c_probe()
屬於i2c-core
中的函式,
i2c-core
中管理著所有註冊過的裝置和驅動列表,
i2c_probe()
中也不能隨意傳入位址,否則容易導致系統混亂或有潛在的風險,所以
i2c-core
也不允許這麼做!
b.作者自行定義位址結構
典型例子如下:
若自行定義,則參考如下:
static unsigned short normal_i2c = ;///
實際裝置的位址
list
static unsigned short probe[2] =
;static unsigned short ignore[2] =
;static struct i2c_client_address_data addr_data = ;
或者根本就不定義完整的
i2c_client_address_data
結構,只根據需要定義
normal_i2c,probe,ignore
,forces,
然後呼叫
i2c_probe(adapter,&addr_data,
&my_probe)
即可。
在my_probe()
中把實際的位址賦於
i2c_client
,呼叫i2c_set_clientdata()
設定i2c_client->dev->drv_data,
並呼叫i2c_attach_client(client)
向系統註冊裝置。
最後,i2c_probe()
中探測時的位址優先順序:
forces, probe, normal_i2c(
其中忽略
ignore
中的項)。
i2c裝置在實際使用中比較廣泛,
sensor,rtc,audio, codec,etc.
因裝置複雜性不同,
linux
中有些驅動中對位址的定義不在同一檔案,這時多數情況都在
arch
中對裝置作為
platform_device
進行初始化並註冊的**中。
九 IIC驅動原理分析
學習目標 學習iic驅動原理 一 iic匯流排協議 iic序列匯流排包括一條資料線 sda 和一條時鐘線 scl 支援 一主多從 和 多主機 模式 每個從機裝置都有唯一的位址來識別。圖 1 iic 主從結構 二 iic訊號和時序 iic匯流排有3種型別訊號 1 開始訊號s scl為高電平,sda由高...
IIC驅動程式分析(一)
根據上一節課的分析,我們來解讀這段 include include include include include include include static unsigned short ignore static unsigned short normal addr 位址值是7位 static...
IIC驅動程式分析(二)
在上一節的實驗中,我們採用的是normal i2c 的方式,即 要發出s訊號和裝置位址並得到ack訊號,才能確定存在這個裝置。那麼如果本身不存在這個裝置當然啊不會給出應答訊號,這是就不會呼叫i2c probe adapter,addr data,at24cxx detect 函式中的at24cxx ...