概述
开发板:tiny4412SDK + S702 + 4GB Flash
要移植的内核版本:Linux-4.4.0 (支持device tree)
u-boot版本:友善之臂自带的 U-Boot 2010.12
busybox版本:busybox 1.25
目标:
学习设备树中GPIO资源的使用,实现按键中断简单驱动程序。
原理图:
tiny4412 底板上有4颗按键,分别为连接在 GPX3_2、GPX3_3、GPX3_4、GPX3_5 ,引脚状态常高。
设备树:
interrupt_demo: interrupt_demo {
compatible = "tiny4412,interrupt_demo";
tiny4412,int_gpio1 = <&gpx3 2 GPIO_ACTIVE_HIGH>;
tiny4412,int_gpio2 = <&gpx3 3 GPIO_ACTIVE_HIGH>;
tiny4412,int_gpio3 = <&gpx3 4 GPIO_ACTIVE_HIGH>;
tiny4412,int_gpio4 = <&gpx3 5 GPIO_ACTIVE_HIGH>;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
<&gpx3 2 GPIO_ACTIVE_HIGHT> 代表什么含义呢?
Eg: <&gpx2 6 0>
<[phandle of the gpio controller node]
[pin number within the gpio controller]
[flags]>
Values for gpio specifier:
- Pin number: is a value between 0 to 7.
- Flags: 0 - Active High 1 - Active Low
- &gpx3 引用 gpx3 这个节点,代表这个 GPIO 是属于控制器 gpx3
- 2 则表示gpx3 这组管脚中的哪一个,gpx3_2
- GPIO_ACTIVE_HIGHT 则表示引脚状态为常高的
驱动程序:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
typedef struct
{
int gpio;
int irq;
char name[20];
}int_demo_data_t;
static irqreturn_t int_demo_isr(int irq, void *dev_id)
{
int_demo_data_t *data = dev_id;
printk("%s enter, %s: gpio:%d, irq: %dn", __func__, data->name, data->gpio, data->irq);
return IRQ_HANDLED;
}
static int int_demo_probe(struct platform_device *pdev) {
struct device *dev = &pdev->dev;
int irq_gpio = -1;
int irq = -1;
int ret = 0;
int i = 0;
int_demo_data_t *data = NULL;
printk("%s enter.n", __func__);
if (!dev->of_node) {
dev_err(dev, "no platform data.n");
goto err1;
}
data = devm_kmalloc(dev, sizeof(*data)*4, GFP_KERNEL);
if (!data) {
dev_err(dev, "no memory.n");
goto err0;
}
#if 1
for (i = 3; i >= 0; i--) {
sprintf(data[i].name, "tiny4412,int_gpio%d", i+1);//名字是我们自己填充的,并不是获取到的
#else
for (i = 0; i < 4; i++) {
#endif
irq_gpio = of_get_named_gpio(dev->of_node, data[i].name, 0);//通过名字获取gpio
if (irq_gpio < 0) {
dev_err(dev, "Looking up %s property in node %s failed %dn",
data[i].name, dev->of_node->full_name, irq_gpio);
goto err1;
}
data[i].gpio = irq_gpio;
irq = gpio_to_irq(irq_gpio); //将gpio转换成对应的中断号
if (irq < 0) {
dev_err(dev,
"Unable to get irq number for GPIO %d, error %dn",
irq_gpio, irq);
goto err1;
}
data[i].irq = irq;
printk("%s: gpio: %d ---> irq (%d)n", __func__, irq_gpio, irq);
//注册中断
ret = devm_request_any_context_irq(dev, irq, int_demo_isr, IRQF_TRIGGER_FALLING, data[i].name, data+i);
if (ret < 0) {
dev_err(dev, "Unable to claim irq %d; error %dn",
irq, ret);
goto err1;
}
}
return 0;
err1:
devm_kfree(dev, data);
err0:
return -EINVAL;
}
static int int_demo_remove(struct platform_device *pdev) {
printk("%s enter.n", __func__);
return 0;
}
static const struct of_device_id int_demo_dt_ids[] = {
{ .compatible = "tiny4412,interrupt_demo", },
{},
};
MODULE_DEVICE_TABLE(of, int_demo_dt_ids);
static struct platform_driver int_demo_driver = {
.driver = {
.name = "interrupt_demo",
.of_match_table = of_match_ptr(int_demo_dt_ids),
},
.probe = int_demo_probe,
.remove = int_demo_remove,
};
static int __init int_demo_init(void)
{
int ret;
ret = platform_driver_register(&int_demo_driver);
if (ret)
printk(KERN_ERR "int demo: probe failed: %dn", ret);
return ret;
}
module_init(int_demo_init);
static void __exit int_demo_exit(void)
{
platform_driver_unregister(&int_demo_driver);
}
module_exit(int_demo_exit);
MODULE_LICENSE("GPL");
在M6G2C平台下的应用
设备树文件:
/*
* Copyright (C) 2015 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 "imx6g2c-base.dtsi"
/ {
model = "ZLG EPC-M6G2C Board";
compatible = "fsl,imx6ul-14x14-evk", "fsl,imx6ul";
chosen {
stdout-path = &uart1;
};
memory {
reg = <0x80000000 0x10000000>; /* 256M */
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x2000000>; /* 32M */
linux,cma-default;
};
};
watchdog: watchdog {
compatible = "cat82x-gpio-wdt";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wdt>;
gpios = <&gpio5 0 0>;
hw_margin_ms = <700>;
};
backlight {
compatible = "pwm-backlight";
pwms = <&pwm5 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
};
beep {
compatible = "pwm-leds";
beep-leds {
label = "beeper-pwm";
pwms = <&pwm6 0 400000>;
max-brightness = <127>;
};
};
pxp_v4l2 {
compatible = "fsl,imx6ul-pxp-v4l2", "fsl,imx6sx-pxp-v4l2", "fsl,imx6sl-pxp-v4l2";
status = "okay";
};
sound-mqs {
compatible = "fsl,imx-audio-mqs";
model = "mqs-audio";
cpu-dai = <&sai1>;
asrc-controller = <&asrc>;
audio-codec = <&mqs>;
};
leds {
compatible = "gpio-leds";
green-led {
label = "led-run";
gpios = <&gpio4 16 1>;
linux,default-trigger = "heartbeat";
};
red-led {
label = "led-err";
gpios = <&gpio4 14 1>;
default-state = "keep";
};
};
/* add by Codebreaker */
regulators {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <0>;
reg_3p3v: 3p3v {
compatible = "regulator-fixed";
regulator-name = "3P3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
reg_1p8v: 1p8v {
compatible = "regulator-fixed";
regulator-name = "1P8V";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
};
i2c_gpio: analog-i2c {
compatible = "i2c-gpio";
gpios = <&gpio5 8 0 /* sda */
&gpio5 7 0 /* scl */
>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c>;
i2c-gpio,delay-us = <5>;
i2c-gpio,timeout-ms = <100>;
#address-cells = <1>;
#size-cells = <0>;
rtc@51 {
compatible = "nxp,pcf85063";
reg = <0x51>;
};
adv7180: adv7180@20 {
compatible = "adv,adv7180";
reg = <0x20>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_csi0>;
clocks = <&clks IMX6UL_CLK_CSI>;
clock-names = "csi_mclk";
DOVDD-supply = <®_3p3v>;
AVDD-supply = <®_1p8v>;
DVDD-supply = <®_1p8v>;
PVDD-supply = <®_1p8v>;
pwn-gpios = <&gpio5 6 0>;
rst-gpios = <&gpio5 5 0>;
csi_id = <0>;
mclk = <22000000>;
mclk_source = <0>;
cvbs = <1>;
status = "disabled";
port {
adv7180_ep: adv-endpoint {
remote-endpoint = <&csi1_ep>;
};
};
};
};
interrupt_demo:interrupt-demo{
compatible = "interrupt_demo";
tiny4412,int_gpio1 = <&gpio3 4 GPIO_ACTIVE_HIGH>;
};
};
&cpu0 {
arm-supply = <®_arm>;
soc-supply = <®_soc>;
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <786432000>;
};
&csi {
status = "disabled";
port {
csi1_ep: endpoint {
remote-endpoint = <&adv7180_ep>;
};
};
};
&sai1 {
assigned-clocks = <&clks IMX6UL_CLK_SAI1_SEL>,
<&clks IMX6UL_CLK_SAI1>;
assigned-clock-parents = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <0>, <24576000>;
status = "okay";
};
&mqs {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mqs>;
clocks = <&clks IMX6UL_CLK_SAI1>;
clock-names = "mclk";
status = "okay";
};
&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@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
ethphy1: ethernet-phy@5 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <5>;
};
};
};
&flexcan1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan1>;
status = "okay";
};
&flexcan2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexcan2>;
status = "okay";
};
&gpc {
fsl,cpu_pupscr_sw2iso = <0x1>;
fsl,cpu_pupscr_sw = <0x0>;
fsl,cpu_pdnscr_iso2sw = <0x1>;
fsl,cpu_pdnscr_iso = <0x1>;
/* fsl,wdog-reset = <1>;*/ /* watchdog select of reset source */
fsl,ldo-bypass = <0>; /* use ldo-bypass, u-boot will check it and configure */
};
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
display = <&display0>;
status = "okay";
display0: display {
bits-per-pixel = <16>;
bus-width = <16>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9000000>;
hactive = <480>;
vactive = <272>;
hfront-porch = <8>;
hback-porch = <43>;
hsync-len = <4>;
vback-porch = <8>;
vfront-porch = <8>;
vsync-len = <6>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
&pwm5 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm5>;
status = "okay";
};
&pwm6 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm6>;
status = "okay";
};
&pxp {
status = "okay";
};
&tsc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_tsc>;
xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
measure_delay_time = <0xffff>;
pre_charge_time = <0xfff>;
status = "okay";
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
status = "okay";
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
status = "okay";
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart4>;
status = "okay";
};
&uart5 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart5>;
status = "okay";
};
&uart6 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart6>;
status = "okay";
};
&uart7 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart7>;
status = "okay";
};
&uart8 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart8>;
status = "okay";
};
&usbotg1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg1>;
dr_mode = "otg";
hnp-disable;
srp-disable;
adp-disable;
status = "okay";
};
&usbotg2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotg2>;
dr_mode = "host";
disable-over-current;
status = "okay";
};
&usbphy1 {
tx-d-cal = <0x5>;
};
&usbphy2 {
tx-d-cal = <0x5>;
};
&usdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc1>;
no-1-8-v;
cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
keep-power-in-suspend;
enable-sdio-wakeup;
status = "okay";
};
&usdhc2 {
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2>;
pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
keep-power-in-suspend;
enable-sdio-wakeup;
wifi-host;
};
&adc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_adc1>;
num-channels = <10>;
status = "okay";
};
&gpmi {
pinctrl-names = "defalut";
pinctrl-0 = <&pinctrl_gpmi_nand_1>;
status = "okay";
nand-on-flash-bbt;
partition@0 {
label = "u-boot";
reg = <0x0000000 0x400000>; /* 4M */
};
partition@400000 {
label = "dtb";
reg = <0x400000 0x100000>; /* 1M */
};
partition@500000 {
label = "kernel-0";
reg = <0x500000 0x800000>; /* 8M */
};
partition@d00000 {
label = "kernel-1";
reg = <0xd00000 0x800000>; /* 8M */
};
partition@1500000 {
label = "logo";
reg = <0x1500000 0x400000>; /* 4M */
};
partition@1900000 {
label = "rootfs";
reg = <0x1900000 0x4900000>; /* 73M */
};
partition@5900000 {
label = "opt";
reg = <0x6200000 0x9e00000>; /* 158M */
};
};
/*&qspi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_qspi>;
status = "okay";
ddrsmp=<0>;
flash0: mr25h256@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "everspin,mr25h256", "mr25h256";
spi-max-frequency = <40000000>;
reg = <0>;
};
}; */
&ecspi1 {
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio4 26 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1_1 &pinctrl_ecspi1_cs_1>;
status = "okay";
flash: mx25l1653@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "rohm,dh2228fv"; /* spidev */
spi-max-frequency = <2000000>;
reg = <0>;
};
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;
imx6ul-evk {
pinctrl_hog_1: hoggrp-1 {
fsl,pins = <
MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x17059 /* err led */
MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x17059 /* run led */
MX6UL_PAD_LCD_RESET__GPIO3_IO04 0x17059 /* gpio3_4 */
MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x17059 /* gpio5_9 */
MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x17059 /* sys mode */
MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x17059 /* clr reg */
MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x17059 /* eth1_reset */
MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x17059 /* eth2_reset */
>;
};
pinctrl_wdt: wdtgrp {
fsl,pins = <
MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059 /* wdog */
>;
};
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_flexcan1: flexcan1grp{
fsl,pins = <
MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
>;
};
pinctrl_flexcan2: flexcan2grp{
fsl,pins = <
MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
>;
};
pinctrl_lcdif_dat: lcdifdatgrp {
fsl,pins = <
MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79
MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79
MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79
MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79
MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79
MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79
MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79
MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79
MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79
MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79
MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79
MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79
MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79
MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79
MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79
MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79
>;
};
pinctrl_lcdif_ctrl: lcdifctrlgrp {
fsl,pins = <
MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79
MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79
MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79
MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79
>;
};
pinctrl_pwm5: pwm5grp {
fsl,pins = <
MX6UL_PAD_LCD_DATA18__PWM5_OUT 0x110b0
>;
};
pinctrl_pwm6: pwm6grp {
fsl,pins = <
MX6UL_PAD_LCD_DATA19__PWM6_OUT 0x110b0
>;
};
pinctrl_mqs: mqsgrp {
fsl,pins = <
MX6UL_PAD_LCD_DATA22__MQS_RIGHT 0x11088
MX6UL_PAD_LCD_DATA23__MQS_LEFT 0x11088
>;
};
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x1b0b1
>;
};
pinctrl_uart2: uart2grp {
fsl,pins = <
MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
>;
};
pinctrl_uart3: uart3grp {
fsl,pins = <
MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x1b0b1
MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x1b0b1
>;
};
pinctrl_uart4: uart4grp {
fsl,pins = <
MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x1b0b1
MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x1b0b1
>;
};
pinctrl_uart5: uart5grp {
fsl,pins = <
MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x1b0b1
MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x1b0b1
>;
};
pinctrl_uart6: uart6grp {
fsl,pins = <
MX6UL_PAD_CSI_MCLK__UART6_DCE_TX 0x1b0b1
MX6UL_PAD_CSI_PIXCLK__UART6_DCE_RX 0x1b0b1
>;
};
pinctrl_uart7: uart7grp {
fsl,pins = <
MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x1b0b1
MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x1b0b1
>;
};
pinctrl_uart8: uart8grp {
fsl,pins = <
MX6UL_PAD_LCD_DATA20__UART8_DCE_TX 0x1b0b1
MX6UL_PAD_LCD_DATA21__UART8_DCE_RX 0x1b0b1
>;
};
pinctrl_usbotg1: usbotg1grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059
>;
};
pinctrl_usbotg2: usbotg2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO05__ANATOP_OTG2_ID 0x17059
>;
};
pinctrl_usdhc1: usdhc1grp {
fsl,pins = <
MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x10059
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
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x17059 /* SD1 WP */
>;
};
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17059
MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x17059
MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17059
MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17059
MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17059
MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17059
>;
};
pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
fsl,pins = <
MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x170b9
MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x170b9
MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x170b9
MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x170b9
MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x170b9
MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x170b9
>;
};
pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
fsl,pins = <
MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x170f9
MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x170f9
MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x170f9
MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x170f9
MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x170f9
MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x170f9
>;
};
pinctrl_tsc: tscgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0
MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0
MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0
MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0
>;
};
pinctrl_adc1: adc1grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO08__GPIO1_IO08 0xb0 /* adc 8 */
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0xb0 /* adc 9 */
>;
};
pinctrl_gpmi_nand_1: gpmi-nand-1 {
fsl,pins = <
MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0xb0b1
MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0xb0b1
MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0xb0b1
MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0xb0b1
MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0xb0b1
MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0xb0b1
MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0xb0b1
MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0xb0b1
MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0xb0b1
MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0xb0b1
MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0xb0b1
MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0xb0b1
MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0xb0b1
MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0xb0b1
MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0xb0b1
>;
};
pinctrl_ecspi1_cs_1: ecspi1_cs_grp-1 {
fsl,pins = <
MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x17059
>;
};
pinctrl_ecspi1_1: escpi1grp {
fsl,pins = <
MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x100b1
MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x100b1
MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x100b1
>;
};
pinctrl_csi0: csi0grp {
fsl,pins = <
MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x1b088
MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x1b088
MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x1b088
MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x1b088
MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x1b088
MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x1b088
MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x1b088
MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x1b088
MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x1b088
MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x1b088
MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x1b088
MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x1b088
MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x17059 /* csi_reset */
MX6UL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x17059 /* csi_en */
>;
};
pinctrl_i2c: i2cgrp {
fsl,pins = <
MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x4001b8b0 /*scl */
MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x4001b8b0 /*sda */
>;
};
pinctrl_wifi: wifigrp {
fsl,pins = <
MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x17059 /* WL_REG_ON */
MX6UL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x17059 /* WL_HOST_WK*/
>;
};
pinctrl_blueth: bluethgrp {
fsl,pins = <
MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS 0x1b0b1
MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x1b0b1
MX6UL_PAD_LCD_DATA20__GPIO3_IO25 0x17059 /* BT_WAKE */
MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x17059 /* BT_RST_N */
>;
};
/* pinctrl_qspi: qspigrp {
fsl,pins = <
MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x70a1
MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x70a1
MX6UL_PAD_NAND_DATA04__QSPI_B_DATA02 0x70a1
MX6UL_PAD_NAND_DATA05__QSPI_B_DATA03 0x70a1
MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x70a1
MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x70a1
>;
}; */
};
};
驱动文件:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/interrupt.h>
typedef struct
{
int gpio;
int irq;
char name[20];
}int_demo_data_t;
static irqreturn_t int_demo_isr(int irq, void *dev_id)
{
int_demo_data_t *data = dev_id;
printk("%s enter, %s: gpio:%d, irq: %dn", __func__, data->name, data->gpio, data->irq);
return IRQ_HANDLED;
}
static int int_demo_probe(struct platform_device *pdev) {
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
int irq_gpio = -1;
int irq = -1;
int ret = 0;
int i = 0;
int_demo_data_t *data = NULL;
printk("%s enter.n", __func__);
if (!dev->of_node) {
dev_err(dev, "no platform data.n");
goto err1;
}
data = devm_kmalloc(dev, sizeof(*data)*4, GFP_KERNEL);
if (!data) {
dev_err(dev, "no memory.n");
goto err0;
}
for (i = 0; i >= 0; i--) {
sprintf(data[i].name, "tiny4412,int_gpio%d", i+1);//名字是我们自己填充的,并不是获取到的
irq_gpio = of_get_named_gpio(np, data[i].name, 0);//通过名字获取gpio
if (irq_gpio < 0) {
dev_err(dev, "Looking up %s property in node %s failed %dn",
data[i].name, dev->of_node->full_name, irq_gpio);
goto err1;
}
data[i].gpio = irq_gpio;
irq = gpio_to_irq(irq_gpio); //将gpio转换成对应的中断号
if (irq < 0) {
dev_err(dev,
"Unable to get irq number for GPIO %d, error %dn",
irq_gpio, irq);
goto err1;
}
data[i].irq = irq;
printk("%s: gpio: %d ---> irq (%d)n", __func__, irq_gpio, irq);
//注册中断
ret = devm_request_any_context_irq(dev, irq, int_demo_isr, IRQF_TRIGGER_FALLING, data[i].name, data+i);
if (ret < 0) {
dev_err(dev, "Unable to claim irq %d; error %dn",
irq, ret);
goto err1;
}
}
return 0;
err1:
devm_kfree(dev, data);
err0:
return -EINVAL;
}
static int int_demo_remove(struct platform_device *pdev) {
printk("%s enter.n", __func__);
return 0;
}
static const struct of_device_id int_demo_dt_ids[] = {
{ .compatible = "interrupt_demo", },
{},
};
MODULE_DEVICE_TABLE(of, int_demo_dt_ids);
static struct platform_driver int_demo_driver = {
.driver = {
.name = "interrupt_demo",
.of_match_table = of_match_ptr(int_demo_dt_ids),
},
.probe = int_demo_probe,
.remove = int_demo_remove,
};
static int __init int_demo_init(void)
{
int ret;
ret = platform_driver_register(&int_demo_driver);
if (ret)
printk(KERN_ERR "int demo: probe failed: %dn", ret);
return ret;
}
module_init(int_demo_init);
static void __exit int_demo_exit(void)
{
platform_driver_unregister(&int_demo_driver);
}
module_exit(int_demo_exit);
MODULE_LICENSE("GPL");
结果:
欢迎关注并加入物联网行业联盟,积累行业人脉和资源。
最后
以上就是坦率发夹为你收集整理的设备树学习之(一)GPIO中断在M6G2C平台下的应用设备树文件:的全部内容,希望文章能够帮你解决设备树学习之(一)GPIO中断在M6G2C平台下的应用设备树文件:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复