原文:i2c_probe()及I2C設備地址 - 驅動開發、總結與體會
以下部分內容修正過:
I2C的設備驅動是通過i2c_add_driver(&my_driver)向i2c-core註冊的,my_driver中的核心是
detach和attach函數,在attach中通過probe探測到 bus 上的設備並把設備和驅動建立連接以完成設備的初始化。如何探測 bus 上的設備、
Linux中i2c設備地址如何標識並引用?
I2C中, 典型的attach如下所示:
static int my_attach(struct i2c_adapter *adapter){
return i2c_probe(adapter, &addr_data, my_probe);
}
static int my_probe(struct i2c_adapter *adapter, int address, int kind){
..........
}
addr_data是在 include/linux/i2c.h 中定義的或自己在自己驅動程式中定義的一個i2c_client_address_data結構:
static struct i2c_client_address_data addr_data = { \
.normal_i2c = normal_i2c, \
.probe = probe, \
.ignore = ignore, \
.forces = forces, \
}
若自己不定義,則用i2c.h中的預設定義。
/*
i2c_client_address_data is the struct for holding default
client addresses for a driver and for the parameters supplied on the
command line */
struct i2c_client_address_data {
unsigned short *normal_i2c;
unsigned short *probe;
unsigned short *ignore;
unsigned short **forces;
};
根據作者自行定義設備地址與否,有兩種情形:
a.
採用預設定義:
一般是不會work,畢竟大多數i2c-core中是不可能提前知道所接設備地址的,這樣通過i2c_probe()探測肯定不可能找到,
也不可能建立兩者之間的聯繫;況且,i2c_probe()屬於i2c-core中的函數,i2c-core中管理著所有註冊過的裝置和驅動列表,i2c_probe()中也不能隨意傳入地址,否則容易導致系統混亂或有潛在的風險,所以i2c-core也不允許這麼做!
b. 作者自行定義地址結構:
典型例子如下:
/* Addresses to scan */
static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1, I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};/// 實際設備的地址List
static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
static struct i2c_client_address_data addr_data = {
normal_i2c,
probe,
ignore,
};
或者根本就不定義完整的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進行初始化並註冊的代碼中。
留言列表