The driver didn't work, because it expects the whole data packet in a
single interrupt. Reality shows that with current kernels a 81 bytes packet is split into 3 interrupts with 32 + 32 + 17 bytes. I have added a workaround to deal with it. The Geyser2 devices with 64 byte packets are unsupported at the moment. Somebody needs to test it. New: Added support for the iBook 12-inch trackpad.
This commit is contained in:
parent
722eddfd32
commit
155d37a03c
|
@ -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 <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usbdevs.h>
|
||||
#include <dev/usb/uhidev.h>
|
||||
#include <dev/usb/hid.h>
|
||||
|
||||
#include <dev/wscons/wsconsio.h>
|
||||
#include <dev/wscons/wsmousevar.h>
|
||||
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue