aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorMichael Hanselmann <linux-kernel@hansmi.ch>2005-12-21 00:50:23 -0500
committerDmitry Torokhov <dtor_core@ameritech.net>2005-12-21 00:50:23 -0500
commite1e02c9f766e5cf20d951d35e6d2bc2683aa87ef (patch)
treee01d10f57fdf1af64ebaab85caa414989e44f50d /drivers/usb
parent041387d98460b3947587929ef3a4773b8c48538f (diff)
Input: appletouch - add support for Geyser 2
This patch adds support for the Geyser 2 touchpads used on post Oct 2005 Apple PowerBooks to the appletouch driver. Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch> Acked-by: Rene Nussbaumer <linux-kernel@killerfox.forkbomb.ch> Acked-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Stelian Pop <stelian@popies.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/input/appletouch.c145
1 files changed, 109 insertions, 36 deletions
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index 15840db092a5..6cce8527ba06 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -6,6 +6,7 @@
6 * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 6 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
9 * 10 *
10 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. 11 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
11 * 12 *
@@ -38,6 +39,11 @@
38/* Apple has powerbooks which have the keyboard with different Product IDs */ 39/* Apple has powerbooks which have the keyboard with different Product IDs */
39#define APPLE_VENDOR_ID 0x05AC 40#define APPLE_VENDOR_ID 0x05AC
40 41
42/* These names come from Info.plist in AppleUSBTrackpad.kext */
43#define GEYSER_ANSI_PRODUCT_ID 0x0214
44#define GEYSER_ISO_PRODUCT_ID 0x0215
45#define GEYSER_JIS_PRODUCT_ID 0x0216
46
41#define ATP_DEVICE(prod) \ 47#define ATP_DEVICE(prod) \
42 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 48 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
43 USB_DEVICE_ID_MATCH_INT_CLASS | \ 49 USB_DEVICE_ID_MATCH_INT_CLASS | \
@@ -53,13 +59,17 @@ static struct usb_device_id atp_table [] = {
53 { ATP_DEVICE(0x020F) }, 59 { ATP_DEVICE(0x020F) },
54 { ATP_DEVICE(0x030A) }, 60 { ATP_DEVICE(0x030A) },
55 { ATP_DEVICE(0x030B) }, 61 { ATP_DEVICE(0x030B) },
56 { } /* Terminating entry */ 62
63 /* PowerBooks Oct 2005 */
64 { ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
65 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
66 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
67
68 /* Terminating entry */
69 { }
57}; 70};
58MODULE_DEVICE_TABLE (usb, atp_table); 71MODULE_DEVICE_TABLE (usb, atp_table);
59 72
60/* size of a USB urb transfer */
61#define ATP_DATASIZE 81
62
63/* 73/*
64 * number of sensors. Note that only 16 instead of 26 X (horizontal) 74 * number of sensors. Note that only 16 instead of 26 X (horizontal)
65 * sensors exist on 12" and 15" PowerBooks. All models have 16 Y 75 * sensors exist on 12" and 15" PowerBooks. All models have 16 Y
@@ -108,6 +118,8 @@ struct atp {
108 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; 118 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS];
109 /* accumulated sensors */ 119 /* accumulated sensors */
110 int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; 120 int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
121 int overflowwarn; /* overflow warning printed? */
122 int datalen; /* size of an USB urb transfer */
111}; 123};
112 124
113#define dbg_dump(msg, tab) \ 125#define dbg_dump(msg, tab) \
@@ -124,7 +136,7 @@ struct atp {
124 if (debug) printk(format, ##a); \ 136 if (debug) printk(format, ##a); \
125 } while (0) 137 } while (0)
126 138
127MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold"); 139MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
128MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); 140MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
129MODULE_LICENSE("GPL"); 141MODULE_LICENSE("GPL");
130 142
@@ -132,6 +144,16 @@ static int debug = 1;
132module_param(debug, int, 0644); 144module_param(debug, int, 0644);
133MODULE_PARM_DESC(debug, "Activate debugging output"); 145MODULE_PARM_DESC(debug, "Activate debugging output");
134 146
147/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
148static inline int atp_is_geyser_2(struct atp *dev)
149{
150 int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct);
151
152 return (productId == GEYSER_ANSI_PRODUCT_ID) ||
153 (productId == GEYSER_ISO_PRODUCT_ID) ||
154 (productId == GEYSER_JIS_PRODUCT_ID);
155}
156
135static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, 157static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
136 int *z, int *fingers) 158 int *z, int *fingers)
137{ 159{
@@ -168,13 +190,20 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
168static void atp_complete(struct urb* urb, struct pt_regs* regs) 190static void atp_complete(struct urb* urb, struct pt_regs* regs)
169{ 191{
170 int x, y, x_z, y_z, x_f, y_f; 192 int x, y, x_z, y_z, x_f, y_f;
171 int retval, i; 193 int retval, i, j;
172 struct atp *dev = urb->context; 194 struct atp *dev = urb->context;
173 195
174 switch (urb->status) { 196 switch (urb->status) {
175 case 0: 197 case 0:
176 /* success */ 198 /* success */
177 break; 199 break;
200 case -EOVERFLOW:
201 if(!dev->overflowwarn) {
202 printk("appletouch: OVERFLOW with data "
203 "length %d, actual length is %d\n",
204 dev->datalen, dev->urb->actual_length);
205 dev->overflowwarn = 1;
206 }
178 case -ECONNRESET: 207 case -ECONNRESET:
179 case -ENOENT: 208 case -ENOENT:
180 case -ESHUTDOWN: 209 case -ESHUTDOWN:
@@ -189,23 +218,45 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
189 } 218 }
190 219
191 /* drop incomplete datasets */ 220 /* drop incomplete datasets */
192 if (dev->urb->actual_length != ATP_DATASIZE) { 221 if (dev->urb->actual_length != dev->datalen) {
193 dprintk("appletouch: incomplete data package.\n"); 222 dprintk("appletouch: incomplete data package.\n");
194 goto exit; 223 goto exit;
195 } 224 }
196 225
197 /* reorder the sensors values */ 226 /* reorder the sensors values */
198 for (i = 0; i < 8; i++) { 227 if (atp_is_geyser_2(dev)) {
199 /* X values */ 228 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
200 dev->xy_cur[i ] = dev->data[5 * i + 2]; 229
201 dev->xy_cur[i + 8] = dev->data[5 * i + 4]; 230 /*
202 dev->xy_cur[i + 16] = dev->data[5 * i + 42]; 231 * The values are laid out like this:
203 if (i < 2) 232 * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ...
204 dev->xy_cur[i + 24] = dev->data[5 * i + 44]; 233 * '-' is an unused value.
205 234 */
206 /* Y values */ 235
207 dev->xy_cur[i + 26] = dev->data[5 * i + 1]; 236 /* read X values */
208 dev->xy_cur[i + 34] = dev->data[5 * i + 3]; 237 for (i = 0, j = 19; i < 20; i += 2, j += 3) {
238 dev->xy_cur[i] = dev->data[j];
239 dev->xy_cur[i + 1] = dev->data[j + 1];
240 }
241
242 /* read Y values */
243 for (i = 0, j = 1; i < 9; i += 2, j += 3) {
244 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j];
245 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 1];
246 }
247 } else {
248 for (i = 0; i < 8; i++) {
249 /* X values */
250 dev->xy_cur[i ] = dev->data[5 * i + 2];
251 dev->xy_cur[i + 8] = dev->data[5 * i + 4];
252 dev->xy_cur[i + 16] = dev->data[5 * i + 42];
253 if (i < 2)
254 dev->xy_cur[i + 24] = dev->data[5 * i + 44];
255
256 /* Y values */
257 dev->xy_cur[i + 26] = dev->data[5 * i + 1];
258 dev->xy_cur[i + 34] = dev->data[5 * i + 3];
259 }
209 } 260 }
210 261
211 dbg_dump("sample", dev->xy_cur); 262 dbg_dump("sample", dev->xy_cur);
@@ -216,16 +267,24 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
216 dev->x_old = dev->y_old = -1; 267 dev->x_old = dev->y_old = -1;
217 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 268 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
218 269
219 /* 17" Powerbooks have 10 extra X sensors */ 270 /* 17" Powerbooks have extra X sensors */
220 for (i = 16; i < ATP_XSENSORS; i++) 271 for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
221 if (dev->xy_cur[i]) { 272 if (!dev->xy_cur[i]) continue;
222 printk("appletouch: 17\" model detected.\n"); 273
274 printk("appletouch: 17\" model detected.\n");
275 if(atp_is_geyser_2(dev))
276 input_set_abs_params(dev->input, ABS_X, 0,
277 (20 - 1) *
278 ATP_XFACT - 1,
279 ATP_FUZZ, 0);
280 else
223 input_set_abs_params(dev->input, ABS_X, 0, 281 input_set_abs_params(dev->input, ABS_X, 0,
224 (ATP_XSENSORS - 1) * 282 (ATP_XSENSORS - 1) *
225 ATP_XFACT - 1, 283 ATP_XFACT - 1,
226 ATP_FUZZ, 0); 284 ATP_FUZZ, 0);
227 break; 285
228 } 286 break;
287 }
229 288
230 goto exit; 289 goto exit;
231 } 290 }
@@ -282,7 +341,8 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
282 memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); 341 memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
283 } 342 }
284 343
285 input_report_key(dev->input, BTN_LEFT, !!dev->data[80]); 344 input_report_key(dev->input, BTN_LEFT,
345 !!dev->data[dev->datalen - 1]);
286 346
287 input_sync(dev->input); 347 input_sync(dev->input);
288 348
@@ -353,6 +413,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
353 413
354 dev->udev = udev; 414 dev->udev = udev;
355 dev->input = input_dev; 415 dev->input = input_dev;
416 dev->overflowwarn = 0;
417 dev->datalen = (atp_is_geyser_2(dev)?64:81);
356 418
357 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 419 dev->urb = usb_alloc_urb(0, GFP_KERNEL);
358 if (!dev->urb) { 420 if (!dev->urb) {
@@ -360,7 +422,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
360 goto err_free_devs; 422 goto err_free_devs;
361 } 423 }
362 424
363 dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL, 425 dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL,
364 &dev->urb->transfer_dma); 426 &dev->urb->transfer_dma);
365 if (!dev->data) { 427 if (!dev->data) {
366 retval = -ENOMEM; 428 retval = -ENOMEM;
@@ -369,7 +431,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
369 431
370 usb_fill_int_urb(dev->urb, udev, 432 usb_fill_int_urb(dev->urb, udev,
371 usb_rcvintpipe(udev, int_in_endpointAddr), 433 usb_rcvintpipe(udev, int_in_endpointAddr),
372 dev->data, ATP_DATASIZE, atp_complete, dev, 1); 434 dev->data, dev->datalen, atp_complete, dev, 1);
373 435
374 usb_make_path(udev, dev->phys, sizeof(dev->phys)); 436 usb_make_path(udev, dev->phys, sizeof(dev->phys));
375 strlcat(dev->phys, "/input0", sizeof(dev->phys)); 437 strlcat(dev->phys, "/input0", sizeof(dev->phys));
@@ -385,14 +447,25 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
385 447
386 set_bit(EV_ABS, input_dev->evbit); 448 set_bit(EV_ABS, input_dev->evbit);
387 449
388 /* 450 if (atp_is_geyser_2(dev)) {
389 * 12" and 15" Powerbooks only have 16 x sensors, 451 /*
390 * 17" models are detected later. 452 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
391 */ 453 * later.
392 input_set_abs_params(input_dev, ABS_X, 0, 454 */
393 (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); 455 input_set_abs_params(input_dev, ABS_X, 0,
394 input_set_abs_params(input_dev, ABS_Y, 0, 456 ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
395 (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0); 457 input_set_abs_params(input_dev, ABS_Y, 0,
458 ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
459 } else {
460 /*
461 * 12" and 15" Powerbooks only have 16 x sensors,
462 * 17" models are detected later.
463 */
464 input_set_abs_params(input_dev, ABS_X, 0,
465 (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
466 input_set_abs_params(input_dev, ABS_Y, 0,
467 (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
468 }
396 input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); 469 input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
397 470
398 set_bit(EV_KEY, input_dev->evbit); 471 set_bit(EV_KEY, input_dev->evbit);
@@ -427,7 +500,7 @@ static void atp_disconnect(struct usb_interface *iface)
427 usb_kill_urb(dev->urb); 500 usb_kill_urb(dev->urb);
428 input_unregister_device(dev->input); 501 input_unregister_device(dev->input);
429 usb_free_urb(dev->urb); 502 usb_free_urb(dev->urb);
430 usb_buffer_free(dev->udev, ATP_DATASIZE, 503 usb_buffer_free(dev->udev, dev->datalen,
431 dev->data, dev->urb->transfer_dma); 504 dev->data, dev->urb->transfer_dma);
432 kfree(dev); 505 kfree(dev);
433 } 506 }