Skip to content

boards/esp32p4-tab5: add the ILI9881C and GT911 hardware variant - #20017

Merged
xiaoxiang781216 merged 2 commits into
apache:masterfrom
JorgeGzm:tab5_add_lcd_ili9881c
Aug 31, 2026
Merged

boards/esp32p4-tab5: add the ILI9881C and GT911 hardware variant#20017
xiaoxiang781216 merged 2 commits into
apache:masterfrom
JorgeGzm:tab5_add_lcd_ili9881c

Conversation

@JorgeGzm

Copy link
Copy Markdown
Member

Summary

The M5Stack Tab5 ships in two hardware variants and the board in tree
supports only the newer one. This adds the older one.

Variant Panel Touch controller
Earlier units ILI9881C GT911 (I2C 0x14)
Later units ST7121 / ST7123 ST7123 (I2C 0x55)

The panel and the touch controller always come as a pair, so scanning I2C0
identifies the board: a GT911 on 0x14 means an earlier unit, and therefore
an ILI9881C panel. This is the same criterion the Espressif BSP uses.

On an earlier unit today the panel stays lit but black, and the touch
bring-up fails with failed to register ST7123: -5.

Two commits, because the touch also needs two fixes in the shared GT9XX
driver, neither of them specific to this board:

  • input/gt9xx. The register write used I2C_M_NOSTART, which not
    every controller can honour; on ESP32-P4 every write returned
    -ETIMEDOUT, so the buffer status clear never reached the controller.
    And read() returned a zero point sample instead of -EAGAIN when there
    was no contact, which makes the LVGL touchscreen driver loop on
    continue_reading and stop refreshing the display.

  • boards/esp32p4-tab5. Adds the ILI9881C panel and the GT911 as new
    options. The init table comes from the Espressif BSP (Apache-2.0,
    credited in the file header); its timings differ from the ST7123 ones, so
    they became per panel. The GT911 units have a pull-up to 3V3 on the touch
    interrupt line that stops the controller from scanning, so the line is
    driven low and no interrupt is used, as the BSP also does.

The commit messages carry the details.

Impact

No change for the later units: the defaults still select the ST7121 panel
and the ST7123 touch controller, and no defconfig in tree changed. Owners
of an earlier unit select ESP32P4_TAB5_LCD_ILI9881C and
ESP32P4_TAB5_TOUCH_GT911.

drivers/input/gt9xx.c is shared with pinephone. The write change puts
identical bytes on the wire. The read change only affects a non blocking
reader with no contact pending; a blocking reader, such as
apps/examples/touchscreen, is unaffected. pinephone:lvgl builds clean,
but I have no PinePhone to test on and would welcome confirmation.

Switching either choice changes which source is compiled, so an existing
tree needs make clean when moving between variants.

Testing

Host Linux x86_64, riscv-none-elf-gcc 14.2.0, on a Tab5 earlier unit (ESP32-P4 rev v1.0).

Identifying the board with esp32p4-tab5:nsh (0x14 present, 0x55 absent):

nsh> i2c dev -b 0 0x03 0x77
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
10: 10 -- -- -- 14 -- -- -- -- -- -- -- -- -- -- --
30: -- -- 32 -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 41 -- 43 44 -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --

esp32p4-tab5:lvgl_term with both options selected, on that hardware:

ILI9881C panel init...
ili9881c: panel ID 98 81 5c
/dev/fb0 ready 720x1280 RGB565 @ 0x48000040
/dev/fb0 registered (ILI9881C)
gt911: product "911" (39 31 31 00) fw 1060
GT911 touchscreen controller initialized!

98 81 is the Ilitek signature, 911 the GT911 product ID, both read from
the chips. The LVGL terminal renders and responds to touch: 589 contacts
over a 45 s window with CONFIG_DEBUG_INPUT_INFO, coordinates inside
720x1280. Before the read fix the same instrumentation counted 7498 touch
reads against 1 display refresh in 15 s.

Builds clean: esp32p4-tab5:lvgl_demo (defaults), esp32p4-tab5:lvgl_term
with ILI9881C plus GT911, the same with ST7123 plus ST7123, and
pinephone:lvgl.

tools/checkpatch.sh -f passes on every file touched. The one error it
reports in drivers/input/gt9xx.c is a missing blank line in gt9xx_poll()
already present at 1401179. tools/refresh.sh --silent was run on the
three defconfigs in tree that mention the affected symbols
(esp32p4-tab5:lvgl_demo, esp32p4-tab5:lvgl_term, pinephone:lvgl);
none changed.

@github-actions github-actions Bot added Area: Drivers Drivers issues Size: L The size of the change in this PR is large Board: risc-v labels Aug 31, 2026
Two defects keep the driver from reporting touches on a board that
cannot use the interrupt line.

The register write built two messages joined by I2C_M_NOSTART.  That
puts the same bytes on the wire as a single three byte message, but
resuming a transfer without a start condition is optional, and a
controller that does not implement it fails the transfer.  On the
ESP32-P4 every write returned -ETIMEDOUT, so the buffer status clear
at 0x814E never reached the controller and gt9xx_read_touch_data()
returned an error for every read.  Send the register address and the
value as a single message.

read() returned a full struct touch_sample_s even when the controller
reported no contact, with npoints set to zero.  A caller that judges
the read by its return value takes that for valid data: the LVGL
touchscreen driver reads a second sample to decide whether to keep
reading, always gets one, so it sets continue_reading on every pass
and lv_indev_read() never returns.  The display then stops refreshing
after the first frame while the touch reads spin.  Return -EAGAIN when
there is no contact and the file was opened with O_NONBLOCK, which is
what the touchscreen upper half does in the same situation.  A
blocking reader keeps the previous behaviour.

While here, add the blank line after the declaration in gt9xx_poll() that
nxstyle asks for.  It predates this change, but the CI runs checkpatch over
every file a commit touches, so it has to go.

Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
The Tab5 ships in two hardware variants and the board supported only
one of them.  The earlier units carry an ILI9881C panel and a GT911
touch controller, the later ones a ST7121/ST7123 panel and a ST7123
touch controller, and the two always come as a pair.  On an earlier
unit the panel stays lit but black, and the touch bring-up fails with
"failed to register ST7123: -5".

Add the ILI9881C initialization table, taken from the Espressif BSP,
along with the display timings it needs, which differ from the ST7123
ones in the DPI clock (60 MHz instead of 70 MHz) and in every porch.
The panel identification lives on command page 1 and is read and
logged during bring-up, so the boot log says which panel answered.

Add the GT911 to the touch controller choice.  These units have a
pull-up to 3V3 on the touch interrupt line that keeps the controller
from scanning, so the line is driven low instead of being used as an
interrupt, and contacts are picked up when the device is read.  The
controller identification is logged the same way.

Split esp32p4_touch.c into one file per controller, which is how the
panels are already handled, and document both variants together with
the I2C scan that tells which one is fitted.  The defaults are
unchanged, so an existing configuration still selects the ST7121
panel and the ST7123 touch controller.

Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
@JorgeGzm
JorgeGzm force-pushed the tab5_add_lcd_ili9881c branch from ab23a56 to 11f0a3f Compare August 31, 2026 04:25
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@xiaoxiang781216
xiaoxiang781216 merged commit 89ac35c into apache:master Aug 31, 2026
54 checks passed
@fdcavalcanti

Copy link
Copy Markdown
Contributor

Thank you @JorgeGzm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Drivers Drivers issues Board: risc-v Size: L The size of the change in this PR is large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants