【linux】驅動-10-pinctrl子系統
- 2021 年 4 月 12 日
- 筆記
- /label/driver/10, /label/linux, /label/linux/driver, /label/lzm, linux, 嵌入式, 教程集合, 程序框架
前言
參考文檔:
- 內核文檔鏈接://www.kernel.org/doc/Documentation/
- 內核源碼doc:Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
建議配合 GPIO 子系統使用。
建議,複製 原文鏈接觀看,排版清晰,便於學習:
10. pinctrl子系統
pinctrl子系統 用於引腳的配置。如復用為那種引腳,電器特性等等。
gpio子系統 用於引腳的控制。如配置輸出,輸出高低電平等等。
當pinctrl子系統配置引腳為GPIO模式後,才能用gpio子系統控制引腳。
(pinctrl子系統可以把引腳配置為 GPIO模式,I2C模式* 等等*)
10.1 參考路徑
pinctrl子系統內核文檔:Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
pinctrl子系統源碼路徑:drivers/pinctrl
10.2 pinctrl子系統主要工作
pinctrl子系統 主要工作內容(內核實現):
- 獲取設備樹中用戶配置的 PIN 信息。
- 根據獲取到的信息,配置 PIN 的復用功能、電氣特性。
以上工作內容都是內核實現的,用戶不需要自己編寫代碼,只需要配置好設備樹即可。
10.2 pinctrl子系統格式說明
pin controller 子節點格式是由芯片廠商自定義的,即每家芯片pin controller子節點格式都是不一樣的。
各個廠商的 pinctrl 使用說明可以參考廠商提供的文檔或去內核源碼路徑 Documentation/devicetree/bindings/pinctrl 目錄下找到對應廠商的使用說明。
格式規範如:
imx6ull格式:
//client端:
@節點名字 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_自定義名字A>;
status = "okay";
};
//pincontroller服務端
pinctrl_自定義名字A: 自定義名字B {
fsl,pins = <
引腳復用宏定義 PAD(引腳)屬性, // 引腳 A
引腳復用宏定義 PAD(引腳)屬性; // 引腳 B
>;
};
rk3288實例:
//client端
@uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; //它使用三個節點來表示三組引腳。
status = "okay";
};
//pincontroller服務端
gpio4_uart0 {
// 引腳 A
uart0_xfer: uart0-xfer {
rockchip,pins = <UART0BT_SIN>, <UART0BT_SOUT>; //使用rockchip,pins來指定使用哪些引腳,就等效於groups
rockchip,pull = <VALUE_PULL_DISABLE>; //引腳的參數
rockchip,drive = <VALUE_DRV_DEFAULT>; //引腳的參數
};
// 引腳 B
uart0_cts: uart0-cts {
rockchip,pins = <UART0BT_CTSN>;
rockchip,pull = <VALUE_PULL_DISABLE>;
rockchip,drive = <VALUE_DRV_DEFAULT>;
};
// 引腳 C
uart0_rts: uart0-rts {
rockchip,pins = <UART0BT_RTSN>;
rockchip,pull = <VALUE_PULL_DISABLE>;
rockchip,drive = <VALUE_DRV_DEFAULT>;
};
uart0_rts_gpio: uart0-rts-gpio {
rockchip,pins = <FUNC_TO_GPIO(UART0BT_RTSN)>;
rockchip,drive = <VALUE_DRV_DEFAULT>;
};
};
10.3 概念
上面例子中說到 pin controller 和 client device,這兩個節點說明都在文件 pinctrl-bindings.txt 中有說明。
pin controller:
- 服務端。
- 提供引腳的配置信息。
client device:
- 客戶端。
- 聲明需要使用哪個引腳。(使用來自客戶端提供的引腳信息)
- 客戶端其實就是需要使用該引腳的設備樹節點。
/* For a client device requiring named states */
device {
pinctrl-names = "active", "idle"; // 該設備有兩種狀態,分別對應 pinctrl-0 和 pinctrl-1
pinctrl-0 = <&state_0_node_a>; // 第 0 個狀態的名字為 active。對應的引腳在 pinctrl-0 里。
pinctrl-1 = <&state_1_node_a &state_1_node_b>; // 第 1 個狀態的名字為 idle。對應的引腳在 pinctrl-1 里。
};
function:
- 功能。
groups:
- 使用 function 功能的 N 組引腳。
如:
state_0_node_a
{
uart0
{
function = "uart0";
groups = "u0rxtx", "u0rtscts";
};
};
10.4 實例分析
以 IMX6UL 為例子分析。
參考 NXP 提供的關於 pinctrl 文檔或去 Documentation/devicetree/bindings/pinctrl 下找到文檔 fsl,imx6ul-pinctrl.txt 和 fsl,imx-pinctrl.txt。
工具相應文檔編寫 pinctrl 配置信息。
根據文檔得出以下幾點關於 IMX6ULL pinctrl 子系統開發的要求:
- 節點 iomux 匯總所需引腳的配置信息。即是 pinctrl 子系統存儲使用着 iomux 節點信息。
- 要在特定功能上工作的 pin ,應該在該特定功能節點下定義。
- 驅動程序可以使用客戶節點的名稱和服務節點的名稱來描述引腳功能和組層次結構。
- 例如,Linux IMX pinctrl驅動程序以客戶節點的名稱作為函數名,服務節點的名稱作為組名來創建映射表。
- 每個管腳配置節點都應該有一個phandle(即是pinctrl-0),設備可以通過引用該管腳配置節點的phandle 來設置管腳配置。
10.4.1 pin controller服務端
有些SoC 把 PIN 叫 PAD
格式有芯片廠商定義
引腳復用宏 & 引腳屬性值:
引腳復用宏定義 如 MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 在 內核源碼/arch/arm/boot/dts/imx6ul-pinfunc.h 文件中定義,由芯片廠商編寫。
如圖:
-
-
引腳復用宏 由5個參數組成,分別為:
- mux_reg:復用選擇寄存器的偏移地址。
- conf_reg:引腳屬性控制的偏移地址。
- input_reg:輸入選擇寄存器偏移地址。(用於輸入的引腳)
- mux_mode:復用選擇寄存器模式選擇位的值。
- input_val:輸入選擇寄存器的值。
前面三個均為 寄存器地址偏移值,後面兩個為對應要寫入寄存器的值。
對應規則:
- mux_reg <– mux_mode
- conf_reg <– 引腳屬性值 (宏後面的參數)
- 因為引腳屬性配置比較多樣靈活,所以由用戶決定該值,便提出到宏外。
- input_reg <– input_val
10.4.2 client device客戶端
格式規範由設備樹規定
客戶端其實就是需要使用該引腳的設備樹節點。
客戶端必須至少有一個 pinctrl-0 狀態。