傳統配置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...