Download raw body.
sys/ihidev: replace HONOR's touchpad quirk
tech@,
Old quirk made touchpad with multitouch wroks, but it was unstable and
doesn't work each boot.
Here better quirck which simple re-reads reports multiple times and
usually 2-3 repeated read are enough.
With new quirck multitouch works each boot, I've tested 10 reboot and 10
cold boot.
Open questions: shall it be kept as device quirck or generic policy?
Ok to commit as a quirk?
Index: sys/dev/i2c/ihidev.c
===================================================================
RCS file: /home/cvs/src/sys/dev/i2c/ihidev.c,v
diff -u -p -r1.43 ihidev.c
--- sys/dev/i2c/ihidev.c 23 May 2026 11:10:57 -0000 1.43
+++ sys/dev/i2c/ihidev.c 23 May 2026 13:57:30 -0000
@@ -76,7 +76,7 @@ int ihidev_maxrepid(void *buf, int len);
int ihidev_print(void *aux, const char *pnp);
int ihidev_submatch(struct device *parent, void *cf, void *aux);
-#define IHIDEV_QUIRK_RE_POWER_ON 0x1
+#define IHIDEV_QUIRK_RETRY_GET_REPORT 0x1
const struct ihidev_quirks {
uint16_t ihq_vid;
@@ -84,7 +84,7 @@ const struct ihidev_quirks {
int ihq_quirks;
} ihidev_devs[] = {
/* HONOR MagicBook Art 14 Touchpad (QTEC0002) */
- { 0x35cc, 0x0104, IHIDEV_QUIRK_RE_POWER_ON },
+ { 0x35cc, 0x0104, IHIDEV_QUIRK_RETRY_GET_REPORT },
};
const struct cfattach ihidev_ca = {
@@ -368,6 +368,7 @@ ihidev_hid_command(struct ihidev_softc *
int dataoff = 4;
int report_id = rreq->id;
int report_len = rreq->len + 2 + 1;
+ int attempt, ntries;
int d;
uint8_t *tmprep;
@@ -403,8 +404,22 @@ ihidev_hid_command(struct ihidev_softc *
tmprep = malloc(report_len, M_DEVBUF, M_WAITOK | M_ZERO);
/* type 3 id 8: 22 00 38 02 23 00 */
- res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr,
- &cmd, cmdlen, tmprep, report_len, 0);
+ ntries = (sc->sc_quirks & IHIDEV_QUIRK_RETRY_GET_REPORT) ?
+ 5 : 1;
+ for (attempt = 0; attempt < ntries; attempt++) {
+ memset(tmprep, 0, report_len);
+ res = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
+ sc->sc_addr, &cmd, cmdlen, tmprep, report_len, 0);
+
+ d = tmprep[0] | tmprep[1] << 8;
+ if (res == 0 &&
+ d == report_len &&
+ tmprep[2] == rreq->id)
+ break;
+
+ if (attempt + 1 < ntries)
+ ihidev_sleep(sc, 100);
+ }
d = tmprep[0] | tmprep[1] << 8;
if (d != report_len)
@@ -653,23 +668,6 @@ ihidev_hid_desc_parse(struct ihidev_soft
printf("%s: failed fetching HID report\n",
sc->sc_dev.dv_xname);
return (1);
- }
-
- if (sc->sc_quirks & IHIDEV_QUIRK_RE_POWER_ON) {
- if (ihidev_poweron(sc))
- return (1);
-
- /*
- * 7.2.8 states that a device shall not respond back
- * after receiving the power on command, and must ensure
- * that it transitions to power on state in less than 1
- * second. The ihidev_poweron function uses a shorter
- * sleep, sufficient for the ON-RESET sequence. Here,
- * however, it sleeps for the full second to accommodate
- * cold boot scenarios on affected devices.
- */
-
- ihidev_sleep(sc, 1000);
}
return (0);
--
wbr, Kirill
sys/ihidev: replace HONOR's touchpad quirk