diff --git a/sys/arch/macppc/dev/pbms.c b/sys/arch/macppc/dev/pbms.c index 0fbbf58e34a6..23438d9741c5 100644 --- a/sys/arch/macppc/dev/pbms.c +++ b/sys/arch/macppc/dev/pbms.c @@ -1,4 +1,4 @@ -/* $Id: pbms.c,v 1.11 2010/11/19 18:27:12 phx Exp $ */ +/* $Id: pbms.c,v 1.12 2010/12/20 19:18:24 phx Exp $ */ /* * Copyright (c) 2005, Johan Wallén @@ -67,10 +67,11 @@ * 2, 7, 12, 17, 22, 27, 32, 37, 4, 9, 14, 19, 24, 29, 34, 39, 42, * 47, 52, 57, 62, 67, 72, 77, 44 and 49; * - * in the Y direction, the sensors correspond to byte positions + * In the Y direction, the sensors correspond to byte positions * * 1, 6, 11, 16, 21, 26, 31, 36, 3, 8, 13, 18, 23, 28, 33 and 38. * + * On 12 inch iBooks only the 9 first sensors in Y-direction are used. * The change in the sensor values over time is more interesting than * their absolute values: if the pressure increases, we know that the * finger has just moved there. @@ -128,6 +129,7 @@ #include #include #include +#include #include #include @@ -206,8 +208,9 @@ static struct pbms_dev pbms_devices[] = .y_factor = (y_fact), \ .y_sensors = 16 \ } - /* 12 inch PowerBooks */ + /* 12 inch PowerBooks/iBooks */ POWERBOOK_TOUCHPAD(12, 0x030a, 69, 16, 52), /* XXX Not tested. */ + POWERBOOK_TOUCHPAD(12, 0x030b, 73, 15, 96), /* 15 inch PowerBooks */ POWERBOOK_TOUCHPAD(15, 0x020e, 85, 16, 57), /* XXX Not tested. */ POWERBOOK_TOUCHPAD(15, 0x020f, 85, 16, 57), @@ -230,10 +233,12 @@ static struct pbms_dev pbms_devices[] = struct pbms_softc { struct uhidev sc_hdev; /* USB parent (got the struct device). */ int is_geyser2; - int sc_datalen; + int sc_datalen; /* Size of a data packet */ + int sc_bufusage; /* Number of bytes in sc_databuf */ int sc_acc[PBMS_SENSORS]; /* Accumulated sensor values. */ unsigned char sc_prev[PBMS_SENSORS]; /* Previous sample. */ unsigned char sc_sample[PBMS_SENSORS]; /* Current sample. */ + uint8_t sc_databuf[PBMS_DATA_LEN]; /* Buffer for a data packet */ device_t sc_wsmousedev; /* WSMouse device. */ int sc_noise; /* Amount of noise. */ int sc_theshold; /* Threshold value. */ @@ -354,6 +359,8 @@ pbms_attach(device_t parent, device_t self, void *aux) sc->sc_datalen = 64; sc->sc_y_sensors = 9; } + else if (product == 0x030b) + sc->sc_y_sensors = 9; break; } } @@ -421,6 +428,7 @@ pbms_enable(void *v) sc->sc_status |= PBMS_ENABLED; sc->sc_status &= ~PBMS_VALID; + sc->sc_bufusage = 0; sc->sc_buttons = 0; memset(sc->sc_sample, 0, sizeof(sc->sc_sample)); @@ -463,20 +471,39 @@ void pbms_intr(struct uhidev *addr, void *ibuf, unsigned int len) { struct pbms_softc *sc = (struct pbms_softc *)addr; - unsigned char *data; + uint8_t *data; int dx, dy, dz, i, s; uint32_t buttons; - /* Ignore incomplete data packets. */ - if (len != sc->sc_datalen) - return; - data = ibuf; + /* + * We may have to construct the full data packet over two or three + * sequential interrupts, as the device only sends us chunks of + * 32 or 64 bytes of data. + * This also requires some synchronization, to make sure we place + * the first protocol-byte at the first byte in the bufffer. + */ + if (sc->is_geyser2) { + /* XXX Need to check this. */ + } else { + /* the last chunk is always 17 bytes */ + if (len == 17 && sc->sc_bufusage + len != sc->sc_datalen) { + sc->sc_bufusage = 0; /* discard bad packet */ + return; + } + } + memcpy(sc->sc_databuf + sc->sc_bufusage, ibuf, len); + sc->sc_bufusage += len; + if (sc->sc_bufusage != sc->sc_datalen) + return; /* wait until packet is complete */ + + /* process the now complete protocol and clear the buffer */ + data = sc->sc_databuf; + sc->sc_bufusage = 0; #if 0 - printf("("); - for (i = 0; i < len; i++) - printf(" %d", data[i]); - printf(" )\n"); + for (i = 0; i < sc->sc_datalen; i++) + printf(" %02x", data[i]); + printf("\n"); #endif /* The last byte is 1 if the button is pressed and 0 otherwise. */