1. 程式人生 > 其它 >裝置驅動-【轉載】Pinctrl的配置與使用

裝置驅動-【轉載】Pinctrl的配置與使用

版權宣告:本文為CSDN博主「spongebob1912」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/spongebob1912/article/details/109496964

 

 

簡述

soc內部管腳眾多,而多數管腳又可以配置成不同的功能,我們稱之為管腳複用;Linux引入pinctrl子系統,是為了統一各晶片廠商對這些管腳的管理跟配置。

通過調整pinctrl暫存器,我們可以配置一個或一組管教,配置項包括function、上拉下拉、驅動強度等,下面僅從使用者的角度介紹pinctrl在實踐中的應用。

應用例項

1.管腳定義

以高通平臺為例,在dts資料夾中我們會找到名為pinctrl的dtsi,裡面配置了幾乎所有用到的管腳,個別裡面沒有配置的管腳預設用作gpio,以下面一組管腳為例

  1.   /* interrupt active */
  2.   pmx_ts_int_active {
  3.   ts_int_active: ts_int_active {
  4.   mux {
  5.   pins = "gpio65";
  6.   function = "gpio";
  7.   };
  8.    
  9.   config {
  10.   pins = "gpio65"
    ;
  11.   drive-strength = <8>;
  12.   bias-pull-up;
  13.   };
  14.   };
  15.   };
  16.   /* interrupt suspend */
  17.   pmx_ts_int_suspend {
  18.   ts_int_suspend: ts_int_suspend {
  19.   mux {
  20.   pins = "gpio65";
  21.   function = "gpio";
  22.   };
  23.    
  24.   config {
  25.   pins = "gpio65"
    ;
  26.   drive-strength = <2>;
  27.   bias-pull-down;
  28.   };
  29.   };
  30.   };

裡面定義了一個管腳的兩種狀態,分別是active狀態管腳gpio65,function gpio內建上拉,強度為8;suspend狀態管腳gpio65,function gpio內建下拉,強度為2;

2.pinctrl state定義

為裝置新增自己的管腳定義,這個過程我們稱之為pinctrl state定義;

  1.   pinctrl-names = "cyttsp_ts_active",
  2.   "cyttsp_ts_suspend","cyttsp_ts_release";
  3.   pinctrl-0 = <&ts_int_active &ts_reset_active>;
  4.   pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
  5.   pinctrl-2 = <&ts_release>;

在dts中某個裝置的節點中新增如上引用,三個pinctrl name分別對應下面三個pinctrl-x,每個pinctrl-x我們稱之為一個pinctrl state,後續我們將在程式碼中通過name來找到相應的pinctrl state;

每組pinctrl state可以引用多個管腳定義。

3.pinctrl state切換

在完成管腳定義及pinctrl state定義之後,我們將在程式碼中獲取pinctrl state,並使用他們;

  1.   #define PINCTRL_STATE_ACTIVE "cyttsp_ts_active"
  2.   #define PINCTRL_STATE_SUSPEND "cyttsp_ts_suspend"
  3.   #define PINCTRL_STATE_RELEASE "cyttsp_ts_release"
  4.    
  5.   struct pinctrl *ts_pinctrl;
  6.   struct pinctrl_state *pinctrl_state;
  7.    
  8.   /* get pinctrl handle */
  9.   ts_pinctrl = devm_pinctrl_get(dev);
  10.   if (IS_ERR_OR_NULL(ts_pinctrl)) {
  11.   rc = PTR_ERR(ts_pinctrl);
  12.   dev_err(dev, "%s: Target does not use pinctrl %d\n", __func__, rc);
  13.   return rc;
  14.   }
  15.    
  16.   /* find pinctrl state by name */
  17.   pinctrl_state = pinctrl_lookup_state(ts_pinctrl, PINCTRL_STATE_ACTIVE);
  18.   if (IS_ERR_OR_NULL(pinctrl_state)) {
  19.   rc = PTR_ERR(pinctrl_state);
  20.   dev_err(dev, "%s: Can not lookup cyttsp_ts_active pinstate %d\n", __func__, rc);
  21.   return rc;
  22.   }
  23.    
  24.   /* select the pinctrl state */
  25.   rc = pinctrl_select_state(ts_pinctrl, pinctrl_state);
  26.   if (rc < 0)
  27.   dev_err(dev, "%s: Cannot get active pinctrl state\n", __func__);

1.獲取pinctrl handler,每個裝置都會有自己的pinctrl handler,如果沒有,呼叫介面時將為它建立一個

原始碼參考/kernel/msm-3.18/drivers/pinctrl/core.c create_pinctrl();

2.得到pinctrl handler後,我們通過dts裡配置的pinctrl-name,找到相應的pinctrl state;

示例中找的是cyttsp_ts_active,對應dts裡的state為pinctrl-0,該state包含兩個管腳定義,分別是ts_int_active,ts_reset_active,具體定義到pinctrl dtsi裡面檢視;

3.找到相應的pinctrl state,只需呼叫pinctrl介面切換至該state即可,相應管腳即可切換為pinctrl dtsi中定義的狀態;

示例中將切換至ts_int_active狀態,相應的管腳gpio65將被配置為gpio,內建上拉,強度為8,其他管腳同理。

補充說明

在驅動跟裝置成功匹配後,驅動探測時將獲取該裝置名為default的pinctrl state,並切換至該state,這個過程中就會呼叫devm_pinctrl_get,獲取或建立pinctrl handler;

若相應dts節點沒有定義名為default的pinctrl state,則輸出日誌後返回,執行driver probe;

具體原始碼請參考/kernel/msm-3.18/drivers/base/dd.c really_probe()

 

參考連結:https://blog.csdn.net/u012830148/article/details/80609337?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160448812319724839240545%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160448812319724839240545&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-80609337.pc_first_rank_v2_rank_v28&utm_term=devm_pinctrl_get&spm=1018.2118.3001.4449