Linux的I2C驅動架構

來源:互聯網
上載者:User

Linux的I2C驅動架構
1. Linux的I2C驅動架構Linux中I2C匯流排的驅動分為兩個部分,匯流排驅動(BUS)和裝置驅動(DEVICE)。其中匯流排驅動的職責,是為系統中每個I2C匯流排增加相應的讀寫方法。但是匯流排驅動本身並不會進行任何的通訊,它只是存在在那裡,等待裝置驅動調用其函數。

裝置驅動則是與掛在I2C匯流排上的具體的裝置通訊的驅動。通過I2C匯流排驅動提供的函數,裝置驅動可以忽略不同匯流排控制器的差異,不考慮其實現細節地與硬體裝置通訊。

1.1 匯流排驅動在系統開機時,首先裝載的是I2C匯流排驅動。一個匯流排驅動用於支援一條特定的I2C匯流排的讀寫。一個匯流排驅動通常需要兩個模組,一個struct i2c_adapter和一個struct i2c_algorithm來描述:

static struct i2c_adapter pb1550_board_adapter = {
name: "pb1550 adapter",
id: I2C_HW_AU1550_PSC,
algo: NULL,
algo_data: &pb1550_i2c_info,
inc_use: pb1550_inc_use,
dec_use: pb1550_dec_use,
client_register: pb1550_reg,
client_unregister: pb1550_unreg,
client_count: 0,
};

這個範例掛接了一個叫做“pb1550 adapter”的驅動。但這個模組並未提供讀寫函數,具體的讀寫方法由第二個模組,struct i2c_algorithm提供。

static struct i2c_algorithm au1550_algo = {

.name = "Au1550 algorithm",

.id = I2C_ALGO_AU1550,

.master_xfer = au1550_xfer,

.functionality = au1550_func,

};

i2c_adap->algo = &au1550_algo;

這個範例給上述匯流排驅動增加了讀寫“演算法”。通常情況下每個I2C匯流排驅動都定義一個自己的讀寫演算法,但鑒於有些匯流排使用相同的演算法,因而可以共用同一套讀寫函數。本例中的驅動定義了自己的讀寫演算法模組,起名叫“Au1550 algorithm”。

全部填妥後,通過調用:

i2c_add_adapter(i2c_adap);

將這兩個模組註冊到作業系統裡,匯流排驅動就算裝上了。對於AMD au1550,這部分已經由AMD提供了。

1.2 裝置驅動如前所述,匯流排驅動只是提供了對一條匯流排的讀寫機制,本身並不會去做通訊。通訊是由I2C裝置驅動來做的,裝置驅動透過I2C匯流排同具體的裝置進行通訊。一個裝置驅動有兩個模組來描述,struct i2c_driver和struct i2c_client。

當系統開機、I2C匯流排驅動裝入完成後,就可以裝入裝置驅動了。首先裝入如下結構:

static struct i2c_driver driver = {

.name = "i2c TV tuner driver",

.id = I2C_DRIVERID_TUNER,

.flags = I2C_DF_NOTIFY,

.attach_adapter = tuner_probe,

.detach_client = tuner_detach,

.command = tuner_command,

};

i2c_add_driver(&driver);

這個i2c_driver一旦裝入完成,其中的attach_adapter函數就會被調用。在其中可以遍曆系統中的每個i2c匯流排驅動,探測想要訪問的裝置:

static int tuner_probe(struct i2c_adapter *adap)

{

return i2c_probe(adap, &addr_data, tuner_attach);

}

注意探測可能會找到多個裝置,因而不僅一個I2C匯流排可以掛多個不同類型的裝置,一個裝置驅動也可以同時為掛在多個不同I2C匯流排上的裝置服務。

每當裝置驅動探測到了一個它能支援的裝置,它就建立一個struct i2c_client來標識這個裝置:

new_client->addr = address;

new_client->adapter = adapter;

new_client->driver = &driver;

/* Tell the I2C layer a new client has arrived */

err = i2c_attach_client(new_client);

if (err)

goto error;

可見,一個i2c_client代表著位於adapter匯流排上,地址為address,使用driver來驅動的一個裝置。它將匯流排驅動與裝置驅動,以及裝置地址綁定在了一起。一個i2c_client就代表著一個I2C裝置。

當得到I2C裝置後,就可以直接對此裝置進行讀寫:

/*

* The master routines are the ones normally used to transmit data to devices

* on a bus (or read from them). Apart from two basic transfer functions to

* transmit one message at a time, a more complex version can be used to

* transmit an arbitrary number of messages without interruption.

*/

extern int i2c_master_send(struct i2c_client *,const char* ,int);

extern int i2c_master_recv(struct i2c_client *,char* ,int);

與通常意義上的讀寫函數一樣,這兩個函數對i2c_client指標指定的裝置,讀寫int個char。傳回值為讀寫的位元組數。對於我們現有的SLIC的驅動,只要將最後要往匯流排上進行讀寫的資料引出傳輸到這兩個函數中,移植工作就算完成了,我們將得到一個Linux版的I2C裝置驅動。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.