Skip to content

Commit bd19cf7

Browse files
committed
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. Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
1 parent 1401179 commit bd19cf7

1 file changed

Lines changed: 26 additions & 26 deletions

File tree

drivers/input/gt9xx.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@
3030
****************************************************************************/
3131

3232
#include <nuttx/config.h>
33+
3334
#include <sys/types.h>
3435
#include <stdbool.h>
3536
#include <stdint.h>
3637
#include <string.h>
3738
#include <poll.h>
3839
#include <assert.h>
3940
#include <errno.h>
41+
#include <fcntl.h>
4042
#include <nuttx/debug.h>
4143

4244
#include <nuttx/arch.h>
@@ -237,40 +239,27 @@ static int gt9xx_i2c_write(FAR struct gt9xx_dev_s *dev,
237239
{
238240
int ret;
239241

240-
/* Send the Register Address, MSB first */
242+
/* Send the Register Address MSB first, followed by the value, as a
243+
* single message. Splitting it into two messages joined by
244+
* I2C_M_NOSTART puts the same bytes on the wire, but not every I2C
245+
* controller can resume a transfer that way.
246+
*/
241247

242-
uint8_t regbuf[2] =
248+
uint8_t buf[3] =
243249
{
244-
reg >> 8, /* First Byte: MSB */
245-
reg & 0xff /* Second Byte: LSB */
250+
reg >> 8, /* First Byte: Register Address MSB */
251+
reg & 0xff, /* Second Byte: Register Address LSB */
252+
val /* Third Byte: Value to be written */
246253
};
247254

248-
/* Send the Register Value */
255+
/* Compose the I2C Message */
249256

250-
uint8_t buf[1] =
251-
{
252-
val /* Value to be written */
253-
};
254-
255-
/* Compose the I2C Messages */
256-
257-
struct i2c_msg_s msgv[2] =
257+
struct i2c_msg_s msgv[1] =
258258
{
259259
{
260-
/* Send the I2C Register Address */
261-
262260
.frequency = CONFIG_INPUT_GT9XX_I2C_FREQUENCY,
263261
.addr = dev->addr,
264262
.flags = 0,
265-
.buffer = regbuf,
266-
.length = sizeof(regbuf)
267-
},
268-
{
269-
/* Send the I2C Register Value */
270-
271-
.frequency = CONFIG_INPUT_GT9XX_I2C_FREQUENCY,
272-
.addr = dev->addr,
273-
.flags = I2C_M_NOSTART,
274263
.buffer = buf,
275264
.length = sizeof(buf)
276265
}
@@ -551,9 +540,20 @@ static ssize_t gt9xx_read(FAR struct file *filep, FAR char *buffer,
551540
iinfo("skip duplicate x=%d, y=%d\n", priv->x, priv->y);
552541
}
553542

554-
/* Return the Touch Point */
543+
/* Return the Touch Point, if there is one. With no contact and a
544+
* non-blocking read there is nothing to hand over: a sample carrying
545+
* zero points would look like valid data to callers that judge the
546+
* read by its return value.
547+
*/
555548

556-
memcpy(buffer, &sample, sizeof(sample));
549+
if (sample.npoints == 0 && (filep->f_oflags & O_NONBLOCK) != 0)
550+
{
551+
ret = -EAGAIN;
552+
}
553+
else
554+
{
555+
memcpy(buffer, &sample, sizeof(sample));
556+
}
557557

558558
/* Begin Critical Section */
559559

0 commit comments

Comments
 (0)