|
@@ -2,12 +2,13 @@
|
|
|
* Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
|
|
|
*
|
|
|
* Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
|
|
|
- * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
|
|
|
+ * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net)
|
|
|
* Copyright (C) 2005 Stelian Pop (stelian@popies.net)
|
|
|
* Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
|
|
|
* Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
|
|
|
* Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
|
|
|
* Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
|
|
|
+ * Copyright (C) 2007-2008 Sven Anders (anders@anduras.de)
|
|
|
*
|
|
|
* Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
|
|
|
*
|
|
@@ -34,77 +35,64 @@
|
|
|
#include <linux/module.h>
|
|
|
#include <linux/usb/input.h>
|
|
|
|
|
|
-/* Apple has powerbooks which have the keyboard with different Product IDs */
|
|
|
-#define APPLE_VENDOR_ID 0x05AC
|
|
|
-
|
|
|
-/* These names come from Info.plist in AppleUSBTrackpad.kext */
|
|
|
-#define FOUNTAIN_ANSI_PRODUCT_ID 0x020E
|
|
|
-#define FOUNTAIN_ISO_PRODUCT_ID 0x020F
|
|
|
-
|
|
|
-#define FOUNTAIN_TP_ONLY_PRODUCT_ID 0x030A
|
|
|
-
|
|
|
-#define GEYSER1_TP_ONLY_PRODUCT_ID 0x030B
|
|
|
-
|
|
|
-#define GEYSER_ANSI_PRODUCT_ID 0x0214
|
|
|
-#define GEYSER_ISO_PRODUCT_ID 0x0215
|
|
|
-#define GEYSER_JIS_PRODUCT_ID 0x0216
|
|
|
-
|
|
|
-/* MacBook devices */
|
|
|
-#define GEYSER3_ANSI_PRODUCT_ID 0x0217
|
|
|
-#define GEYSER3_ISO_PRODUCT_ID 0x0218
|
|
|
-#define GEYSER3_JIS_PRODUCT_ID 0x0219
|
|
|
-
|
|
|
-/*
|
|
|
- * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext
|
|
|
- * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables
|
|
|
- */
|
|
|
-#define GEYSER4_ANSI_PRODUCT_ID 0x021A
|
|
|
-#define GEYSER4_ISO_PRODUCT_ID 0x021B
|
|
|
-#define GEYSER4_JIS_PRODUCT_ID 0x021C
|
|
|
-
|
|
|
-#define GEYSER4_HF_ANSI_PRODUCT_ID 0x0229
|
|
|
-#define GEYSER4_HF_ISO_PRODUCT_ID 0x022A
|
|
|
-#define GEYSER4_HF_JIS_PRODUCT_ID 0x022B
|
|
|
+/* Type of touchpad */
|
|
|
+enum atp_touchpad_type {
|
|
|
+ ATP_FOUNTAIN,
|
|
|
+ ATP_GEYSER1,
|
|
|
+ ATP_GEYSER2,
|
|
|
+ ATP_GEYSER3,
|
|
|
+ ATP_GEYSER4
|
|
|
+};
|
|
|
|
|
|
-#define ATP_DEVICE(prod) \
|
|
|
+#define ATP_DEVICE(prod, type) \
|
|
|
+{ \
|
|
|
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
|
|
|
USB_DEVICE_ID_MATCH_INT_CLASS | \
|
|
|
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
|
|
|
- .idVendor = APPLE_VENDOR_ID, \
|
|
|
+ .idVendor = 0x05ac, /* Apple */ \
|
|
|
.idProduct = (prod), \
|
|
|
.bInterfaceClass = 0x03, \
|
|
|
- .bInterfaceProtocol = 0x02
|
|
|
+ .bInterfaceProtocol = 0x02, \
|
|
|
+ .driver_info = ATP_ ## type, \
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Table of devices (Product IDs) that work with this driver.
|
|
|
+ * (The names come from Info.plist in AppleUSBTrackpad.kext,
|
|
|
+ * According to Info.plist Geyser IV is the same as Geyser III.)
|
|
|
+ */
|
|
|
|
|
|
-/* table of devices that work with this driver */
|
|
|
static struct usb_device_id atp_table [] = {
|
|
|
- { ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) },
|
|
|
+ /* PowerBooks Feb 2005, iBooks G4 */
|
|
|
+ ATP_DEVICE(0x020e, FOUNTAIN), /* FOUNTAIN ANSI */
|
|
|
+ ATP_DEVICE(0x020f, FOUNTAIN), /* FOUNTAIN ISO */
|
|
|
+ ATP_DEVICE(0x030a, FOUNTAIN), /* FOUNTAIN TP ONLY */
|
|
|
+ ATP_DEVICE(0x030b, GEYSER1), /* GEYSER 1 TP ONLY */
|
|
|
|
|
|
/* PowerBooks Oct 2005 */
|
|
|
- { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
|
|
|
+ ATP_DEVICE(0x0214, GEYSER2), /* GEYSER 2 ANSI */
|
|
|
+ ATP_DEVICE(0x0215, GEYSER2), /* GEYSER 2 ISO */
|
|
|
+ ATP_DEVICE(0x0216, GEYSER2), /* GEYSER 2 JIS */
|
|
|
|
|
|
/* Core Duo MacBook & MacBook Pro */
|
|
|
- { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
|
|
|
+ ATP_DEVICE(0x0217, GEYSER3), /* GEYSER 3 ANSI */
|
|
|
+ ATP_DEVICE(0x0218, GEYSER3), /* GEYSER 3 ISO */
|
|
|
+ ATP_DEVICE(0x0219, GEYSER3), /* GEYSER 3 JIS */
|
|
|
|
|
|
/* Core2 Duo MacBook & MacBook Pro */
|
|
|
- { ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) },
|
|
|
+ ATP_DEVICE(0x021a, GEYSER4), /* GEYSER 4 ANSI */
|
|
|
+ ATP_DEVICE(0x021b, GEYSER4), /* GEYSER 4 ISO */
|
|
|
+ ATP_DEVICE(0x021c, GEYSER4), /* GEYSER 4 JIS */
|
|
|
|
|
|
- { ATP_DEVICE(GEYSER4_HF_ANSI_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER4_HF_ISO_PRODUCT_ID) },
|
|
|
- { ATP_DEVICE(GEYSER4_HF_JIS_PRODUCT_ID) },
|
|
|
+ /* Core2 Duo MacBook3,1 */
|
|
|
+ ATP_DEVICE(0x0229, GEYSER4), /* GEYSER 4 HF ANSI */
|
|
|
+ ATP_DEVICE(0x022a, GEYSER4), /* GEYSER 4 HF ISO */
|
|
|
+ ATP_DEVICE(0x022b, GEYSER4), /* GEYSER 4 HF JIS */
|
|
|
|
|
|
/* Terminating entry */
|
|
|
{ }
|
|
|
};
|
|
|
-MODULE_DEVICE_TABLE (usb, atp_table);
|
|
|
+MODULE_DEVICE_TABLE(usb, atp_table);
|
|
|
|
|
|
/*
|
|
|
* number of sensors. Note that only 16 instead of 26 X (horizontal)
|
|
@@ -124,9 +112,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
|
|
|
* We try to keep the touchpad aspect ratio while still doing only simple
|
|
|
* arithmetics.
|
|
|
* The factors below give coordinates like:
|
|
|
- * 0 <= x < 960 on 12" and 15" Powerbooks
|
|
|
- * 0 <= x < 1600 on 17" Powerbooks
|
|
|
- * 0 <= y < 646
|
|
|
+ *
|
|
|
+ * 0 <= x < 960 on 12" and 15" Powerbooks
|
|
|
+ * 0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro
|
|
|
+ * 0 <= x < 1216 on MacBooks and 15" MacBook Pro
|
|
|
+ *
|
|
|
+ * 0 <= y < 646 on all Powerbooks
|
|
|
+ * 0 <= y < 774 on all MacBooks
|
|
|
*/
|
|
|
#define ATP_XFACT 64
|
|
|
#define ATP_YFACT 43
|
|
@@ -147,43 +139,46 @@ MODULE_DEVICE_TABLE (usb, atp_table);
|
|
|
/* Structure to hold all of our device specific stuff */
|
|
|
struct atp {
|
|
|
char phys[64];
|
|
|
- struct usb_device * udev; /* usb device */
|
|
|
- struct urb * urb; /* usb request block */
|
|
|
- signed char * data; /* transferred data */
|
|
|
- struct input_dev * input; /* input dev */
|
|
|
- unsigned char open; /* non-zero if opened */
|
|
|
- unsigned char valid; /* are the sensors valid ? */
|
|
|
- unsigned char size_detect_done;
|
|
|
- unsigned char overflowwarn; /* overflow warning printed? */
|
|
|
+ struct usb_device *udev; /* usb device */
|
|
|
+ struct urb *urb; /* usb request block */
|
|
|
+ signed char *data; /* transferred data */
|
|
|
+ struct input_dev *input; /* input dev */
|
|
|
+ enum atp_touchpad_type type; /* type of touchpad */
|
|
|
+ bool open;
|
|
|
+ bool valid; /* are the samples valid? */
|
|
|
+ bool size_detect_done;
|
|
|
+ bool overflow_warned;
|
|
|
int x_old; /* last reported x/y, */
|
|
|
int y_old; /* used for smoothing */
|
|
|
- /* current value of the sensors */
|
|
|
signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS];
|
|
|
- /* last value of the sensors */
|
|
|
signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
|
|
|
- /* accumulated sensors */
|
|
|
int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
|
|
|
- int datalen; /* size of an USB urb transfer */
|
|
|
- int idlecount; /* number of empty packets */
|
|
|
- struct work_struct work;
|
|
|
+ int datalen; /* size of USB transfer */
|
|
|
+ int idlecount; /* number of empty packets */
|
|
|
+ struct work_struct work;
|
|
|
};
|
|
|
|
|
|
#define dbg_dump(msg, tab) \
|
|
|
if (debug > 1) { \
|
|
|
- int i; \
|
|
|
- printk("appletouch: %s %lld", msg, (long long)jiffies); \
|
|
|
- for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \
|
|
|
- printk(" %02x", tab[i]); \
|
|
|
+ int __i; \
|
|
|
+ printk(KERN_DEBUG "appletouch: %s", msg); \
|
|
|
+ for (__i = 0; __i < ATP_XSENSORS + ATP_YSENSORS; __i++) \
|
|
|
+ printk(" %02x", tab[__i]); \
|
|
|
printk("\n"); \
|
|
|
}
|
|
|
|
|
|
#define dprintk(format, a...) \
|
|
|
do { \
|
|
|
- if (debug) printk(KERN_DEBUG format, ##a); \
|
|
|
+ if (debug) \
|
|
|
+ printk(KERN_DEBUG format, ##a); \
|
|
|
} while (0)
|
|
|
|
|
|
-MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
|
|
|
-MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
|
|
|
+MODULE_AUTHOR("Johannes Berg");
|
|
|
+MODULE_AUTHOR("Stelian Pop");
|
|
|
+MODULE_AUTHOR("Frank Arnold");
|
|
|
+MODULE_AUTHOR("Michael Hanselmann");
|
|
|
+MODULE_AUTHOR("Sven Anders");
|
|
|
+MODULE_DESCRIPTION("Apple PowerBook and MacBook USB touchpad driver");
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
|
/*
|
|
@@ -191,46 +186,14 @@ MODULE_LICENSE("GPL");
|
|
|
*/
|
|
|
static int threshold = ATP_THRESHOLD;
|
|
|
module_param(threshold, int, 0644);
|
|
|
-MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value");
|
|
|
+MODULE_PARM_DESC(threshold, "Discard any change in data from a sensor"
|
|
|
+ " (the trackpad has many of these sensors)"
|
|
|
+ " less than this value.");
|
|
|
|
|
|
-static int debug = 1;
|
|
|
+static int debug;
|
|
|
module_param(debug, int, 0644);
|
|
|
MODULE_PARM_DESC(debug, "Activate debugging output");
|
|
|
|
|
|
-static inline int atp_is_fountain(struct atp *dev)
|
|
|
-{
|
|
|
- u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
|
|
|
-
|
|
|
- return productId == FOUNTAIN_ANSI_PRODUCT_ID ||
|
|
|
- productId == FOUNTAIN_ISO_PRODUCT_ID ||
|
|
|
- productId == FOUNTAIN_TP_ONLY_PRODUCT_ID;
|
|
|
-}
|
|
|
-
|
|
|
-/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
|
|
|
-static inline int atp_is_geyser_2(struct atp *dev)
|
|
|
-{
|
|
|
- u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
|
|
|
-
|
|
|
- return (productId == GEYSER_ANSI_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER_ISO_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER_JIS_PRODUCT_ID);
|
|
|
-}
|
|
|
-
|
|
|
-static inline int atp_is_geyser_3(struct atp *dev)
|
|
|
-{
|
|
|
- u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
|
|
|
-
|
|
|
- return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER3_ISO_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER3_JIS_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER4_ANSI_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER4_ISO_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER4_JIS_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER4_HF_ANSI_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER4_HF_ISO_PRODUCT_ID) ||
|
|
|
- (productId == GEYSER4_HF_JIS_PRODUCT_ID);
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* By default newer Geyser devices send standard USB HID mouse
|
|
|
* packets (Report ID 2). This code changes device mode, so it
|
|
@@ -240,6 +203,7 @@ static int atp_geyser_init(struct usb_device *udev)
|
|
|
{
|
|
|
char data[8];
|
|
|
int size;
|
|
|
+ int i;
|
|
|
|
|
|
size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
|
|
|
ATP_GEYSER_MODE_READ_REQUEST_ID,
|
|
@@ -248,8 +212,11 @@ static int atp_geyser_init(struct usb_device *udev)
|
|
|
ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
|
|
|
|
|
|
if (size != 8) {
|
|
|
- err("Could not do mode read request from device"
|
|
|
- " (Geyser Raw mode)");
|
|
|
+ dprintk("atp_geyser_init: read error\n");
|
|
|
+ for (i = 0; i < 8; i++)
|
|
|
+ dprintk("appletouch[%d]: %d\n", i, data[i]);
|
|
|
+
|
|
|
+ err("Failed to read mode from device.");
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
@@ -263,8 +230,11 @@ static int atp_geyser_init(struct usb_device *udev)
|
|
|
ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000);
|
|
|
|
|
|
if (size != 8) {
|
|
|
- err("Could not do mode write request to device"
|
|
|
- " (Geyser Raw mode)");
|
|
|
+ dprintk("atp_geyser_init: write error\n");
|
|
|
+ for (i = 0; i < 8; i++)
|
|
|
+ dprintk("appletouch[%d]: %d\n", i, data[i]);
|
|
|
+
|
|
|
+ err("Failed to request geyser raw mode");
|
|
|
return -EIO;
|
|
|
}
|
|
|
return 0;
|
|
@@ -280,15 +250,15 @@ static void atp_reinit(struct work_struct *work)
|
|
|
struct usb_device *udev = dev->udev;
|
|
|
int retval;
|
|
|
|
|
|
+ dprintk("appletouch: putting appletouch to sleep (reinit)\n");
|
|
|
dev->idlecount = 0;
|
|
|
|
|
|
atp_geyser_init(udev);
|
|
|
|
|
|
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
|
|
|
- if (retval) {
|
|
|
- err("%s - usb_submit_urb failed with result %d",
|
|
|
- __FUNCTION__, retval);
|
|
|
- }
|
|
|
+ if (retval)
|
|
|
+ err("atp_reinit: usb_submit_urb failed with error %d",
|
|
|
+ retval);
|
|
|
}
|
|
|
|
|
|
static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
|
|
@@ -323,7 +293,8 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
|
|
|
*
|
|
|
* - Jason Parekh <jasonparekh@gmail.com>
|
|
|
*/
|
|
|
- if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
|
|
|
+ if (i < 1 ||
|
|
|
+ (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
|
|
|
(*fingers)++;
|
|
|
is_increasing = 1;
|
|
|
} else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) {
|
|
@@ -331,11 +302,11 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * Subtracts threshold so a high sensor that just passes the threshold
|
|
|
- * won't skew the calculated absolute coordinate. Fixes an issue
|
|
|
- * where slowly moving the mouse would occassionaly jump a number of
|
|
|
- * pixels (let me restate--slowly moving the mouse makes this issue
|
|
|
- * most apparent).
|
|
|
+ * Subtracts threshold so a high sensor that just passes the
|
|
|
+ * threshold won't skew the calculated absolute coordinate.
|
|
|
+ * Fixes an issue where slowly moving the mouse would
|
|
|
+ * occasionally jump a number of pixels (slowly moving the
|
|
|
+ * finger makes this issue most apparent.)
|
|
|
*/
|
|
|
pcum += (xy_sensors[i] - threshold) * i;
|
|
|
psum += (xy_sensors[i] - threshold);
|
|
@@ -356,7 +327,7 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
|
|
|
input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
|
|
|
}
|
|
|
|
|
|
-static void atp_complete(struct urb* urb)
|
|
|
+static void atp_complete(struct urb *urb)
|
|
|
{
|
|
|
int x, y, x_z, y_z, x_f, y_f;
|
|
|
int retval, i, j;
|
|
@@ -368,22 +339,22 @@ static void atp_complete(struct urb* urb)
|
|
|
/* success */
|
|
|
break;
|
|
|
case -EOVERFLOW:
|
|
|
- if(!dev->overflowwarn) {
|
|
|
+ if (!dev->overflow_warned) {
|
|
|
printk(KERN_WARNING "appletouch: OVERFLOW with data "
|
|
|
"length %d, actual length is %d\n",
|
|
|
dev->datalen, dev->urb->actual_length);
|
|
|
- dev->overflowwarn = 1;
|
|
|
+ dev->overflow_warned = true;
|
|
|
}
|
|
|
case -ECONNRESET:
|
|
|
case -ENOENT:
|
|
|
case -ESHUTDOWN:
|
|
|
/* This urb is terminated, clean up */
|
|
|
- dbg("%s - urb shutting down with status: %d",
|
|
|
- __FUNCTION__, urb->status);
|
|
|
+ dbg("atp_complete: urb shutting down with status: %d",
|
|
|
+ urb->status);
|
|
|
return;
|
|
|
default:
|
|
|
- dbg("%s - nonzero urb status received: %d",
|
|
|
- __FUNCTION__, urb->status);
|
|
|
+ dbg("atp_complete: nonzero urb status received: %d",
|
|
|
+ urb->status);
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
@@ -396,7 +367,7 @@ static void atp_complete(struct urb* urb)
|
|
|
}
|
|
|
|
|
|
/* reorder the sensors values */
|
|
|
- if (atp_is_geyser_3(dev)) {
|
|
|
+ if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
|
|
|
memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
|
|
|
|
|
|
/*
|
|
@@ -415,7 +386,7 @@ static void atp_complete(struct urb* urb)
|
|
|
dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
|
|
|
dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
|
|
|
}
|
|
|
- } else if (atp_is_geyser_2(dev)) {
|
|
|
+ } else if (dev->type == ATP_GEYSER2) {
|
|
|
memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
|
|
|
|
|
|
/*
|
|
@@ -438,7 +409,7 @@ static void atp_complete(struct urb* urb)
|
|
|
} else {
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
/* X values */
|
|
|
- dev->xy_cur[i ] = dev->data[5 * i + 2];
|
|
|
+ dev->xy_cur[i + 0] = dev->data[5 * i + 2];
|
|
|
dev->xy_cur[i + 8] = dev->data[5 * i + 4];
|
|
|
dev->xy_cur[i + 16] = dev->data[5 * i + 42];
|
|
|
if (i < 2)
|
|
@@ -454,21 +425,22 @@ static void atp_complete(struct urb* urb)
|
|
|
|
|
|
if (!dev->valid) {
|
|
|
/* first sample */
|
|
|
- dev->valid = 1;
|
|
|
+ dev->valid = true;
|
|
|
dev->x_old = dev->y_old = -1;
|
|
|
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
|
|
|
|
|
|
if (dev->size_detect_done ||
|
|
|
- atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
|
|
|
+ dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */
|
|
|
goto exit;
|
|
|
|
|
|
/* 17" Powerbooks have extra X sensors */
|
|
|
- for (i = (atp_is_geyser_2(dev) ? 15 : 16); i < ATP_XSENSORS; i++) {
|
|
|
+ for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
|
|
|
+ i < ATP_XSENSORS; i++) {
|
|
|
if (!dev->xy_cur[i])
|
|
|
continue;
|
|
|
|
|
|
printk(KERN_INFO "appletouch: 17\" model detected.\n");
|
|
|
- if (atp_is_geyser_2(dev))
|
|
|
+ if (dev->type == ATP_GEYSER2)
|
|
|
input_set_abs_params(dev->input, ABS_X, 0,
|
|
|
(20 - 1) *
|
|
|
ATP_XFACT - 1,
|
|
@@ -548,11 +520,15 @@ static void atp_complete(struct urb* urb)
|
|
|
* several hundred times a second. Re-initialization does not
|
|
|
* work on Fountain touchpads.
|
|
|
*/
|
|
|
- if (!atp_is_fountain(dev)) {
|
|
|
+ if (dev->type != ATP_FOUNTAIN) {
|
|
|
+ /*
|
|
|
+ * Button must not be pressed when entering suspend,
|
|
|
+ * otherwise we will never release the button.
|
|
|
+ */
|
|
|
if (!x && !y && !key) {
|
|
|
dev->idlecount++;
|
|
|
if (dev->idlecount == 10) {
|
|
|
- dev->valid = 0;
|
|
|
+ dev->valid = false;
|
|
|
schedule_work(&dev->work);
|
|
|
/* Don't resubmit urb here, wait for reinit */
|
|
|
return;
|
|
@@ -561,12 +537,11 @@ static void atp_complete(struct urb* urb)
|
|
|
dev->idlecount = 0;
|
|
|
}
|
|
|
|
|
|
-exit:
|
|
|
+ exit:
|
|
|
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
|
|
|
- if (retval) {
|
|
|
- err("%s - usb_submit_urb failed with result %d",
|
|
|
- __FUNCTION__, retval);
|
|
|
- }
|
|
|
+ if (retval)
|
|
|
+ err("atp_complete: usb_submit_urb failed with result %d",
|
|
|
+ retval);
|
|
|
}
|
|
|
|
|
|
static int atp_open(struct input_dev *input)
|
|
@@ -593,7 +568,7 @@ static int atp_handle_geyser(struct atp *dev)
|
|
|
{
|
|
|
struct usb_device *udev = dev->udev;
|
|
|
|
|
|
- if (!atp_is_fountain(dev)) {
|
|
|
+ if (dev->type != ATP_FOUNTAIN) {
|
|
|
/* switch to raw sensor mode */
|
|
|
if (atp_geyser_init(udev))
|
|
|
return -EIO;
|
|
@@ -604,7 +579,8 @@ static int atp_handle_geyser(struct atp *dev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
|
|
|
+static int atp_probe(struct usb_interface *iface,
|
|
|
+ const struct usb_device_id *id)
|
|
|
{
|
|
|
struct atp *dev;
|
|
|
struct input_dev *input_dev;
|
|
@@ -640,13 +616,12 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|
|
|
|
|
dev->udev = udev;
|
|
|
dev->input = input_dev;
|
|
|
- dev->overflowwarn = 0;
|
|
|
- if (atp_is_geyser_3(dev))
|
|
|
- dev->datalen = 64;
|
|
|
- else if (atp_is_geyser_2(dev))
|
|
|
- dev->datalen = 64;
|
|
|
- else
|
|
|
+ dev->type = id->driver_info;
|
|
|
+ dev->overflow_warned = false;
|
|
|
+ if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1)
|
|
|
dev->datalen = 81;
|
|
|
+ else
|
|
|
+ dev->datalen = 64;
|
|
|
|
|
|
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
|
|
|
if (!dev->urb)
|
|
@@ -680,7 +655,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|
|
|
|
|
set_bit(EV_ABS, input_dev->evbit);
|
|
|
|
|
|
- if (atp_is_geyser_3(dev)) {
|
|
|
+ if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
|
|
|
/*
|
|
|
* MacBook have 20 X sensors, 10 Y sensors
|
|
|
*/
|
|
@@ -688,7 +663,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|
|
((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
|
|
|
input_set_abs_params(input_dev, ABS_Y, 0,
|
|
|
((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
|
|
|
- } else if (atp_is_geyser_2(dev)) {
|
|
|
+ } else if (dev->type == ATP_GEYSER2) {
|
|
|
/*
|
|
|
* Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
|
|
|
* later.
|
|
@@ -703,9 +678,11 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
|
|
|
* 17" models are detected later.
|
|
|
*/
|
|
|
input_set_abs_params(input_dev, ABS_X, 0,
|
|
|
- (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
|
|
|
+ (16 - 1) * ATP_XFACT - 1,
|
|
|
+ ATP_FUZZ, 0);
|
|
|
input_set_abs_params(input_dev, ABS_Y, 0,
|
|
|
- (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
|
|
|
+ (ATP_YSENSORS - 1) * ATP_YFACT - 1,
|
|
|
+ ATP_FUZZ, 0);
|
|
|
}
|
|
|
input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
|
|
|
|
|
@@ -774,7 +751,7 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
|
|
|
struct atp *dev = usb_get_intfdata(iface);
|
|
|
|
|
|
usb_kill_urb(dev->urb);
|
|
|
- dev->valid = 0;
|
|
|
+ dev->valid = false;
|
|
|
|
|
|
return 0;
|
|
|
}
|