第七章 驱动程序开发-LED驱动-7.10.2 gpio子系统

7.10.2.GPIO子系统概念

     也来问4个问题:

 1什么是GPIO子系统?配置GPIO引脚电气特性的系统;

 2如何表现?找到gpio.txt看下,

1) gpios property

    需要用"[-]gpios"命名,

	gpio1: gpio1 { //名字
		gpio-controller
		 #gpio-cells = <2>;
	};
	data-gpios = <&gpio1 12 0>,
		     <&gpio1 13 0>,

通常定义GPIO的标志位都是用include/dt-bindings/gpio/gpio.h中的宏来定义,看下这个文件:

/*
 * This header provides constants for most GPIO bindings.
 *
 * Most GPIO bindings include a flags cell as part of the GPIO specifier.
 * In most cases, the format of the flags cell uses the standard values
 * defined in this header.
 */
#ifndef _DT_BINDINGS_GPIO_GPIO_H
#define _DT_BINDINGS_GPIO_GPIO_H

/* Bit 0 express polarity */
#define GPIO_ACTIVE_HIGH 0  //电平?
#define GPIO_ACTIVE_LOW 1 

/* Bit 1 express single-endedness */
#define GPIO_PUSH_PULL 0  //上拉?
#define GPIO_SINGLE_ENDED 2

/*
 * Open Drain/Collector is the combination of single-ended active low,
 * Open Source/Emitter is the combination of single-ended active high.
 */
#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_ACTIVE_LOW) //开漏
#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_ACTIVE_HIGH)

#endif
Example of a node using GPIOs:
	node {
		enable-gpios = <&qe_pio_e 18 GPIO_ACTIVE_HIGH>; //18是引脚数
	};
GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes
GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller.
  1. gpio-controller nodes

Example:

gpio-controller@00000000 {
	compatible = "foo";
	reg = <0x00000000 0x1000>;
	gpio-controller; //必须有
	#gpio-cells = <2>; //必须有
	ngpios = <18>;
	gpio-line-names = "MMC-CD", "MMC-WP", "VDD eth", "RST eth", "LED R",
		"LED G", "LED B", "Col A", "Col B", "Col C", "Col D",
		"Row A", "Row B", "Row C", "Row D", "NMI button",
		"poweroff", "reset";
}

2.1) gpio- and pin-controller interaction

     Gpio-和pin controller的关联:Some or all of the GPIOs provided by a GPIO controller may be routed to pins on the package via a pin controller. This allows muxing those pins between GPIO and other functions.

基本概念已经理清楚了,小结:

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

     3如何使用?分为设备树中使用和代码中使用;

3.1设备树中使用

	//client device
    leds {
		compatible = "gpio-leds";
		pinctrl-names = "default"; //1种状态,default
		pinctrl-0 = <&pinctrl_leds>; //引脚defaul状态在pinctrl_leds定义

	};
************************************************************************
//pin controller
&iomuxc_snvs {
	pinctrl-names = "default_snvs";
	imx6ul-evk {
		pinctrl_leds: ledgrp {
		fsl,pins = <
			 MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03        0x000110A0
			>; //0x000110A0代表什么意思???
		};
	};
};

    搜索参考手册并没有找到这个变量,MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03,google一下找到https://github.com/Xilinx/linux-xlnx/blob/master/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h提到了这个变量的定义在linux-xlnx/arch/arm/boot/dts/imx6ull-pinfunc-snvs.h中,好吧和.dts在一个文件夹中,看下它的具体内容:

#ifndef __DTS_IMX6ULL_PINFUNC_SNVS_H
#define __DTS_IMX6ULL_PINFUNC_SNVS_H
/*
 * The pin function ID is a tuple of
 * 
 */
#define MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03  0x0014 0x0058 0x0000 0x5 0x0//后面这一串是什么意思???

#endif /* __DTS_IMX6ULL_PINFUNC_SNVS_H */

    根据ZDYZ的手册分析下:PAD_SNVS_TAMPER3的复用功能就是GPIO5_IO03,后面5个配置值分别对应

    0x0014:mux_reg寄存器偏移地址,设备树中的 iomuxc_snvs节点就是 iomuxc_snvs外设对应的节点,根 据 其 reg 属 性 可 知 iomuxc_snvs外 设 寄 存 器 起 始 地 址 为 0x02290000。因此0x02290000+0x0014 = 0x02290014,即IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3的地址。

iomuxc_snvs: iomuxc-snvs@02290000 {
				compatible = "fsl,imx6ull-iomuxc-snvs";
				reg = <0x02290000 0x10000>;
			};

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

0x0058:conf_reg 寄存器偏移地址,和 mux_reg 一样, 0x02290000+0x0058=0x02290058,即IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3的地址。

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

    0x0000:input_reg 寄存器偏移地址,有些外设有 input_reg 寄存器,有 input_reg 寄存器的外设需要配置 input_reg 寄存器。没有的话就不需要设置。

    0x5:mux_reg 寄 存 器 值 , 在 这 里 就 相 当 于 设 置IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 寄存器为 0x5,也即是设置 PAD_SNVS_TAMPER3这个 PIN 复用为 GPIO5_IO03。

    0x0:input_reg 寄存器值,在这里无效。

    这就是对宏分析,发现并没有conf_reg寄存器的值, config_reg 寄存器是设置一个PIN 的电气特性的,这么重要的寄存器怎么没有值呢?回到示例代码中, 0x000110A0 就是 conf_reg 寄存器值!此值由用户自行设置,通过此值来设置一个 IO 的上 /下拉、驱动能力和速度等。在这里就相当于设置寄存器IOMUXC_SNVS_SW_PAD_CTL_PAD_SNVS_TAMPER3的值为 0x000110A0 ,即0b0001,0001,0000,1010,0000‬,具体代表什么意思看下参考手册。

3.2驱动代码中使用

    也就是 GPIO 子系统的接口函数是什么?GPIO 子系统有两套接口: 基于描述符的(descriptor-based)、老的(legacy)。前者的函数都有前缀“gpiod_”,它使用 gpio_desc 结构体来表示一个引脚;后者的函数都有前缀“gpio_”,它使用一个整数来表示一个引脚。要操作一个引脚,首先要 get 引脚,然后设置方向,读值、写值。

第七章 驱动程序开发-LED驱动-7.10.2 gpio子系统_第4张图片

    “在 GPIO 子系统中,每注册一个 GPIO Controller 时会确定它的“base number”,那么这个控制器里的第 n 号引脚的号码就是: base number + n。但是如果硬件有变化、设备树有变化,这个 base number 并不能保证是固定的,应该查看 sysfs 来确定 base number。”

3.3sysfs 中的访问方法

    这一块内容再补充。

 

 

 

 

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