From: kettenis Date: Sun, 2 Oct 2022 19:00:46 +0000 (+0000) Subject: Fetch vendor and product IDs from the keyboard/touchpad controller. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5db73e2946db6c38f3707ae831c8b7b108bb1f62;p=openbsd Fetch vendor and product IDs from the keyboard/touchpad controller. To be used in a future diff to handle machines with touchbar a bit better. ok robert@ --- diff --git a/sys/arch/arm64/dev/aplhidev.c b/sys/arch/arm64/dev/aplhidev.c index fdefe5b9fc6..dc221a0f677 100644 --- a/sys/arch/arm64/dev/aplhidev.c +++ b/sys/arch/arm64/dev/aplhidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aplhidev.c,v 1.7 2022/09/16 16:30:10 robert Exp $ */ +/* $OpenBSD: aplhidev.c,v 1.8 2022/10/02 19:00:46 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis * Copyright (c) 2013-2014 joshua stein @@ -51,6 +51,7 @@ #define APLHIDEV_TP_DEVICE 2 #define APLHIDEV_INFO_DEVICE 208 +#define APLHIDEV_GET_INFO 0x0120 #define APLHIDEV_GET_DESCRIPTOR 0x1020 #define APLHIDEV_DESC_MAX 512 #define APLHIDEV_KBD_REPORT 0x0110 @@ -88,6 +89,17 @@ struct aplhidev_msghdr { uint16_t cmdlen; }; +struct aplhidev_info_hdr { + uint16_t unknown[2]; + uint16_t num_devices; + uint16_t vendor; + uint16_t product; + uint16_t version; + uint16_t vendor_str[2]; + uint16_t product_str[2]; + uint16_t serial_str[2]; +}; + struct aplhidev_get_desc { struct aplhidev_msghdr hdr; uint16_t crc; @@ -119,6 +131,9 @@ struct aplhidev_softc { uint32_t *sc_gpio; int sc_gpiolen; + uint16_t sc_vendor; + uint16_t sc_product; + struct device *sc_kbd; uint8_t sc_kbddesc[APLHIDEV_DESC_MAX]; size_t sc_kbddesclen; @@ -139,6 +154,7 @@ struct cfdriver aplhidev_cd = { NULL, "aplhidev", DV_DULL }; +void aplhidev_get_info(struct aplhidev_softc *); void aplhidev_get_descriptor(struct aplhidev_softc *, uint8_t); void aplhidev_set_leds(struct aplhidev_softc *, uint8_t); void aplhidev_set_mode(struct aplhidev_softc *, uint8_t); @@ -196,6 +212,14 @@ aplhidev_attach(struct device *parent, struct device *self, void *aux) fdt_intr_establish(sc->sc_node, IPL_TTY, aplhidev_intr, sc, sc->sc_dev.dv_xname); + aplhidev_get_info(sc); + for (retry = 10; retry > 0; retry--) { + aplhidev_intr(sc); + delay(1000); + if (sc->sc_vendor != 0 && sc->sc_product != 0) + break; + } + aplhidev_get_descriptor(sc, APLHIDEV_KBD_DEVICE); for (retry = 10; retry > 0; retry--) { aplhidev_intr(sc); @@ -231,6 +255,39 @@ aplhidev_attach(struct device *parent, struct device *self, void *aux) } } +void +aplhidev_get_info(struct aplhidev_softc *sc) +{ + struct aplhidev_spi_packet packet; + struct aplhidev_get_desc *msg; + struct aplhidev_spi_status status; + + memset(&packet, 0, sizeof(packet)); + packet.flags = APLHIDEV_WRITE_PACKET; + packet.device = APLHIDEV_INFO_DEVICE; + packet.len = sizeof(*msg); + + msg = (void *)&packet.data[0]; + msg->hdr.type = APLHIDEV_GET_INFO; + msg->hdr.device = APLHIDEV_INFO_DEVICE; + msg->hdr.msgid = sc->sc_msgid++; + msg->hdr.cmdlen = 0; + msg->hdr.rsplen = APLHIDEV_DESC_MAX; + msg->crc = crc16(0, (void *)msg, sizeof(*msg) - 2); + + packet.crc = crc16(0, (void *)&packet, sizeof(packet) - 2); + + spi_acquire_bus(sc->sc_spi_tag, 0); + spi_config(sc->sc_spi_tag, &sc->sc_spi_conf); + spi_transfer(sc->sc_spi_tag, (char *)&packet, NULL, sizeof(packet), + SPI_KEEP_CS); + delay(100); + spi_read(sc->sc_spi_tag, (char *)&status, sizeof(status)); + spi_release_bus(sc->sc_spi_tag, 0); + + delay(1000); +} + void aplhidev_get_descriptor(struct aplhidev_softc *sc, uint8_t device) { @@ -376,6 +433,15 @@ aplhidev_intr(void *arg) } /* Replies to commands we sent. */ + if (packet.flags == APLHIDEV_WRITE_PACKET && + packet.device == APLHIDEV_INFO_DEVICE && + hdr->type == APLHIDEV_GET_INFO) { + struct aplhidev_info_hdr *info = + (struct aplhidev_info_hdr *)&packet.data[8]; + sc->sc_vendor = info->vendor; + sc->sc_product = info->product; + return 1; + } if (packet.flags == APLHIDEV_WRITE_PACKET && packet.device == APLHIDEV_INFO_DEVICE && hdr->type == APLHIDEV_GET_DESCRIPTOR) {