第七章 驱动程序开发-LED驱动-7.10.1 pincrtl子系统

    昨晚看完pincrtl+gpio子系统才发现原来按键驱动是下一部分内容,只是录制上传中次序颠倒了,LED驱动程序还没有结束!

7.10.1.Pinctrl子系统概念

“对于一个 PIN 的配置主要包括两方面,一个是设置这个 PIN 的复用功能,另一个就是设置这个 PIN 的电气特性。”

第七章 驱动程序开发-LED驱动-7.10.1 pincrtl子系统_第1张图片

    老师的文档已经写的很清楚了,这里感觉不用再废话了,问自己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.

具体看下它们之间的关系:

第七章 驱动程序开发-LED驱动-7.10.1 pincrtl子系统_第2张图片

  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.内核如何使用?先了解下,后面代码中具体分析。

第七章 驱动程序开发-LED驱动-7.10.1 pincrtl子系统_第3张图片

/**
 * 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的文档:

 

你可能感兴趣的:(I.MX6)