Linux驅動 I2C匯流排

2021-10-04 14:58:25 字數 2184 閱讀 1465

這裡以rk3288為例子,使用的是linux4.14,根據裝置樹節點i2c 與rk3x_i2c_driver,match之後,就會呼叫對應的probe(rk3x_i2c_probe),這裡主要就是註冊乙個adapt(i2c_add_adapter),也就是i2c控制器,或者說是i2c主裝置,既然是主裝置,就需要提供讀寫的能力,以及scl的時鐘:

1.i2c->adap.algo = &rk3x_i2c_algorithm;//提供讀寫的方法

2.clk_rate = clk_get_rate(i2c->clk);

rk3x_i2c_adapt_div(i2c, clk_rate); //設定時鐘分頻

3.ret = devm_request_irq(&pdev->dev, irq, rk3x_i2c_irq, 0, dev_name(&pdev->dev), i2c);

//申請對應的中斷

4.ret = i2c_add_adapter(&i2c->adap); //註冊adapt

在ret = i2c_add_adapter(&i2c->adap);中有乙個特別的函式of_i2c_register_devices(adap);

它會根據adapt對應的裝置節點,輪詢其子節點,然後of_i2c_register_device(adap, node);,這裡最後就會註冊i2c_client,既然是從裝置,那麼也有幾點必須的:

1.of_modalias_node(node, info.type, sizeof(info.type)) //名字,用於與i2c_driver匹配

2.addr_be = of_get_property(node, "reg", &len); //每一種從裝置都有自己的位址,位址其實是實現i2c匯流排的基礎

3.i2c_new_device(adap, &info);

然後另一方面,各種各樣的i2c_driver也會註冊到i2c_bus中,i2c_driver會與i2c_client 進行match (i2c_match中對type有要求,adapt不會被匹配上),如果匹配上,就會呼叫driver->probe,至於probe中幹什麼事情,就得根據該i2c的用途來決定了,比如是rt5640(音訊),那麼裡面就會註冊乙個codec,如果是觸控螢幕,那就就會註冊乙個輸入裝置等等,但是無論是用於什麼,裡面一定會提供讀寫的方法,而這個方法最後一定會呼叫到 i2c->adap.algo->master_xfer。這樣i2c的基本流程就已經完成了。

通過裝置樹可以發現,乙個adapt下往往掛著多個client,那麼就有問題了,

1.該如何傳送給我想要傳送的那個client呢?

2.a,b兩個從裝置同時掛在乙個adapt下,如果兩個同時傳送,會怎麼處理呢?

第乙個問題上面也已經提到了,每一種裝置都有乙個裝置位址,通過傳送不同的裝置位址,就可以訪問到想要訪問的從裝置。

第二個問題,就拿一般的i2c裝置來說,讀寫會呼叫i2c_transfer

if (in_atomic() || irqs_disabled())  else
這一段**,使用互斥鎖,保證了乙個程序正在使用該adapt時,另乙個程序就會被進入睡眠,如果在進行原子操作或者中斷是關閉的(不允許排程),那麼直接返回。

最後看一下傳送的具體實現:rk3x_i2c_xfer

1.clk_enable(i2c->clk);clk_enable(i2c->pclk);  //使能時鐘 

2.rk3x_i2c_setup(i2c, msgs + i, num - i); //配置從裝置位址,以及讀還是寫

3.rk3x_i2c_start(i2c); //使能i2c控制器,使能start中斷,i2c的模式,最後傳送start訊號。

4.wait_event_timeout(i2c->wait, !i2c->busy,msecs_to_jiffies(wait_timeout));//等待喚醒。

由於在第3步中使能了start中斷,並且開啟了start訊號,就會進入到中斷服務函式,那麼檢視一下中斷服務函式rk3x_i2c_irq:其實就是乙個很簡單的狀態機

switch (i2c->state)

I2C匯流排架構 之 裝置驅動

i2c裝置驅動是i2c框架中最接近應用層的,其上接應用層,下接i2c核心。也是驅動開發人員需要實現的 在此驅動中我們只需負責以下步驟 以ap3216c為例 a.新增硬體資訊 裝置樹 b.搭建驅動框架 c.構建i2c driver,並註冊到linux d.註冊字元裝置 e.向應用層提供i2c裝置操作介...

i2c匯流排時序

一心想踏入linux device driver的世界,想著i2c匯流排相對於usb等其他匯流排較為簡單,就以i2c作為切入點,希望可以逐步理解ldd的設計思想,並能理解其裝置模型的概念。在此對近期於i2c匯流排及驅動原始碼的理解做備忘,以免徒勞。平台友善之臂s70 tiny6410 cpusams...

I2C匯流排死鎖

原文 現象 最近發現訪問i2c裝置時,主裝置復位可能會引起i2c死鎖,表現為scl為高,sda一直為低,後發現是從裝置拉死i2c匯流排,從裝置斷電之後,sda變高,上電後通訊正常。後來通過拉低scl訊號線,sda就會自動變成高電平,i2c匯流排恢復。原因 在正常情況下,i2c匯流排協議能夠保證匯流排...