第七章 驅動程序開發-LED驅動-7.10.1 pincrtl子系統

    昨晚看完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 = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
				<GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
	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的文檔:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章