上一章我們詳細的講解了 Linux 下的驅動分離與分層,以及總線、設備和驅動這樣的驅動框架。基于總線、設備和驅動這樣的驅動框架, Linux 內核提出來 platform 這個虛擬總線,相應的也有 platform 設備和 platform 驅動。
上一章我們講解了傳統的、未采用設備樹的 platform 設備和驅動編寫方法。最新的 Linux 內核已經支持了設備樹,因此在設備樹下如何編寫 platform驅動就顯得尤為重要,本章我們就來學習一下如何在設備樹下編寫 platform 驅動。
1、設備樹下的 platform 驅動簡介
platform 驅動框架分為總線、設備和驅動,其中總線不需要我們這些驅動程序員去管理,這個是 Linux 內核提供的,我們在編寫驅動的時候只要關注于設備和驅動的具體實現即可。==在沒有設備樹的 Linux 內核下,我們需要分別編寫并注冊 platform_device 和 platform_driver,分別代表設備和驅動。==在使用設備樹的時候,設備的描述被放到了設備樹中,因此 platform_device 就不需要我們去編寫了,我們只需要實現 platform_driver 即可。
1.1、修改 pinctrl-stm32.c 文件
在前面第 25 章的時候我們詳細的講解了 pinctrl,但是在后續的實驗中卻一直沒有使用pinctrl。也就是之前講的pinctrl子系統知識,按道理來講,在我們使用某個引腳的時候需要先配置其電氣屬性,比如復用、輸入還是輸入、默認上下拉等!但是在前面的實驗中均沒有配置引腳的電氣屬性,也就是引腳的 pinctrl配置。這是因為 ST 針對 STM32MP1 提供的 Linux 系統中,其 pinctrl 配置的電氣屬性只能在platform 平臺下被引用,前面的實驗都沒用到 platform,所以 pinctrl 配置是不起作用的!
Linux 系統啟動運行過程中會自動解析設備樹下的 pinctrl 配置,然后初始化引腳的電氣屬性,不需要 platform 驅動框架。所以 pinctrl 什么時候有效,不同的芯片廠商有不同的處理方法,一切以實際所使用的芯片為準!
對于 STM32MP1 來說,在使用 pinctrl 的時候需要修改一下 pinctrl-stm32.c 這個文件,否則當某個引腳用作 GPIO 的時候會提示此引腳無法申請到!
1.2、創建設備的 pinctrl 節點
上面已經說了,在 platform 驅動框架下必須使用 pinctrl 來配置引腳復用功能。我們以本章實驗需要用到的 LED0 為例,編寫 LED0 引腳的 pinctrl 配置。打開 stm32mp15-pinctrl.dtsi 文件, STM32MP1 的所有引腳 pinctrl 配置都是在這個文件里面完成的,在 pinctrl 節點下添加如下所示內容:
1.3、在設備樹中創建設備節點
接下來要在設備樹中創建設備節點來描述設備信息,重點是要設置好 compatible 屬性的值,因為 platform 總線需要通過設備節點的 compatible 屬性值來匹配驅動!這點要切記。
1.4、編寫 platform 驅動的時候要注意兼容屬性
上一章已經詳細的講解過了,在使用設備樹的時候 platform 驅動會通過 of_match_table 來保存兼容性值,也就是表明此驅動兼容哪些設備。所以, of_match_table 將會尤為重要,比如本例程的 platform 驅動中 platform_driver 就可以按照如下所示設置:
最后就是編寫驅動程序,基于設備樹的 platform 驅動和上一章無設備樹的 platform 驅動基本一樣,都是當驅動和設備匹配成功以后先根據設備樹里的 pinctrl 屬性設置 PIN 的電氣特性再去執行 probe 函數。我們需要在 probe 函數里面執行字符設備驅動那一套,當注銷驅動模塊的時候 remove 函數就會執行,都是大同小異的。
2、檢查引腳復用配置
2.1、檢查引腳 pinctrl 配置
正點原子 STM32MP1 開發板上將 PI0 連接到了 LED0 上,也就是將其用作普通的 GPIO,對應的 pinctrl 配置就是示例代碼 35.1.2.1。但是 stm32mp15-pinctrl.dtsi 是 ST 根據自己官方 EVK開發板編寫的,因此 PI0 就可能被 ST 官方用作其他功能,大家在 stm32mp15-pinctrl.dtsi 里面找到如下所示代碼:
從圖 35.2.1.1 可以看出, ST 官方默認將 PI0 復用為 LCD_G5,前面說了,一個 IO 只能復用為一個功能,因此我們需要將圖 35.2.1.1 中的“<STM32_PINMUX(‘I’, 0, AF14)>”屏蔽掉,因為我們現在要將 PI0 用作 GPIO。同樣的,繼續在 stm32mp15-pinctrl.dtsi 文件里面查找,會發現如圖 35.2.1.2 所示的地方也將 PI0 復用為了 LCD_G5:
當然可能會有小伙伴會問,為什么之前實驗不用屏蔽這些復用功能?
因為之前的實驗并未用到pinctrl這個配置,也未用到platform。之前只是初步的講了pinctrl子系統的知識!