pinctrl和gpio子系統

2021-10-10 20:14:53 字數 3186 閱讀 9130

傳統配置pin的方式是直接操作暫存器,這種方式比較繁瑣和容易出問題,pinctrl子系統就是為了解決這個問題而引入的。pinctrl子系統的主要工作內容如下:

●獲取裝置樹中的pin資訊

●根據獲取到的pin資訊來設定pin的復用功能

●根據獲取到的pin資訊來設定pin的電氣特性,比如上下拉,速度,驅動能力等

對於使用者來說,在裝置樹提供相應的資訊就可以了,pinctrl子系統會來完成剩下的工作。

使用pinctrl的另外乙個好處是,驅動**與單板無關。

pinctrl涉及到兩個概念,pin controller和client device

前者提供服務:可以用它來復用引腳、配置引腳

後者使用服務:宣告自己要使用哪些引腳的哪些功能,怎麼配置他們。

pin controller節點的格式沒有統一標準!!!!每家晶元都不一樣,由晶元bsp廠商定義。pinctrl子系統,晶元相關的操作也是需要bsp廠商編寫**並註冊給核心。所以pin controller節點屬性的格式,跟bsp廠商的風格關聯比較大。

如imx6ull的引腳配置由iomuxc模組負責,pin controller就在該節點下實現

&iomuxc ;
上面的fsl,pins屬性的值如下:

#define mx6ul_pad_uart1_rts_b__gpio1_io19 0x0090 0x031c 0x0000 0x5 0x0

展開相應的巨集發現是5個值,實際上是對應了

imx晶元io配置暫存器的位址和設定的值。

從這個巨集的名字也能想到就是配置pad_uart1_rts_b這個引腳的功能為gpio1_io19。後面跟著的config是配置上下拉,驅動能力,速度等電氣特性。

上面這個pinctrl的節點資訊,imx有個pins_tool_for_i.mx_processors軟體可以通過ui介面生成。

下面就是不同晶元的pin controller的定義,可以發現屬性名稱不太一樣,但是使用的概念是一樣的。都是用controller節點配置引腳,client device裝置使用引腳。

pinctrl子系統在使用者driver的作用流程

●設定了pin controller的引腳配置

●在client device引用了引腳配置

●在裝置狀態切換的時候,pinctrl會被自動呼叫如:

pinctrl子系統重點是配置pad的復用和電氣特性,如果pinctrl子系統將乙個pad復用為gpio的話,接下來就要用到gpio子系統。gpio子系統的主要目的是方便驅動開發這使用gpio,開發出來的驅動也可以做到和單板無關。

在bsp工程師實現了gpio子系統後,我們可以:

bsp定義了gpio controller如:imx晶元的定義

在裝置樹的模組節點加入io的引用:

格式為gpios屬性,或者name-gpios屬性

如上面的reset引腳,用的是gpio5的引腳2

獲取gpio

gpiod_get

gpiod_get_index

gpiod_get_array

devm_gpiod_get

devm_gpiod_get_index

devm_gpiod_get_array

設定方向

gpiod_direction_input

gpiod_direction_output

讀值寫值

gpiod_get_value

gpiod_set_value

釋放gpio

gpio_free

gpiod_put

gpiod_put_array

devm_gpiod_put

devm_gpiod_put_array

●裝置樹相關節點編寫

3.1新增pinctrl節點

用pins_tool_for_i.mx_processors_v6_x64.exe工具生成pinctrl配置

或者自己手動根據廠家的規則編寫

pinctrl_io:iogrp;
將該節點新增到iomuxc節點

3.2新增io裝置節點

gpiotest
●io驅動編寫

a.定義、註冊乙個platform_driver

b.在probe函式裡面:

根據platform_device的裝置樹資訊確定gpio:gpiod_get

c在file_operations的函式中使用gpio子系統的函式操作gpio:

gpiod_direction_output、gpiod_set_value

a.定義、註冊platform_driver的參考**

static const struct of_device_id test_io = ,,};

/* 1. 定義platform_driver */

static struct platform_driver chip_demo_gpio_driver = ,

};/* 2. 在入口函式註冊platform_driver */

static int __init io_init(void)

c.	使用gpio子系統的函式操作gpio

在open函式中呼叫gpio函式設定引腳方向:

static int io_drv_open (struct inode *node, struct file *file)

在write函式中呼叫gpio函式設定引腳值:

/* write(fd, &val, 1); */

static ssize_t io_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)

釋放gpio:

gpiod_put(io_gpio);

pinctrl 和 gpio 子系統

將工作分為兩部分 of device id 結構體陣列,它裡面儲存著這個驅動檔案的相容性值,裝置樹中的 compatible 屬性值會和 of device id 中的所有相容性字串比較,檢視是否可以使用此驅動。1 platform driver 是平台裝置驅動,2 platform driver ...

pinctrl子系統分析(一)

pinctrl子系統分析 一 pinctrl子系統分析 二 pinctrl子系統分析 三 許多soc的內部都包含了pin控制器,通過pin控制器,我們可以匹配引腳的狀態和功能特性。在了解pinctrl子系統之前,我們先來了解一些基本的概念。soc的很多引腳都可以配置成不同的功能,如a1和a2兩個引腳...

pinctrl子系統分析(二)

pinctrl子系統分析 一 pinctrl子系統分析 二 pinctrl子系統分析 三 pin控制器驅動的主要工作是,列舉pin控制器的資訊,如控制器有多少個引腳,支援多少個function,每個function對應幾個group,支援多少個group等,建立table儲存這些資訊,最後呼叫pin...