Linux pinctrl子系統分析之二 從數據結構關聯理解pinctrl子系統

 

     上一章我們對pinctrl子系統進行概述,說明了pinctrl子系統相關的概念、軟件框架等內容,本章我們主要從pinctrl子系統數據結構間的關聯,從而理解pinctrl子系統的設計。

 

 

 

pinctrl數據結構說明

      在上一章我們畫出了pinctrl子系統的軟件架構(如下圖所示),而在linux內核的各子系統設計過程中,軟件框架基本上就是由數據結構間關聯以及對外接口實現子系統的設計,因此理解了一個子系統數據結構間的關聯,基本上就掌握了一個子系統大致實現流程。在linux 內核中,當學習一個新的子系統中,先熟悉其數據結構,基本上可以做到事半功倍。

 

      我們首先理清數據結構間的關聯。如下圖,通過pinctrl子系統的數據結構、處理接口構建的pinctrl子系統框架。下面我們分類說明。

 

Soc pin 描述

       針對一款soc芯片,我們通過其數據手冊,可以知道其提供的引腳個數、每一個引腳複用情況、每一個引腳的配置信息、每一個function包含的引腳使用組合(如iic0可以支持{pin8、pin9}、{pin20、pin21}兩種group類型供選擇,而基於該款soc設計的開發板,則需要針對iic0選擇一組作爲iic0的引腳。如開發板1基於該soc選擇{pin8、pin9}作爲iic0的引腳,而開發板2基於該soc選擇{pin20、pin21}作爲iic0的引腳)等信息。而針對soc芯片而言,其無需關注具體基於該soc的開發板的引腳複用,其只需要列出該soc芯片針對引腳配置的所有信息即可。

   在pinctrl子系統中,soc pin controller的描述通過數據結構struct pinctrl_dev描述,其包含如下信息:

  1. 存儲該soc支持的所有引腳的描述,此處使用基數樹pin_desc_tree存儲所有struct pin_desc類型的變量,而struct pin_desc主要描述一個pin引腳,包括該引腳當前配置的引腳複用情況、引腳名稱、引腳複用設置的次數,以及該引腳所屬的pinctrl device;
  2. 存儲該soc支持的所有group的描述(該項內容在4.4以後的內核版本中添加的,在之前的版本中,group與function的描述由各soc pin controller自行描述,struct pinctrl_dev中沒有描述,pinctrl子系統只要求各soc pin controller driver提供group、function的訪問方法即可,其不進行function與group的存儲情況,而在4.4內核以後,pinctrl子系統提供了function與gropu的存儲,均是通過基數樹進行存儲,並定義struct group_desc 、struct function_desc描述group、function ),新的內核版本將group、function也納入pinctrl子系統的管理確實是一個大的提升,因爲pinctrl子系統沒有提供group、function存儲時,各soc pin controller driver定義的group、function數據結構基本上是類似的,因此這些數據結構由pinctrl子系統接管是最好的。
  3. 存儲該soc支持的所有function的描述;
  4. 提供引腳複用相關的操作接口(struct pinmux_ops定義的操作接口);
  5. 提供引腳配置相關的操作接口(struct pinconf_ops定義的操作接口)

 

       以上幾點就完整的描述了soc pin controller相關的信息,包含哪些引腳、包含哪些可能的組合、包含哪些可能功能、引腳配置相關的操作接口、引腳複用相關的操作接口等信息。關於pinctrl dev及引腳配置、引腳複用相關的驅動均是由soc 廠家提供。soc廠家提供了進行引腳分配及複用的接口,而具體怎麼用,則由使用該soc的廠商決定。

 

board pin 描述

      上面講的pinctrl_dev對應的是soc pin controller,而此處介紹的board pin描述,則是針對使用soc芯片的board,其所對應的具體的引腳使用,這部分引腳使用由具體的開發板廠家分配,也就是我們大部分驅動工程師的工作。下面即介紹board pin描述相關的信息。

    在pinctrl 子系統中,使用數據結構struct pinctrl_maps描述一個board的引腳使用情況,包含引腳的複用以及引腳配置信息等。具體包含如下信息:

  1. 每一個struct pinctrl_map表示一個function在某一個狀態下對應的引腳複用及引腳配置信息,包含:
    1. function名稱、狀態名稱(default、sleep、idle等);
    2. 所屬pinctrl dev的名稱、dev名稱(即該pinctrl_map所依附的設備名稱,如iic1等)
    3. map類型(引腳複用、引腳配置、group配置等)。
    4. 針對引腳複用,則包含function名稱、group名稱,通過pinctrl dev名稱、function名稱、group名稱即可查找具體的pins信息。
    5. 針對pin/group配置,則包含group或pin名稱,引腳配置信息等內容。

 

       針對板級引腳描述而言,主要描述該board所需要設置的所有function對應的引腳複用、引腳配置信息。針對board pin描述而言,基本上就是我們大部分驅動工程師的工作。但針對現有的pinctrl子系統而言,我們也就只需要在dts中配置一下引腳複用及配置情況即可。若內核不支持設備樹,則需要在板級文件中定義引腳複用情況,並調用pinctrl_register_maps將其註冊到pinctrl子系統即可。

 

       以上soc pin以及board pin以及完成了soc pin controller、board pin config and pin mux的描述,那board pin config and pin mux是如何完成針對具體device的配置的呢?這就涉及dev與pinctrl之間的關聯了。pinctrl子系統在設計時,爲了讓具體外設設備驅動開發者對pin ctrl子系統無感知,在struct device中實現了該device與具體引腳配置function的關聯,並在設備驅動模型子系統的device_driver probe之前,完成引腳的配置(主要通過pinctrl_bind_pins函數實現)。下一個小節則介紹dev與pinctrl的關聯。

 

Dev與pinctrl關聯描述

      如下圖所示,struct device總增加了struct dev_pin_info類型的數據結構,實現了dev與pinctrl子系統進行的關聯。

struct dev_pin_info包含如下信息:

  1. 該device pin支持的狀態,包括idle_state狀態下的引腳配置參數、init state下的引腳配置參數、default_state狀態下的引腳配置參數(大多數設備一般只需要定義一個default state即可。只有少數的設備,其正常工作狀態下與sleep狀態下,引腳複用不同,如在sleep狀態下可以釋放該引腳,由別的設備使用,一般的話只需要設置default_state即可);
  2. struct pinctrl表示一個設備針對引腳控制的holder,其包括
    1. 該device所支持的引腳控制狀態(如支持default、sleep狀態的引腳控制策略);
    2. 每一個狀態通過struct pinctrl_state描述,一個pinctrl state中包含該state下需要進行的設置策略(可有多個設置策略,每一個設置策略對應一個struct pinctrl_setting類型的變量,設置策略包含引腳複用的設置策略、引腳的配置策略、group的配置策略,針對一個device的一個state,可以包含多個引腳複用、引腳配置的策略),而struct pinctrl_setting類型主要根據function、group名稱

 

 

 

 

 

         通過上面的soc pin controller 描述、board pin 描述、dev與pinctrl關聯描述,即可完成引腳複用的配置以及引腳的配置。通過soc pin controller描述,說明一個soc pin controller支持的所有引腳、group、function等描述;通過board pin描述,說明一個board對引腳功能、引腳配置、引腳複用的使用情況;最後藉助dev與pinctrl子系統的關聯,將board pin描述與soc pin controller描述關聯,並完成引腳的具體配置操作。以上就是本篇文章的主要內容。我們通過數據結構之間的關聯,說明pinctrl子系統的設計框架。下一章介紹具體的數據結構定義。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章