aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/input/appletouch.c95
-rw-r--r--drivers/usb/input/hid-core.c7
-rw-r--r--drivers/usb/input/hid-input.c4
-rw-r--r--drivers/usb/input/hid.h1
4 files changed, 90 insertions, 17 deletions
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index 4c213513484d..c77291d3d063 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -38,14 +38,29 @@
38#define APPLE_VENDOR_ID 0x05AC 38#define APPLE_VENDOR_ID 0x05AC
39 39
40/* These names come from Info.plist in AppleUSBTrackpad.kext */ 40/* These names come from Info.plist in AppleUSBTrackpad.kext */
41#define GEYSER_ANSI_PRODUCT_ID 0x0214 41#define FOUNTAIN_ANSI_PRODUCT_ID 0x020E
42#define GEYSER_ISO_PRODUCT_ID 0x0215 42#define FOUNTAIN_ISO_PRODUCT_ID 0x020F
43#define GEYSER_JIS_PRODUCT_ID 0x0216 43
44#define FOUNTAIN_TP_ONLY_PRODUCT_ID 0x030A
45
46#define GEYSER1_TP_ONLY_PRODUCT_ID 0x030B
47
48#define GEYSER_ANSI_PRODUCT_ID 0x0214
49#define GEYSER_ISO_PRODUCT_ID 0x0215
50#define GEYSER_JIS_PRODUCT_ID 0x0216
44 51
45/* MacBook devices */ 52/* MacBook devices */
46#define GEYSER3_ANSI_PRODUCT_ID 0x0217 53#define GEYSER3_ANSI_PRODUCT_ID 0x0217
47#define GEYSER3_ISO_PRODUCT_ID 0x0218 54#define GEYSER3_ISO_PRODUCT_ID 0x0218
48#define GEYSER3_JIS_PRODUCT_ID 0x0219 55#define GEYSER3_JIS_PRODUCT_ID 0x0219
56
57/*
58 * Geyser IV: same as Geyser III according to Info.plist in AppleUSBTrackpad.kext
59 * -> same IOClass (AppleUSBGrIIITrackpad), same acceleration tables
60 */
61#define GEYSER4_ANSI_PRODUCT_ID 0x021A
62#define GEYSER4_ISO_PRODUCT_ID 0x021B
63#define GEYSER4_JIS_PRODUCT_ID 0x021C
49 64
50#define ATP_DEVICE(prod) \ 65#define ATP_DEVICE(prod) \
51 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 66 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
@@ -58,20 +73,26 @@
58 73
59/* table of devices that work with this driver */ 74/* table of devices that work with this driver */
60static struct usb_device_id atp_table [] = { 75static struct usb_device_id atp_table [] = {
61 { ATP_DEVICE(0x020E) }, 76 { ATP_DEVICE(FOUNTAIN_ANSI_PRODUCT_ID) },
62 { ATP_DEVICE(0x020F) }, 77 { ATP_DEVICE(FOUNTAIN_ISO_PRODUCT_ID) },
63 { ATP_DEVICE(0x030A) }, 78 { ATP_DEVICE(FOUNTAIN_TP_ONLY_PRODUCT_ID) },
64 { ATP_DEVICE(0x030B) }, 79 { ATP_DEVICE(GEYSER1_TP_ONLY_PRODUCT_ID) },
65 80
66 /* PowerBooks Oct 2005 */ 81 /* PowerBooks Oct 2005 */
67 { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) }, 82 { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
68 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, 83 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
69 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, 84 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
70 85
86 /* Core Duo MacBook & MacBook Pro */
71 { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) }, 87 { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
72 { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) }, 88 { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
73 { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) }, 89 { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
74 90
91 /* Core2 Duo MacBook & MacBook Pro */
92 { ATP_DEVICE(GEYSER4_ANSI_PRODUCT_ID) },
93 { ATP_DEVICE(GEYSER4_ISO_PRODUCT_ID) },
94 { ATP_DEVICE(GEYSER4_JIS_PRODUCT_ID) },
95
75 /* Terminating entry */ 96 /* Terminating entry */
76 { } 97 { }
77}; 98};
@@ -108,7 +129,7 @@ MODULE_DEVICE_TABLE (usb, atp_table);
108 */ 129 */
109#define ATP_THRESHOLD 5 130#define ATP_THRESHOLD 5
110 131
111/* MacBook Pro (Geyser 3) initialization constants */ 132/* MacBook Pro (Geyser 3 & 4) initialization constants */
112#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1 133#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1
113#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9 134#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9
114#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300 135#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300
@@ -154,6 +175,13 @@ MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
154MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); 175MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
155MODULE_LICENSE("GPL"); 176MODULE_LICENSE("GPL");
156 177
178/*
179 * Make the threshold a module parameter
180 */
181static int threshold = ATP_THRESHOLD;
182module_param(threshold, int, 0644);
183MODULE_PARM_DESC(threshold, "Discards any change in data from a sensor (trackpad has hundreds of these sensors) less than this value");
184
157static int debug = 1; 185static int debug = 1;
158module_param(debug, int, 0644); 186module_param(debug, int, 0644);
159MODULE_PARM_DESC(debug, "Activate debugging output"); 187MODULE_PARM_DESC(debug, "Activate debugging output");
@@ -174,7 +202,10 @@ static inline int atp_is_geyser_3(struct atp *dev)
174 202
175 return (productId == GEYSER3_ANSI_PRODUCT_ID) || 203 return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
176 (productId == GEYSER3_ISO_PRODUCT_ID) || 204 (productId == GEYSER3_ISO_PRODUCT_ID) ||
177 (productId == GEYSER3_JIS_PRODUCT_ID); 205 (productId == GEYSER3_JIS_PRODUCT_ID) ||
206 (productId == GEYSER4_ANSI_PRODUCT_ID) ||
207 (productId == GEYSER4_ISO_PRODUCT_ID) ||
208 (productId == GEYSER4_JIS_PRODUCT_ID);
178} 209}
179 210
180static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, 211static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
@@ -183,16 +214,48 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
183 int i; 214 int i;
184 /* values to calculate mean */ 215 /* values to calculate mean */
185 int pcum = 0, psum = 0; 216 int pcum = 0, psum = 0;
217 int is_increasing = 0;
186 218
187 *fingers = 0; 219 *fingers = 0;
188 220
189 for (i = 0; i < nb_sensors; i++) { 221 for (i = 0; i < nb_sensors; i++) {
190 if (xy_sensors[i] < ATP_THRESHOLD) 222 if (xy_sensors[i] < threshold) {
223 if (is_increasing)
224 is_increasing = 0;
225
191 continue; 226 continue;
192 if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD)) 227 }
228
229 /*
230 * Makes the finger detection more versatile. For example,
231 * two fingers with no gap will be detected. Also, my
232 * tests show it less likely to have intermittent loss
233 * of multiple finger readings while moving around (scrolling).
234 *
235 * Changes the multiple finger detection to counting humps on
236 * sensors (transitions from nonincreasing to increasing)
237 * instead of counting transitions from low sensors (no
238 * finger reading) to high sensors (finger above
239 * sensor)
240 *
241 * - Jason Parekh <jasonparekh@gmail.com>
242 */
243 if (i < 1 || (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) {
193 (*fingers)++; 244 (*fingers)++;
194 pcum += xy_sensors[i] * i; 245 is_increasing = 1;
195 psum += xy_sensors[i]; 246 } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) {
247 is_increasing = 0;
248 }
249
250 /*
251 * Subtracts threshold so a high sensor that just passes the threshold
252 * won't skew the calculated absolute coordinate. Fixes an issue
253 * where slowly moving the mouse would occassionaly jump a number of
254 * pixels (let me restate--slowly moving the mouse makes this issue
255 * most apparent).
256 */
257 pcum += (xy_sensors[i] - threshold) * i;
258 psum += (xy_sensors[i] - threshold);
196 } 259 }
197 260
198 if (psum > 0) { 261 if (psum > 0) {
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index f1d0e1d69828..0811c39bd14f 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1670,6 +1670,9 @@ void hid_init_reports(struct hid_device *hid)
1670#define USB_VENDOR_ID_AIRCABLE 0x16CA 1670#define USB_VENDOR_ID_AIRCABLE 0x16CA
1671#define USB_DEVICE_ID_AIRCABLE1 0x1502 1671#define USB_DEVICE_ID_AIRCABLE1 0x1502
1672 1672
1673#define USB_VENDOR_ID_LOGITECH 0x046d
1674#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101
1675
1673/* 1676/*
1674 * Alphabetically sorted blacklist by quirk type. 1677 * Alphabetically sorted blacklist by quirk type.
1675 */ 1678 */
@@ -1841,7 +1844,9 @@ static const struct hid_blacklist {
1841 { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE }, 1844 { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
1842 1845
1843 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 1846 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
1844 1847
1848 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
1849
1845 { 0, 0 } 1850 { 0, 0 }
1846}; 1851};
1847 1852
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 68e7ebb978a9..3a7e5fbff025 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -581,6 +581,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
581 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) 581 || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
582 goto ignore; 582 goto ignore;
583 583
584 if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) &&
585 usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
586 field->flags &= ~HID_MAIN_ITEM_RELATIVE;
587
584 set_bit(usage->type, input->evbit); 588 set_bit(usage->type, input->evbit);
585 589
586 while (usage->code <= max && test_and_set_bit(usage->code, bit)) 590 while (usage->code <= max && test_and_set_bit(usage->code, bit))
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index 2a9bf07944c0..76ad68d9edfd 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -261,6 +261,7 @@ struct hid_item {
261#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 261#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
262#define HID_QUIRK_INVERT_HWHEEL 0x00004000 262#define HID_QUIRK_INVERT_HWHEEL 0x00004000
263#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 263#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000
264#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
264 265
265/* 266/*
266 * This is the global environment of the parser. This information is 267 * This is the global environment of the parser. This information is