Android5内核设备树中如何正确配置Atmel MXT641T触摸芯片INT线的中断?
How to correctly configure interrupt for INT line of Atmel MXT641T touch chip in Android 5 kernel device tree?
我无法在 Android 5 平台上使用由 Atmel MXT641T 供电的触摸屏。
我的设置如下:
- 硬件:配备 Qualcomm Snapdragon 410 msm8916 ARM64 处理器的 Inforce 6309 SBC。
- 带有Atmel MXT641T控制器芯片的定制触摸屏。
- 连接到 I2C0 的 Atmel 和 Snapdragon 之间的 I2C 连接。
- Android 5 操作系统使用 Linux 内核 3.10 来自
git://codeaurora.org/kernel/msm-3.10.git
分支 Rel_V1.3
(这是 SBC 附带的 BSP 的一部分)...
- ...但最新版本的 Atmel 驱动程序
atmel_mxt_ts.c
覆盖在内核树上(但也使用 msm-3.10.git
中的 atmel_maxtouch_ts.c
版本进行了测试,显示出相同的行为) .
- 来自 Atmel 芯片的 INT 线连接到 GPIO 53(这是此板的
EXT_CONN_GPIO_1
)并带有外部上拉电阻至 1.8V。
- 来自 Atmel 芯片的 RESET 线已断开连接。
为了达到这一点,我所做的是修改设备树以包含 Atmel 设备,如下所示:
&i2c_0 {
atmel_maxtouch_ts@4a {
compatible = "atmel,maxtouch";
reg = <0x4a>;
interrupt-parent = <&msm_gpio>;
interrupts = <53 0>;
atmel,panel-coords = <0 0 1024 768>;
atmel,display-coords = <0 0 1024 768>;
atmel,family-id = <164>;
atmel,variant-id = <2>;
atmel,version = <21>;
atmel,build = <0xaa>;
};
};
作为参考,msm_gpio
在 BSP 中定义如下(未修改)。
&soc {
tlmm_pinmux: pinctrl@1000000 {
compatible = "qcom,msm-tlmm-8916";
reg = <0x1000000 0x300000>;
interrupts = <0 208 0>;
/*General purpose pins*/
gp: gp {
qcom,num-pins = <122>;
#qcom,pin-cells = <1>;
msm_gpio: msm_gpio {
compatible = "qcom,msm-tlmm-gp";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
num_irqs = <122>;
};
};
我把内核编译成一个模块(CONFIG_TOUCHSCREEN_ATMEL_MXT=m
),我是运行insmod
手动
我看到的是:
- 当使用 Atmel 实用程序时
mxt-app
设备工作:当我触摸屏幕时消息进来,所以 I2C 连接正常(但它使用轮询)。
- 加载驱动程序时调用
mxt_start
,其中启用中断。我已经在驱动程序中添加了一些调试语句来验证它是否真的在加载。
- 加载驱动程序时,会从设备读取信息块,并在示波器上显示简短的 I2C 流量。 I2C 地址是从设备树中读取的,所以我确定我的设备树已加载。
- 输入设备注册为
/dev/input/event6
,可以用cat
打开(但触摸屏幕时没有消息出现)。
- 中断在
/proc/interrupts
中可见,但从未触发(见下文)。
- 每当我触摸屏幕时,来自 Atmel 芯片的 INT 线被芯片拉低,但示波器上看不到 I2C 流量。
- 我通过手动引起高电平和中断线上的低点:在任何事件中都不会触发中断。
/proc/interrupts
中的条目:
$ cat /proc/interrupts
...
326: 0 0 0 0 msm_tlmm_irq maxtouch
...
这是 dmesg
中出现的内容:
<6>[ 55.290620] atmel_mxt_ts 0-004a: Family: 164 Variant: 2 Firmware V1.5.AA Objects: 43
<4>[ 55.291252] atmel_mxt_ts 0-004a: Enabling RETRIGEN workaround
<6>[ 55.365918] atmel_mxt_ts 0-004a: Touchscreen size X1024Y768
<6>[ 55.367017] input: Atmel maXTouch Touchscreen as /devices/soc.0/78b6000.i2c/i2c-0/0-004a/input/input6
阅读atmel_mxt_ts.c
中的驱动程序代码我了解到,驱动程序应该在此中断线上触发,然后通过启动I2C传输来查询设备以读取T5消息,设备在该消息上将 return 一个触摸列表,然后将其传递给操作系统。我没有找到正确解释这一点的数据表或文件,但这是我根据目前所见所怀疑的。
我已经通过执行以下操作手动测试了 GPIO 引脚 53(我通常将 Atmel 芯片的 INT 线连接到该引脚):
$ echo 955 > /sys/class/gpio/export # 955 because EXP_CONN_GPIO_1 is GPIO pin 53, which has offset 902
cat /sys/class/gpio/gpio955/value
当我将 INT 线连接到 V+ 或接地时,这个值会改变,所以我确定我必须使用 GPIO 53。
/sys/kernel/debug/gpio
:
中未显示 maxtouch 驱动程序的 GPIO
$ cat /sys/kernel/debug/gpio
GPIOs 576-607, platform/qcom,smp2pgpio-ssr-smp2p-4-out.19, master-kernel:
GPIOs 608-639, platform/qcom,smp2pgpio-ssr-smp2p-4-in.18, slave-kernel:
GPIOs 640-671, platform/qcom,smp2pgpio-ssr-smp2p-1-out.13, master-kernel:
GPIOs 672-703, platform/qcom,smp2pgpio-ssr-smp2p-1-in.12, slave-kernel:
GPIOs 704-735, platform/qcom,smp2pgpio-smp2p-4-out.16, smp2p:
GPIOs 736-767, platform/qcom,smp2pgpio-smp2p-4-in.14, smp2p:
GPIOs 768-799, platform/qcom,smp2pgpio-smp2p-1-out.10, smp2p:
GPIOs 800-831, platform/qcom,smp2pgpio-smp2p-1-in.8, smp2p:
GPIOs 832-863, platform/qcom,smp2pgpio-smp2p-7-out.6, smp2p:
GPIOs 864-895, platform/qcom,smp2pgpio-smp2p-7-in.4, smp2p:
GPIOs 896-899, spmi/qpnp-pin-ffffffc031550c00, pm8916-gpio:
gpio-898 (qcom,hub-reset-gpio ) out hi
gpio-899 (qcom,sw-sel-gpio ) in lo
GPIOs 900-901, spmi/qpnp-pin-ffffffc031550800, pm8916-mpp:
GPIOs 902-1023, platform/1000000.pinctrl, msm_tlmm_gpio:
gpio-922 (adv7533_hpd_irq_gpio) in lo
gpio-923 (led1 ) out lo
gpio-927 (disp_rst_n ) in hi
gpio-933 (adv7533_irq_gpio ) in hi
gpio-934 (hdmi_lvds ) in lo
gpio-940 (7864900.sdhci cd ) in hi
gpio-1009 (volume_up ) in hi
gpio-1010 (camera_focus ) in hi
gpio-1011 (camera_snapshot ) in hi
gpio-1022 (led2 ) out lo
gpio-1023 (USB_ID_GPIO ) in hi
我提出了一些具体问题来帮助解决这个难题:
- 注册中断的正确方法是什么?我使用
interrupt-parent = <&msm_gpio>;
和 interrupts = <53 0>
来识别 Snapdragon 的 GPIO 引脚 53。我测试了 <53 0>
和 <53 8>
.
- 我有时看到人们使用
0x2008
作为单元格中的第二个条目。我认为 0x0008
是将中断设置为低电平触发,但是第 13 位是做什么的?我用 0x0
和 0x8
进行了测试,没有区别(还 :-))。
- 我应该在
/sys/kernel/debug/gpio
中看到一个条目吗?
- 是否需要设备树中的任何其他条目来将 maxtouch 中断连接到物理引脚?
/proc/interrupts
中的 IRQ 号 326
来自哪里,有没有办法验证它链接到哪个引脚?
- 是否可以配置 INT 线由 Snapdragon 上拉,而不必使用外部上拉电阻?
在此先感谢您的帮助。
PS:还有一个无关紧要的问题:我怎样才能快速测试设备树的更新,而不必等待 20 分钟加载所有 Makefile 并重新编译内核,然后将新 boot.img
闪存到设备并重新启动?我使用命令 make bootimage
.
在发现设备树中已经或多或少地工作了触摸屏定义但引脚不同后,我最终得到了以下设备树:
&i2c_0 {
atmel_maxtouch_ts@4a {
compatible = "atmel,maxtouch";
reg = <0x4a>;
interrupt-parent = <&msm_gpio>;
interrupts = <53 0x2008>;
pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_suspend";
pinctrl-0 = <&ts_int_active &ts_reset_active>;
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
pinctrl-2 = <&ts_release>;
atmel,irq-gpio = <&msm_gpio 53 0x2008>;
atmel,reset-gpio = <&msm_gpio 54 0>;
atmel,panel-coords = <0 0 800 480>;
atmel,display-coords = <0 0 800 480>;
atmel,family-id = <164>;
atmel,variant-id = <2>;
atmel,version = <21>;
atmel,build = <0xaa>;
};
};
所以,下面几行是不同的:
interrupts = <53 0x2008>;
pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_suspend";
pinctrl-0 = <&ts_int_active &ts_reset_active>;
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
pinctrl-2 = <&ts_release>;
atmel,irq-gpio = <&msm_gpio 53 0x2008>;
atmel,reset-gpio = <&msm_gpio 54 0>;
需要0x2008让Snapdragon拉起这条中断线并在下降沿触发。
pinctrl 定义已经位于 BSP 附带的 qcom/msm8916-pinctrl.dtsi
中,但是,对于我的情况,我必须将引脚 12 更改为 54,将引脚 13 更改为 53:
diff --git a/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi
index 204c718..80a2a6d 100644
--- a/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi
@@ -30,16 +30,6 @@
};
};
- atmel-int-pin {
- qcom,pins = <&gp 53>;
- qcom,num-grp-pins = <1>;
- label = "atmel-int-pin";
- default {
- drive-strength = <0>;
- bias-pull-up;
- };
- };
-
ext-cdc-tlmm-lines {
qcom,pins = <&gp 116>, <&gp 112>, <&gp 117>,
<&gp 118>, <&gp 119>;
@@ -1175,7 +1165,7 @@
/* add pingrp for touchscreen */
pmx_ts_int_active {
- qcom,pins = <&gp 13>;
+ qcom,pins = <&gp 53>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_int_active";
@@ -1187,7 +1177,7 @@
};
pmx_ts_int_suspend {
- qcom,pins = <&gp 13>;
+ qcom,pins = <&gp 53>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_int_suspend";
@@ -1199,7 +1189,7 @@
};
pmx_ts_reset_active {
- qcom,pins = <&gp 12>;
+ qcom,pins = <&gp 54>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_reset_active";
@@ -1211,7 +1201,7 @@
};
pmx_ts_reset_suspend {
- qcom,pins = <&gp 12>;
+ qcom,pins = <&gp 54>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_reset_suspend";
@@ -1223,7 +1213,7 @@
};
pmx_ts_release {
- qcom,pins = <&gp 13>, <&gp 12>;
+ qcom,pins = <&gp 53>, <&gp 54>;
qcom,num-grp-pins = <2>;
label = "pmx_ts_release";
我无法在 Android 5 平台上使用由 Atmel MXT641T 供电的触摸屏。
我的设置如下:
- 硬件:配备 Qualcomm Snapdragon 410 msm8916 ARM64 处理器的 Inforce 6309 SBC。
- 带有Atmel MXT641T控制器芯片的定制触摸屏。
- 连接到 I2C0 的 Atmel 和 Snapdragon 之间的 I2C 连接。
- Android 5 操作系统使用 Linux 内核 3.10 来自
git://codeaurora.org/kernel/msm-3.10.git
分支Rel_V1.3
(这是 SBC 附带的 BSP 的一部分)... - ...但最新版本的 Atmel 驱动程序
atmel_mxt_ts.c
覆盖在内核树上(但也使用msm-3.10.git
中的atmel_maxtouch_ts.c
版本进行了测试,显示出相同的行为) . - 来自 Atmel 芯片的 INT 线连接到 GPIO 53(这是此板的
EXT_CONN_GPIO_1
)并带有外部上拉电阻至 1.8V。 - 来自 Atmel 芯片的 RESET 线已断开连接。
为了达到这一点,我所做的是修改设备树以包含 Atmel 设备,如下所示:
&i2c_0 {
atmel_maxtouch_ts@4a {
compatible = "atmel,maxtouch";
reg = <0x4a>;
interrupt-parent = <&msm_gpio>;
interrupts = <53 0>;
atmel,panel-coords = <0 0 1024 768>;
atmel,display-coords = <0 0 1024 768>;
atmel,family-id = <164>;
atmel,variant-id = <2>;
atmel,version = <21>;
atmel,build = <0xaa>;
};
};
作为参考,msm_gpio
在 BSP 中定义如下(未修改)。
&soc {
tlmm_pinmux: pinctrl@1000000 {
compatible = "qcom,msm-tlmm-8916";
reg = <0x1000000 0x300000>;
interrupts = <0 208 0>;
/*General purpose pins*/
gp: gp {
qcom,num-pins = <122>;
#qcom,pin-cells = <1>;
msm_gpio: msm_gpio {
compatible = "qcom,msm-tlmm-gp";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
num_irqs = <122>;
};
};
我把内核编译成一个模块(CONFIG_TOUCHSCREEN_ATMEL_MXT=m
),我是运行insmod
手动
我看到的是:
- 当使用 Atmel 实用程序时
mxt-app
设备工作:当我触摸屏幕时消息进来,所以 I2C 连接正常(但它使用轮询)。 - 加载驱动程序时调用
mxt_start
,其中启用中断。我已经在驱动程序中添加了一些调试语句来验证它是否真的在加载。 - 加载驱动程序时,会从设备读取信息块,并在示波器上显示简短的 I2C 流量。 I2C 地址是从设备树中读取的,所以我确定我的设备树已加载。
- 输入设备注册为
/dev/input/event6
,可以用cat
打开(但触摸屏幕时没有消息出现)。 - 中断在
/proc/interrupts
中可见,但从未触发(见下文)。 - 每当我触摸屏幕时,来自 Atmel 芯片的 INT 线被芯片拉低,但示波器上看不到 I2C 流量。
- 我通过手动引起高电平和中断线上的低点:在任何事件中都不会触发中断。
/proc/interrupts
中的条目:
$ cat /proc/interrupts
...
326: 0 0 0 0 msm_tlmm_irq maxtouch
...
这是 dmesg
中出现的内容:
<6>[ 55.290620] atmel_mxt_ts 0-004a: Family: 164 Variant: 2 Firmware V1.5.AA Objects: 43
<4>[ 55.291252] atmel_mxt_ts 0-004a: Enabling RETRIGEN workaround
<6>[ 55.365918] atmel_mxt_ts 0-004a: Touchscreen size X1024Y768
<6>[ 55.367017] input: Atmel maXTouch Touchscreen as /devices/soc.0/78b6000.i2c/i2c-0/0-004a/input/input6
阅读atmel_mxt_ts.c
中的驱动程序代码我了解到,驱动程序应该在此中断线上触发,然后通过启动I2C传输来查询设备以读取T5消息,设备在该消息上将 return 一个触摸列表,然后将其传递给操作系统。我没有找到正确解释这一点的数据表或文件,但这是我根据目前所见所怀疑的。
我已经通过执行以下操作手动测试了 GPIO 引脚 53(我通常将 Atmel 芯片的 INT 线连接到该引脚):
$ echo 955 > /sys/class/gpio/export # 955 because EXP_CONN_GPIO_1 is GPIO pin 53, which has offset 902
cat /sys/class/gpio/gpio955/value
当我将 INT 线连接到 V+ 或接地时,这个值会改变,所以我确定我必须使用 GPIO 53。
/sys/kernel/debug/gpio
:
$ cat /sys/kernel/debug/gpio
GPIOs 576-607, platform/qcom,smp2pgpio-ssr-smp2p-4-out.19, master-kernel:
GPIOs 608-639, platform/qcom,smp2pgpio-ssr-smp2p-4-in.18, slave-kernel:
GPIOs 640-671, platform/qcom,smp2pgpio-ssr-smp2p-1-out.13, master-kernel:
GPIOs 672-703, platform/qcom,smp2pgpio-ssr-smp2p-1-in.12, slave-kernel:
GPIOs 704-735, platform/qcom,smp2pgpio-smp2p-4-out.16, smp2p:
GPIOs 736-767, platform/qcom,smp2pgpio-smp2p-4-in.14, smp2p:
GPIOs 768-799, platform/qcom,smp2pgpio-smp2p-1-out.10, smp2p:
GPIOs 800-831, platform/qcom,smp2pgpio-smp2p-1-in.8, smp2p:
GPIOs 832-863, platform/qcom,smp2pgpio-smp2p-7-out.6, smp2p:
GPIOs 864-895, platform/qcom,smp2pgpio-smp2p-7-in.4, smp2p:
GPIOs 896-899, spmi/qpnp-pin-ffffffc031550c00, pm8916-gpio:
gpio-898 (qcom,hub-reset-gpio ) out hi
gpio-899 (qcom,sw-sel-gpio ) in lo
GPIOs 900-901, spmi/qpnp-pin-ffffffc031550800, pm8916-mpp:
GPIOs 902-1023, platform/1000000.pinctrl, msm_tlmm_gpio:
gpio-922 (adv7533_hpd_irq_gpio) in lo
gpio-923 (led1 ) out lo
gpio-927 (disp_rst_n ) in hi
gpio-933 (adv7533_irq_gpio ) in hi
gpio-934 (hdmi_lvds ) in lo
gpio-940 (7864900.sdhci cd ) in hi
gpio-1009 (volume_up ) in hi
gpio-1010 (camera_focus ) in hi
gpio-1011 (camera_snapshot ) in hi
gpio-1022 (led2 ) out lo
gpio-1023 (USB_ID_GPIO ) in hi
我提出了一些具体问题来帮助解决这个难题:
- 注册中断的正确方法是什么?我使用
interrupt-parent = <&msm_gpio>;
和interrupts = <53 0>
来识别 Snapdragon 的 GPIO 引脚 53。我测试了<53 0>
和<53 8>
. - 我有时看到人们使用
0x2008
作为单元格中的第二个条目。我认为0x0008
是将中断设置为低电平触发,但是第 13 位是做什么的?我用0x0
和0x8
进行了测试,没有区别(还 :-))。 - 我应该在
/sys/kernel/debug/gpio
中看到一个条目吗? - 是否需要设备树中的任何其他条目来将 maxtouch 中断连接到物理引脚?
/proc/interrupts
中的 IRQ 号326
来自哪里,有没有办法验证它链接到哪个引脚?- 是否可以配置 INT 线由 Snapdragon 上拉,而不必使用外部上拉电阻?
在此先感谢您的帮助。
PS:还有一个无关紧要的问题:我怎样才能快速测试设备树的更新,而不必等待 20 分钟加载所有 Makefile 并重新编译内核,然后将新 boot.img
闪存到设备并重新启动?我使用命令 make bootimage
.
在发现设备树中已经或多或少地工作了触摸屏定义但引脚不同后,我最终得到了以下设备树:
&i2c_0 {
atmel_maxtouch_ts@4a {
compatible = "atmel,maxtouch";
reg = <0x4a>;
interrupt-parent = <&msm_gpio>;
interrupts = <53 0x2008>;
pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_suspend";
pinctrl-0 = <&ts_int_active &ts_reset_active>;
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
pinctrl-2 = <&ts_release>;
atmel,irq-gpio = <&msm_gpio 53 0x2008>;
atmel,reset-gpio = <&msm_gpio 54 0>;
atmel,panel-coords = <0 0 800 480>;
atmel,display-coords = <0 0 800 480>;
atmel,family-id = <164>;
atmel,variant-id = <2>;
atmel,version = <21>;
atmel,build = <0xaa>;
};
};
所以,下面几行是不同的:
interrupts = <53 0x2008>;
pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_suspend";
pinctrl-0 = <&ts_int_active &ts_reset_active>;
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
pinctrl-2 = <&ts_release>;
atmel,irq-gpio = <&msm_gpio 53 0x2008>;
atmel,reset-gpio = <&msm_gpio 54 0>;
需要0x2008让Snapdragon拉起这条中断线并在下降沿触发。
pinctrl 定义已经位于 BSP 附带的 qcom/msm8916-pinctrl.dtsi
中,但是,对于我的情况,我必须将引脚 12 更改为 54,将引脚 13 更改为 53:
diff --git a/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi
index 204c718..80a2a6d 100644
--- a/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8916-pinctrl.dtsi
@@ -30,16 +30,6 @@
};
};
- atmel-int-pin {
- qcom,pins = <&gp 53>;
- qcom,num-grp-pins = <1>;
- label = "atmel-int-pin";
- default {
- drive-strength = <0>;
- bias-pull-up;
- };
- };
-
ext-cdc-tlmm-lines {
qcom,pins = <&gp 116>, <&gp 112>, <&gp 117>,
<&gp 118>, <&gp 119>;
@@ -1175,7 +1165,7 @@
/* add pingrp for touchscreen */
pmx_ts_int_active {
- qcom,pins = <&gp 13>;
+ qcom,pins = <&gp 53>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_int_active";
@@ -1187,7 +1177,7 @@
};
pmx_ts_int_suspend {
- qcom,pins = <&gp 13>;
+ qcom,pins = <&gp 53>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_int_suspend";
@@ -1199,7 +1189,7 @@
};
pmx_ts_reset_active {
- qcom,pins = <&gp 12>;
+ qcom,pins = <&gp 54>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_reset_active";
@@ -1211,7 +1201,7 @@
};
pmx_ts_reset_suspend {
- qcom,pins = <&gp 12>;
+ qcom,pins = <&gp 54>;
qcom,pin-func = <0>;
qcom,num-grp-pins = <1>;
label = "pmx_ts_reset_suspend";
@@ -1223,7 +1213,7 @@
};
pmx_ts_release {
- qcom,pins = <&gp 13>, <&gp 12>;
+ qcom,pins = <&gp 53>, <&gp 54>;
qcom,num-grp-pins = <2>;
label = "pmx_ts_release";