Posts OpenWrt GPIO(MT7688AN)
Post
Cancel

OpenWrt GPIO(MT7688AN)

1. 设备树

在开发板上查看引脚使用情况:

1
2
3
4
5
6
7
8
9
10
11
root@OpenWrt:~# cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-31, parent: platform/10000600.gpio, 10000600.gpio:
 gpio-6   (                    |reboot              ) in  hi

gpiochip1: GPIOs 32-63, parent: platform/10000600.gpio, 10000600.gpio:
 gpio-38  (                    |reset               ) in  hi
 gpio-41  (                    |skw92a:green:wps    ) out hi
 gpio-42  (                    |skw92a:green:wlan   ) out hi

gpiochip2: GPIOs 64-95, parent: platform/10000600.gpio, 10000600.gpio:
root@OpenWrt:~#

设备树位于 “openwrt-19.07.2/target/linux/ramips/dts” 目录下,手中的开发板对应的设备树文件中有如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
gpio-leds {
	compatible = "gpio-leds";

	led_power: wps {
		label = "skw92a:green:wps";
		gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
	};

	wlan {
		label = "skw92a:green:wlan";
		gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
	};
};

可以看出设备树文件中 led_power: wps 对应开发板上的 gpio-41wlan 对应开发板上的 gpio-42

设备树文件中的 gpios = <&gpio1 9 GPIO_ACTIVE_LOW> 是该 gpio 口信息的属性值,格式为 <&gpio控制器节点名 具体gpio口的标识符>,其中,gpio 的标识符是由多个数字组成, 数字的个数由所用的 gpio 控制器节点里的 #gpio-cells 属性值指定的,该属性值可以在开发板所包含的设备树文件 mt7628an.dtsi 中找到。

“openwrt-19.07.2/target/linux/ramips/dts/mt7628an.dtsi” 里关于gpio控制器的节点信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
gpio@600 {
	#address-cells = <1>;
	#size-cells = <0>;

	compatible = "mtk,mt7628-gpio", "mtk,mt7621-gpio";
	reg = <0x600 0x100>;

	interrupt-parent = <&intc>;
	interrupts = <6>;

	gpio0: bank@0 {
		reg = <0>;
		compatible = "mtk,mt7621-gpio-bank";
		gpio-controller;
		#gpio-cells = <2>; 
	};

	gpio1: bank@1 {
		reg = <1>;
		compatible = "mtk,mt7621-gpio-bank";
		gpio-controller;
		#gpio-cells = <2>;
	};

	gpio2: bank@2 {
		reg = <2>;
		compatible = "mtk,mt7621-gpio-bank";
		gpio-controller;
		#gpio-cells = <2>;
	};
};

其中,#gpio-cells = <2> 表明每个 gpio 口的标识符由 2 个数字来识别。从下面的帮助文档可以得知,第 1 个数字表示引脚在所属 gpio controller 内的编号, 第 2 个数字是标志位(高电平或低电平)。其中,高低电平定义在 “openwrt-19.07.2/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.171/include/dt-bindings/gpio/gpio.h”中。

帮助文档:

  • openwrt-19.07.2/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.171/Documentation/devicetree/bindings/gpio/gpio.txt

文档中有如下内容:

Every GPIO controller node must contain both an empty “gpio-controller” property, and a #gpio-cells integer property, which indicates the number of cells in a gpio-specifier.

Some system-on-chips (SoCs) use the concept of GPIO banks. A GPIO bank is an instance of a hardware IP core on a silicon die, usually exposed to the programmer as a coherent range of I/O addresses. Usually each such bank is exposed in the device tree as an individual gpio-controller node, reflecting the fact that the hardware was synthesized by reusing the same IP block a few times over.

Optionally, a GPIO controller may have a “ngpios” property. This property indicates the number of in-use slots of available slots for GPIOs. The typical example is something like this: the hardware register is 32 bits wide, but only 18 of the bits have a physical counterpart. The driver is generally written so that all 32 bits can be used, but the IP block is reused in a lot of designs, some using all 32 bits, some using 18 and some using 12. In this case, setting “ngpios = <18>;” informs the driver that only the first 18 GPIOs, at local offset 0 .. 17, are in use.

结合 MT7688_Datasheet_v1_4.pdf 5.8.4 一节可以看出,MT7688 有 3 个 gpio 控制器,每个控制器的 ngpios 属性是 32:

gpio_register

引脚的编号和设备树中的标识符关系如下:

引脚编号 = 所属控制器基数 * ngpios + 在所属控制寄存器中对应的位数

以前面的设备树文件中的 gpio 标识符 <&gpio1 9 GPIO_ACTIVE_LOW> 来举例,对应的引脚为 1 * 32 + 9,即 gpio-41。

2. 使用 GPIO

引脚的复用功能定义在 openwrt-19.07.2/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-4.14.171/arch/mips/ralink/mt7620.c 文件中,例如:

1
2
3
4
5
6
static struct rt2880_pmx_func gpio_grp_mt7628[] = {
	FUNC("pcie", 3, 11, 1),
	FUNC("refclk", 2, 11, 1),
	FUNC("gpio", 1, 11, 1),
	FUNC("gpio", 0, 11, 1),	/* "gpio" 使用的 gpio 从 GPIO#11 开始,共 1 个引脚 */
};

数组 mt7628an_pinmux_data 中包含了所有的组。

如果想使用开发板上的 GPIO0 引脚,在 MT7688_Datasheet_v1_4.pdf 中可以看到 GPIO0 对应的引脚是 GPIO#11

GPIO0

1
2
3
4
5
6
7
8
# 使用 GPIO#11
echo "11" > /sys/class/gpio/export
# 设置方向为输出
echo "out" > /sys/class/gpio/gpio11/direction
# 输出高电平
echo "1" > /sys/class/gpio/gpio11/value
# 输出低电平
echo "0" > /sys/class/gpio/gpio11/value

如果想使用其他引脚,可能需要通过设备树文件修改端口复用功能,参考 [4]

参考

[1] OpenWRT GPIO 口配置

[2] OpenWrt之GPIO操作

[3] Linux驱动之GPIO子系统和pinctrl子系统

[4] openwrt gpio控制与使用

This post is licensed under CC BY 4.0 by the author.