歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

Linux I2C核心、總線與設備驅動

I2C總線僅僅使用SCL、SDA兩根信號線就實現了設備之間的數據交互,極大地簡化對硬件資源和PCB板布線空間的占用。因此,I2C總線被非常廣泛地應用在EEPROM、實時鐘、小型LCD等設備與CPU的接口中。

Linux定義了系統的I2C驅動體系結構,在Linux系統中,I2C驅動由3部分組成,即I2C核心、I2C總線驅動和I2C設備驅動。這3部分相互協作,形成了非常通用、可適應性很強的I2C框架。

本章第1節將對Linux I2C體系結構進行分析,講明3個組成部分各自的功能及相互聯系。

第2節將對Linux I2C核心進行分析,解釋i2c-core.c文件的功能和主要函數的實現。

第3、4節將分別詳細介紹I2C總線驅動和I2C設備驅動的編寫方法,給出可供參考的設計模板。

第5、6節將以第3、4節給出的設計模板為基礎,講解S3C2410 ARM處理器I2C總線驅動及掛接在上的SAA7113H視頻模擬/數字轉換芯片設備驅動的編寫方法。

15.1 Linux I2C體系結構

Linux的I2C體系結構分為3個組成部分:

? I2C核心

I2C核心提供了I2C總線驅動和設備驅動的注冊、注銷方法,I2C通信方法(即“algorithm”,筆者認為直譯為“運算方法”並不合適,為免引起誤解,下文將直接使用“algorithm”)上層的、與具體適配器無關的代碼以及探測設備、檢測設備地址的上層代碼等。

? I2C總線驅動

I2C總線驅動是對I2C硬件體系結構中適配器端的實現,適配器可由CPU控制,甚至直接集成在CPU內部。

I2C總線驅動主要包含了I2C適配器數據結構i2c_adapter、I2C適配器的algorithm數據結構i2c_algorithm和控制I2C適配器產生通信信號的函數。

經由I2C總線驅動的代碼,我們可以控制I2C適配器以主控方式產生開始位、停止位、讀寫周期,以及以從設備方式被讀寫、產生ACK等。

? I2C設備驅動

I2C設備驅動是對I2C硬件體系結構中設備端的實現,設備一般掛接在受CPU控制的I2C適配器上,通過I2C適配器與CPU交換數據。

I2C設備驅動主要包含了數據結構i2c_driver和i2c_client,我們需要根據具體設備實現其中的成員函數。

 

圖15.1 Linux I2C體系結構

在Linux 2.6內核中,所有的I2C設備都被在sysfs文件系統中顯示,存在於/sys/bus/i2c/目錄,以適配器地址和芯片地址的形式列出,如:

$ tree /sys/bus/i2c/

/sys/bus/i2c/

|-- devices

| |-- 0-0048 -> ../../../devices/legacy/i2c-0/0-0048

| |-- 0-0049 -> ../../../devices/legacy/i2c-0/0-0049

| |-- 0-004a -> ../../../devices/legacy/i2c-0/0-004a

| |-- 0-004b -> ../../../devices/legacy/i2c-0/0-004b

| |-- 0-004c -> ../../../devices/legacy/i2c-0/0-004c

| |-- 0-004d -> ../../../devices/legacy/i2c-0/0-004d

| |-- 0-004e -> ../../../devices/legacy/i2c-0/0-004e

| `-- 0-004f -> ../../../devices/legacy/i2c-0/0-004f

`-- drivers

|-- i2c_adapter

`-- lm75

|-- 0-0048 -> ../../../../devices/legacy/i2c-0/0-0048

|-- 0-0049 -> ../../../../devices/legacy/i2c-0/0-0049

|-- 0-004a -> ../../../../devices/legacy/i2c-0/0-004a

|-- 0-004b -> ../../../../devices/legacy/i2c-0/0-004b

|-- 0-004c -> ../../../../devices/legacy/i2c-0/0-004c

|-- 0-004d -> ../../../../devices/legacy/i2c-0/0-004d

|-- 0-004e -> ../../../../devices/legacy/i2c-0/0-004e

`-- 0-004f -> ../../../../devices/legacy/i2c-0/0-004f

在Linux內核源代碼中的drivers目錄下包含一個i2c目錄,而在i2c目錄下又包含如下文件和文件夾:

? i2c-core.c

這個文件實現了I2C核心的功能以及/proc/bus/i2c*接口。

? i2c-dev.c

實現了I2C適配器設備文件的功能,每一個I2C適配器都被分配一個設備。通過適配器訪問設備時的主設備號都為89,次設備號為0~255。應用程序通過“i2c-%d” (i2c-0, i2c-1, ..., i2c-10, ...)文件名並使用文件操作接口open()、write()、read()、ioctl()和close()等來訪問這個設備。

i2c-dev.c並沒有針對特定的設備而設計,只是提供了通用的read()、write()和ioctl()等接口,應用層可以借用這些接口訪問掛接在適配器上的I2C設備的存儲空間或寄存器並控制I2C設備的工作方式。

? chips文件夾

這個目錄中包含了一些特定的I2C設備驅動,如Dallas公司的DS1337實時鐘芯片、EPSON公司的RTC8564實時鐘芯片和I2C接口的EEPROM驅動等。

? busses文件夾

這個文件中包含了一些I2C總線的驅動,如S3C2410的I2C控制器驅動為i2c-s3c2410.c。

? algos文件夾

實現了一些I2C總線適配器的algorithm。

此外,內核中的i2c.h這個頭文件對i2c_driver、i2c_client、i2c_adapter和i2c_algorithm這4個數據結構進行了定義。理解這4個結構體的作用十分關鍵,代碼清單15.1、15.2、15.3、15.4分別給出了它們的定義。

代碼清單15.1 i2c_adapter結構體

1 struct i2c_adapter {

2 struct module *owner;/*所屬模塊*/

3 unsigned int id; /*algorithm的類型,定義於i2c-id.h,以I2C_ALGO_開始*/

4 unsigned int class;

5 struct i2c_algorithm *algo;/*總線通信方法結構體指針 */

6 void *algo_data; /* algorithm數據 */

7 int (*client_register)(struct i2c_client *); /*client注冊時調用*/

8 int (*client_unregister)(struct i2c_client *); /*client注銷時調用*/

9 struct semaphore bus_lock; /*控制並發訪問的自旋鎖*/

10 struct semaphore clist_lock;

11 int timeout;

12 int retries; /*重試次數*/

13 struct device dev; /* 適配器設備 */

14 struct class_device class_dev; /* 類設備 */

15 int nr;

16 struct list_head clients; /* client鏈表頭*/

17 struct list_head list;

Copyright © Linux教程網 All Rights Reserved