Wait for a reply to the command that switches the touchpad into raw mode.
authorkettenis <kettenis@openbsd.org>
Mon, 21 Nov 2022 14:39:23 +0000 (14:39 +0000)
committerkettenis <kettenis@openbsd.org>
Mon, 21 Nov 2022 14:39:23 +0000 (14:39 +0000)
If we don't do this, the SMC appears to crash on machines with firmware
from macOS 12.6.1.  Insert a small delay of 1ms after sending the command
as polling for the reply too soon makes the command fail.

ok tobhe@

sys/arch/arm64/dev/aplhidev.c

index f1c3f5a..265c519 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: aplhidev.c,v 1.9 2022/11/09 10:05:18 robert Exp $     */
+/*     $OpenBSD: aplhidev.c,v 1.10 2022/11/21 14:39:23 kettenis Exp $  */
 /*
  * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
  * Copyright (c) 2013-2014 joshua stein <jcs@openbsd.org>
@@ -133,6 +133,7 @@ struct aplhidev_softc {
        uint32_t                *sc_gpio;
        int                     sc_gpiolen;
 
+       uint8_t                 sc_mode;
        uint16_t                sc_vendor;
        uint16_t                sc_product;
 
@@ -238,7 +239,14 @@ aplhidev_attach(struct device *parent, struct device *self, void *aux)
                        break;
        }
 
+       sc->sc_mode = APLHIDEV_MODE_HID;
        aplhidev_set_mode(sc, APLHIDEV_MODE_RAW);
+       for (retry = 10; retry > 0; retry--) {
+               aplhidev_intr(sc);
+               delay(1000);
+               if (sc->sc_mode == APLHIDEV_MODE_RAW)
+                       break;
+       }
 
        printf("\n");
 
@@ -394,6 +402,8 @@ aplhidev_set_mode(struct aplhidev_softc *sc, uint8_t mode)
        delay(100);
        spi_read(sc->sc_spi_tag, (char *)&status, sizeof(status));
        spi_release_bus(sc->sc_spi_tag, 0);
+
+       delay(1000);
 }
 
 int
@@ -460,6 +470,12 @@ aplhidev_intr(void *arg)
 
                return 1;
        }
+       if (packet.flags == APLHIDEV_WRITE_PACKET &&
+           packet.device == APLHIDEV_TP_DEVICE &&
+           hdr->type == APLHIDEV_SET_MODE) {
+               sc->sc_mode = APLHIDEV_MODE_RAW;
+               return 1;
+       }
 
        /* Valid, but unrecognized packet; ignore for now. */
        return 1;