gpio子系統與pinctrl子系統通用API

lethe1203發表於2024-03-23
此篇不涉及gpio子系統和pinctrl原理解釋,只列舉相關操作函式:

通用的GPIO操作:

1. gpio_request(unsigned gpio, const char *label):向核心申請指定gpio,所申請的IO口會被核心記錄
引數:gpio:申請IO口編號 ,label:申請者的名字,隨便。
返回:int值,成功:0;失敗:負數
注:在使用gpio口之前,應先用gpio_request()申請gpio口。
若申請成功,則說明該gpio口未被使用。
若申請失敗,則說明該gpio口不存在或未被釋放。
2. gpio_set_value(unsigned gpio, int value):設定gpio口的值
引數:gpio:要設定的IO口編號 ,value:要設定的值(0或1)
返回:無
3. gpio_get_value(unsigned gpio):獲取gpio口的值
引數:gpio:要獲取的IO口編號
返回:int值,IO口狀態
4. gpio_direction_input(unsigned gpio):設定gpio為輸入功能
引數:gpio:要設定的IO口編號
返回:int值
5. gpio_direction_output(unsigned gpio, int value):設定gpio為輸出功能,同時設定gpio輸出的值
引數:gpio:要設定的IO口編號 ,value:要設定的值(0或1)
返回:int值
注:一般來說,設定一個GPIO口為輸出,先執行一次gpio_direction_output,然後接下來只需執行gpio_set_value就行了。
6. gpio_free(unsigned gpio):釋放gpio口,釋放的IO口會在核心記錄消除
注:在使用完gpio口之後,應及時釋放gpio口。釋放的io,可以再次被申請。
與gpio子系統相關的of函式:
7、of_gpio_named_count 函式
of_gpio_named_count 函式用於獲取裝置樹某個屬性裡面定義了幾個 GPIO 資訊,要注意的是空的 GPIO 資訊也會被統計到,比如:
gpios = <0
     &gpio1 1 2
     0
     &gpio2 3 4>;
上述程式碼的“gpios”節點一共定義了 4 個 GPIO,但是有 2 個是空的,沒有實際的含義。透過 of_gpio_named_count 函式統計出來的 GPIO 數量就是 4 個
int of_gpio_named_count(struct device_node *np, const char *propname)

// 引數說明
np:裝置節點。
propname:要統計的 GPIO 屬性。
返回值:正值,統計到的 GPIO 數量;負值,失敗。
8、of_gpio_count 函式
和 of_gpio_named_count 函式一樣,但是不同的地方在於,此函式統計的是“gpios”這個屬性的 GPIO 數量,而 of_gpio_named_count 函式可以統計任意屬性的 GPIO 資訊,函式原型如下所示:
int of_gpio_count(struct device_node *np)

// 引數說明
np:裝置節點。
返回值:正值,統計到的 GPIO 數量;負值,失敗。

9、of_get_named_gpio 函式
此函式獲取 GPIO 編號,因為 Linux 核心中關於 GPIO 的 API 函式都要使用 GPIO 編號,此函式會將裝置樹中類似<&gpio5 7 GPIO_ACTIVE_LOW>的屬性資訊轉換為對應的 GPIO 編號,此函式在驅動中使用很頻繁!函式原型如下:
int of_get_named_gpio(struct device_node  *np,
                 const char *propname, int index)

// 引數說明
np:裝置節點。
propname:包含要獲取 GPIO 資訊的屬性名。
index:GPIO 索引,因為一個屬性裡面可能包含多個 GPIO,此引數指定要獲取哪個 GPIO的編號,如果只有一個 GPIO 資訊的話此引數為 0。
返回值:正值,獲取到的 GPIO 編號;負值,失敗。

通用PINCTRL操作:

重要結構體:
struct pinctrl {
    struct device *dev;                    // 指向擁有該 pinctrl 結構體的裝置的裝置結構體指標。
    const char *name;                      // pinctrl 的名稱,用於標識該 pinctrl 結構體所管理的裝置引腳配置
    struct module *owner;                  // 指向擁有該 pinctrl 結構體的模組的模組結構體指標
    struct list_head pin_ctrls;            // 用於儲存與該 pinctrl 相關的 pin control 結構體的連結串列頭
    const struct pinctrl_ops *ops;         // 指向 pinctrl 操作函式的指標,包含了對該 pinctrl 結構體進行操作的函式指標
};

struct pinctrl_state {
    struct list_head node;                // 用於將 struct pinctrl_state 結構體連結到狀態列表中的節點
    const char *name;                     // 狀態的名稱,用於標識不同的狀態
    unsigned long *pins;                  // 一個無符號長整型陣列,儲存了裝置需要配置的引腳號
    unsigned int num_pins;                // 表示 pins 陣列中引腳的數量
    struct pinctrl *p;                    // 指向該狀態所屬的 pinctrl 控制代碼的指標。
};
相關函式:
1、struct pinctrl *devm_pinctrl_get(struct device *dev):從裝置樹中獲取指定裝置的 pinctrl 控制代碼
引數:dev 是裝置結構體指標,代表需要獲取 pinctrl 控制代碼的裝置。
返回值:如果成功,返回一個指向 struct pinctrl 結構體的指標;如果失敗,返回一個錯誤指標或錯誤碼。
2、struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *state_name):查詢給定 pinctrl 控制代碼中的特定狀態
引數:p 是 pinctrl 控制代碼,state_name 是需要查詢的狀態名稱。
返回值:如果找到對應狀態,返回一個指向 struct pinctrl_state 結構體的指標;否則返回 NULL
3、int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);:選擇並啟用指定的狀態,以配置裝置的引腳
引數:p是要配置的裝置的 pinctrl 控制代碼,s是要應用到裝置引腳的狀態
返回 0 表示成功,負值表示出現錯誤。
4、void pinctrl_put(struct pinctrl *p);用於釋放 pinctrl 控制代碼的函式
引數:p表示要釋放的 pinctrl 控制代碼,釋放後該控制代碼將不再可用
無返回值
5、struct pinctrl *pinctrl_get(struct device *dev);獲取指定裝置的 pinctrl 結構體的函式
引數:dev是指向要獲取 pinctrl 結構體的裝置結構體指標
成功獲取到指定裝置的 pinctrl 結構體,則返回該 pinctrl 結構體的指標;獲取失敗或者該裝置沒有配置 pinctrl,則返回 NULL
pinctrl_get和pinctrl_put結合使用,效果等於devm_pinctrl_get
devm開頭表示裝置管理(device management)的函式,使用devm_字首表示它是一種裝置管理資源,並且會與裝置的生命週期進行關聯。所以devm_pinctrl_get獲取到的pinctrl控制代碼不用釋放

相關文章