pinctrl 子系統(tǒng) API
pinctrl 子系統(tǒng)的 API 有很多,對于驅(qū)動工程師來說,pinctrl 操作一個 GPIO 只需要三步:
1、devm_pinctrl_get
2、pinctrl_lookup_state
3、pinctrl_select_state
在 Linux 中,加 devm_ 開頭的函數(shù),代表這個函數(shù)支持資源管理。一般情況下,我們寫一個驅(qū)動程序,在程序開頭都會申請資源,比如內(nèi)存、中斷號等,萬一后面哪一步申請出錯,我們要回滾到第一步,去釋放已經(jīng)申請的資源,這樣很麻煩。后來 Linux 開發(fā)出了很多 devm_ 開頭的函數(shù),代表這個函數(shù)有支持資源管理的版本,不管哪一步出錯,只要錯誤退出,就會自動釋放所申請的資源。
1)devm_pinctrl_get:用于獲取設(shè)備樹中自己用 pinctrl 建立的節(jié)點的句柄;
2) pinctrl_lookup_state:用于選擇其中一個 pinctrl 的狀態(tài),同一個 pinctrl 可以有很多狀態(tài)。比如 GPIO50 , 一開始初始化的時候是 I2C ,設(shè)備待機時候,我希望切換到普通 GPIO 模式,并且配置為下拉輸入,省電 。這時候如果 pinctrl 節(jié)點有描述,我們就可以在代碼中切換 pin 的功能,從 I2C 功能切換成普通 GPIO 功能;
3) pinctrl_select_stat:用于真正設(shè)置,在上一步獲取到某個狀態(tài)以后,這一步真正設(shè)置為這個狀態(tài)。
對于 pinctrl 子系統(tǒng)的設(shè)備樹配置,是遵守 service 和 client 結(jié)構(gòu) 。
client 端各個平臺基本都是一樣的,server 端每個平臺都不一樣,使用的字符串的配置也不一樣。
設(shè)備樹配置:
//client端,設(shè)置不同狀態(tài)
&test {
pinctrl-names = "default","test_low","test_high";
pinctrl-0 = < &test_default >;
pinctrl-1 = < &test_low >;
pinctrl-2 = < &test_high >;
gpio = < &gpio5 1 GPIO_ACTIVE_LOW >;
status = "okay";
};
//server 即 pin controller 端,設(shè)置 GPIO 幾種功能狀態(tài)
&gpio5 {
test_default:test_default{};
test_low:test_low{
fsl,pins = <
MX6UL_PAD_GPIO5_IO01__GPIO5_IO01 0x17059
>
};
test_high:test_low{
fsl,pins = <
MX6UL_PAD_GPIO5_IO01__GPIO5_IO01 0x1b0b1
>
};
};
pinctrl.c
#include < linux/init.h >
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/platform_device.h >
#include < linux/delay.h >
#include < linux/pinctrl/pinctrl.h >
#include < linux/pinctrl/consumer.h >
static int __init mypinctrl_init(void)
{
int ret = 0;
struct pinctrl *pctrl;
struct platform_device *pdev;
struct pinctrl_state *test_high;
struct pinctrl_state *test_low;
pctrl = devm_pinctrl_get(&pdev- >dev);
if(IS_ERR(pctrl)){
ret = PTR_ERR(pctrl);
printk("devm_pinctrl_get errorn");
return ret;
}
test_high = pinctrl_lookup_state(pctrl,"test_high");
if(IS_ERR(pctrl)){
ret = PTR_ERR(test_high);
printk("pinctrl_lookup_state test_high errorn");
return ret;
}
test_low = pinctrl_lookup_state(pctrl,"test_low");
if(IS_ERR(pctrl)){
ret = PTR_ERR(test_low);
printk("pinctrl_lookup_state test_low errorn");
return ret;
}
pinctrl_select_state(pctrl,test_low);
udelay(200);
pinctrl_select_state(pctrl,test_high);
return 0;
}
static void __exit mypinctrl_exit(void)
{
printk("%sn",__func__);
}
module_init(mypinctrl_init);
module_exit(mypinctrl_exit);
MUDULE_LICENSE("GPL");
Makefile 與上面相同,只是更改一下編譯輸出的名字。
這個驅(qū)動加載上去,可以切換GPIO口的功能狀態(tài),我這里只是控制GPIO輸出高低,具體看你設(shè)備樹怎么配,比如你可以配置某個GPIO一開始是I2C功能,待機時候是普通GPIO功能,達到省電的目的。
-
Linux
+關(guān)注
關(guān)注
87文章
11304瀏覽量
209538 -
API
+關(guān)注
關(guān)注
2文章
1501瀏覽量
62034 -
子系統(tǒng)
+關(guān)注
關(guān)注
0文章
109瀏覽量
12402 -
GPIO
+關(guān)注
關(guān)注
16文章
1204瀏覽量
52106
發(fā)布評論請先 登錄
相關(guān)推薦
評論