I am having troubles getting a touch screen powered by an Atmel MXT641T on an Android 5 platform to work.
The setup I have is as follows:
- Hardware: Inforce 6309 SBC with Qualcomm Snapdragon 410 msm8916 ARM64 processor.
- Custom touch screen with Atmel MXT641T controller chip.
- I2C connection between Atmel and Snapdragon connected to I2C0.
- Android 5 operating system using Linux kernel 3.10 from
git://codeaurora.org/kernel/msm-3.10.git
branchRel_V1.3
(this is part of the BSP that comes with the SBC)... - ... but with the latest version of the Atmel driver
atmel_mxt_ts.c
overlaid on the kernel tree (but also tested with version ofatmel_maxtouch_ts.c
inmsm-3.10.git
which shows same behaviour). - INT line from Atmel chip connected to GPIO 53 (this is
EXT_CONN_GPIO_1
of this board) and with external pull-up resistor to 1.8V. - RESET line from Atmel chip disconnected.
What I did to get to this point is to modify the device tree to include the Atmel device as follows:
&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>;
};
};
For reference, the msm_gpio
is defined as follows in the BSP (untouched).
&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>;
};
};
I compiled the kernel as a module (CONFIG_TOUCHSCREEN_ATMEL_MXT=m
) and I am running insmod
manually.
What I see is the following:
- When using the Atmel utility
mxt-app
the device works: when I touch the screen messages come in, so the I2C connection is ok (but it uses polling). - When loading the driver
mxt_start
is called, in which the interrupt is enabled. I have added a number of debug statements to the driver to verify that it is actually loading. - When loading the driver the info block is read from the device and brief I2C traffic shows on the oscilloscope. The I2C address is read from the device tree so I am sure that my device tree is loaded.
- The input device is registered as
/dev/input/event6
and can be opened withcat
(but no messages appear when touching the screen). - The interrupt is visible in
/proc/interrupts
but never fires (see below). - Whenever I touch the screen, the INT line from the Atmel chip is pulled low by the chip, but no I2C traffic is visible on the oscilloscope.
- I verified that the interrupt triggering condition (
0x0
,0x8
or0x2008
as second element in the interrupt cell in the device tree) does not matter by manually causing highs and lows on the interrupt line: no interrupt is triggered in any event.
Entry in /proc/interrupts
:
$ cat /proc/interrupts
...
326: 0 0 0 0 msm_tlmm_irq maxtouch
...
This is what appears in 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
What I understand from reading the driver code in atmel_mxt_ts.c
is that the driver should trigger on this interrupt line, and then query the device by starting an I2C transfer to read the T5 message, upon which the device will return a list of touches which are then passed on to the operating system. I have not found a datasheet or document properly explaining this, but this is what I suspect based on what I have seen so far.
I have tested the GPIO pin 53 (to which I normally connect the INT line of the Atmel chip) manually by doing the following:
$ 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
This value changes when I connect the INT line to V+ or ground, so I am sure that I have to use GPIO 53.
No GPIO for the maxtouch driver is shown in /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
I phrased some specific questions to help solve the puzzle:
- What is the correct way to register the interrupt? I am using
interrupt-parent = <&msm_gpio>;
andinterrupts = <53 0>
to identify the GPIO pin 53 of the Snapdragon. I tested with both<53 0>
and<53 8>
. - I sometimes see people use
0x2008
as second entry in the cell. I think the0x0008
is to set the interrupt to trigger on LOW level, but what does the 13-th bit do? I tested with both0x0
and0x8
, does not make a difference (yet :-)). - Should I expect an entry in
/sys/kernel/debug/gpio
? - Are any additional entries in the device tree needed to hook up the maxtouch interrupt to the physical pin?
- Where does the IRQ number
326
in/proc/interrupts
come from, and is there a way to verify what pin it is linked to? - Is it possible to configure that the INT line will be pulled up by the Snapdragon, instead of having to use an external pull-up resistor?
Thanks in advance for your help.
PS: And a tangentially related question: how can I quickly test updates of the device tree without having to wait 20 minutes for all Makefiles to load and the kernel to recompile and then flash the new boot.img
to the device and reboot? I use the command make bootimage
.
After finding out that there is already a more or less working touchscreen definition in the device tree but that the pins are different, I ended up with the following device tree:
so, the following lines are different:
The 0x2008 is needed to make the Snapdragon pull up this interrupt line and trigger on the falling edge.
The pinctrl definitions were already located in
qcom/msm8916-pinctrl.dtsi
that comes with the BSP, however, for my case I had to change pin 12 to 54 and pin 13 to 53: