This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit e884b6c3c8b213ac1dc5d772dc37c4d16d773c04 Author: Jorge Guzman <[email protected]> AuthorDate: Mon Aug 31 01:23:30 2026 -0300 input/gt9xx: fix register write and no-contact read 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 <[email protected]> --- drivers/input/gt9xx.c | 53 ++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/drivers/input/gt9xx.c b/drivers/input/gt9xx.c index 30ebf183ad6..6875e7aa1ce 100644 --- a/drivers/input/gt9xx.c +++ b/drivers/input/gt9xx.c @@ -30,6 +30,7 @@ ****************************************************************************/ #include <nuttx/config.h> + #include <sys/types.h> #include <stdbool.h> #include <stdint.h> @@ -37,6 +38,7 @@ #include <poll.h> #include <assert.h> #include <errno.h> +#include <fcntl.h> #include <nuttx/debug.h> #include <nuttx/arch.h> @@ -237,40 +239,27 @@ static int gt9xx_i2c_write(FAR struct gt9xx_dev_s *dev, { int ret; - /* Send the Register Address, MSB first */ - - uint8_t regbuf[2] = - { - reg >> 8, /* First Byte: MSB */ - reg & 0xff /* Second Byte: LSB */ - }; - - /* Send the Register Value */ + /* Send the Register Address MSB first, followed by the value, as a + * single message. Splitting it into two messages joined by + * I2C_M_NOSTART puts the same bytes on the wire, but not every I2C + * controller can resume a transfer that way. + */ - uint8_t buf[1] = + uint8_t buf[3] = { - val /* Value to be written */ + reg >> 8, /* First Byte: Register Address MSB */ + reg & 0xff, /* Second Byte: Register Address LSB */ + val /* Third Byte: Value to be written */ }; - /* Compose the I2C Messages */ + /* Compose the I2C Message */ - struct i2c_msg_s msgv[2] = + struct i2c_msg_s msgv[1] = { { - /* Send the I2C Register Address */ - .frequency = CONFIG_INPUT_GT9XX_I2C_FREQUENCY, .addr = dev->addr, .flags = 0, - .buffer = regbuf, - .length = sizeof(regbuf) - }, - { - /* Send the I2C Register Value */ - - .frequency = CONFIG_INPUT_GT9XX_I2C_FREQUENCY, - .addr = dev->addr, - .flags = I2C_M_NOSTART, .buffer = buf, .length = sizeof(buf) } @@ -551,9 +540,20 @@ static ssize_t gt9xx_read(FAR struct file *filep, FAR char *buffer, iinfo("skip duplicate x=%d, y=%d\n", priv->x, priv->y); } - /* Return the Touch Point */ + /* Return the Touch Point, if there is one. With no contact and a + * non-blocking read there is nothing to hand over: a sample carrying + * zero points would look like valid data to callers that judge the + * read by its return value. + */ - memcpy(buffer, &sample, sizeof(sample)); + if (sample.npoints == 0 && (filep->f_oflags & O_NONBLOCK) != 0) + { + ret = -EAGAIN; + } + else + { + memcpy(buffer, &sample, sizeof(sample)); + } /* Begin Critical Section */ @@ -826,6 +826,7 @@ static int gt9xx_poll(FAR struct file *filep, FAR struct pollfd *fds, /* If Poll Teardown: Remove the poll setup */ FAR struct pollfd **slot = (FAR struct pollfd **)fds->priv; + DEBUGASSERT(slot != NULL); *slot = NULL;
