利用linux中iic子系統做IIC驅動

2021-06-02 23:12:55 字數 3363 閱讀 4178

利用linux中iic裝置子系統移植iic裝置驅動

背景描述

iic匯流排在嵌入式系統中應用十分廣泛,常見的有eeprom,rtc。一般的處理器會包含iic的控制器,用來完成iic時序的控制;另外一方面,由於iic的時序簡單,使用gpio口來模擬時序也是常見的做法。面對不同的iic控制器,各種各樣的晶元以及linux原始碼,如何更快做好iic裝置驅動。

問題描述

在我們的方案中,我們會用到eeprom,rtc以及tw2865。由於hi3520的iic控制器設計有問題,無法正常使用。而iic控制器的sda和scl管腳正好是和兩個gpio管腳復用的。hisi將控制gpio來實現iic的時序,從而對iic裝置進行操作。這種設計方式簡單明瞭,但使用iic子系統,可以更方便的移植和維護其他的裝置驅動。

問題分析

hisi對於gpio口,rtc晶元以及tw2865的處理方式如下:將gpio口做成乙個模組化的驅動,該驅動模擬iic時序,並向外提供一些函式介面,比如:export_symbol(gpio_i2c_read_tw2815);等。對於具體的rtc晶元,將其註冊為乙個misc裝置,並利用gpio模組匯出的函式進行rtc晶元的配置操作。

其實對於linux-2.6.24\drivers\i2c目錄下**,我們可以加以利用。

linux的iic字結構分為三個組成部分:

iic核心

iic核心提供了iic匯流排驅動和裝置驅動的註冊、登出方法,iicalgorithm上層的、與具體介面卡無關的**以及探測裝置、檢測裝置位址的上層**。

iic匯流排驅動

iic匯流排驅動是對iic硬體體系結構中介面卡端的實現。

iic裝置驅動

iic裝置驅動是對iic硬體體系總裝置端的實現。

我們檢視下該目錄下的makefile和kconfig:

obj-$(config_i2c_boardinfo) +=i2c-boardinfo.o

obj-$(config_i2c) += i2c-core.o

obj-$(config_i2c_chardev) +=i2c-dev.o

obj-y +=busses/ chips/ algos/

i2c-core.c就是iic核心,buses中的檔案是主流處理器中iic匯流排的匯流排驅動,而chips中的檔案就是常用晶元的驅動,algos中的檔案實現了一些匯流排介面卡的algorithm,其中就包括我們要用到的i2c-algo-bit.c檔案。

我們首先利用i2c-gpio.c和i2c-algo-bit.c做好匯流排驅動。

在i2c-gpio.c中,module_initi2c_gpio_initplatform_driver_probe(&i2c_gpio_driver,i2c_gpio_probe);

將其註冊為platform虛擬匯流排的驅動。

在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,

定義了如下三個結構體:

structi2c_gpio_platform_data *pdata;//平台相關的gpio的設定

structi2c_algo_bit_data *bit_data;//包含algorithm的具體函式,setor get sda和scl

structi2c_adapter *adap;//介面卡

i2c_gpio_probe主要做了下面幾件事:

填充bit_data結構的各個函式指標,關聯到具體的操作sda和scl函式。

填充adap結構,adap->algo_data= bit_data;

pdata= pdev->dev.platform_data;

bit_data->data= pdata;

pdev->dev->driver_data= adap;

在i2c-core中註冊介面卡型別。

inti2c_bit_add_numbered_bus(struct i2c_adapter *adap)

在staticint i2c_bit_prepare_bus(struct i2c_adapter *adap)中

adap->algo= &i2c_bit_algo;

將i2c_bit_algo與adap關聯上。

static const structi2c_algorithm i2c_bit_algo = ;

其中,master_xfer函式指標就是iic傳輸函式指標。

i2c-algo-bit.c還實現了iic開始條件,結束條件的模擬,傳送位元組,接收位元組以及應答位的處理。

i2c-gpio.c中的i2c_gpio_setsda_val等函式是與具體平台gpio相關的。

修改對應arch-hi3520v100目錄下的gpio.h中的各個函式,這些函式是通過操作暫存器來控制gpio的方向和值。

在對應mach-hi3520v100中的platform-devices.c中新增如下:

static structi2c_gpio_platform_data pdata = ;

static struct platform_devicehisilicon_i2c_gpio_device = ;

static struct platform_device*hisilicon_plat_devs __initdata = ;

int __inithisilicon_register_platform_devices(void)

通過platform新增devices和driver,使得pdev->dev.platform_data=pdata

綜合上面的過程,我們完成了adapter的註冊,並將用gpio口模擬的algorithm與adapter完成了關聯。

這樣,在rtc-x1205.c中,x1205_attach函式利用i2c核心完成client和adap的關聯。

在x1205_probe函式中填充i2c_client結構體,並呼叫i2c_attach_client通知iic核心。

接著註冊rtc驅動。

最後我們要讀取時間,就需要構造i2c_msg結構體,如下所示:

struct i2c_msg msgs = , /* setup read ptr */

, /* read date */ };

/* read date registers */

if((i2c_transfer(client->adapter, &msgs[0], 2)) != 2)

dt_addr是暫存器的位址,i2c_m_rd表示iicread。

經驗總結

iic匯流排雖然並不複雜,但linux下的iic子系統卻有相當的複雜度。做了很多的抽象工作,**變得得難理解,但為後續移植驅動工作提供了很多便利條件。在除錯gpio的adap時,最關鍵的是對於busdevice driver裝置模型的理解。對sysfs和proc檔案系統很熟悉的話,在除錯驅動和後期維護方面大有益處。

Linux輸入子系統

1.1.input子系統概述 輸入裝置 如按鍵,鍵盤,觸控螢幕,滑鼠等 是典型的字元裝置,其一般的工作機制是低層在按鍵,觸控等動作發生時產生乙個中斷 或驅動通過timer定時查詢 然後cpu通過spi,i2c或者外部儲存器匯流排讀取鍵值,座標等資料,放乙個緩衝區,字元裝置驅動管理該緩衝區,而驅動的r...

Linux輸入子系統

linux系統提供了input子系統,按鍵 觸控螢幕 鍵盤 滑鼠等輸入都可以利用input介面函式來實現裝置驅動,最重要的資料結構是struct input dev 在linux 核心中,input裝置用input dev 結構 體描述,使用input子系統實現輸入裝置驅動的時候,驅動的核心工作是向...

Linux輸入子系統

位址 linux輸入子系統 按鍵與觸控螢幕的裝置驅動,在linux系統中實現這類裝置驅動的方法是利用input子系統。linux系統提供了input子系統,按鍵 觸控螢幕 鍵盤 滑鼠等輸入都可以利用input介面函式來實現裝置驅動,按鍵和觸控螢幕裝置驅動都可以作為input裝置驅動而實現。在linu...