第五十七讲 GPIO子系统
文章目录
一、前言
很抱歉,前面都没怎么更新!!!
二、GPIO 子系统
1、GPIO
上图是在 ebf_linux_kernel/arch/arm/boot/dts/imx6ull.dtsi
文件里面截取的一段代码。aliases 的翻译过来是别名的意思,这里以 gpio0 为例,将 gpio0 取别名为 gpio1。
gpio1: gpio@209c000 {
compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
reg = <0x209c000 0x4000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_GPIO1>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-ranges = <&iomuxc 0 23 10>, <&iomuxc 10 17 6>,
<&iomuxc 16 33 16>;
};
上面是 gpio1 的一些属性,这个有跟 gpio 子系统做匹配的作用。
- compatible 属性是操作系统用来决定绑定设备驱动的关键因素,它是一个字符串列表,格式为
<制造商>,<型号>
。其余的字符串表示与之兼容的设备。 - reg 属性是寄存器组,gpio1 的起始地址为 0x209c000
- interrupts 描述 gpio 中断相关内容
- clocks 初始化 gpio 时钟
- gpio-controller 表明 gpio1 是 gpio 的控制器
- #gpio-cells = <2> 表示用两个 cell 描述一个 gpio 引脚
- interrupt-controller 表示 gpio1 节点是个中断控制器
- gpio-ranges gpio 编号转换为 pin 编号
2、新增一个 gpio 节点
rgb_led{
#address-cells = <1>;
#size-cells = <1>;
pinctrl-names = "default";
compatible = "fire,rgb-led";
pinctrl-0 = <&pinctrl_rgb_led>;
rgb_led_red = <&gpio1 4 GPIO_ACTIVE_LOW>;
rgb_led_green = <&gpio4 20 GPIO_ACTIVE_LOW>;
rgb_led_blue = <&gpio4 19 GPIO_ACTIVE_LOW>;
status = "okay";
};
- compatible:属性值,与 led 平台驱动做匹配
- pinctrl-0:指定 RGB 灯的引脚 pinctrl 信息
- rgb_led_red:自定义属性
- &gpio1 4:表示GPIO_PIN4(gpio1 表示 GPIO组 4表示GPIO编号)
- GPIO_ACTIVE_LOW:低电平有效
注意:
以上这一段依赖另外一段代码,如果加上报错误
Reference to non-existent node or label "pinctrl_rgb_led"
需要加上
pinctrl_rgb_led:rgb_led{
fsl,pins=<
MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x000010B1
MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x000010B1
MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x000010B1
>;
};
3、常用 API 讲解
-
获取 GPIO 编号函数 of_get_named_gpio
gpio 子系统有很多函数会用到 gpio 编号,可以通过
of_get_named_gpio
函数获取/** * of_get_named_gpio() - Get a GPIO number to use with GPIO API * @np: device node to get GPIO from * @propname: Name of property containing gpio specifier(s) * @index: index of the GPIO * * Returns GPIO number to use with Linux generic GPIO API, or one of the errno * value on the error condition. */ static inline int of_get_named_gpio(struct device_node *np, const char *propname, int index)
-
GPIO 申请函数 gpio_request
申请 GPIO
/* 参数: • gpio: 要申请的 GPIO 编号,该值是函数 of_get_named_gpio 的返回值。 • label: 引脚名字,相当于为申请得到的引脚取了个别名。 返回值: • 成功: 返回 0, • 失败: 返回负数。 */ static inline int gpio_request(unsigned gpio, const char *label);
-
GPIO 释放函数
/*
gpio_free 函数与 gpio_request 是一对相反的函数,一个申请,一个释放。一个 GPIO 只能被申请
一次,当不再使用某一个引脚时记得将其释放掉。
参数:
• gpio:要释放的 GPIO 编号。
返回值:无
*/
static inline void gpio_free(unsigned gpio);
注意:摘自 /ebf_linux_kernel/Documentation/translations/zh_CN/gpio.txt
(这里仅摘抄了部分,更多的可以查阅文档,里面介绍的很详细)
声明和释放 GPIO
----------------------------
为了有助于捕获系统配置错误,定义了两个函数。
/* 申请 GPIO, 返回 0 或负的错误代码.
* 非空标签可能有助于诊断.
*/
int gpio_request(unsigned gpio, const char *label);
/* 释放之前声明的 GPIO */
void gpio_free(unsigned gpio);
将无效的 GPIO 编码传递给 gpio_request()会导致失败,申请一个已使用这个
函数声明过的 GPIO 也会失败。gpio_request()的返回值必须检查。你应该在
进程上下文中调用这些函数。然而,对于自旋锁安全的 GPIO,在板子启动的早期、
进入进程之前是可以申请的。
这个函数完成两个基本的目标。一是标识那些实际上已作为 GPIO 使用的信号线,
这样便于更好地诊断;系统可能需要服务几百个可用的 GPIO,但是对于任何一个
给定的电路板通常只有一些被使用。另一个目的是捕获冲突,查明错误:如两个或
更多驱动错误地认为他们已经独占了某个信号线,或是错误地认为移除一个管理着
某个已激活信号的驱动是安全的。也就是说,申请 GPIO 的作用类似一种锁机制。
某些平台可能也使用 GPIO 作为电源管理激活信号(例如通过关闭未使用芯片区和
简单地关闭未使用时钟)。
对于 GPIO 使用 pinctrl 子系统已知的引脚,子系统应该被告知其使用情况;
一个 gpiolib 驱动的 .request()操作应调用 pinctrl_gpio_request(),
而 gpiolib 驱动的 .free()操作应调用 pinctrl_gpio_free()。pinctrl
子系统允许 pinctrl_gpio_request()在某个引脚或引脚组以复用形式“属于”
一个设备时都成功返回。
任何须将 GPIO 信号导向适当引脚的引脚复用硬件的编程应该发生在 GPIO
驱动的 .direction_input()或 .direction_output()函数中,以及
任何输出 GPIO 值的设置之后。这样可使从引脚特殊功能到 GPIO 的转换
不会在引脚产生毛刺波形。有时当用一个 GPIO 实现其信号驱动一个非 GPIO
硬件模块的解决方案时,就需要这种机制。
某些平台允许部分或所有 GPIO 信号使用不同的引脚。类似的,GPIO 或引脚的
其他方面也需要配置,如上拉/下拉。平台软件应该在对这些 GPIO 调用
gpio_request()前将这类细节配置好,例如使用 pinctrl 子系统的映射表,
使得 GPIO 的用户无须关注这些细节。
还有一个值得注意的是在释放 GPIO 前,你必须停止使用它。
-
GPIO 输出设置函数 gpio_direction_output
用于将引脚设置为输出模式
/* 函数参数: • gpio: 要设置的 GPIO 的编号。 • value: 输出值,1,表示高电平。0 表示低电平。 返回值: • 成功: 返回 0 • 失败: 返回负数 */ static inline int gpio_direction_output(unsigned gpio , int value);
-
GPIO 输入设置函数 gpio_direction_input
用于将引脚设置为输入模式
/* 函数参数: • gpio: 要设置的 GPIO 的编号。 返回值: • 成功: 返回 0 • 失败: 返回负数。 */ static inline int gpio_direction_input(unsigned gpio)
-
获取 GPIO 引脚值函数 gpio_get_value
用于获取引脚的当前状态。无论引脚被设置为输出或者输入都可以用该函数获取引脚的当前状
态。/* 函数参数: • gpio: 要获取的 GPIO 的编号。 返回值: • 成功: 获取得到的引脚状态 • 失败: 返回负数 */ static inline int gpio_get_value(unsigned gpio)
-
设置 GPIO 输出值 gpio_set_value
该函数只用于那些设置为输出模式的 GPIO.
/* 函数参数 • gpio:设置的 GPIO 的编号。 • value:设置的输出值,为 1 输出高电平,为 0 输出低电平。 返回值: • 成功: 返回 0 • 失败: 返回负数 */ static inline int gpio_set_value(unsigned gpio, int value)
三、 GPIO 子系统实验
1、设备树编译
- 在文件
imx6ull-mmc-npi.dts
添加以下代码
rgb_led{
#address-cells = <1>;
#size-cells = <1>;
pinctrl-names = "default";
compatible = "fire,rgb-led";
pinctrl-0 = <&pinctrl_rgb_led>;
rgb_led_red = <&gpio1 4 GPIO_ACTIVE_LOW>;
rgb_led_green = <&gpio4 20 GPIO_ACTIVE_LOW>;
rgb_led_blue = <&gpio4 19 GPIO_ACTIVE_LOW>;
status = "okay";
};
-
增加 pinctl 节点
pinctrl_rgb_led:rgb_led{ fsl,pins=< MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x000010B1 MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x000010B1 MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x000010B1 >; };
-
编译设备树
make ARCH=arm -j1 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
-
将编译好的 debo 移动到开发板上面
-
替换开发板上面的
imx6ull-mmc-npi.dtbo
文件sudo mv imx6ull-mmc-npi.dtb /usr/lib/linux-image-4.19.35-imx6/
-
重新启动开发板
sudo reboot
2、 编写测试代码
Makefile
KERNEL_DIR=../../ebf_linux_kernel_6ull_depth1/build_image/build/
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH CROSS_COMPILE
obj-m := rgb_led.o
all:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
.PHONE:clean copy
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
rgb_led.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include "rgb_led.h"
int led_red_name, led_green_name, led_blue_name;
int rgbLedOpen (struct inode *node, struct file *file)
{
printk("\n open form driver \n");
return 0;
}
ssize_t rgbLedWrite (struct file *file, const char __user *usr, size_t size, loff_t *loff)
{
char lRecvBuf[10] = {0};
printk("<1> Led write");
if(size >= 10)
{
printk("<1> size error!");
return -1;
}
if(copy_from_user(lRecvBuf, usr, size) < 0)
{
printk("<1> copy error!");
return -1;
}
printk("<1> recv is %s", lRecvBuf);
if(strstr(lRecvBuf, "red on") != NULL)
{
gpio_set_value(led_red_name, 0);
}
else if(strstr(lRecvBuf, "red off") != NULL)
{
gpio_set_value(led_red_name, 1);
}
else if(strstr(lRecvBuf, "green on") != NULL)
{
gpio_set_value(led_green_name, 0);
}
else if(strstr(lRecvBuf, "green off") != NULL)
{
gpio_set_value(led_green_name, 1);
}
else if(strstr(lRecvBuf, "blue on") != NULL)
{
gpio_set_value(led_blue_name, 0);
}
else if(strstr(lRecvBuf, "blue off") != NULL)
{
gpio_set_value(led_blue_name, 1);
}
else
{
printk("error data %s", lRecvBuf);
gpio_set_value(led_red_name, 1);
gpio_set_value(led_green_name, 1);
gpio_set_value(led_blue_name, 1);
}
return size;
}
struct cdev gRGBLedCdev =
{
.owner = THIS_MODULE,
};
struct file_operations gRGBLedFp =
{
.owner = THIS_MODULE,
.open = rgbLedOpen,
.write = rgbLedWrite,
};
/**
* @brief Get the Gpio Named object
*
* @param vDeviceNode
* @return int
*/
int GetGpioNamed(struct device_node *vDeviceNode){
// get name
led_red_name = of_get_named_gpio(vDeviceNode, "rgb_led_red", 0);
if(led_red_name < 0){
printk("<1> of_get_named_gpio rgb_led_red failed! \n");
return -1;
}
led_blue_name = of_get_named_gpio(vDeviceNode, "rgb_led_blue", 0);
if(led_red_name < 0){
printk("<1> of_get_named_gpio rgb_led_blue failed! \n");
return -1;
}
led_green_name = of_get_named_gpio(vDeviceNode, "rgb_led_green", 0);
if(led_red_name < 0){
printk("<1> of_get_named_gpio rgb_led_green failed! \n");
return -1;
}
return 0;
}
static int rgbProbe(struct platform_device *pdv)
{
struct device_node *pRGBLedDeviceNode;
/*查找设备树节点*/
printk("<1> path is rgb_led");
pRGBLedDeviceNode = of_find_node_by_path("/rgb_led");
if(pRGBLedDeviceNode == NULL)
{
printk("<1> Find node by path failed! \n");
return -1;
}
// get name
// if(0 != GetGpioNamed(pRGBLedDeviceNode)){
// printk("<1> of_get_named_gpio failed!\n");
// return -1;
// }
led_red_name = of_get_named_gpio(pRGBLedDeviceNode, "rgb_led_red", 0);
if(led_red_name < 0){
printk("<1> of_get_named_gpio rgb_led_red failed! \n");
return -1;
}
led_blue_name = of_get_named_gpio(pRGBLedDeviceNode, "rgb_led_blue", 0);
if(led_red_name < 0){
printk("<1> of_get_named_gpio rgb_led_blue failed! \n");
return -1;
}
led_green_name = of_get_named_gpio(pRGBLedDeviceNode, "rgb_led_green", 0);
if(led_red_name < 0){
printk("<1> of_get_named_gpio rgb_led_green failed! \n");
return -1;
}
// request gpio
// int nRet = gpio_request(led_red_name, "rgb_red");
// if(0 != nRet){
// printk("Request red gpio failed! %d\n", nRet);
// return -1;
// }
// if(0 != gpio_request(led_blue_name, "rgb_blue")){
// printk("Request blue gpio failed!\n");
// gpio_free(led_red_name);
// return -1;
// }
// if(0 != gpio_request(led_green_name, "rgb_green")){
// printk("Request green gpio failed!\n");
// gpio_free(led_red_name);
// gpio_free(led_blue_name);
// return -1;
// }
// set gpio direction
if(0 != gpio_direction_output(led_red_name, 1)){
printk("Set red direction failed!");
}
if(0 != gpio_direction_output(led_blue_name, 1)){
printk("Set blue direction failed!");
}
if(0 != gpio_direction_output(led_green_name, 1)){
printk("Set green direction failed!");
}
if( alloc_chrdev_region(&rgbDev, 0, 1, DEVICE_NAME) < 0)
{
printk("<1> alloc_chrdev_region failed \n");
return -1;
}
cdev_init(&gRGBLedCdev, &gRGBLedFp);
cdev_add(&gRGBLedCdev, rgbDev, 1);
rgbClass = class_create(THIS_MODULE, DEVICE_NAME);
device_create(rgbClass, NULL, rgbDev, NULL, DEVICE_NAME);
return 0;
}
static const struct of_device_id rgbLed[] =
{
{.compatible = "fire,rgb-led"},
{/* sentinel */}
};
struct platform_driver rgbPlatformDriver =
{
.probe = rgbProbe,
.driver =
{
.name = "rgb_led_platform",
.owner = THIS_MODULE,
.of_match_table = rgbLed,
},
};
static __init int RGBInit(void)
{
int driverState;
driverState = platform_driver_register(&rgbPlatformDriver);
printk(KERN_ALERT "\tDriverState is %d\n", driverState);
return 0;
}
static __exit void RGBExit(void)
{
}
module_init(RGBInit);
module_exit(RGBExit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yeyu");
MODULE_DESCRIPTION("RGBModule");
MODULE_ALIAS("RGBModule");
rgb_led.h
/*
* @LastEditors: 夜雨
* @Date: 2022-03-17 22:41:17
* @LastEditTime: 2022-03-19 12:23:54
* @FilePath: \code\kernel\012rgb_led\rgb_led.h
*/
#include <linux/of.h>
#include <asm/io.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/of_gpio.h>
#include <linux/io.h>
#include <linux/of_address.h>
#define DEVICE_NAME "rgb_led"
typedef struct
{
struct device_node *device_node;
void __iomem *virtual_CCM_CCGR;
void __iomem *virtual_IOMUXC_SW_MUX_CTL_PAD;
void __iomem *virtual_IOMUXC_SW_PAD_CTL_PAD;
void __iomem *virtual_DR;
void __iomem *virtual_GDIR;
}rgbLedStr;
dev_t rgbDev;
struct class * rgbClass;
rgbLedStr gRGBLedStr[3];
步骤
-
编译代码
make
-
将 rgb_led.ko 移动到开发板上面
-
加载模块
sudo insmod rgb_led.ko
-
查看模块是否加载成功(出现
rgb_led
代表成功)debian@npi:~/ftp$ ls /dev/r ram0 ram11 ram14 ram3 ram6 ram9 rtc ram1 ram12 ram15 ram4 ram7 random rtc0 ram10 ram13 ram2 ram5 ram8 rgb_led
3、点灯
红灯亮
debian@npi:~/ftp$ sudo sh -c "echo 'red on'>/dev/rgb_led"
[ 754.806648]
[ 754.806648] open form driver
[ 754.813186] <1> Led write
[ 754.813208] <1> recv is red on
红灯灭
debian@npi:~/ftp$ sudo sh -c "echo 'red off'>/dev/rgb_led"
[ 801.206930]
[ 801.206930] open form driver
[ 801.211582] <1> Led write
[ 801.211595] <1> recv is red off
蓝灯亮
debian@npi:~/ftp$ sudo sh -c "echo 'blue on'>/dev/rgb_led"
[ 1007.684984]
[ 1007.684984] open form driver
[ 1007.689639] <1> Led write
[ 1007.689651] <1> recv is blue on
蓝灯灭
debian@npi:~/ftp$ sudo sh -c "echo 'blue off'>/dev/rgb_led"
[ 890.756871] <1> size error!
[ 995.945819]
[ 995.945819] open form driver
[ 995.953263] <1> Led write
[ 995.953276] <1> recv is blue off
最后再说一句
这里绿灯灭的实验做不了,无法让绿灯灭
debian@npi:~/ftp$ sudo sh -c "echo 'green off'>/dev/rgb_led"
[ 1065.208778]
[ 1065.208778] open form driver
[ 1065.213431] <1> Led write
sh: 1: echo: echo: I/O error
猜测是冲突了
还有就是调用 gpio_request 会报错误 16
感兴趣的同学可以找找原因,但是这里就不多说了,不影响整体实验。
四、附录1(imx6ull-mmc-npi.dts)
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"
/ {
model = "Embedfire i.MX6ULL Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
aliases {
pwm0 = &pwm1;
pwm1 = &pwm2;
pwm2 = &pwm3;
pwm3 = &pwm4;
};
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;
};
};
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
reg_sd1_vmmc: regulator@1 {
compatible = "regulator-fixed";
regulator-name = "VSD_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio1 9 GPIO_ACTIVE_HIGH>;
off-on-delay = <20000>;
enable-active-high;
};
/*
reg_gpio_dvfs: regulator-gpio {
compatible = "regulator-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dvfs>;
regulator-min-microvolt = <1300000>;
regulator-max-microvolt = <1400000>;
regulator-name = "gpio_dvfs";
regulator-type = "voltage";
gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>;
states = <1300000 0x1 1400000 0x0>;
};
*/
};
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_led>;
led0: cpu {
label = "cpu";
gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
default-state = "on";
linux,default-trigger = "heartbeat";
};
};
/* External sound card */
sound: sound {
status = "disabled";
};
spi4: 74hc595 {
compatible = "spi-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi4>;
pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
status = "disabled";
gpio-sck = <&gpio5 11 0>;
gpio-mosi = <&gpio5 10 0>;
cs-gpios = <&gpio5 7 0>;
num-chipselects = <1>;
#address-cells = <1>;
#size-cells = <0>;
gpio_spi: gpio_spi@0 {
compatible = "fairchild,74hc595";
gpio-controller;
#gpio-cells = <2>;
reg = <0>;
registers-number = <1>;
registers-default = /bits/ 8 <0x57>;
spi-max-frequency = <100000>;
};
};
rgb_led{
#address-cells = <1>;
#size-cells = <1>;
pinctrl-names = "default";
compatible = "fire,rgb-led";
pinctrl-0 = <&pinctrl_rgb_led>;
rgb_led_red = <&gpio1 4 GPIO_ACTIVE_LOW>;
rgb_led_green = <&gpio4 20 GPIO_ACTIVE_LOW>;
rgb_led_blue = <&gpio4 19 GPIO_ACTIVE_LOW>;
status = "okay";
};
};
&cpu0 {
/*dc-supply = <®_gpio_dvfs>;*/
clock-frequency = <800000000>;
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <786432000>;
};
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
status = "okay";
};
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rmii";
phy-handle = <ðphy1>;
status = "okay";
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy0: ethernet-phy@2 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET_REF>;
clock-names = "rmii-ref";
};
ethphy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
micrel,led-mode = <1>;
clocks = <&clks IMX6UL_CLK_ENET2_REF>;
clock-names = "rmii-ref";
};
};
};
&gpc {
fsl,cpu_pupscr_sw2iso = <0xf>;
fsl,cpu_pupscr_sw = <0x0>;
fsl,cpu_pdnscr_iso2sw = <0x1>;
fsl,cpu_pdnscr_iso = <0x1>;
fsl,ldo-bypass = <0>; /* DCDC, ldo-enable */
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
pinctrl_rgb_led:rgb_led{
fsl,pins=<
MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x000010B1
MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x000010B1
MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x000010B1
>;
};
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
>;
};
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031
>;
};
pinctrl_enet2: enet2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031
>;
};
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
>;
};
/*
pinctrl_dvfs: dvfsgrp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x79
>;
};
*/
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10071
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
>;
};
pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170b9
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100b9
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9
>;
};
pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x170f9
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x100f9
MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170f9
MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170f9
MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170f9
MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170f9
>;
};
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10069
MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
>;
};
pinctrl_usdhc2_8bit: usdhc2grp_8bit {
fsl,pins = <
MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x10059
MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x17059
MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x17059
MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x17059
MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x17059
MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x17059
MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x17059
MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x17059
MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x17059
MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x17059
>;
};
pinctrl_usdhc2_8bit_100mhz: usdhc2grp_8bit_100mhz {
fsl,pins = <
MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100b9
MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170b9
MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170b9
MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170b9
MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170b9
MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170b9
MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170b9
MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170b9
MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170b9
MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170b9
>;
};
pinctrl_usdhc2_8bit_200mhz: usdhc2grp_8bit_200mhz {
fsl,pins = <
MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x100f9
MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x170f9
MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x170f9
MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x170f9
MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x170f9
MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x170f9
MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x170f9
MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x170f9
MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x170f9
MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x170f9
>;
};
pinctrl_led: ledgrp {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x1b0b0
>;
};
};
&iomuxc_snvs {
pinctrl-names = "default_snvs";
pinctrl-0 = <&pinctrl_hog_2>;
pinctrl_hog_2: hoggrp-2 {
fsl,pins = <
MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x80000000
>;
};
pinctrl_spi4: spi4grp {
fsl,pins = <
MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
>;
};
};
&snvs_pwrkey {
status = "okay";
};
&pxp {
status = "okay";
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
};
&usbotg1 {
dr_mode = "otg";
srp-disable;
hnp-disable;
adp-disable;
status = "okay";
};
&usbotg2 {
dr_mode = "host";
disable-over-current;
status = "okay";
};
&usbphy1 {
fsl,tx-d-cal = <106>;
};
&usbphy2 {
fsl,tx-d-cal = <106>;
};
&usdhc1 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc1>;
pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
no-1-8-v;
/*cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;*/
keep-power-in-suspend;
/*non-removable;*/
enable-sdio-wakeup;
vmmc-supply = <®_sd1_vmmc>;
status = "okay";
};
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
non-removable;
status = "okay";
};