-/* $OpenBSD: apldc.c,v 1.11 2023/09/22 01:10:43 jsg Exp $ */
+/* $OpenBSD: apldc.c,v 1.12 2024/01/20 08:00:59 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
*
uint8_t sc_mtdesc[APLDCHIDEV_DESC_MAX];
size_t sc_mtdesclen;
int sc_mt_ready;
+ int sc_x_min;
+ int sc_x_max;
+ int sc_y_min;
+ int sc_y_max;
+ int sc_h_res;
+ int sc_v_res;
struct apldchidev_gpio sc_gpio[APLDCHIDEV_NUM_GPIOS];
u_int sc_ngpios;
uint8_t sc_cmd_iface;
uint8_t sc_cmd_seq;
+ uint8_t sc_data[APLDCHIDEV_DESC_MAX];
+ size_t sc_data_len;
uint32_t sc_retcode;
int sc_busy;
};
uint8_t cmd[512];
} __packed;
+struct mtp_dim {
+ uint32_t width;
+ uint32_t height;
+ int16_t x_min;
+ int16_t y_min;
+ int16_t x_max;
+ int16_t y_max;
+};
+
#define MTP_CMD_RESET_INTERFACE 0x40
#define MTP_CMD_SEND_FIRMWARE 0x95
#define MTP_CMD_ENABLE_INTERFACE 0xb4
#define MTP_CMD_ACK_GPIO_CMD 0xa1
+#define MTP_CMD_GET_DIMENSIONS 0xd9
void
apldchidev_handle_gpio_req(struct apldchidev_softc *sc, uint8_t iface,
printf("%s: got ack with unexpected seq\n",
sc->sc_dev.dv_xname);
}
+ if (MTP_REQ(shdr->flags) == MTP_REQ_GET_REPORT &&
+ shdr->len <= sizeof(sc->sc_data)) {
+ memcpy(sc->sc_data, (shdr + 1), shdr->len);
+ sc->sc_data_len = shdr->len;
+ } else {
+ sc->sc_data_len = 0;
+ }
sc->sc_retcode = shdr->retcode;
sc->sc_busy = 0;
wakeup(sc);
return 0;
}
+void
+apldchidev_get_dimensions(struct apldchidev_softc *sc)
+{
+ uint8_t cmd[1] = { MTP_CMD_GET_DIMENSIONS };
+ struct mtp_dim dim;
+ uint8_t flags;
+
+ flags = MTP_GROUP_CMD << MTP_GROUP_SHIFT;
+ flags |= MTP_REQ_GET_REPORT << MTP_REQ_SHIFT;
+ apldchidev_cmd(sc, sc->sc_iface_mt, flags, cmd, sizeof(cmd));
+ apldchidev_wait(sc);
+
+ if (sc->sc_retcode == 0 && sc->sc_data_len == sizeof(dim) + 1 &&
+ sc->sc_data[0] == MTP_CMD_GET_DIMENSIONS) {
+ memcpy(&dim, &sc->sc_data[1], sizeof(dim));
+ sc->sc_x_min = dim.x_min;
+ sc->sc_x_max = dim.x_max;
+ sc->sc_y_min = dim.y_min;
+ sc->sc_y_max = dim.y_max;
+ sc->sc_h_res = (100 * (dim.x_max - dim.x_min)) / dim.width;
+ sc->sc_v_res = (100 * (dim.y_max - dim.y_min)) / dim.height;
+ }
+}
+
void
apldchidev_attachhook(struct device *self)
{
if (error)
goto out;
+ apldchidev_get_dimensions(sc);
+
aa.aa_name = "multi-touch";
aa.aa_desc = sc->sc_mtdesc;
aa.aa_desclen = sc->sc_mtdesclen;
#define DEFAULT_PRESSURE 40
struct apldcms_softc {
- struct device sc_dev;
- struct device *sc_wsmousedev;
+ struct device sc_dev;
+ struct apldchidev_softc *sc_hidev;
+ struct device *sc_wsmousedev;
- int sc_enabled;
+ int sc_enabled;
- int tp_offset;
- int tp_fingerpad;
+ int tp_offset;
+ int tp_fingerpad;
- struct mtpoint frame[UBCMTP_MAX_FINGERS];
- int contacts;
- int btn;
+ struct mtpoint frame[UBCMTP_MAX_FINGERS];
+ int contacts;
+ int btn;
};
int apldcms_enable(void *);
struct apldcms_softc *sc = (struct apldcms_softc *)self;
struct wsmousedev_attach_args aa;
+ sc->sc_hidev = (struct apldchidev_softc *)parent;
+
printf("\n");
sc->tp_offset = UBCMTP_TYPE4_TPOFF;
{
struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev);
- /* The values below are for the MacBookPro17,1 */
hw->type = WSMOUSE_TYPE_TOUCHPAD;
hw->hw_type = WSMOUSEHW_CLICKPAD;
- hw->x_min = -6046;
- hw->x_max = 6536;
- hw->y_min = -164;
- hw->y_max = 7439;
+ hw->x_min = sc->sc_hidev->sc_x_min;
+ hw->x_max = sc->sc_hidev->sc_x_max;
+ hw->y_min = sc->sc_hidev->sc_y_min;
+ hw->y_max = sc->sc_hidev->sc_y_max;
+ hw->h_res = sc->sc_hidev->sc_h_res;
+ hw->v_res = sc->sc_hidev->sc_v_res;
hw->mt_slots = UBCMTP_MAX_FINGERS;
hw->flags = WSMOUSEHW_MT_TRACKING;