設備樹中pinctrl的簡單使用

pinctrl介紹文檔:

內核目錄\Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt

 

首先介紹幾個概念:
Bank: 以引腳名爲依據, 這些引腳分爲若干組, 每組稱爲一個Bank
比如s3c2440裏有GPA、GPB、GPC等Bank。
每個Bank中有若干個引腳, 比如GPA0,GPA1, ..., GPC0, GPC1,...等引腳


Group: 以功能爲依據, 具有相同功能的引腳稱爲一個Group
比如s3c2440中串口0的TxD、RxD引腳使用 GPH2,GPH3, 那這2個引腳可以列爲一組
比如s3c2440中串口0的流量控制引腳使用 GPH0,GPH1, 那這2個引腳也可以列爲一組

State: 設備的某種狀態, 比如內核自己定義的"default","init","idel","sleep"狀態;
也可以是其他自己定義的狀態, 比如串口的"flow_ctrl"狀態(使用流量控制)
每種狀態會對應一組或多組group。
可以通過函數設置設備狀態。

 

a. 設備樹中pinctrl節點:
a.1 它定義了各種 pin bank, 比如s3c2440有GPA,GPB,GPC,...,GPB各種BANK, 每個BANK中有若干引腳:

	pinctrl_0: pinctrl@56000000 {
		reg = <0x56000000 0x1000>;

		gpa: gpa {
			gpio-controller; //表示是一個bank
			#gpio-cells = <2>;  /* 使用gpa bank中的引腳時, 需要2個u32來指定引腳 */
		};

		gpb: gpb {
			gpio-controller;
			#gpio-cells = <2>;
		};

		gpc: gpc {
			gpio-controller;
			#gpio-cells = <2>;
		};

		gpd: gpd {
			gpio-controller;
			#gpio-cells = <2>;
		};
	};

a.2 它還定義了各種group(組合), 某種功能所涉及的引腳稱爲group,

pin groups是pinctrl下面的子節點

比如串口0要用到2個引腳: gph0, gph1:

	uart0_data: uart0-data {
/* 在GPHCON寄存器中gph0,gph1可以設置以下值:
   0 --- 輸入功能
   1 --- 輸出功能
   2 --- 串口功能
我們要使用串口功能,samsung,pin-function 設置爲2
*/
		samsung,pins = "gph-0", "gph-1"; //用哪些引腳實現這個功能
		samsung,pin-function = <2>;//使用這個功能需要將寄存器設置成什麼值   
  	};

	uart0_sleep: uart0_sleep {
/* 在GPHCON寄存器中gph0,gph1可以設置以下值:
   0 --- 輸入功能
   1 --- 輸出功能
   2 --- 串口功能
我們要使用輸入功能,samsung,pin-function 設置爲0
*/     
		samsung,pins = "gph-0", "gph-1";
		samsung,pin-function = <0>;   
	};
 

samsung-pinctrl.txt中也定義了一下幾種屬性的用法:

- samsung,pin-val: Initial value of pin output buffer.

- samsung,pin-pud: Pull up/down configuration.

- samsung,pin-drv: Drive strength configuration.

- samsung,pin-pud-pdn: Pull up/down configuration in power down mode.

- samsung,pin-drv-pdn: Drive strength configuration in power down mode.

b. 設備節點中要使用某一個 pin group:

	serial@50000000 {
	    ......
		pinctrl-names = "default", "sleep";  /* 既是名字, 也稱爲state(狀態) */
		pinctrl-0 = <&uart0_data>;
		pinctrl-1 = <&uart0_sleep>;
	};
	
	pinctrl-names中定義了2種state: default 和 sleep,
	default 對應的引腳是: pinctrl-0, 它指定了使用哪些pin group: uart0_data
	sleep   對應的引腳是: pinctrl-1, 它指定了使用哪些pin group: uart0_sleep

c. platform_device, platform_driver匹配時對pinctrl的處理:

platform_device和platform_driver的匹配完成後,最終都會調用到 really_probe()函數 (drivers/base/dd.c)

really_probe:
	/* If using pinctrl, bind pins now before probing */
	ret = pinctrl_bind_pins(dev);
				dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
								PINCTRL_STATE_DEFAULT);  /* 獲得"default"狀態的pinctrl */
				dev->pins->init_state = pinctrl_lookup_state(dev->pins->p,
								PINCTRL_STATE_INIT);    /* 獲得"init"狀態的pinctrl */

				ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);    /* 優先設置"init"狀態的引腳 */
				ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state); /* 如果沒有init狀態, 則設置"default"狀態的引腳 */
								
	......
	ret = drv->probe(dev);

如果設備節點中指定了pinctrl, 在對應的probe函數被調用之前, 先"bind pins", 即先綁定、設置引腳狀態。

 

d. 在驅動程序中設置引腳狀態:

   devm_pinctrl_get_select_default(struct device *dev); // 將引腳設置爲"default"狀態
   
   // 根據name將引腳設置爲某種狀態 比如default,sleep
   pinctrl_get_select(struct device *dev, const char *name); 
   
   pinctrl_put(struct pinctrl *p);   // 不再使用, 退出時調用

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