diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/macppc/dev/tpms.c | 209 |
1 files changed, 114 insertions, 95 deletions
diff --git a/sys/arch/macppc/dev/tpms.c b/sys/arch/macppc/dev/tpms.c index 5319a9e405c..13be917e32b 100644 --- a/sys/arch/macppc/dev/tpms.c +++ b/sys/arch/macppc/dev/tpms.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tpms.c,v 1.12 2007/06/14 10:11:16 mbalmer Exp $ */ +/* $OpenBSD: tpms.c,v 1.13 2009/03/08 14:10:08 robert Exp $ */ /* * Copyright (c) 2005, Johan Wallén @@ -35,7 +35,7 @@ /* * The tpms driver provides support for the trackpad on new (post - * February 2005) Apple PowerBooks (and iBooks?) that are not standard + * February 2005) Apple PowerBooks and iBooks that are not standard * USB HID mice. */ @@ -125,35 +125,6 @@ #include <dev/wscons/wsmousevar.h> /* - * Debugging output. - */ - -/* XXX Should be redone, and its use should be added back. */ - -#ifdef TPMS_DEBUG - -/* - * Print the error message (preceded by the driver and function) - * specified by the string literal fmt (followed by newline) if - * tpmsdebug is greater than n. The macro may only be used in the - * scope of sc, which must be castable to struct device *. There must - * be at least one vararg. Do not define TPMS_DEBUG on non-C99 - * compilers. - */ - -#define DPRINTFN(n, fmt, ...) \ -do { \ - if (tpmsdebug > (n)) \ - logprintf("%s: %s: " fmt "\n", \ - ((struct device *) sc)->dv_xname, \ - __func__, __VA_ARGS__); \ -} while ( /* CONSTCOND */ 0) - -int tpmsdebug = 0; - -#endif /* TPMS_DEBUG */ - -/* * Magic numbers. */ @@ -170,7 +141,8 @@ int tpmsdebug = 0; * can be different for each device. The meanings of the parameters * are as follows. * - * desc: A printable description used for dmesg output. + * type: Type of the trackpad device, used for dmesg output, and + * to know some of the device parameters. * * noise: Amount of noise in the computed position. This controls * how large a change must be to get reported, and how @@ -200,7 +172,10 @@ int tpmsdebug = 0; */ struct tpms_dev { - const char *descr; /* Description of the driver (for dmesg). */ + int type; /* Type of the trackpad. */ +#define FOUNTAIN 0x00 +#define GEYSER1 0x01 +#define GEYSER2 0x02 int noise; /* Amount of noise in the computed position. */ int threshold; /* Changes less than this are ignored. */ int x_factor; /* Factor used in computation with X-coordinates. */ @@ -214,9 +189,9 @@ struct tpms_dev { /* Devices supported by this driver. */ static struct tpms_dev tpms_devices[] = { -#define POWERBOOK_TOUCHPAD(inches, prod, x_fact, x_sens, y_fact) \ +#define POWERBOOK_TOUCHPAD(ttype, prod, x_fact, x_sens, y_fact) \ { \ - .descr = #inches " inch PowerBook Trackpad", \ + .type = (ttype), \ .vendor = USB_VENDOR_APPLE, \ .product = (prod), \ .noise = 16, \ @@ -227,14 +202,17 @@ static struct tpms_dev tpms_devices[] = .y_sensors = 16 \ } /* 12 inch PowerBooks */ - POWERBOOK_TOUCHPAD(12, 0x030a, 69, 16, 52), /* XXX Not tested. */ - /* 14 inch iBook G4 */ - POWERBOOK_TOUCHPAD(14, 0x030b, 69, 16, 52), + POWERBOOK_TOUCHPAD(FOUNTAIN, 0x030a, 69, 16, 52), /* XXX Not tested. */ + /* 12 and 14 inch iBook G4 */ + POWERBOOK_TOUCHPAD(GEYSER1, 0x030b, 69, 16, 52), /* 15 inch PowerBooks */ - POWERBOOK_TOUCHPAD(15, 0x020e, 85, 16, 57), /* XXX Not tested. */ - POWERBOOK_TOUCHPAD(15, 0x020f, 85, 16, 57), + POWERBOOK_TOUCHPAD(FOUNTAIN, 0x020e, 85, 16, 57), /* XXX Not tested. */ + POWERBOOK_TOUCHPAD(FOUNTAIN, 0x020f, 85, 16, 57), + POWERBOOK_TOUCHPAD(GEYSER2, 0x0214, 90, 15, 107), + POWERBOOK_TOUCHPAD(GEYSER2, 0x0215, 90, 15, 107), + POWERBOOK_TOUCHPAD(GEYSER2, 0x0216, 90, 15, 107), /* 17 inch PowerBooks */ - POWERBOOK_TOUCHPAD(17, 0x020d, 71, 26, 68) /* XXX Not tested. */ + POWERBOOK_TOUCHPAD(FOUNTAIN, 0x020d, 71, 26, 68) /* XXX Not tested. */ #undef POWERBOOK_TOUCHPAD }; @@ -248,9 +226,11 @@ static struct tpms_dev tpms_devices[] = /* Device data. */ struct tpms_softc { struct uhidev sc_hdev; /* USB parent (got the struct device). */ + int sc_type; /* Type of the trackpad */ + int sc_datalen; int sc_acc[TPMS_SENSORS]; /* Accumulated sensor values. */ - signed char sc_prev[TPMS_SENSORS]; /* Previous sample. */ - signed char sc_sample[TPMS_SENSORS]; /* Current sample. */ + unsigned char sc_prev[TPMS_SENSORS]; /* Previous sample. */ + unsigned char sc_sample[TPMS_SENSORS]; /* Current sample. */ struct device *sc_wsmousedev; /* WSMouse device. */ int sc_noise; /* Amount of noise. */ int sc_threshold; /* Threshold value. */ @@ -275,7 +255,7 @@ void tpms_intr(struct uhidev *, void *, unsigned int); int tpms_enable(void *); void tpms_disable(void *); int tpms_ioctl(void *, unsigned long, caddr_t, int, struct proc *); -void reorder_sample(signed char *, signed char *); +void reorder_sample(struct tpms_softc*, unsigned char *, unsigned char *); int compute_delta(struct tpms_softc *, int *, int *, int *, uint32_t *); int detect_pos(int *, int, int, int, int *, int *); int smooth_pos(int, int, int); @@ -352,6 +332,8 @@ tpms_attach(struct device *parent, struct device *self, void *aux) int i; uint16_t vendor, product; + sc->sc_datalen = TPMS_DATA_LEN; + /* Fill in device-specific parameters. */ if ((udd = usbd_get_device_descriptor(uha->parent->sc_udev)) != NULL) { product = UGETW(udd->idProduct); @@ -359,7 +341,21 @@ tpms_attach(struct device *parent, struct device *self, void *aux) for (i = 0; i < TPMS_NUM_DEVICES; i++) { pd = &tpms_devices[i]; if (product == pd->product && vendor == pd->vendor) { - printf(": %s\n", pd->descr); + switch (pd->type) { + case FOUNTAIN: + printf(": Fountain"); + break; + case GEYSER1: + printf(": Geyser"); + break; + case GEYSER2: + sc->sc_type = GEYSER2; + sc->sc_datalen = 64; + sc->sc_y_sensors = 9; + printf(": Geyser 2"); + break; + } + printf(" Trackpad\n"); sc->sc_noise = pd->noise; sc->sc_threshold = pd->threshold; sc->sc_x_factor = pd->x_factor; @@ -480,20 +476,20 @@ void tpms_intr(struct uhidev *addr, void *ibuf, unsigned int len) { struct tpms_softc *sc = (struct tpms_softc *)addr; - signed char *data; + unsigned char *data; int dx, dy, dz, i, s; uint32_t buttons; /* Ignore incomplete data packets. */ - if (len != TPMS_DATA_LEN) + if (len != sc->sc_datalen) return; data = ibuf; /* The last byte is 1 if the button is pressed and 0 otherwise. */ - buttons = !!data[TPMS_DATA_LEN - 1]; + buttons = !!data[sc->sc_datalen - 1]; /* Everything below assumes that the sample is reordered. */ - reorder_sample(sc->sc_sample, data); + reorder_sample(sc, sc->sc_sample, data); /* Is this the first sample? */ if (!(sc->sc_status & TPMS_VALID)) { @@ -506,7 +502,9 @@ tpms_intr(struct uhidev *addr, void *ibuf, unsigned int len) } /* Accumulate the sensor change while keeping it nonnegative. */ for (i = 0; i < TPMS_SENSORS; i++) { - sc->sc_acc[i] += sc->sc_sample[i] - sc->sc_prev[i]; + sc->sc_acc[i] += + (signed char)(sc->sc_sample[i] - sc->sc_prev[i]); + if (sc->sc_acc[i] < 0) sc->sc_acc[i] = 0; } @@ -535,26 +533,40 @@ tpms_intr(struct uhidev *addr, void *ibuf, unsigned int len) */ void -reorder_sample(signed char *to, signed char *from) +reorder_sample(struct tpms_softc *sc, unsigned char *to, unsigned char *from) { int i; - for (i = 0; i < 8; i++) { - /* X-sensors. */ - to[i] = from[5 * i + 2]; - to[i + 8] = from[5 * i + 4]; - to[i + 16] = from[5 * i + 42]; + if (sc->sc_type == GEYSER2) { + int j; + + memset(to, 0, TPMS_SENSORS); + for (i = 0, j = 19; i < 20; i += 2, j += 3) { + to[i] = from[j]; + to[i + 1] = from[j + 1]; + } + for (i = 0, j = 1; i < 9; i += 2, j += 3) { + to[TPMS_X_SENSORS + i] = from[j]; + to[TPMS_X_SENSORS + i + 1] = from[j + 1]; + } + } else { + for (i = 0; i < 8; i++) { + /* X-sensors. */ + to[i] = from[5 * i + 2]; + to[i + 8] = from[5 * i + 4]; + to[i + 16] = from[5 * i + 42]; #if 0 - /* - * XXX This seems to introduce random vertical jumps, so - * we ignore these sensors until we figure out their meaning. - */ - if (i < 2) - to[i + 24] = from[5 * i + 44]; + /* + * XXX This seems to introduce random ventical jumps, so + * we ignore these sensors until we figure out their meaning. + */ + if (i < 2) + to[i + 24] = from[5 * i + 44]; #endif /* 0 */ - /* Y-sensors. */ - to[i + 26] = from[5 * i + 1]; - to[i + 34] = from[5 * i + 3]; + /* Y-sensors. */ + to[i + 26] = from[5 * i + 1]; + to[i + 34] = from[5 * i + 3]; + } } } @@ -582,42 +594,49 @@ compute_delta(struct tpms_softc *sc, int *dx, int *dy, int *dz, fingers = max(x_fingers, y_fingers); /* Check the number of fingers and if we have detected a position. */ - if (fingers > 1) { - /* More than one finger detected, resetting. */ - memset(sc->sc_acc, 0, sizeof(sc->sc_acc)); - sc->sc_x_raw = sc->sc_y_raw = sc->sc_x = sc->sc_y = -1; - return 0; - } else if (x_det == 0 && y_det == 0) { + if (x_det == 0 && y_det == 0) { /* No position detected, resetting. */ memset(sc->sc_acc, 0, sizeof(sc->sc_acc)); sc->sc_x_raw = sc->sc_y_raw = sc->sc_x = sc->sc_y = -1; } else if (x_det > 0 && y_det > 0) { - /* Smooth position. */ - if (sc->sc_x_raw >= 0) { - sc->sc_x_raw = (3 * sc->sc_x_raw + x_raw) / 4; - sc->sc_y_raw = (3 * sc->sc_y_raw + y_raw) / 4; - /* - * Compute virtual position and change if we already - * have a decent position. - */ - if (sc->sc_x >= 0) { - x = smooth_pos(sc->sc_x, sc->sc_x_raw, - sc->sc_noise); - y = smooth_pos(sc->sc_y, sc->sc_y_raw, - sc->sc_noise); - *dx = x - sc->sc_x; - *dy = y - sc->sc_y; - sc->sc_x = x; - sc->sc_y = y; + switch (fingers) { + case 1: + /* Smooth position. */ + if (sc->sc_x_raw >= 0) { + sc->sc_x_raw = (3 * sc->sc_x_raw + x_raw) / 4; + sc->sc_y_raw = (3 * sc->sc_y_raw + y_raw) / 4; + /* + * Compute virtual position and change if we + * already have a decent position. + */ + if (sc->sc_x >= 0) { + x = smooth_pos(sc->sc_x, sc->sc_x_raw, + sc->sc_noise); + y = smooth_pos(sc->sc_y, sc->sc_y_raw, + sc->sc_noise); + *dx = x - sc->sc_x; + *dy = y - sc->sc_y; + sc->sc_x = x; + sc->sc_y = y; + } else { + /* Initialise virtual position. */ + sc->sc_x = sc->sc_x_raw; + sc->sc_y = sc->sc_y_raw; + } } else { - /* Initialise virtual position. */ - sc->sc_x = sc->sc_x_raw; - sc->sc_y = sc->sc_y_raw; + /* Initialise raw position. */ + sc->sc_x_raw = x_raw; + sc->sc_y_raw = y_raw; } - } else { - /* Initialise raw position. */ - sc->sc_x_raw = x_raw; - sc->sc_y_raw = y_raw; + break; + case 2: + if (*buttons == 1) + *buttons = 4; + break; + case 3: + if (*buttons == 1) + *buttons = 2; + break; } } return (1); |