1、前言
在嵌入式系統中,許多SoC的內部都包含了pin控制器,通過芯片內部的pin控制器,我們可以配置一個或者一組引腳的狀態和功能特性,Linux內核為了統一各SoC廠商的引腳管理,提供了pinctrl子系統。
2、引腳功能分類
嵌入式芯片手冊往往有一個GPIO控制的章節來描述SoC的引腳如何進行配置,該描述具有大量的寄存器操作,但是通過配置這些寄存器實現的功能基本有三類,如下:
(1)通過設置pin controller硬件的控制單元,可以實現
(1.1)引腳的功能配置,例如設定I/O引腳是普通的GPIO輸入輸出功能,還是具有特殊功能的引腳;
(1.2)引腳特性配置,例如引腳內部的上/下拉電阻和驅動強度的設定。
(2)如果一組pin被配置成SPI,則將會和SPI controller連接,如果配置成了GPIO,則將會和GPIO controller進行連接,通過配置GPIO controller的寄存器,可以實現
(2.1)設置GPIO的方向,例如輸入或者輸出;
(2.2)當GPIO設置為輸出方向時,能夠設定該引腳的電平是高電平還是低電平;
(2.3)當GPIO設置為輸入方向時,能夠讀取該引腳的電平狀態。
(3)如果IO口具有中斷控制功能時,通過訪問IO口的中斷控制寄存器,可以實現
(3.1)設置中斷控制是否使能;
(3.2)設置中斷的觸發方式,例如上升沿/下降沿觸發;
(3.3)通過設置寄存器將中斷狀態清除。
3、通過軟件抽象來掩蓋硬件差異
在Linux的內核的pinctrl系統架構中,使用了3個軟件模塊來對應上述的三類功能,如下:
(1)pinctrl子系統,用於pin controller硬件的驅動軟件子系統;
(2)GPIO subsystem,用於GPIO controller硬件的驅動軟件子系統;
(3)GPIO interrupt chip driver,該模塊作為interrupt subsystem的底層硬件驅動模塊存在。
下圖為pinctrl subsystem的模塊圖:
底層的specific pin controller driver是硬件相關的模塊,與嵌入式SoC相關,pin control core模塊是一個與硬件無關的模塊,它抽象了所有pin controller的硬件特性,它對用戶(other driver)提供了頂層的接口函數,因此,用戶不再需要關注pin controller的硬件底層相關知識。
下圖則是GPIO subsystem的模塊圖:
該軟件框架圖和pinctrl subsystem的軟件框架圖一樣,其軟件抽象的思想是一樣的,內部的具體實現不一樣。
4、pinctrl子系統相關文件
(1)核心源文件
在kernel/drivers/pinctrl目錄下,包含了pinctrl子系統的核心驅動文件:
在最后的源文件pinctrl-xxx.c,舉個例子,例如高通msm提供的pinctrl子系統底層驅動文件有如下文件pinctrl-msm.c、pinctrl-msm.h、pinctrl-msm-tlmm.c。
(2)內核模塊提供的接口文件
Linux內核中很多模塊需要用到pinctrl子系統的服務,因此需要提供pinctrl子系統的外部接口和相關的數據結構,這些頭文件在kernel/include/linux/pinctrl目錄下,列表如下:
(3)與SoC相關的底層pinctrl子系統驅動接口
pinctrl子系統提供給底層驅動實現的頭文件如下:
5、pinctrl子系統與其它內核模塊關系
pinctrl子系統與其它內核模塊的關系圖如下所示:
在上圖可以看到,GPIO子系統的管理歸屬於pinctrl子系統,並且pinctrl子系統與設備驅動模型也有密切的聯系。