raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.15k stars 4.99k forks source link

RPI 5 - Goodix capacitive touchscreen not working on latest Kernel #6456

Open blastbeng opened 15 hours ago

blastbeng commented 15 hours ago

Describe the bug

Hello, I have used for years on my old Pi3 this product, working flawlessy on buster (with touchscreen support)

https://www.waveshare.com/wiki/3.5inch_DPI_LCD

I recently upgraded to a Pi5 and formatted it with Bookworm looking at the waveshare wiki, I configured the Display and it powers on without any problem

But the issue is the touchscreen, It doesnt responds to touch events and after some reboots the "Goodix touchscreen" also disappears from evtest or dmesg.

After so many reformats and tests I finally discovered that it could be a driver/kernel related issue

The kernel module that it loads is called goodix_ts

$ lsmod | grep goodix_ts
goodix_ts              49152  0

I am attaching the logs of what I've found

Steps to reproduce the behaviour

Format Pi5 MicroSD wiith latest arm64 image based on bookworm Configure the touch panel using the steps described in the waveshare wiki: https://www.waveshare.com/wiki/3.5inch_DPI_LCD Reboot the device.

Using dmesg | grep Goodix you will see the error after boot

Device (s)

Raspberry Pi 5

System

$ cat /etc/rpi-issue
Raspberry Pi reference 2024-10-22
Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, ecda2579ebbc125b321984c571e3128f6fd959d4, stage4
$ vcgencmd version
2024/11/05 12:38:12
Copyright (c) 2012 Broadcom
version 3c4fc886 (release) (embedded)
uname -a
Linux blastpi5 6.6.51-v8-16k+ #1802 SMP PREEMPT Tue Oct  8 17:27:04 BST 2024 aarch64 GNU/Linux

Logs

$ dmesg | grep Good
[    3.396228] Goodix-TS 11-0014: supply AVDD28 not found, using dummy regulator
[    3.398837] Goodix-TS 11-0014: supply VDDIO not found, using dummy regulator
[    3.401971] Goodix-TS 11-0014: Error reading 1 bytes from 0x8140: -6
[    3.430738] Goodix-TS 11-0014: Error reading 1 bytes from 0x8140: -6
[    3.455302] Goodix-TS 11-0014: I2C communication failure: -6
[    3.455508] Goodix-TS 11-005d: supply AVDD28 not found, using dummy regulator
[    3.455549] Goodix-TS 11-005d: supply VDDIO not found, using dummy regulator
[    3.456790] Goodix-TS 11-005d: Error reading 1 bytes from 0x8140: -6
[    3.521255] Goodix-TS 11-005d: Error reading 1 bytes from 0x8140: -6
[    3.547287] Goodix-TS 11-005d: I2C communication failure: -6

Additional context

My actual rpi config.txt is as follows:

## For more options and information see
# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
#dtparam=i2c=on

# Enable audio (loads snd_bcm2835)
#dtparam=audio=on

# Additional overlays and parameters are documented
# /boot/firmware/overlays/README

# Automatically load overlays for detected cameras
#camera_auto_detect=1

# Automatically load overlays for detected DSI displays
#display_auto_detect=1

# Automatically load initramfs files, if found
auto_initramfs=1

#enable_uart=1
#dtoverlay=uart0-pi5

# Enable DRM VC4 V3D driver
#dtoverlay=vc4-kms-v3d
#max_framebuffers=2

#max_usb_current=1

# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1

# Run in 64-bit mode
arm_64bit=1

# Disable compensation for displays with overscan
disable_overscan=1

# Run as fast as firmware / board allows
arm_boost=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1

[all]
dtoverlay=vc4-kms-v3d
dtoverlay=vc4-kms-DPI-35inch
dtoverlay=waveshare-35dpi-3b-4b
dtoverlay=waveshare-35dpi-3b
dtoverlay=waveshare-35dpi-4b
dtoverlay=waveshare-35dpi
dtoverlay=waveshare-touch-35dpi

All the dtoverlay overlays configured in the config.txt can be found in /boot/overlays (copied from waveshare wiki).

pelwell commented 15 hours ago

WaveShare should be your first port of call for support of their products. We don't even have the sources to those overlays.

From the looks of the error messages they are using a bit-bashed I2C interface, and the driver is failing to find the device. What does i2cdetect -y 11 report?

blastbeng commented 15 hours ago

WaveShare should be your first port of call for support of their products. We don't even have the sources to those overlays.

From the looks of the error messages they are using a bit-bashed I2C interface, and the driver is failing to find the device. What does i2cdetect -y 11 report?

I am emailing waveshare, they told me that the screen is working good iin their tests, with touch support. I did all the steps they described but the problem persists. And it is not related to faulty Pi5 hardware(as i tried with 3 diffferent Pi5 bought from amazon) or faulty waveshare screen(as it is working on Pi2B and Pi3)

It is like a 3 days I chat with their support.

Output of sudo i2cdetect -y 11

$ sudo i2cdetect -y 11
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- 5d -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
6by9 commented 15 hours ago

As pelwell has just posted, none of those overlays are part of the Raspberry Pi kernel repo, so aren't our responsibility.

The Goodix touchscreen driver is also used on the Pimoroni HyperPixel4 display, again via a bit-bashed I2C bus. I've just tested that with a 6.6.57 kernel on a Pi5, and touch is working fine there, so there's nothing fundamentally wrong with the driver.

If address 0x5d is responding to i2cdetect but not being probed correctly, then you could try reloading the module via sudo rmmod goodix_ts and sudo modprobe goodix_ts to see if it is a powering up timing issue in their screen.

blastbeng commented 15 hours ago

As pelwell has just posted, none of those overlays are part of the Raspberry Pi kernel repo, so aren't our responsibility.

The Goodix touchscreen driver is also used on the Pimoroni HyperPixel4 display, again via a bit-bashed I2C bus. I've just tested that with a 6.6.57 kernel on a Pi5, and touch is working fine there, so there's nothing fundamentally wrong with the driver.

If address 0x5d is responding to i2cdetect but not being probed correctly, then you could try reloading the module via sudo rmmod goodix_touch and sudo modprobe goodix_touch to see if it is a powering up timing issue in their screen.

These modules doesn't exists in my Pi5 Raspbian installation

blast@blastpi5:~ $ sudo rmmod goodix_touch
rmmod: ERROR: Module goodix_touch is not currently loaded
blast@blastpi5:~ $ sudo modprobe goodix_touch
modprobe: FATAL: Module goodix_touch not found in directory /lib/modules/6.6.51-v8-16k+

How can I install them?

6by9 commented 15 hours ago

Typo. It's goodix_ts. I'll edit my earlier comment too.

blastbeng commented 15 hours ago

Typo. It's goodix_ts. I'll edit my earlier comment too.

Same problem, nothing changed....


blast@blastpi5:~ $ sudo rmmod goodix_ts
blast@blastpi5:~ $ sudo modprobe goodix_ts
blast@blastpi5:~ $ dmesg | grep Goodix
[ 2651.942561] Goodix-TS 11-0014: supply AVDD28 not found, using dummy regulator
[ 2651.942630] Goodix-TS 11-0014: supply VDDIO not found, using dummy regulator
[ 2651.943683] Goodix-TS 11-0014: Error reading 1 bytes from 0x8140: -6
[ 2651.973345] Goodix-TS 11-0014: Error reading 1 bytes from 0x8140: -6
[ 2652.000346] Goodix-TS 11-0014: I2C communication failure: -6
[ 2652.000425] Goodix-TS 11-005d: supply AVDD28 not found, using dummy regulator
[ 2652.000459] Goodix-TS 11-005d: supply VDDIO not found, using dummy regulator
[ 2652.003560] Goodix-TS 11-005d: ID 911, version: 1060
[ 2652.038469] input: 11-005d Goodix Capacitive TouchScreen as /devices/platform/i2c@0/i2c-11/11-005d/input/input7
pelwell commented 15 hours ago

Read it again - that's a change.

blastbeng commented 15 hours ago

Read it again - that's a change.

You are right, something changed also in i2cdetect


$ sudo i2cdetect -y 11
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

But i don't think I have the skills to understand what's happening

6by9 commented 15 hours ago

You now have the driver loaded and registered as an input device.

Install evtest (sudo apt install evtest if not already isntalled), run it from a terminal, select the device relevant device number for your Goodix touch controller, and you should be able to observe any touch events.

blastbeng commented 14 hours ago

You now have the driver loaded and registered as an input device.

Install evtest (sudo apt install evtest if not already isntalled), run it from a terminal, select the device relevant device number for your Goodix touch controller, and you should be able to observe any touch events.

I did this kind of test already and It wasnt registering any touch input

Now the steps i followed are:

blast@blastpi5:/etc/modprobe.d $ sudo nano blacklist-goodix_ts.conf >> added goodix_ts here

blast@blastpi5:~ $ cat /etc/modprobe.d/blacklist-goodix_ts.conf
blacklist goodix_ts

Rebooted

After reboot:


blast@blastpi5:~ $ dmesg | grep Goodix
blast@blastpi5:~ $ sudo modprobe goodix_ts
blast@blastpi5:~ $ dmesg | grep Goodix
[   38.617551] Goodix-TS 11-0014: supply AVDD28 not found, using dummy regulator
[   38.617659] Goodix-TS 11-0014: supply VDDIO not found, using dummy regulator
[   38.619169] Goodix-TS 11-0014: Error reading 1 bytes from 0x8140: -6
[   38.644185] Goodix-TS 11-0014: Error reading 1 bytes from 0x8140: -6
[   38.671211] Goodix-TS 11-0014: I2C communication failure: -6
[   38.671364] Goodix-TS 11-005d: supply AVDD28 not found, using dummy regulator
[   38.671429] Goodix-TS 11-005d: supply VDDIO not found, using dummy regulator
[   38.674434] Goodix-TS 11-005d: ID 911, version: 1060
[   38.708434] input: 11-005d Goodix Capacitive TouchScreen as /devices/platform/i2c@0/i2c-11/11-005d/input/input16
blast@blastpi5:~ $ sudo evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      vc4-hdmi-0
/dev/input/event1:      vc4-hdmi-0 HDMI Jack
/dev/input/event2:      vc4-hdmi-1
/dev/input/event3:      vc4-hdmi-1 HDMI Jack
/dev/input/event4:      pwr_button
/dev/input/event5:      Logitech K400
/dev/input/event6:      11-005d Goodix Capacitive TouchScreen
Select the device event number [0-6]: 6
Input driver version is 1.0.1
Input device ID: bus 0x18 vendor 0x416 product 0x38f version 0x1060
Input device name: "11-005d Goodix Capacitive TouchScreen"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 59 (KEY_F1)
    Event code 60 (KEY_F2)
    Event code 61 (KEY_F3)
    Event code 62 (KEY_F4)
    Event code 63 (KEY_F5)
    Event code 64 (KEY_F6)
    Event code 125 (KEY_LEFTMETA)
    Event code 330 (BTN_TOUCH)
  Event type 3 (EV_ABS)
    Event code 0 (ABS_X)
      Value      0
      Min        0
      Max      479
    Event code 1 (ABS_Y)
      Value      0
      Min        0
      Max      639
    Event code 47 (ABS_MT_SLOT)
      Value      0
      Min        0
      Max        4
    Event code 48 (ABS_MT_TOUCH_MAJOR)
      Value      0
      Min        0
      Max      255
    Event code 50 (ABS_MT_WIDTH_MAJOR)
      Value      0
      Min        0
      Max      255
    Event code 53 (ABS_MT_POSITION_X)
      Value      0
      Min        0
      Max      479
    Event code 54 (ABS_MT_POSITION_Y)
      Value      0
      Min        0
      Max      639
    Event code 57 (ABS_MT_TRACKING_ID)
      Value      0
      Min        0
      Max    65535
Properties:
  Property type 1 (INPUT_PROP_DIRECT)
Testing ... (interrupt to exit)

Now touching the screen isn't registering any touch event, it just stays like that.

6by9 commented 14 hours ago

Decompiled their overlay

/dts-v1/;

/ {
    compatible = "brcm,bcm2708";

    fragment@0 {
        target = <0xffffffff>;

        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <0x01>;
        };
    };

    fragment@1 {
        target = <0xffffffff>;

        __overlay__ {

            dpi18_pins {
                brcm,pins = <0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x14 0x15 0x16 0x17 0x18 0x19>;
                brcm,function = <0x06>;
                brcm,pull = <0x00>;
                phandle = <0x01>;
            };
        };
    };

    fragment@2 {
        target-path = "/";

        __overlay__ {

            rpi_backlight {
                compatible = "gpio-backlight";
                gpios = <0xffffffff 0x12 0x01>;
                default-on;
            };
        };
    };

    fragment@3 {
        target-path = "/";

        __overlay__ {

            i2c@0 {
                compatible = "i2c-gpio";
                gpios = <0xffffffff 0x0a 0x00 0xffffffff 0x0b 0x00>;
                i2c-gpio,delay-us = <0x04>;
                #address-cells = <0x01>;
                #size-cells = <0x00>;
                phandle = <0x02>;
            };
        };
    };

    fragment@4 {
        target-path = "/__symbols__";

        __overlay__ {
            i2c_gpio = "/i2c@0";
        };
    };

    fragment@5 {
        target = <0x02>;

        __overlay__ {
            #address-cells = <0x01>;
            #size-cells = <0x00>;

            ft6236@14 {
                compatible = "goodix,gt911";
                reg = <0x14>;
                interrupt-parent = <0xffffffff>;
                irq-gpios = <0xffffffff 0x1b 0x02>;
                touchscreen-size-x = <0x280>;
                touchscreen-size-y = <0x1e0>;
                touchscreen-x-mm = <0x46>;
                touchscreen-y-mm = <0x35>;
                touchscreen-swapped-x-y;
                touchscreen-inverted-x;
            };

            ft6236@5d {
                compatible = "goodix,gt911";
                reg = <0x5d>;
                interrupt-parent = <0xffffffff>;
                irq-gpios = <0xffffffff 0x1b 0x02>;
                touchscreen-size-x = <0x280>;
                touchscreen-size-y = <0x1e0>;
                touchscreen-x-mm = <0x46>;
                touchscreen-y-mm = <0x35>;
                touchscreen-swapped-x-y;
                touchscreen-inverted-x;
            };
        };
    };

    __overrides__ {
        touchscreen-inverted-x = [00 00 00 01 2b 32 00];
        touchscreen-swapped-x-y = [00 00 00 00 2d 31 00];
    };

    __fixups__ {
        fb = "/fragment@0:target:0";
        gpio = "/fragment@1:target:0\0/fragment@2/__overlay__/rpi_backlight:gpios:0\0/fragment@3/__overlay__/i2c@0:gpios:0\0/fragment@3/__overlay__/i2c@0:gpios:12\0/fragment@5/__overlay__/ft6236@14:interrupt-parent:0\0/fragment@5/__overlay__/ft6236@14:irq-gpios:0\0/fragment@5/__overlay__/ft6236@5d:interrupt-parent:0\0/fragment@5/__overlay__/ft6236@5d:irq-gpios:0";
    };

    __local_fixups__ {

        fragment@5 {
            target = <0x00>;
        };
    };
};

So nominally it is registering to use GPIO 27 (hex 0x1b) for the interrupt line. Check /proc/interrupts and you should have a line similar to

188:       4943          0          0          0  pinctrl-rp1  27 Edge      gt911

and that 4943 is the number of interrupts that have triggered. You can also check the state of GPIO 27 with

pi@bookworm64-1:~ $ pinctrl get 27
27: ip    pu | hi // GPIO27 = input

It is edge triggered, and should normally be high (falling edge triggered).

I vaguely recall an issue with another touch overlay where the polarity of the GPIO was incorrectly defined, so it was triggering on every release, not on each touch. It looks like that was ads7846 though (commit c895cecf59190b45b8cfe3ad3f8edf3a7267c7f0). It's possible that this is something similar in Waveshare's overlay.

blastbeng commented 14 hours ago

So nominally it is registering to use GPIO 27 (hex 0x1b) for the interrupt line. Check /proc/interrupts and you should have a line similar to

188:       4943          0          0          0  pinctrl-rp1  27 Edge      gt911

and that 4943 is the number of interrupts that have triggered. You can also check the state of GPIO 27 with

pi@bookworm64-1:~ $ pinctrl get 27
27: ip    pu | hi // GPIO27 = input

It is edge triggered, and should normally be high (falling edge triggered).

I vaguely recall an issue with another touch overlay where the polarity of the GPIO was incorrectly defined, so it was triggering on every release, not on each touch. It looks like that was ads7846 though (commit c895cec). It's possible that this is something similar in Waveshare's overlay.

I have this exact line using cat /proc/interrupts and after loading the kernel module

167: 0 0 0 0 pinctrl-rp1 27 Edge gt911

pinctrl get 27
27: ip    pd | lo // GPIO27 = input

What could be the solution of this issue in your opinion? Do i need an older ads7846 dtbo file? Or do they need to update their waveshare overlays package with a fix?

I have the skills to decompile/compile things, as i am a computer programmer, but I'm kinda new to all of this. I could try to decompile their overlays but I will need some help understaing what I have to change in their code.

6by9 commented 14 hours ago

Reference to ads7846 was only as a thought of similar issues recently. It's not directly applicable to your panel.

You have no interrupts registered by the kernel, but the interrupt line is low (ie interrupt state). Being edge triggered means that the interrupt handler will never be called, and therefore the interrupt will never get cleared in order to be able to trigger again.

Reading the devicetree binding, it implies that the interrupt should be of the form

        interrupts = <0 0>;

which is weird as I don't believe 0 is an option for trigger mode. Defined values are

    - bits[3:0] trigger type and level flags
        1 = low-to-high edge triggered
        2 = high-to-low edge triggered
        4 = active high level-sensitive
        8 = active low level-sensitive

It may just be used as an example, not guidance. Active low level-sensitive is probably what is required in this case, but I haven't read the datasheet to confirm. Looking at other users in the mainline kernel tree, they seem to be using any number of edge triggered or level triggered options, so there isn't one true answer.

blastbeng commented 14 hours ago

Thanks for the help I think I will send all these infos to the waveshare support.

But I hope someone will find a solution... As for now the only solution for me is refund my new pi5 and keep using my old pi3

Or buy a new panel for the new pi5... But this will be a waste of money in my opinion as I already have a touch panel. I was using it to control my home domotics

6by9 commented 12 hours ago

I've stuck one of those displays on order to see what is going on. Should be here tomorrow.

I do wish Waveshare would upstream the source for their overlays rather than distributing random precompiled blobs. Blobs make support almost impossible for anyone other than themselves, and they seem to sometimes not be the most responsive. We do accept 3rd party overlays into our kernel tree here, as long as they've been implemented in a clean manner.

blastbeng commented 12 hours ago

Thanks a lot for your support, I will be waiting for any good news