1. 程式人生 > >linux裝置樹裡的gpio應用

linux裝置樹裡的gpio應用

參考核心原始碼裡的Documentation/devicetree/bindings/gpio/gpio.txt
在裝置樹裡的節點裝置需要使用到gpio口,則需要在一個或多個節點屬性裡提供gpio口的資訊.

關於gpio口資訊的節點屬性命名方式是: name-gpios , 其中name用於指此gpio口在裝置裡的具體用途.
如用於復位的io口,則屬性可以命名為: reset-gpios

出於相容舊版本裝置樹的原因,屬性名裡也可以不寫name而直接使用gpios作為屬性名.這種方式核心以後不再允許使用.

關於gpio口的節點屬性名還可以命名: name-gpio, 但這種方式核心也不會再使用.

關於gpio口的屬性值.
一個屬性值可以寫單個的gpio口資訊, 也可以寫多個的gpio口資訊

單個gpio口資訊的屬性值: <&gpio控制器節點名 具體gpio口的識別符號>
一個具有多個gpio口資訊的屬性值: <&gpio控制器節點名 具體gpio口的識別符號>,<&gpio控制器節點名 具體gpio口的識別符號> …;
具體gpio口的識別符號是由多個數字組成, 數字的個數由所用的gpio控制器節點裡的#gpio-cells屬性值指定.
如:

sunxi-h3-h5.dtsi裡關於gpio控制器的節點資訊:
        pio: 
[email protected]
{ /*也可以通過此基地址在晶片手冊裡確認具體是哪個控制器 */ ... gpio-controller; /* 標明此節點是gpio控制器 */ #gpio-cells = <3>; /* 標明每個gpio口的識別符號由3個數字來識別(第0個數字表示gpio的組, 第1個數字表示組內的gpio口序號, 第3個數字表示gpio口的有效狀態) */ /* 有些方案只用兩個數字 */ ... }; ---------- gpio口的有效狀態在核心標頭檔案include/dt-bindings/gpio/gpio.h裡定義: /* Bit 0
express polarity */ #define GPIO_ACTIVE_HIGH 0 #define GPIO_ACTIVE_LOW 1 /* Bit 1 express single-endedness */ #define GPIO_PUSH_PULL 0 #define GPIO_SINGLE_ENDED 2 #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_ACTIVE_LOW) #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_ACTIVE_HIGH) ---------- 則表示一個PA17口上接的led燈時,則可以如下指定: myleds { compatible = "myleds"; led0 { label = "led0"; led0-gpios = <&pio 0 17 GPIO_ACTIVE_HIGH> /* 0表示PA組的io口, 因h5裡第0組的io口就是以PA開始命名的 */ }; };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
如裝置使用多個gpio口,也可以寫在一個屬性值裡.
    myleds {
        ...

        leds-gpios = <&pio 0  18  GPIO_ACTIVE_HIGH>, <&pio 0  19  GPIO_ACTIVE_HIGH>;
        ...
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在以前沒用裝置樹的核心裡使用u32型別的一個數值表示一個gpio口, 具體的數值由晶片廠商負責定義好.
呼叫gpio口時只需使用如下的函式即可:

#include <linux/gpio.h>

int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_get_value(unsigned gpio);
void gpio_set_value(unsigned gpio, int value);
int gpio_to_irq(unsigned gpio);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

使用裝置樹的核心裡使用struct gpio_desc型別的一個物件表示裝置樹節點屬性裡的一個gpio口, 物件裡的成員值由晶片廠商的驅動程式碼負責初始化,我們只需使用函式gpiod_get()獲取即可.
可使用struct gpio_descs型別的一個物件裝載struct gpio_desc多個物件(gpiod_get_array()函式獲取).

#include <linux/gpio/consumer.h>

struct gpio_descs {
    unsigned int ndescs;
    struct gpio_desc *desc[];
};


在獲取一個或多個在裝置樹裝置節點屬性裡的gpio口時,可以指定獲取的gpio口是作輸入/輸出.
#define GPIOD_FLAGS_BIT_DIR_SET     BIT(0)
#define GPIOD_FLAGS_BIT_DIR_OUT     BIT(1)
#define GPIOD_FLAGS_BIT_DIR_VAL     BIT(2)

enum gpiod_flags {
    GPIOD_ASIS  = 0,
    GPIOD_IN    = GPIOD_FLAGS_BIT_DIR_SET, //作輸入
    GPIOD_OUT_LOW   = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT, //作輸出且輸出低電平
    GPIOD_OUT_HIGH  = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
              GPIOD_FLAGS_BIT_DIR_VAL, //作輸出且輸出高電平
};

int gpiod_count(struct device *dev, const char *con_id); //獲取裝置節點裡的gpio口個數


//以下函式用於獲取裝置節點(不是它的子節點)屬性值裡gpio口的資訊 
//引數con_id用於指定自定義的屬性名的字首,如屬性名"leds-gpios", 則con_id應為"leds"
//flags用於指定獲取gpio口資訊時指定gpio是作輸入或輸出高低電平

struct gpio_desc *__must_check gpiod_get(struct device *dev,
                     const char *con_id,
                     enum gpiod_flags flags);
struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
                           const char *con_id,
                           unsigned int idx,
                           enum gpiod_flags flags);
struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
                          const char *con_id,
                          enum gpiod_flags flags);
struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
                            const char *con_id,
                            unsigned int index,
                            enum gpiod_flags flags);
struct gpio_descs *__must_check gpiod_get_array(struct device *dev,
                        const char *con_id,
                        enum gpiod_flags flags);
struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev,
                            const char *con_id,
                            enum gpiod_flags flags);

struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
                          const char *con_id,
                          enum gpiod_flags flags);
struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
                            const char *con_id,
                            unsigned int idx,
                            enum gpiod_flags flags);
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
                               const char *con_id,
                               enum gpiod_flags flags);
struct gpio_desc *__must_check
devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
                  unsigned int index, enum gpiod_flags flags);
struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
                             const char *con_id,
                             enum gpiod_flags flags);
struct gpio_descs *__must_check
devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
                  enum gpiod_flags flags);

//下面4個*_put函式用於回收裝置節點屬性裡關於gpio口的資訊.
//**注意只有釋放gpio_desc資源後才可重新獲取**
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs);
void gpiod_put(struct gpio_desc *desc); 
void gpiod_put_array(struct gpio_descs *descs);

//函式以devm開頭的是有標明相應的資源是屬於哪個struct device物件的功能.


////////////////////////////////////////////////////////////
//獲取到gpio口的struct gpio_desc物件地址後,就可以通過下面函式操作gpio口

int gpiod_get_direction(struct gpio_desc *desc); //判斷gpio是作輸入或輸出
int gpiod_direction_input(struct gpio_desc *desc); //gpio口作輸入
int gpiod_direction_output(struct gpio_desc *desc, int value); //作輸出, value用於指定輸出的電平, 1表示輸出有效電平,0表示輸出失效電平。與在裝置節點裡設定GPIO_ACTIVIE_HIGHT/LOW有關
int gpiod_direction_output_raw(struct gpio_desc *desc, int value); //作輸出, value用於直接指定是輸出高低電平, 1表示高電平, 0表示低平, 帶raw的函式是不會管ACTIVIE_LOW/ACTIVIE_HIGH的狀態的


int gpiod_get_value(const struct gpio_desc *desc);
void gpiod_set_value(struct gpio_desc *desc, int value);
void gpiod_set_array_value(unsigned int array_size,
               struct gpio_desc **desc_array, int *value_array);
int gpiod_get_raw_value(const struct gpio_desc *desc);
void gpiod_set_raw_value(struct gpio_desc *desc, int value);
void gpiod_set_raw_array_value(unsigned int array_size,
                   struct gpio_desc **desc_array,
                   int *value_array);


int gpiod_get_value_cansleep(const struct gpio_desc *desc);
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
void gpiod_set_array_value_cansleep(unsigned int array_size,
                    struct gpio_desc **desc_array,
                    int *value_array);
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
void gpiod_set_raw_array_value_cansleep(unsigned int array_size,
                    struct gpio_desc **desc_array,
                    int *value_array);

///////////////////////////////////////////////////
int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); //設定過濾抖動電平訊號

int gpiod_is_active_low(const struct gpio_desc *desc);
int gpiod_cansleep(const struct gpio_desc *desc);

int gpiod_to_irq(const struct gpio_desc *desc); //根據gpio_desc資訊找到gpio口對應的中斷號

struct gpio_desc *gpio_to_desc(unsigned gpio); //根據u32的gpio號找到gpio口對應的gpio_desc物件地址
int desc_to_gpio(const struct gpio_desc *desc); //根據gpio口的gpio_desc物件找到物件的u32的gpio號.


////////////////////////////////////////////////////
//獲取裝置節點裡子節點關於gpio的屬性值函式:

struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
                     const char *propname, int index,
                     enum gpiod_flags dflags,
                     const char *label);
struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev,
                        const char *con_id, int index,
                        struct fwnode_handle *child,
                        enum gpiod_flags flags,
                        const char *label);
static inline
struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev,
                           const char *con_id,
                           struct fwnode_handle *child,
                           enum gpiod_flags flags,
                           const char *label);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142

相關推薦

linux裝置gpio應用

參考核心原始碼裡的Documentation/devicetree/bindings/gpio/gpio.txt 在裝置樹裡的節點裝置需要使用到gpio口,則需要在一個或多個節點屬性裡提供gpio口的資訊. 關於gpio口資訊的節點屬性命名方式是:

09 linux裝置gpio應用

參考核心原始碼裡的Documentation/devicetree/bindings/gpio/gpio.txt 在裝置樹裡的節點裝置需要使用到gpio口,則需要在一個或多個節點屬性裡提供gpio口的資訊. 關於gpio口資訊的節點屬性命名方式是: n

04-Linux裝置系列-GPIO驅動實踐

1. 前言 GPIO驅動開發可能算是Linux核心裝置驅動開發中最為簡單、最常見的一個方向,對於開發板的按鍵、LED、蜂鳴器、電源控制等模組,可能都是使用GPIO實現的。Linux核心的GPIO子系統在核心不斷的演進過程中進行了多次的重構,本文的第二

linux裝置gpio

#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/version.h> #include &

tiny4412學習(四)之移植linux-裝置(1)裝置基礎知識及GPIO中斷

#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/of.

ARM Linux裝置

1 ARM裝置樹 DT: Device Tree FDT: Flattened DeviceTree OF: Open Firmware(開啟韌體,這個字首在後面的api中會用到) DTS : device tree souke DTSI: device tree sourc

Linux裝置語法詳解【轉】

轉自:https://www.cnblogs.com/xiaojiang1025/p/6131381.html 概念 Linux核心從3.x開始引入裝置樹的概念,用於實現驅動程式碼與裝置資訊相分離。在裝置樹出現以前,所有關於裝置的具體資訊都要寫在驅動裡,一旦外圍裝置變化,驅動程式碼就要重寫。引入了裝置樹之

Linux裝置語法詳解

概念 Linux核心從3.x開始引入裝置樹的概念,用於實現驅動程式碼與裝置資訊相分離。在裝置樹出現以前,所有關於裝置的具體資訊都要寫在驅動裡,一旦外圍裝置變化,驅動程式碼就要重寫。引入了裝置樹之後,驅動程式碼只負責處理驅動的邏輯,而關於裝置的具體資訊存放到裝置樹檔案中,

Linux裝置使用

本頁面介紹瞭如何為新machine編寫裝置樹檔案。它旨在提供裝置樹概念的概述以及它們如何用於描述machine。 有關裝置樹資料格式的完整技術說明,請參閱ePAPR v1.1規範。ePAPR規範比本頁面介紹的基本主題包含更多詳細資訊,請參閱此頁面以獲取本頁未涵蓋的更高階用法

(最新核心3.4)Linux 裝置載入I2C client adapter 的流程(核心3.4 高通)

BLSP(BAM Low-Speed Peripheral) , 每一個BLSP含有兩個QUP, 每一個QUP可以被配置為I2C, SPI, UART, UIM介面, BLSP是高通對於低速介面的一種管理方式。 [email protec

基於裝置gpio的簡單操作

目標: 學習裝置樹中GPIO資源的使用,實現按鍵中斷簡單驅動程式。原理圖:  tiny4412 底板上有4顆按鍵,分別為連線在 GPX3_2、GPX3_3、GPX3_4、GPX3_5 ,引腳狀態常高。裝置樹: interrupt_demo: interrupt_demo

基於裝置GPIO驅動(通過系統節點控制)

#include <linux/types.h> #include <linux/pm.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/init.h> #inclu

linux裝置筆記__基於msm8x10的基本分析

由文章,linux裝置樹筆記__dts基本概念及語法,我們知道了基本概念,知道了大概的裝置樹節點及其屬性,而節點下的屬性大多是自定義,除了保留的幾個屬性,大多從.dts是無法知道其用途的,這個就需要看驅動是如何解析屬性值的了,這點也可作技術細節的部分隱藏。 在原始碼的ms

linux裝置

1.    ARM Device Tree起源 Linus Torvalds在2011年3月17日的ARM Linux郵件列表宣稱“this whole ARM thing is a f*cking pain in the ass”,引發ARM Linux社群的地震,隨

第18章 ARM Linux裝置之四(常用的OF API)

18.4 常用的OF API除了前文介紹的of_machine_is_compatible()、of_device_is_compatible()等常用函式以外,在Linux的BSP和驅動程式碼中,經常會使用到一些Linux中其他裝置樹的API,這些API通常被冠以of_字首

24 裝置描述spi裝置

核心文件裡沒有直接增加spi裝置的驅動方法, 但可通過裝置樹裡現有spi裝置的描述來學習. spi裝置在裝置樹裡像描述i2c裝置一樣,需要在spi控制器節點裡用子節點描述spi裝置節點: &spi0 { /* spi控制器節點 */ .

linux裝置中pinctrl的配置(上)

最近在移植linux,用到kernel版本為3.18.22和4.1.3,在高版本的核心原始碼中用到了裝置樹(device-tree),裝置樹中用到pinctrl的配置,記錄一下。 1、普通設定 在配置串列埠時,pinctrl的配置資訊如下所示: <span st

linux裝置中pinctrl的配置(下)

上一篇記錄了裝置樹檔案中管腳普通配置的查詢與確定,這篇介紹一下特殊的配置。 首先還是先看程式碼,看看到底特殊到哪裡。 <span style="font-size:14px;"> pi

Linux 裝置(Device Tree)簡介

DTS (device tree source)   .dts檔案是一種ASCII 文字格式的Device Tree描述,此文字格式非常人性化,適合人類的閱讀習慣。基本上,在ARM Linux在,一個

linux 裝置及節點引用

說了這麼半天,跟引入裝置樹有什麼關係呢?華清教學使用的開發板(A8/A9)都使用DM9000網絡卡晶片。DM9000驅動是開源的,在主線核心原始碼中就有。我們每次基於A8/A9板子移植的時候,DM9000驅動並沒有修改過,僅僅是選配了下,主要的工作是在板級檔案中添加了裝置資訊。DM9000驅動使用的是plat