svn commit: r263064 - in stable/9: share/man/man4 sys/dev/usb/input
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Mar 12 07:18:40 UTC 2014
Author: hselasky
Date: Wed Mar 12 07:18:39 2014
New Revision: 263064
URL: http://svnweb.freebsd.org/changeset/base/263064
Log:
MFC r262417, r262439, r262454, r262455 and r262478:
- Several updates and improvements to ATP driver.
- Start effort merging WSP and ATP driver.
Modified:
stable/9/share/man/man4/atp.4
stable/9/sys/dev/usb/input/atp.c
Directory Properties:
stable/9/share/ (props changed)
stable/9/share/man/ (props changed)
stable/9/share/man/man4/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/dev/ (props changed)
Modified: stable/9/share/man/man4/atp.4
==============================================================================
--- stable/9/share/man/man4/atp.4 Wed Mar 12 07:15:41 2014 (r263063)
+++ stable/9/share/man/man4/atp.4 Wed Mar 12 07:18:39 2014 (r263064)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2009 Rohit Grover <rgrover1 at gmail dot com>.
+.\" Copyright (c) 2014 Rohit Grover <rgrover1 at gmail dot com>.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 7, 2014
+.Dd February 24, 2014
.Dt ATP 4
.Os
.Sh NAME
@@ -41,8 +41,7 @@ your kernel configuration file:
.Cd "device usb"
.Ed
.Pp
-Alternatively, to load the driver as a
-module at boot time, place the following line in
+Alternatively, to load the driver as a module at boot time, place the following line in
.Xr loader.conf 5 :
.Bd -literal -offset indent
atp_load="YES"
@@ -50,24 +49,21 @@ atp_load="YES"
.Sh DESCRIPTION
The
.Nm
-driver provides support for the Apple Internal Trackpad
-device found in many Apple laptops.
+driver provides support for the Apple Internal Trackpad device found in many
+Apple laptops. Older (Fountain/Geyser) and the newer (Wellspring) trackpad
+families are all supported through a unified driver.
+.Pp
+The driver simulates a three\-button mouse using multi\-finger tap detection.
+Single finger tap generates a left\-button click; two\-finger tap maps to the
+middle button; whereas a three\-finger tap gets treated as a right button
+click.
+.Pp
+There is support for 2\-finger horizontal scrolling, which translates to
+page\-back/forward events; vertical multi\-finger scrolling emulates the mouse
+wheel.
.Pp
-The driver simulates a three\-button mouse using multi\-finger tap
-detection.
-.
-A single\-finger tap generates a left button click;
-two\-finger tap maps to the middle button; whereas a three\-finger tap
-gets treated as a right button click.
-.
A double\-tap followed by a drag is treated as a selection gesture; a
virtual left\-button click is assumed for the lifespan of the drag.
-.
-.Nm
-attempts to filter away activity at the horizontal edges of the
-trackpad\-\-this is to keep unintentional palm movement from being
-considered as user input.
-.
.Pp
.Nm
supports dynamic reconfiguration using
@@ -76,6 +72,28 @@ through nodes under
.Nm hw.usb.atp .
Pointer sensitivity can be controlled using the sysctl tunable
.Nm hw.usb.atp.scale_factor .
+Smaller values of
+.Fa scale_factor
+result in faster movement.
+.
+A simple high-pass filter is used to reduce contributions
+from small movements; the threshold for this filter may be controlled by
+.Nm hw.usb.atp.small_movement .
+.
+The maximum tolerable duration of a touch gesture is controlled by
+.Nm hw.usb.atp.touch_timeout
+(in microseconds); beyond this period, touches are considered to be slides.
+(This conversion also happens when a finger stroke accumulates at least
+.Nm hw.usb.atp.slide_min_movement
+movement (in mickeys).
+.
+The maximum time (in microseconds) to allow an association between a double-
+tap and drag gesture may be controlled by
+.Nm hw.usb.atp.double_tap_threshold .
+.
+Should one want to disable tap detection and rely only upon physical button
+presses, set the following sysctl to a value of 2
+.Nm hw.usb.atp.tap_minimum .
.
.Sh HARDWARE
The
@@ -84,6 +102,8 @@ driver provides support for the followin
.Pp
.Bl -bullet -compact
.It
+PowerBooks, iBooks (IDs: 0x020e, 0x020f, 0x0210, 0x0214, 0x0215, 0x0216)
+.It
Core Duo MacBook & MacBook Pro (IDs: 0x0217, 0x0218, 0x0219)
.It
Core2 Duo MacBook & MacBook Pro (IDs: 0x021a, 0x021b, 0x021c)
@@ -95,6 +115,14 @@ Core2 Duo MacBook3,1 (IDs: 0x0229, 0x022
15 inch PowerBook (IDs: 0x020e, 0x020f, 0x0215)
.It
17 inch PowerBook (ID: 0x020d)
+.It
+Almost all recent Macbook-Pros and Airs (IDs: 0x0223, 0x0223, 0x0224, 0x0224,
+0x0225, 0x0225, 0x0230, 0x0230, 0x0231, 0x0231, 0x0232, 0x0232, 0x0236,
+0x0236, 0x0237, 0x0237, 0x0238, 0x0238, 0x023f, 0x023f, 0x0240, 0x0241,
+0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0249, 0x024a, 0x024b,
+0x024c, 0x024d, 0x024e, 0x0252, 0x0252, 0x0253, 0x0253, 0x0254, 0x0254,
+0x0259, 0x025a, 0x025b, 0x0262, 0x0262, 0x0263, 0x0264, 0x0290, 0x0291,
+0x0292)
.El
.Pp
To discover the product\-id of a touchpad, search for 'Trackpad' in the
Modified: stable/9/sys/dev/usb/input/atp.c
==============================================================================
--- stable/9/sys/dev/usb/input/atp.c Wed Mar 12 07:15:41 2014 (r263063)
+++ stable/9/sys/dev/usb/input/atp.c Wed Mar 12 07:18:39 2014 (r263064)
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 Rohit Grover
+ * Copyright (c) 2014 Rohit Grover
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,29 +24,64 @@
* SUCH DAMAGE.
*/
+/*
+ * Some tables, structures, definitions and constant values for the
+ * touchpad protocol has been copied from Linux's
+ * "drivers/input/mouse/bcm5974.c" which has the following copyright
+ * holders under GPLv2. All device specific code in this driver has
+ * been written from scratch. The decoding algorithm is based on
+ * output from FreeBSD's usbdump.
+ *
+ * Copyright (C) 2008 Henrik Rydberg (rydberg at euromail.se)
+ * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft at gmail.com)
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg at kroah.com)
+ * Copyright (C) 2005 Johannes Berg (johannes at sipsolutions.net)
+ * Copyright (C) 2005 Stelian Pop (stelian at popies.net)
+ * Copyright (C) 2005 Frank Arnold (frank at scirocco-5v-turbo.de)
+ * Copyright (C) 2005 Peter Osterlund (petero2 at telia.com)
+ * Copyright (C) 2005 Michael Hanselmann (linux-kernel at hansmi.ch)
+ * Copyright (C) 2006 Nicolas Boichat (nicolas at boichat.ch)
+ */
+
+/*
+ * Author's note: 'atp' supports two distinct families of Apple trackpad
+ * products: the older Fountain/Geyser and the latest Wellspring trackpads.
+ * The first version made its appearance with FreeBSD 8 and worked only with
+ * the Fountain/Geyser hardware. A fork of this driver for Wellspring was
+ * contributed by Huang Wen Hui. This driver unifies the Wellspring effort
+ * and also improves upon the original work.
+ *
+ * I'm grateful to Stephan Scheunig, Angela Naegele, and Nokia IT-support
+ * for helping me with access to hardware. Thanks also go to Nokia for
+ * giving me an opportunity to do this work.
+ */
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/stdint.h>
+#include <sys/stddef.h>
#include <sys/param.h>
+#include <sys/types.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/malloc.h>
+#include <sys/bus.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
-#include <sys/bus.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/selinfo.h>
#include <sys/poll.h>
-#include <sys/sysctl.h>
-#include <sys/uio.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbhid.h>
+
#include "usbdevs.h"
#define USB_DEBUG_VAR atp_debug
@@ -61,17 +96,35 @@ __FBSDID("$FreeBSD$");
* `options' statements in the kernel configuration file.
*/
-/* The multiplier used to translate sensor reported positions to mickeys. */
+/* The divisor used to translate sensor reported positions to mickeys. */
#ifndef ATP_SCALE_FACTOR
-#define ATP_SCALE_FACTOR 48
+#define ATP_SCALE_FACTOR 16
+#endif
+
+/* Threshold for small movement noise (in mickeys) */
+#ifndef ATP_SMALL_MOVEMENT_THRESHOLD
+#define ATP_SMALL_MOVEMENT_THRESHOLD 30
+#endif
+
+/* Threshold of instantaneous deltas beyond which movement is considered fast.*/
+#ifndef ATP_FAST_MOVEMENT_TRESHOLD
+#define ATP_FAST_MOVEMENT_TRESHOLD 150
#endif
/*
- * This is the age (in microseconds) beyond which a touch is
- * considered to be a slide; and therefore a tap event isn't registered.
+ * This is the age in microseconds beyond which a touch is considered
+ * to be a slide; and therefore a tap event isn't registered.
*/
#ifndef ATP_TOUCH_TIMEOUT
-#define ATP_TOUCH_TIMEOUT 125000
+#define ATP_TOUCH_TIMEOUT 125000
+#endif
+
+#ifndef ATP_IDLENESS_THRESHOLD
+#define ATP_IDLENESS_THRESHOLD 10
+#endif
+
+#ifndef FG_SENSOR_NOISE_THRESHOLD
+#define FG_SENSOR_NOISE_THRESHOLD 2
#endif
/*
@@ -82,39 +135,40 @@ __FBSDID("$FreeBSD$");
* tap events preceding the slide for such a gesture.
*/
#ifndef ATP_DOUBLE_TAP_N_DRAG_THRESHOLD
-#define ATP_DOUBLE_TAP_N_DRAG_THRESHOLD 200000
+#define ATP_DOUBLE_TAP_N_DRAG_THRESHOLD 200000
#endif
/*
- * The device provides us only with pressure readings from an array of
- * X and Y sensors; for our algorithms, we need to interpret groups
- * (typically pairs) of X and Y readings as being related to a single
- * finger stroke. We can relate X and Y readings based on their times
- * of incidence. The coincidence window should be at least 10000us
- * since it is used against values from getmicrotime(), which has a
- * precision of around 10ms.
- */
-#ifndef ATP_COINCIDENCE_THRESHOLD
-#define ATP_COINCIDENCE_THRESHOLD 40000 /* unit: microseconds */
-#if ATP_COINCIDENCE_THRESHOLD > 100000
-#error "ATP_COINCIDENCE_THRESHOLD too large"
-#endif
-#endif /* #ifndef ATP_COINCIDENCE_THRESHOLD */
+ * The wait duration in ticks after losing a touch contact before
+ * zombied strokes are reaped and turned into button events.
+ */
+#define ATP_ZOMBIE_STROKE_REAP_INTERVAL (hz / 20) /* 50 ms */
+
+/* The multiplier used to translate sensor reported positions to mickeys. */
+#define FG_SCALE_FACTOR 380
/*
- * The wait duration (in microseconds) after losing a touch contact
- * before zombied strokes are reaped and turned into button events.
+ * The movement threshold for a stroke; this is the maximum difference
+ * in position which will be resolved as a continuation of a stroke
+ * component.
*/
-#define ATP_ZOMBIE_STROKE_REAP_WINDOW 50000
-#if ATP_ZOMBIE_STROKE_REAP_WINDOW > 100000
-#error "ATP_ZOMBIE_STROKE_REAP_WINDOW too large"
+#define FG_MAX_DELTA_MICKEYS ((3 * (FG_SCALE_FACTOR)) >> 1)
+
+/* Distance-squared threshold for matching a finger with a known stroke */
+#ifndef WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ
+#define WSP_MAX_ALLOWED_MATCH_DISTANCE_SQ 1000000
#endif
-/* end of driver specific options */
+/* Ignore pressure spans with cumulative press. below this value. */
+#define FG_PSPAN_MIN_CUM_PRESSURE 10
+/* Maximum allowed width for pressure-spans.*/
+#define FG_PSPAN_MAX_WIDTH 4
+
+/* end of driver specific options */
/* Tunables */
-static SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB atp");
+static SYSCTL_NODE(_hw_usb, OID_AUTO, atp, CTLFLAG_RW, 0, "USB ATP");
#ifdef USB_DEBUG
enum atp_log_level {
@@ -130,12 +184,13 @@ SYSCTL_INT(_hw_usb_atp, OID_AUTO, debug,
static u_int atp_touch_timeout = ATP_TOUCH_TIMEOUT;
SYSCTL_UINT(_hw_usb_atp, OID_AUTO, touch_timeout, CTLFLAG_RW,
- &atp_touch_timeout, 125000, "age threshold (in micros) for a touch");
+ &atp_touch_timeout, 125000, "age threshold in microseconds for a touch");
static u_int atp_double_tap_threshold = ATP_DOUBLE_TAP_N_DRAG_THRESHOLD;
SYSCTL_UINT(_hw_usb_atp, OID_AUTO, double_tap_threshold, CTLFLAG_RW,
&atp_double_tap_threshold, ATP_DOUBLE_TAP_N_DRAG_THRESHOLD,
- "maximum time (in micros) between a double-tap");
+ "maximum time in microseconds to allow association between a double-tap and "
+ "drag gesture");
static u_int atp_mickeys_scale_factor = ATP_SCALE_FACTOR;
static int atp_sysctl_scale_factor_handler(SYSCTL_HANDLER_ARGS);
@@ -143,264 +198,539 @@ SYSCTL_PROC(_hw_usb_atp, OID_AUTO, scale
&atp_mickeys_scale_factor, sizeof(atp_mickeys_scale_factor),
atp_sysctl_scale_factor_handler, "IU", "movement scale factor");
-static u_int atp_small_movement_threshold = ATP_SCALE_FACTOR >> 3;
+static u_int atp_small_movement_threshold = ATP_SMALL_MOVEMENT_THRESHOLD;
SYSCTL_UINT(_hw_usb_atp, OID_AUTO, small_movement, CTLFLAG_RW,
- &atp_small_movement_threshold, ATP_SCALE_FACTOR >> 3,
+ &atp_small_movement_threshold, ATP_SMALL_MOVEMENT_THRESHOLD,
"the small movement black-hole for filtering noise");
-/*
- * The movement threshold for a stroke; this is the maximum difference
- * in position which will be resolved as a continuation of a stroke
- * component.
- */
-static u_int atp_max_delta_mickeys = ((3 * ATP_SCALE_FACTOR) >> 1);
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, max_delta_mickeys, CTLFLAG_RW,
- &atp_max_delta_mickeys, ((3 * ATP_SCALE_FACTOR) >> 1),
- "max. mickeys-delta which will match against an existing stroke");
+
+static u_int atp_tap_minimum = 1;
+SYSCTL_UINT(_hw_usb_atp, OID_AUTO, tap_minimum, CTLFLAG_RW,
+ &atp_tap_minimum, 1, "Minimum number of taps before detection");
+
/*
* Strokes which accumulate at least this amount of absolute movement
* from the aggregate of their components are considered as
* slides. Unit: mickeys.
*/
-static u_int atp_slide_min_movement = (ATP_SCALE_FACTOR >> 3);
+static u_int atp_slide_min_movement = 2 * ATP_SMALL_MOVEMENT_THRESHOLD;
SYSCTL_UINT(_hw_usb_atp, OID_AUTO, slide_min_movement, CTLFLAG_RW,
- &atp_slide_min_movement, (ATP_SCALE_FACTOR >> 3),
+ &atp_slide_min_movement, 2 * ATP_SMALL_MOVEMENT_THRESHOLD,
"strokes with at least this amt. of movement are considered slides");
/*
* The minimum age of a stroke for it to be considered mature; this
* helps filter movements (noise) from immature strokes. Units: interrupts.
*/
-static u_int atp_stroke_maturity_threshold = 2;
+static u_int atp_stroke_maturity_threshold = 4;
SYSCTL_UINT(_hw_usb_atp, OID_AUTO, stroke_maturity_threshold, CTLFLAG_RW,
- &atp_stroke_maturity_threshold, 2,
+ &atp_stroke_maturity_threshold, 4,
"the minimum age of a stroke for it to be considered mature");
-/* Accept pressure readings from sensors only if above this value. */
-static u_int atp_sensor_noise_threshold = 2;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, sensor_noise_threshold, CTLFLAG_RW,
- &atp_sensor_noise_threshold, 2,
- "accept pressure readings from sensors only if above this value");
+typedef enum atp_trackpad_family {
+ TRACKPAD_FAMILY_FOUNTAIN_GEYSER,
+ TRACKPAD_FAMILY_WELLSPRING,
+ TRACKPAD_FAMILY_MAX /* keep this at the tail end of the enumeration */
+} trackpad_family_t;
+
+enum fountain_geyser_product {
+ FOUNTAIN,
+ GEYSER1,
+ GEYSER1_17inch,
+ GEYSER2,
+ GEYSER3,
+ GEYSER4,
+ FOUNTAIN_GEYSER_PRODUCT_MAX /* keep this at the end */
+};
-/* Ignore pressure spans with cumulative press. below this value. */
-static u_int atp_pspan_min_cum_pressure = 10;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_min_cum_pressure, CTLFLAG_RW,
- &atp_pspan_min_cum_pressure, 10,
- "ignore pressure spans with cumulative press. below this value");
+enum wellspring_product {
+ WELLSPRING1,
+ WELLSPRING2,
+ WELLSPRING3,
+ WELLSPRING4,
+ WELLSPRING4A,
+ WELLSPRING5,
+ WELLSPRING6A,
+ WELLSPRING6,
+ WELLSPRING5A,
+ WELLSPRING7,
+ WELLSPRING7A,
+ WELLSPRING8,
+ WELLSPRING_PRODUCT_MAX /* keep this at the end of the enumeration */
+};
-/* Maximum allowed width for pressure-spans.*/
-static u_int atp_pspan_max_width = 4;
-SYSCTL_UINT(_hw_usb_atp, OID_AUTO, pspan_max_width, CTLFLAG_RW,
- &atp_pspan_max_width, 4,
- "maximum allowed width (in sensors) for pressure-spans");
-
-/* We support three payload protocols */
-typedef enum {
- ATP_PROT_GEYSER1,
- ATP_PROT_GEYSER2,
- ATP_PROT_GEYSER3,
-} atp_protocol;
+/* trackpad header types */
+enum fountain_geyser_trackpad_type {
+ FG_TRACKPAD_TYPE_GEYSER1,
+ FG_TRACKPAD_TYPE_GEYSER2,
+ FG_TRACKPAD_TYPE_GEYSER3,
+ FG_TRACKPAD_TYPE_GEYSER4,
+};
+enum wellspring_trackpad_type {
+ WSP_TRACKPAD_TYPE1, /* plain trackpad */
+ WSP_TRACKPAD_TYPE2, /* button integrated in trackpad */
+ WSP_TRACKPAD_TYPE3 /* additional header fields since June 2013 */
+};
-/* Define the various flavours of devices supported by this driver. */
-enum {
- ATP_DEV_PARAMS_0,
- ATP_DEV_PARAMS_PBOOK,
- ATP_DEV_PARAMS_PBOOK_15A,
- ATP_DEV_PARAMS_PBOOK_17,
- ATP_N_DEV_PARAMS
+/*
+ * Trackpad family and product and family are encoded together in the
+ * driver_info value associated with a trackpad product.
+ */
+#define N_PROD_BITS 8 /* Number of bits used to encode product */
+#define ENCODE_DRIVER_INFO(FAMILY, PROD) \
+ (((FAMILY) << N_PROD_BITS) | (PROD))
+#define DECODE_FAMILY_FROM_DRIVER_INFO(INFO) ((INFO) >> N_PROD_BITS)
+#define DECODE_PRODUCT_FROM_DRIVER_INFO(INFO) \
+ ((INFO) & ((1 << N_PROD_BITS) - 1))
+
+#define FG_DRIVER_INFO(PRODUCT) \
+ ENCODE_DRIVER_INFO(TRACKPAD_FAMILY_FOUNTAIN_GEYSER, PRODUCT)
+#define WELLSPRING_DRIVER_INFO(PRODUCT) \
+ ENCODE_DRIVER_INFO(TRACKPAD_FAMILY_WELLSPRING, PRODUCT)
+
+/*
+ * The following structure captures the state of a pressure span along
+ * an axis. Each contact with the touchpad results in separate
+ * pressure spans along the two axes.
+ */
+typedef struct fg_pspan {
+ u_int width; /* in units of sensors */
+ u_int cum; /* cumulative compression (from all sensors) */
+ u_int cog; /* center of gravity */
+ u_int loc; /* location (scaled using the mickeys factor) */
+ boolean_t matched; /* to track pspans as they match against strokes. */
+} fg_pspan;
+
+#define FG_MAX_PSPANS_PER_AXIS 3
+#define FG_MAX_STROKES (2 * FG_MAX_PSPANS_PER_AXIS)
+
+#define WELLSPRING_INTERFACE_INDEX 1
+
+/* trackpad finger data offsets, le16-aligned */
+#define WSP_TYPE1_FINGER_DATA_OFFSET (13 * 2)
+#define WSP_TYPE2_FINGER_DATA_OFFSET (15 * 2)
+#define WSP_TYPE3_FINGER_DATA_OFFSET (19 * 2)
+
+/* trackpad button data offsets */
+#define WSP_TYPE2_BUTTON_DATA_OFFSET 15
+#define WSP_TYPE3_BUTTON_DATA_OFFSET 23
+
+/* list of device capability bits */
+#define HAS_INTEGRATED_BUTTON 1
+
+/* trackpad finger structure - little endian */
+struct wsp_finger_sensor_data {
+ int16_t origin; /* zero when switching track finger */
+ int16_t abs_x; /* absolute x coordinate */
+ int16_t abs_y; /* absolute y coordinate */
+ int16_t rel_x; /* relative x coordinate */
+ int16_t rel_y; /* relative y coordinate */
+ int16_t tool_major; /* tool area, major axis */
+ int16_t tool_minor; /* tool area, minor axis */
+ int16_t orientation; /* 16384 when point, else 15 bit angle */
+ int16_t touch_major; /* touch area, major axis */
+ int16_t touch_minor; /* touch area, minor axis */
+ int16_t unused[3]; /* zeros */
+ int16_t multi; /* one finger: varies, more fingers: constant */
+} __packed;
+
+typedef struct wsp_finger {
+ /* to track fingers as they match against strokes. */
+ boolean_t matched;
+
+ /* location (scaled using the mickeys factor) */
+ int x;
+ int y;
+} wsp_finger_t;
+
+#define WSP_MAX_FINGERS 16
+#define WSP_SIZEOF_FINGER_SENSOR_DATA sizeof(struct wsp_finger_sensor_data)
+#define WSP_SIZEOF_ALL_FINGER_DATA (WSP_MAX_FINGERS * \
+ WSP_SIZEOF_FINGER_SENSOR_DATA)
+#define WSP_MAX_FINGER_ORIENTATION 16384
+
+#define ATP_SENSOR_DATA_BUF_MAX 1024
+#if (ATP_SENSOR_DATA_BUF_MAX < ((WSP_MAX_FINGERS * 14 * 2) + \
+ WSP_TYPE3_FINGER_DATA_OFFSET))
+/* note: 14 * 2 in the above is based on sizeof(struct wsp_finger_sensor_data)*/
+#error "ATP_SENSOR_DATA_BUF_MAX is too small"
+#endif
+
+#define ATP_MAX_STROKES MAX(WSP_MAX_FINGERS, FG_MAX_STROKES)
+
+#define FG_MAX_XSENSORS 26
+#define FG_MAX_YSENSORS 16
+
+/* device-specific configuration */
+struct fg_dev_params {
+ u_int data_len; /* for sensor data */
+ u_int n_xsensors;
+ u_int n_ysensors;
+ enum fountain_geyser_trackpad_type prot;
};
-struct atp_dev_params {
- u_int data_len; /* for sensor data */
- u_int n_xsensors;
- u_int n_ysensors;
- atp_protocol prot;
-} atp_dev_params[ATP_N_DEV_PARAMS] = {
- [ATP_DEV_PARAMS_0] = {
- .data_len = 64,
- .n_xsensors = 20,
- .n_ysensors = 10,
- .prot = ATP_PROT_GEYSER3
+struct wsp_dev_params {
+ uint8_t caps; /* device capability bitmask */
+ uint8_t tp_type; /* type of trackpad interface */
+ uint8_t finger_data_offset; /* offset to trackpad finger data */
+};
+
+static const struct fg_dev_params fg_dev_params[FOUNTAIN_GEYSER_PRODUCT_MAX] = {
+ [FOUNTAIN] = {
+ .data_len = 81,
+ .n_xsensors = 16,
+ .n_ysensors = 16,
+ .prot = FG_TRACKPAD_TYPE_GEYSER1
},
- [ATP_DEV_PARAMS_PBOOK] = {
+ [GEYSER1] = {
.data_len = 81,
.n_xsensors = 16,
.n_ysensors = 16,
- .prot = ATP_PROT_GEYSER1
+ .prot = FG_TRACKPAD_TYPE_GEYSER1
+ },
+ [GEYSER1_17inch] = {
+ .data_len = 81,
+ .n_xsensors = 26,
+ .n_ysensors = 16,
+ .prot = FG_TRACKPAD_TYPE_GEYSER1
},
- [ATP_DEV_PARAMS_PBOOK_15A] = {
+ [GEYSER2] = {
.data_len = 64,
.n_xsensors = 15,
.n_ysensors = 9,
- .prot = ATP_PROT_GEYSER2
+ .prot = FG_TRACKPAD_TYPE_GEYSER2
},
- [ATP_DEV_PARAMS_PBOOK_17] = {
- .data_len = 81,
- .n_xsensors = 26,
- .n_ysensors = 16,
- .prot = ATP_PROT_GEYSER1
+ [GEYSER3] = {
+ .data_len = 64,
+ .n_xsensors = 20,
+ .n_ysensors = 10,
+ .prot = FG_TRACKPAD_TYPE_GEYSER3
},
+ [GEYSER4] = {
+ .data_len = 64,
+ .n_xsensors = 20,
+ .n_ysensors = 10,
+ .prot = FG_TRACKPAD_TYPE_GEYSER4
+ }
};
-static const STRUCT_USB_HOST_ID atp_devs[] = {
+static const STRUCT_USB_HOST_ID fg_devs[] = {
+ /* PowerBooks Feb 2005, iBooks G4 */
+ { USB_VPI(USB_VENDOR_APPLE, 0x020e, FG_DRIVER_INFO(FOUNTAIN)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x020f, FG_DRIVER_INFO(FOUNTAIN)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0210, FG_DRIVER_INFO(FOUNTAIN)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x030a, FG_DRIVER_INFO(FOUNTAIN)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x030b, FG_DRIVER_INFO(GEYSER1)) },
+
+ /* PowerBooks Oct 2005 */
+ { USB_VPI(USB_VENDOR_APPLE, 0x0214, FG_DRIVER_INFO(GEYSER2)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0215, FG_DRIVER_INFO(GEYSER2)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0216, FG_DRIVER_INFO(GEYSER2)) },
+
/* Core Duo MacBook & MacBook Pro */
- { USB_VPI(USB_VENDOR_APPLE, 0x0217, ATP_DEV_PARAMS_0) },
- { USB_VPI(USB_VENDOR_APPLE, 0x0218, ATP_DEV_PARAMS_0) },
- { USB_VPI(USB_VENDOR_APPLE, 0x0219, ATP_DEV_PARAMS_0) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0217, FG_DRIVER_INFO(GEYSER3)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0218, FG_DRIVER_INFO(GEYSER3)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0219, FG_DRIVER_INFO(GEYSER3)) },
/* Core2 Duo MacBook & MacBook Pro */
- { USB_VPI(USB_VENDOR_APPLE, 0x021a, ATP_DEV_PARAMS_0) },
- { USB_VPI(USB_VENDOR_APPLE, 0x021b, ATP_DEV_PARAMS_0) },
- { USB_VPI(USB_VENDOR_APPLE, 0x021c, ATP_DEV_PARAMS_0) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x021a, FG_DRIVER_INFO(GEYSER4)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x021b, FG_DRIVER_INFO(GEYSER4)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x021c, FG_DRIVER_INFO(GEYSER4)) },
/* Core2 Duo MacBook3,1 */
- { USB_VPI(USB_VENDOR_APPLE, 0x0229, ATP_DEV_PARAMS_0) },
- { USB_VPI(USB_VENDOR_APPLE, 0x022a, ATP_DEV_PARAMS_0) },
- { USB_VPI(USB_VENDOR_APPLE, 0x022b, ATP_DEV_PARAMS_0) },
-
- /* 12 inch PowerBook and iBook */
- { USB_VPI(USB_VENDOR_APPLE, 0x030a, ATP_DEV_PARAMS_PBOOK) },
- { USB_VPI(USB_VENDOR_APPLE, 0x030b, ATP_DEV_PARAMS_PBOOK) },
-
- /* 15 inch PowerBook */
- { USB_VPI(USB_VENDOR_APPLE, 0x020e, ATP_DEV_PARAMS_PBOOK) },
- { USB_VPI(USB_VENDOR_APPLE, 0x020f, ATP_DEV_PARAMS_PBOOK) },
- { USB_VPI(USB_VENDOR_APPLE, 0x0215, ATP_DEV_PARAMS_PBOOK_15A) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x0229, FG_DRIVER_INFO(GEYSER4)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x022a, FG_DRIVER_INFO(GEYSER4)) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x022b, FG_DRIVER_INFO(GEYSER4)) },
/* 17 inch PowerBook */
- { USB_VPI(USB_VENDOR_APPLE, 0x020d, ATP_DEV_PARAMS_PBOOK_17) },
+ { USB_VPI(USB_VENDOR_APPLE, 0x020d, FG_DRIVER_INFO(GEYSER1_17inch)) },
+};
+static const struct wsp_dev_params wsp_dev_params[WELLSPRING_PRODUCT_MAX] = {
+ [WELLSPRING1] = {
+ .caps = 0,
+ .tp_type = WSP_TRACKPAD_TYPE1,
+ .finger_data_offset = WSP_TYPE1_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING2] = {
+ .caps = 0,
+ .tp_type = WSP_TRACKPAD_TYPE1,
+ .finger_data_offset = WSP_TYPE1_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING3] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING4] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING4A] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING5] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING6] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING5A] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING6A] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING7] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING7A] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE2,
+ .finger_data_offset = WSP_TYPE2_FINGER_DATA_OFFSET,
+ },
+ [WELLSPRING8] = {
+ .caps = HAS_INTEGRATED_BUTTON,
+ .tp_type = WSP_TRACKPAD_TYPE3,
+ .finger_data_offset = WSP_TYPE3_FINGER_DATA_OFFSET,
+ },
};
-/*
- * The following structure captures the state of a pressure span along
- * an axis. Each contact with the touchpad results in separate
- * pressure spans along the two axes.
- */
-typedef struct atp_pspan {
- u_int width; /* in units of sensors */
- u_int cum; /* cumulative compression (from all sensors) */
- u_int cog; /* center of gravity */
- u_int loc; /* location (scaled using the mickeys factor) */
- boolean_t matched; /* to track pspans as they match against strokes. */
-} atp_pspan;
+#define ATP_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+
+/* TODO: STRUCT_USB_HOST_ID */
+static const struct usb_device_id wsp_devs[] = {
+ /* MacbookAir1.1 */
+ ATP_DEV(APPLE, WELLSPRING_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING1)),
+ ATP_DEV(APPLE, WELLSPRING_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING1)),
+ ATP_DEV(APPLE, WELLSPRING_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING1)),
+
+ /* MacbookProPenryn, aka wellspring2 */
+ ATP_DEV(APPLE, WELLSPRING2_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING2)),
+ ATP_DEV(APPLE, WELLSPRING2_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING2)),
+ ATP_DEV(APPLE, WELLSPRING2_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING2)),
+
+ /* Macbook5,1 (unibody), aka wellspring3 */
+ ATP_DEV(APPLE, WELLSPRING3_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING3)),
+ ATP_DEV(APPLE, WELLSPRING3_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING3)),
+ ATP_DEV(APPLE, WELLSPRING3_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING3)),
+
+ /* MacbookAir3,2 (unibody), aka wellspring4 */
+ ATP_DEV(APPLE, WELLSPRING4_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4)),
+ ATP_DEV(APPLE, WELLSPRING4_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING4)),
+ ATP_DEV(APPLE, WELLSPRING4_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING4)),
+
+ /* MacbookAir3,1 (unibody), aka wellspring4 */
+ ATP_DEV(APPLE, WELLSPRING4A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING4A)),
+ ATP_DEV(APPLE, WELLSPRING4A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING4A)),
+ ATP_DEV(APPLE, WELLSPRING4A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING4A)),
+
+ /* Macbook8 (unibody, March 2011) */
+ ATP_DEV(APPLE, WELLSPRING5_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5)),
+ ATP_DEV(APPLE, WELLSPRING5_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING5)),
+ ATP_DEV(APPLE, WELLSPRING5_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING5)),
+
+ /* MacbookAir4,1 (unibody, July 2011) */
+ ATP_DEV(APPLE, WELLSPRING6A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6A)),
+ ATP_DEV(APPLE, WELLSPRING6A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING6A)),
+ ATP_DEV(APPLE, WELLSPRING6A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING6A)),
+
+ /* MacbookAir4,2 (unibody, July 2011) */
+ ATP_DEV(APPLE, WELLSPRING6_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING6)),
+ ATP_DEV(APPLE, WELLSPRING6_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING6)),
+ ATP_DEV(APPLE, WELLSPRING6_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING6)),
+
+ /* Macbook8,2 (unibody) */
+ ATP_DEV(APPLE, WELLSPRING5A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING5A)),
+ ATP_DEV(APPLE, WELLSPRING5A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING5A)),
+ ATP_DEV(APPLE, WELLSPRING5A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING5A)),
+
+ /* MacbookPro10,1 (unibody, June 2012) */
+ /* MacbookPro11,? (unibody, June 2013) */
+ ATP_DEV(APPLE, WELLSPRING7_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7)),
+ ATP_DEV(APPLE, WELLSPRING7_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING7)),
+ ATP_DEV(APPLE, WELLSPRING7_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING7)),
+
+ /* MacbookPro10,2 (unibody, October 2012) */
+ ATP_DEV(APPLE, WELLSPRING7A_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING7A)),
+ ATP_DEV(APPLE, WELLSPRING7A_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING7A)),
+ ATP_DEV(APPLE, WELLSPRING7A_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING7A)),
+
+ /* MacbookAir6,2 (unibody, June 2013) */
+ ATP_DEV(APPLE, WELLSPRING8_ANSI, WELLSPRING_DRIVER_INFO(WELLSPRING8)),
+ ATP_DEV(APPLE, WELLSPRING8_ISO, WELLSPRING_DRIVER_INFO(WELLSPRING8)),
+ ATP_DEV(APPLE, WELLSPRING8_JIS, WELLSPRING_DRIVER_INFO(WELLSPRING8)),
+};
typedef enum atp_stroke_type {
ATP_STROKE_TOUCH,
ATP_STROKE_SLIDE,
} atp_stroke_type;
-#define ATP_MAX_PSPANS_PER_AXIS 3
+typedef enum atp_axis {
+ X = 0,
+ Y = 1,
+ NUM_AXES
+} atp_axis;
+
+#define ATP_FIFO_BUF_SIZE 8 /* bytes */
+#define ATP_FIFO_QUEUE_MAXLEN 50 /* units */
+
+enum {
+ ATP_INTR_DT,
+ ATP_RESET,
+ ATP_N_TRANSFER,
+};
-typedef struct atp_stroke_component {
+typedef struct fg_stroke_component {
/* Fields encapsulating the pressure-span. */
u_int loc; /* location (scaled) */
u_int cum_pressure; /* cumulative compression */
u_int max_cum_pressure; /* max cumulative compression */
boolean_t matched; /*to track components as they match against pspans.*/
- /* Fields containing information about movement. */
int delta_mickeys; /* change in location (un-smoothened movement)*/
- int pending; /* cum. of pending short movements */
- int movement; /* current smoothened movement */
-} atp_stroke_component;
-
-typedef enum atp_axis {
- X = 0,
- Y = 1
-} atp_axis;
-
-#define ATP_MAX_STROKES (2 * ATP_MAX_PSPANS_PER_AXIS)
+} fg_stroke_component_t;
/*
* The following structure captures a finger contact with the
* touchpad. A stroke comprises two p-span components and some state.
*/
typedef struct atp_stroke {
- atp_stroke_type type;
- struct timeval ctime; /* create time; for coincident siblings. */
- u_int age; /*
- * Unit: interrupts; we maintain
- * this value in addition to
- * 'ctime' in order to avoid the
- * expensive call to microtime()
- * at every interrupt.
- */
-
- atp_stroke_component components[2];
- u_int velocity_squared; /*
- * Average magnitude (squared)
- * of recent velocity.
- */
- u_int cum_movement; /* cum. absolute movement so far */
-
- uint32_t flags; /* the state of this stroke */
-#define ATSF_ZOMBIE 0x1
-} atp_stroke;
+ TAILQ_ENTRY(atp_stroke) entry;
-#define ATP_FIFO_BUF_SIZE 8 /* bytes */
-#define ATP_FIFO_QUEUE_MAXLEN 50 /* units */
+ atp_stroke_type type;
+ uint32_t flags; /* the state of this stroke */
+#define ATSF_ZOMBIE 0x1
+ boolean_t matched; /* to track match against fingers.*/
-enum {
- ATP_INTR_DT,
- ATP_RESET,
- ATP_N_TRANSFER,
-};
+ struct timeval ctime; /* create time; for coincident siblings. */
+
+ /*
+ * Unit: interrupts; we maintain this value in
+ * addition to 'ctime' in order to avoid the
+ * expensive call to microtime() at every
+ * interrupt.
+ */
+ uint32_t age;
+
+ /* Location */
+ int x;
+ int y;
+
+ /* Fields containing information about movement. */
+ int instantaneous_dx; /* curr. change in X location (un-smoothened) */
+ int instantaneous_dy; /* curr. change in Y location (un-smoothened) */
+ int pending_dx; /* cum. of pending short movements */
+ int pending_dy; /* cum. of pending short movements */
+ int movement_dx; /* interpreted smoothened movement */
+ int movement_dy; /* interpreted smoothened movement */
+ int cum_movement_x; /* cum. horizontal movement */
+ int cum_movement_y; /* cum. vertical movement */
+
+ /*
+ * The following member is relevant only for fountain-geyser trackpads.
+ * For these, there is the need to track pressure-spans and cumulative
+ * pressures for stroke components.
+ */
+ fg_stroke_component_t components[NUM_AXES];
+} atp_stroke_t;
+
+struct atp_softc; /* forward declaration */
+typedef void (*sensor_data_interpreter_t)(struct atp_softc *sc, u_int len);
struct atp_softc {
- device_t sc_dev;
- struct usb_device *sc_usb_device;
-#define MODE_LENGTH 8
- char sc_mode_bytes[MODE_LENGTH]; /* device mode */
- struct mtx sc_mutex; /* for synchronization */
- struct usb_xfer *sc_xfer[ATP_N_TRANSFER];
- struct usb_fifo_sc sc_fifo;
-
- struct atp_dev_params *sc_params;
-
- mousehw_t sc_hw;
- mousemode_t sc_mode;
- u_int sc_pollrate;
- mousestatus_t sc_status;
- u_int sc_state;
-#define ATP_ENABLED 0x01
-#define ATP_ZOMBIES_EXIST 0x02
-#define ATP_DOUBLE_TAP_DRAG 0x04
-#define ATP_VALID 0x08
-
- u_int sc_left_margin;
- u_int sc_right_margin;
-
- atp_stroke sc_strokes[ATP_MAX_STROKES];
- u_int sc_n_strokes;
-
- int8_t *sensor_data; /* from interrupt packet */
- int *base_x; /* base sensor readings */
- int *base_y;
- int *cur_x; /* current sensor readings */
- int *cur_y;
- int *pressure_x; /* computed pressures */
- int *pressure_y;
+ device_t sc_dev;
+ struct usb_device *sc_usb_device;
+ struct mtx sc_mutex; /* for synchronization */
+ struct usb_fifo_sc sc_fifo;
+
+#define MODE_LENGTH 8
+ char sc_mode_bytes[MODE_LENGTH]; /* device mode */
+
+ trackpad_family_t sc_family;
+ const void *sc_params; /* device configuration */
+ sensor_data_interpreter_t sensor_data_interpreter;
+
+ mousehw_t sc_hw;
+ mousemode_t sc_mode;
+ mousestatus_t sc_status;
+
+ u_int sc_state;
+#define ATP_ENABLED 0x01
+#define ATP_ZOMBIES_EXIST 0x02
+#define ATP_DOUBLE_TAP_DRAG 0x04
+#define ATP_VALID 0x08
+
+ struct usb_xfer *sc_xfer[ATP_N_TRANSFER];
+
+ u_int sc_pollrate;
+ int sc_fflags;
+
+ atp_stroke_t sc_strokes_data[ATP_MAX_STROKES];
+ TAILQ_HEAD(,atp_stroke) sc_stroke_free;
+ TAILQ_HEAD(,atp_stroke) sc_stroke_used;
+ u_int sc_n_strokes;
- u_int sc_idlecount; /* preceding idle interrupts */
-#define ATP_IDLENESS_THRESHOLD 10
+ struct callout sc_callout;
+
+ /*
+ * button status. Set to non-zero if the mouse-button is physically
+ * pressed. This state variable is exposed through softc to allow
+ * reap_sibling_zombies to avoid registering taps while the trackpad
+ * button is pressed.
+ */
+ uint8_t sc_ibtn;
+
+ /*
+ * Time when touch zombies were last reaped; useful for detecting
+ * double-touch-n-drag.
+ */
+ struct timeval sc_touch_reap_time;
- struct timeval sc_reap_time;
- struct timeval sc_reap_ctime; /*ctime of siblings to be reaped*/
+ u_int sc_idlecount;
+
+ /* Regarding the data transferred from t-pad in USB INTR packets. */
+ u_int sc_expected_sensor_data_len;
+ uint8_t sc_sensor_data[ATP_SENSOR_DATA_BUF_MAX] __aligned(4);
+
+ int sc_cur_x[FG_MAX_XSENSORS]; /* current sensor readings */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list