本笔记仅以IMX6ULL为例子,方便本人后续学习回顾所用。

imx6ull 设备树中引脚定义规则和解析——pinctrl

       imx6 引脚定义在 ”imx6ul-pinfunc.h“中,一个引脚一般支持8个可选功能(alternate MUX_MODE 缩写为ALT), 通过IOMUX Controller的控制器进行选择。

        IOMUX Controller主要通过两个寄存器进行引脚的配置:

        IOMUXC_SW_MUX_CTL_PAD_XXX :

        XXX代表某一个PAD的名称,用于配置引脚MUX的输入功能,包括UART,GPIO,CSI 等功能。

        IOMUXC_SW_PAD_CTL_PAD__XXX :

        用于配置具体功能的特性,包括 上拉/下拉,速度,等特性

        这里补充一下本人对Pin和PAD理解,如有不对,欢迎各位指出:

       (1) Pin跟Lead差不多是一回事,都是指Silicon DIE封装后,留给用户使用的引脚。

        (2)PAD是针对DIE的连接而言的,对于芯片使用者是不可见的,可以理解成Die上用于焊接打线的焊盘。

下面为imx6ul-pinfunc.h 中的部分定义:

下面为imx6ul-pinfunc.h 中的部分定义:

#define MX6UL_PAD_UART1_CTS_B__UART1_DCE_CTS                      0x008C 0x0318 0x0000 0x0 0x0
#define MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS                      0x008C 0x0318 0x0620 0x0 0x2
#define MX6UL_PAD_UART1_CTS_B__ENET1_RX_CLK                       0x008C 0x0318 0x0000 0x1 0x0
#define MX6UL_PAD_UART1_CTS_B__USDHC1_WP                          0x008C 0x0318 0x066C 0x2 0x1
#define MX6UL_PAD_UART1_CTS_B__CSI_DATA04                         0x008C 0x0318 0x04D8 0x3 0x0
#define MX6UL_PAD_UART1_CTS_B__ENET2_1588_EVENT1_IN               0x008C 0x0318 0x0000 0x4 0x0
#define MX6UL_PAD_UART1_CTS_B__GPIO1_IO18                         0x008C 0x0318 0x0000 0x5 0x0
#define MX6UL_PAD_UART1_CTS_B__USDHC2_WP                          0x008C 0x0318 0x069C 0x8 0x1

在设备树文件中,定义方法如下:

/* sneak KEY */
		pinctrl_key: keygrp {
			fsl,pins = <
				MX6UL_PAD_UART1_CTS_B__GPIO1_IO18		0xF080	/* KEY0 */
			>;
		};

这里以MX6UL_PAD_UART1_CTS_B__GPIO1_IO18为例

#define MX6UL_PAD_UART1_CTS_B__GPIO1_IO18                         0x008C 0x0318 0x0000 0x5 0x0

其中:

0x008C---> The pin mux register.
0x0318---> The config register.
0x0000---> The select input register
0x5 ---> mux_mode
0 ----> input_value

        这里的mux register和config register对应的数值,都是该寄存器相较于基地址的偏移地址

在设备树文件中上还需要给这个引脚赋值

MX6UL_PAD_UART1_CTS_B__GPIO1_IO18		0xF080	/* KEY0 */

0xF080 ->config value

        这里的赋值可以参考逻辑开发时对该引脚的电气属性配置数值

imx6ull 设备树中引脚定义规则和解析——根节点

一、根节点命名格式

/ {
	model = "Freescale i.MX6 ULL 14x14 EVK Board";
	compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
 
	chosen {
		stdout-path = &uart1;
	};
 
	memory {
		reg = <0x80000000 0x20000000>;
	};
 
	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
 
		linux,cma {
			compatible = "shared-dma-pool";
			reusable;
			size = <0x14000000>;
			linux,cma-default;
		};
	};
 
	backlight {
		compatible = "pwm-backlight";
		pwms = <&pwm1 0 5000000>;
		brightness-levels = <0 4 8 16 32 64 128 255>;
		default-brightness-level = <7>;
		status = "okay";
	};
...
    	/* sneak key 2022/4/18 */
	key {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "sneak-key";		//compatible兼容属性,属性值为一个字符串列表
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_key>;
		key-gpio = <&gpio1 18 GPIO_ACTIVE_LOW>;
		status = "okay";
	};
};

二、设备/根节点的常见属性

样例:

	/* sneak key 2022/4/18 */
	key {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "sneak-key";		//compatible兼容属性,属性值为一个字符串列表
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_key>;
		key-gpio = <&gpio1 18 GPIO_ACTIVE_LOW>;
		status = "okay";
	};

1、#address-cells 和#size-cells 属性
        这两个属性的值都是无符号 32 位整形,#address-cells 和#size-cells这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells属性值决定了子节点reg 属性中地址信息所占用的字长(32 位),#size-cells属性值决定了子节点 reg属性中长度信息所占的字长(32 位)。#address-cells 和#size-cells 表明了子节点应该如何编写reg属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度,reg属性的格式一为:

reg = <address1 length1 address2 length2 address3 length3……>

        每个“address length”组合表示一个地址范围,其中 address是起始地址,length是地址长度,#address-cells表明 address这个数据所占用的字长,#size-cells表明length这个数据所占用的字长,比如:

	/* sneak 2022/4/9 */
	sneak {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "sneak-led";
		status = "okay";
		reg = < 0X020C406C 0X04		/* CCM_CCGR1_BASE */
				0X020E0068 0X04		/* SW_MUX_GPIO1_IO03_BASE */
				0X020E02F4 0x04		/* SW_PAD_GPIO1_IO03_BASE */
				0X0209C000 0x04		/* GPIO1_DR_BASE */
				0X0209C004 0X04 >;	/* GPIO1_GDIR_BASE */
	};

        #address-cells = <1>;//表示用一个32位的数来描述地址
        #size-cells = <1>;//表示用1个32位的数来描述该地址的大小
上面两个信息#address-cells和#size-cells主要用来描述子节点里面reg的信息
reg里面的个数,应该是address-cells + size-cells的整数倍
        解析上方代码:

        reg的起始地址为0X020C406C 大小为0x04

        reg的起始地址为0X020E02F4 大小为0x04

        reg的起始地址为0X020E02F4 大小为0x04等。

2、compatible 属性

  compatible属性也叫做“兼容性”属性,这是非常重要的一个属性!compatible 属性的值是一个字符串列表,compatible属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序,compatible 属性的值格式如下所示:

	model = "SMDK24440";
	compatible = "samsung,smdk2440","samsung,smdk24140","samsung,smdk24xx";

        这里的compatible属性声明想要什么machine_desc,属性值可以是一系列字符串,依次与machine_desc匹配。
        内核最好支持samsung,smdk2440,如果不支持,再尝试是否支持samsung,smdk24140,再不支持,最后尝试samsung,smdk24xx</code
总结如下:
设备树根节点的compatible属性列出了一系列的字符串,表示它兼容的单板名,从"最兼容"到次之;

        特别注意,在设备节点中compatible 属性值是为了匹配 Linux 内核中的驱动程序

3、model 属性

        model 属性值也是一个字符串,一般 model 属性描述设备模块信息,比如名字什么的,比如:

model = "wm8960-audio";

4、status 属性

status属性看名字就知道是和设备状态有关的,status属性值也是字符串,字符串是设备的状态信息,可选的状态如下表所示:

 5、ranges 属性

        ranges属性值可以为空或者按照(child-bus-address,parent-bus-address,length)格式编写的数字矩阵,ranges 是一个地址映射/转换表,ranges 属性每个项目由子地址、父地址和地址空间长度
这三部分组成:
        child-bus-address:子总线地址空间的物理地址,由父节点的#address-cells 确定此物理地址
所占用的字长。
        parent-bus-address:父总线地址空间的物理地址,同样由父节点的#address-cells 确定此物
理地址所占用的字长。
        length:子地址空间的长度,由父节点的#size-cells 确定此地址长度所占用的字长。

6、name 属性

        name 属性值为字符串, name 属性用于记录节点名字, name 属性已经被弃用,不推荐使用
name 属性,一些老的设备树文件可能会使用此属性。

7、device_type 属性

        device_type 属性值为字符串, IEEE 1275 会用到此属性,用于描述设备的 FCode ,但是设
备树没有 FCode ,所以此属性也被抛弃了。此属性只能用于 cpu 节点或者 memory 节点。