昨晚看完pincrtl+gpio子系统才发现原来按键驱动是下一部分内容,只是录制上传中次序颠倒了,LED驱动程序还没有结束!
7.10.1.Pinctrl子系统概念
“对于一个 PIN 的配置主要包括两方面,一个是设置这个 PIN 的复用功能,另一个就是设置这个 PIN 的电气特性。”
老师的文档已经写的很清楚了,这里感觉不用再废话了,问自己4个问题:
1什么是pinctrl系统?管理引脚复用和配置的系统;
2如何表现?首先看下内核种的 Documentation\devicetree\bindings\Pinctrl\Pinctrl-bindings.txt,明确2个对象。
pin controller,3个关键词来描述,引脚复用、参数配置和设备树节点。也就是说它在设备树中也是一个节点,包含引脚复用和参数配置。
Hardware modules that control pin multiplexing(引脚复用) or configuration parameters(参数配置) such as pull-up/down, tri-state, drive-strength etc are designated as pin controllers. Each pin controller must be represented as a node in device tree(设备树节点),just like any other hardware module.
client device,也是3关键词描述,引脚配置、信号成员和设备树节点。也就是说它在设备树中也是一个节点,它的组成信号由引脚配置决定。
Hardware modules whose signals(信号成员) are affected by pin configuration(引脚配置) are designated client devices. Again, each client device must be represented as a node in device tree(设备树节点), just like any other hardware module.
具体看下它们之间的关系:
3.怎么编写pinctrl子系统?比如GPIO5_IO3。
参考下别人的代码,2个来源,1个说明文档pinctrl-bindings.txt,1个.dts文件imx6ull.dtsi。
== Pinctrl client devices ==
每个client device的pin state都会被分配一个整数ID,从0开始连续排列,每个ID是独一无二的,同时也会分配一个名字。
client device绑定的Pin controller必须在设备树中有定义,并且定义ID和name。
必备特性:
pinctrl-0:指向pin configuration node of the pin controllers,也就是一个特性可以指向多个pin controllers;
可选特性: pinctrl-1: pinctrl-n: pinctrl-names:integer state ID,0代表ID0,1代表ID1; pinctrl-assert-gpios:
For example:
/* For a client device requiring named states */
device {
/* ID0="active",ID1="idle" */
pinctrl-names = "active", "idle";
/* pinctrl-0指向state_0_node_a pin controller子节点 */
pinctrl-0 = <&state_0_node_a>;
/* pinctrl-0指向state_1_node pin controller的2个子节点 */
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
};
== Pin controller devices ==
Pin controller devices必须定义node,以便client device调用。For example:
pincontroller {
... /* Standard DT properties for the device itself elided */
state_0_node_a {
...
};
state_1_node_a {
...
};
state_1_node_b {
...也可以是孙节点
};
}
== Generic pin multiplexing node (通用多路复用节点)content ==
pin multiplexing nodes:
function- the mux function to select;
groups - the list of groups to select with this function (either this or "pins" must be specified)
pins - the list of pins to select with this function (either this or "groups" must be specified)(要么用groups,要么用pins,两者必须用一个)
state_0_node_a {
uart0 { //把引脚组u0rxtx和u0rtscts复用为uart0
function = "uart0"; //复用功能
groups = "u0rxtx", "u0rtscts"; //引脚组
};
state_2_node_a {//把引脚mfio29和mfio30复用为i2c0
function = "i2c0";//复用功能
pins = "mfio29", "mfio30";//引脚们
};
};
== Generic pin configuration node content ==
有很多例如pins、group、bias-disable、bias-pull-up、drive-open-drain、input-enable、low-power-enable和output-lo等等。
state_1_node_a {
rts_txd {
pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
output-high;
};
到此可以尝试写写关于GPIO5_IO3的client和pinctrl,要用到复用功能的pinctrl:
/* GPIO5_IO3 client device */
gpio5_io3_my {
/* */
pinctrl-names = "state0";
/* pinctrl-0指向state_0_node_a pin controller子节点 */
pinctrl-0 = <&gpio5_io3_pinctrl>;
};
***********************************************************************
gpio5_io3_pinctrl {
gpio5_io3_mux {//把引脚PAD_SNVS_TAMPER3复用为gpio5_io3
function = "gpio5_io3";//复用功能
pins = "PAD_SNVS_TAMPER3";//引脚们
};
};
不知道对错,有点虚,翻看下imx6ull.dtsi文件,里面应该有gpio5_io3的应用,只找到了gpio5的设备节点定义,好像相关的样子。搜PAD_SNVS_TAMPER3也没有信息。
gpio5: gpio@020ac000 {
compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
reg = <0x020ac000 0x4000>;
interrupts = ,
;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
6ull开发板中肯定用到了这个led,所以去搜索100ask_imx6ull-14x14.dts看下,找到相关信息。
leds {
compatible = "gpio-leds"; //用来匹配platform_driver
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_leds>; //指向pinctrl_leds pin controller
led0: cpu { //好像是cpu灯相关的
label = "cpu";
gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
default-state = "on";
linux,default-trigger = "heartbeat";
};
};
搜下pinctrl_leds,
&iomuxc_snvs {
pinctrl-names = "default_snvs";
pinctrl-0 = <&pinctrl_hog_2>;
imx6ul-evk {
pinctrl_leds: ledgrp {
fsl,pins = < MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x000110A0 >;
}; //什么意思???
};
};
仿照这个修改一下自己写的:
/* GPIO5_IO3 client device */
gpio5_io3_my {
compatible = "gpio-leds";
pinctrl-names = "default";
/* pinctrl-0指向state_0_node_a pin controller子节点 */
pinctrl-0 = <&gpio5_io3_pinctrl>;
};
***********************************************************************
/* GPIO5_IO3 client device */
gpio5_io3_pinctrl {
gpio5_io3_mux: {//把引脚PAD_SNVS_TAMPER3复用为gpio5_io3
//function = "gpio5_io3";//复用功能
//pins = "PAD_SNVS_TAMPER3";//引脚们
fsl,pins = < MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x000110A0 >;
};
};
这个长长的配置不是很清楚,后面再分析。
4.内核如何使用?先了解下,后面代码中具体分析。
/**
* pinctrl_bind_pins() - called by the device core before probe//意思是在probe()函数执行之前先执行?
* @dev: the device that is just about to probe
*/
int pinctrl_bind_pins(struct device *dev)
{}
后来截取ZDYZ的文档: