原文: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進行初始化並註冊的代碼中。

huenlil 發表在 痞客邦 PIXNET 留言(0) 人氣()