一. 简介
 
 前面几篇文章讲解了  
 pinctrl  
 子系统, 
 pinctrl  
 子系统重点是设置  
 PIN( 
 有的  
 SOC  
 叫做  
 PAD) 
 的复用  
 和电气属性。 
 
 
 
 注意:如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gpio 子系统了。如果 PIN用作其他功能如 I2C,串口等功能,就不会用到 gpio子系统。 
 
 
 
 gpio  
 子系统顾名思义,就是用于初始化  
 GPIO, 
 并且提供相应的  
 API  
 函数,比如,设置  
 GPIO  
 为输入输出,读取  
 GPIO  
 的值等。 
 
 
 gpio  
 子系统的主要目的就是方便驱动开发者使用  
 gpio 
 。驱动 
 开发者在设备树中添加  
 gpio  
 相关信息,然后,就可以在驱动程序中使用  
 gpio  
 子系统提供的  
 API  
 函数来操作  
 GPIO 
 , 
 Linux  
 内核向驱动开发者屏蔽掉了  
 GPIO  
 的设置过程,极大的方便了驱动开 
 发者使用  
 GPIO 
 。  
 
 
 
 
 
 
 
二. Linux设备树中的 gpio 信息
1. SD卡设备节点
 
 I.MX6ULL-ALPHA  
 开发板上的  
 UART1_RTS_B  
 做为  
 SD  
 卡的检测引脚, 
 UART1_RTS_B  
 复  
 用为  
 GPIO1_IO19 
 ,通过读取这个  
 GPIO  
 的高低电平,就可以知道  
 SD  
 卡有没有插入。 
 
 
 首先肯定是将  
 UART1_RTS_B  
 这个  
 PIN  
 复用为  
 GPIO1_IO19 
 ,并且设置电气属性,也就是前面几篇文章讲的  
 pinctrl  
 节点。 
 
 
 
 打开  
 imx6ull-alientek-emmc.dts 
 ,  
 UART1_RTS_B  
 这个  
 PIN  
 的  
 pincrtl  
 设置如下:  
 
 
pinctrl_hog_1: hoggrp-1 {
    fsl,pins = <
    MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
......
  >;
}; 
 第  
 3  
 行,设置  
 UART1_RTS_B  
 这个  
 PIN  
 为  
 GPIO1_IO19 
 。  
 
 
 
 
 pinctrl 配置好以后,就是设置 gpio 了。 
 SD  
 卡驱动程序通过读取  
 GPIO1_IO19  
 的值来判断  
 SD  
 
 
 卡有没有插入,但是  
 SD  
 卡驱动程序怎么知道  
 CD  
 引脚连接的  
 GPIO1_IO19  
 呢? 
 
 
 肯定是需要设 
 备树告诉驱动!在设备树中  
 SD  
 卡节点下添加一个属性,来描述  
 SD  
 卡的  
 CD  
 引脚就行了, 
 SD  
 卡驱动直接读取这个属性值,就知道  
 SD  
 卡的  
 CD  
 引脚使用的是哪个  
 GPIO  
 了。 
 
 
 
 
 SD  
 卡连接在  
 I.MX6ULL  
 的  
 usdhc1  
 接口上,在  
 imx6ull-alientek-emmc.dts  
 中找到名为 “ 
 usdhc1 
 ” 的节点,这个  
 节点就是  
 SD 
 卡设备节点,如下所示:  
 
 
&usdhc1 {
	pinctrl-names = "default", "state_100mhz", "state_200mhz";
	pinctrl-0 = <&pinctrl_usdhc1>;
	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
    /* pinctrl-3 = <&pinctrl_hog_1>; */
	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
	keep-power-in-suspend;
	enable-sdio-wakeup;
	vmmc-supply = <®_sd1_vmmc>;
	status = "okay";
}; 
 第  
 6  
 行,此行本来没有,是作者添加的。 
 usdhc1  
 节点作为  
 SD  
 卡设备总节点, 
 usdhc1  
 节点 
 需要描述  
 SD  
 卡所有的信息,因为驱动要使用。本行就是描述  
 SD  
 卡的  
 CD  
 引脚  
 pinctrl  
 信息 
 所在的子节点,因为  
 SD  
 卡驱动需要根据  
 pincrtl  
 节点信息来设置  
 CD  
 引脚的复用功能等。 
 
 
 
 第3~5  
 行的  
 pinctrl-0~2  
 ,都是  
 SD  
 卡其他  
 PIN  
 的  
 pincrtl  
 节点信息。 
 
 
 但是大家会发现,其实在 
 usdhc1  
 节点 
 中,并没有 “ 
 pinctrl-3 = <&pinctrl_hog_1> 
 ” 这一行,也就是说并没有指定  
 CD  
 引脚的 
 pinctrl  
 信息,  
 那么  
 SD  
 卡驱动就没法设置  
 CD  
 引脚的复用功能啊? 
 
 
 这个不用担心,因为在 “ 
 iomuxc 
 ” 节点下  
 引用了  
 pinctrl_hog_1  
 这个节点,所以,  
 Linux  
 内核中的  
 iomuxc  
 驱动就会自动初始化  
 pinctrl_hog_1  
 节点下的所有  
 PIN 
 。  
 
 
 
 
 第  
 7 行, “cd-gpios” 属性描述了 SD  
 卡的  
 CD  
 引脚使用的哪个  
 IO 
 。属性值一共有三个,  
 我们来看一下这三个属性值的含义。 
 
 
 “ 
 &gpio1 
 ” 表示  
 CD  
 引脚所使用的  
 IO  
 属于  
 GPIO1  
 组,“ 
 19 
 ”  
 表示  
 GPIO1  
 组的第  
 19  
 号  
 IO 
 ,通过这两个值  
 SD  
 卡驱动程序就知道  
 CD  
 引脚使用了  
 GPIO1_IO19  
 。“ 
 GPIO_ACTIVE_LOW 
 ” 表示低电平有效,如果改为“ 
 GPIO_ACTIVE_HIGH 
 ”就表 
 示高电平有效。  
 
 
 
 根据上面这些信息,SD 卡驱动程序就可以使用 GPIO1_IO19 来检测 SD 卡的 CD 信号了。 
 
 
 
 
 
 
 
2. gpio1 节点信息
 
 打开  
 imx6ull.dtsi 
 ,在里面找到如下所示内容: 
 
 
gpio1: gpio@0209c000 {
	    compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
		reg = <0x0209c000 0x4000>;
		interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
		    <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
		gpio-controller;
		#gpio-cells = <2>;
		interrupt-controller;
		#interrupt-cells = <2>;
}; 
 gpio1  
 节点信息,描述了  
 GPIO1  
 控制器的所有信息,重点就是  
 GPIO1  
 外设寄存器基地址以及  
 兼 容 属 性 。 关 于  
 I.MX  
 系 列  
 SOC  
 的  
 GPIO  
 控 制 器 绑 定 信 息 请 查 看 文 档  
 
 
 Documentation/devicetree/bindings/gpio/ fsl-imx-gpio.txt 
 (文档在 Linux内核源码目录下)。 
 
 
 
 第  
 2  
 行,设置  
 gpio1  
 节点的  
 compatible  
 属性有两个,分别为“ 
 fsl,imx6ul-gpio 
 ”和“ 
 fsl,imx35-  
 
 
 gpio 
 ”,在  
 Linux  
 内核中搜索这两个字符串就可以找到  
 I.MX6UL  
 的  
 GPIO  
 驱动程序。  
 
 
 
 第  
 3  
 行, 
 reg  
 属性设置了  
 GPIO1  
 控制器的寄存器基地址为  
 0X0209C000 
 ,大家可以打开  
 
 
 《 
 I.MX6ULL  
 参考手册》找到 " 
 Chapter 28" 
 ,有如图  
 45.2.2.1  
 所示的寄存器地址表: 
 
 

 
 从上表中可以看出, 
 GPIO1  
 控制器的基地址就是  
 0X0209C000 
 。  
 
 
 
 第 6 
 行,“ 
 gpio-controller 
 ” 表示  
 gpio1  
 节点是个  
 GPIO  
 控制器。  
 
 
 第  
 7  
 行,“ 
 #gpio-cells 
 ” 属性和 “ 
 #address-cells 
 ” 类似, 
 #gpio-cells  
 应该为  
 2 
 ,表示一共有 
 两个 
 cell 
 ,第一个  
 cell  
 为  
 GPIO  
 编号,比如,“ 
 &gpio1 3 
 ” 就表示  
 GPIO1_IO03 
 。第二个  
 cell  
 表示  
 GPIO  
 极 性 , 如 果 为  
 0(GPIO_ACTIVE_HIGH)  
 的 话, 表 示 高 电 平 有 效 , 如 果 为  
 1(GPIO_ACTIVE_LOW) 
 的话,表示低电平有效。  
 
 
 
 
 
总结:经过上面的分析,可以知道:对于 SD卡而言,SD卡检测引脚就是 GPIO1_19,而且是低电平有效。
所以在写 SD卡驱动时,可以读取 "cd-gpios" (当然对于不同芯片,可能该属性命名就不同)属性信息就可以得到 引脚。
















![[分章:阅读]《我的第一本算法书》](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5CAdministrator%5CAppData%5CLocal%5CTemp%5Cksohtml13556%5Cwps41.png&pos_id=mqmGGETO)

