aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Anders <anders@anduras.de>2008-08-08 16:31:31 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-08-08 16:44:19 -0400
commitd83d213d9fda671dfd84ea81182742f9e329a6b4 (patch)
tree4b02bbb6853fbc1d2dda54489c481518cc5e0eb7
parentce25d7e90c7543f0046c3bdcdcc7594546c57dcc (diff)
Input: appletouch - prepare for geyser 3/4 handling
Split complete function into separate functions for GEYSER1/2 and GEYSER 3/4. Signed-off-by: Sven Anders <anders@anduras.de> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/mouse/appletouch.c266
1 files changed, 197 insertions, 69 deletions
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 1f41ae94f26b..36ebe5c25ee3 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -327,11 +327,14 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
327 input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); 327 input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
328} 328}
329 329
330static void atp_complete(struct urb *urb) 330/* Check URB status and for correct length of data package */
331
332#define ATP_URB_STATUS_SUCCESS 0
333#define ATP_URB_STATUS_ERROR 1
334#define ATP_URB_STATUS_ERROR_FATAL 2
335
336static int atp_status_check(struct urb *urb)
331{ 337{
332 int x, y, x_z, y_z, x_f, y_f;
333 int retval, i, j;
334 int key;
335 struct atp *dev = urb->context; 338 struct atp *dev = urb->context;
336 339
337 switch (urb->status) { 340 switch (urb->status) {
@@ -351,11 +354,12 @@ static void atp_complete(struct urb *urb)
351 /* This urb is terminated, clean up */ 354 /* This urb is terminated, clean up */
352 dbg("atp_complete: urb shutting down with status: %d", 355 dbg("atp_complete: urb shutting down with status: %d",
353 urb->status); 356 urb->status);
354 return; 357 return ATP_URB_STATUS_ERROR_FATAL;
358
355 default: 359 default:
356 dbg("atp_complete: nonzero urb status received: %d", 360 dbg("atp_complete: nonzero urb status received: %d",
357 urb->status); 361 urb->status);
358 goto exit; 362 return ATP_URB_STATUS_ERROR;
359 } 363 }
360 364
361 /* drop incomplete datasets */ 365 /* drop incomplete datasets */
@@ -363,30 +367,33 @@ static void atp_complete(struct urb *urb)
363 dprintk("appletouch: incomplete data package" 367 dprintk("appletouch: incomplete data package"
364 " (first byte: %d, length: %d).\n", 368 " (first byte: %d, length: %d).\n",
365 dev->data[0], dev->urb->actual_length); 369 dev->data[0], dev->urb->actual_length);
366 goto exit; 370 return ATP_URB_STATUS_ERROR;
367 } 371 }
368 372
369 /* reorder the sensors values */ 373 return ATP_URB_STATUS_SUCCESS;
370 if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { 374}
371 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
372 375
373 /* 376/*
374 * The values are laid out like this: 377 * USB interrupt callback functions
375 * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ... 378 */
376 * '-' is an unused value.
377 */
378 379
379 /* read X values */ 380/* Interrupt function for older touchpads: FOUNTAIN/GEYSER1/GEYSER2 */
380 for (i = 0, j = 19; i < 20; i += 2, j += 3) { 381
381 dev->xy_cur[i] = dev->data[j + 1]; 382static void atp_complete_geyser_1_2(struct urb *urb)
382 dev->xy_cur[i + 1] = dev->data[j + 2]; 383{
383 } 384 int x, y, x_z, y_z, x_f, y_f;
384 /* read Y values */ 385 int retval, i, j;
385 for (i = 0, j = 1; i < 9; i += 2, j += 3) { 386 int key;
386 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; 387 struct atp *dev = urb->context;
387 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; 388 int status = atp_status_check(urb);
388 } 389
389 } else if (dev->type == ATP_GEYSER2) { 390 if (status == ATP_URB_STATUS_ERROR_FATAL)
391 return;
392 else if (status == ATP_URB_STATUS_ERROR)
393 goto exit;
394
395 /* reorder the sensors values */
396 if (dev->type == ATP_GEYSER2) {
390 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 397 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
391 398
392 /* 399 /*
@@ -427,33 +434,146 @@ static void atp_complete(struct urb *urb)
427 /* first sample */ 434 /* first sample */
428 dev->valid = true; 435 dev->valid = true;
429 dev->x_old = dev->y_old = -1; 436 dev->x_old = dev->y_old = -1;
437
438 /* Store first sample */
430 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 439 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
431 440
432 if (dev->size_detect_done || 441 /* Perform size detection, if not done already */
433 dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */ 442 if (!dev->size_detect_done) {
443
444 /* 17" Powerbooks have extra X sensors */
445 for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
446 i < ATP_XSENSORS; i++) {
447 if (!dev->xy_cur[i])
448 continue;
449
450 printk(KERN_INFO
451 "appletouch: 17\" model detected.\n");
452
453 if (dev->type == ATP_GEYSER2)
454 input_set_abs_params(dev->input, ABS_X,
455 0,
456 (20 - 1) *
457 ATP_XFACT - 1,
458 ATP_FUZZ, 0);
459 else
460 input_set_abs_params(dev->input, ABS_X,
461 0,
462 (26 - 1) *
463 ATP_XFACT - 1,
464 ATP_FUZZ, 0);
465 break;
466 }
467
468 dev->size_detect_done = 1;
434 goto exit; 469 goto exit;
470 }
471 }
435 472
436 /* 17" Powerbooks have extra X sensors */ 473 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
437 for (i = (dev->type == ATP_GEYSER2 ? 15 : 16); 474 /* accumulate the change */
438 i < ATP_XSENSORS; i++) { 475 signed char change = dev->xy_old[i] - dev->xy_cur[i];
439 if (!dev->xy_cur[i]) 476 dev->xy_acc[i] -= change;
440 continue; 477
441 478 /* prevent down drifting */
442 printk(KERN_INFO "appletouch: 17\" model detected.\n"); 479 if (dev->xy_acc[i] < 0)
443 if (dev->type == ATP_GEYSER2) 480 dev->xy_acc[i] = 0;
444 input_set_abs_params(dev->input, ABS_X, 0, 481 }
445 (20 - 1) * 482
446 ATP_XFACT - 1, 483 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
447 ATP_FUZZ, 0); 484
448 else 485 dbg_dump("accumulator", dev->xy_acc);
449 input_set_abs_params(dev->input, ABS_X, 0, 486
450 (ATP_XSENSORS - 1) * 487 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
451 ATP_XFACT - 1, 488 ATP_XFACT, &x_z, &x_f);
452 ATP_FUZZ, 0); 489 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
453 break; 490 ATP_YFACT, &y_z, &y_f);
491 key = dev->data[dev->datalen - 1] & 1;
492
493 if (x && y) {
494 if (dev->x_old != -1) {
495 x = (dev->x_old * 3 + x) >> 2;
496 y = (dev->y_old * 3 + y) >> 2;
497 dev->x_old = x;
498 dev->y_old = y;
499
500 if (debug > 1)
501 printk(KERN_DEBUG "appletouch: "
502 "X: %3d Y: %3d Xz: %3d Yz: %3d\n",
503 x, y, x_z, y_z);
504
505 input_report_key(dev->input, BTN_TOUCH, 1);
506 input_report_abs(dev->input, ABS_X, x);
507 input_report_abs(dev->input, ABS_Y, y);
508 input_report_abs(dev->input, ABS_PRESSURE,
509 min(ATP_PRESSURE, x_z + y_z));
510 atp_report_fingers(dev->input, max(x_f, y_f));
454 } 511 }
512 dev->x_old = x;
513 dev->y_old = y;
514
515 } else if (!x && !y) {
516
517 dev->x_old = dev->y_old = -1;
518 input_report_key(dev->input, BTN_TOUCH, 0);
519 input_report_abs(dev->input, ABS_PRESSURE, 0);
520 atp_report_fingers(dev->input, 0);
521
522 /* reset the accumulator on release */
523 memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
524 }
525
526 input_report_key(dev->input, BTN_LEFT, key);
527 input_sync(dev->input);
528
529 exit:
530 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
531 if (retval)
532 err("atp_complete: usb_submit_urb failed with result %d",
533 retval);
534}
535
536/* Interrupt function for older touchpads: GEYSER3/GEYSER4 */
537
538static void atp_complete_geyser_3_4(struct urb *urb)
539{
540 int x, y, x_z, y_z, x_f, y_f;
541 int retval, i, j;
542 int key;
543 struct atp *dev = urb->context;
544 int status = atp_status_check(urb);
545
546 if (status == ATP_URB_STATUS_ERROR_FATAL)
547 return;
548 else if (status == ATP_URB_STATUS_ERROR)
549 goto exit;
550
551 /* Reorder the sensors values:
552 *
553 * The values are laid out like this:
554 * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
555 * '-' is an unused value.
556 */
557
558 /* read X values */
559 for (i = 0, j = 19; i < 20; i += 2, j += 3) {
560 dev->xy_cur[i] = dev->data[j + 1];
561 dev->xy_cur[i + 1] = dev->data[j + 2];
562 }
563 /* read Y values */
564 for (i = 0, j = 1; i < 9; i += 2, j += 3) {
565 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
566 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
567 }
568
569 dbg_dump("sample", dev->xy_cur);
570
571 if (!dev->valid) {
572 /* first sample */
573 dev->valid = true;
574 dev->x_old = dev->y_old = -1;
575 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
455 576
456 dev->size_detect_done = 1;
457 goto exit; 577 goto exit;
458 } 578 }
459 579
@@ -514,28 +634,26 @@ static void atp_complete(struct urb *urb)
514 input_sync(dev->input); 634 input_sync(dev->input);
515 635
516 /* 636 /*
517 * Many Geysers will continue to send packets continually after 637 * Geysers 3/4 will continue to send packets continually after
518 * the first touch unless reinitialised. Do so if it's been 638 * the first touch unless reinitialised. Do so if it's been
519 * idle for a while in order to avoid waking the kernel up 639 * idle for a while in order to avoid waking the kernel up
520 * several hundred times a second. Re-initialization does not 640 * several hundred times a second.
521 * work on Fountain touchpads.
522 */ 641 */
523 if (dev->type != ATP_FOUNTAIN) { 642
524 /* 643 /*
525 * Button must not be pressed when entering suspend, 644 * Button must not be pressed when entering suspend,
526 * otherwise we will never release the button. 645 * otherwise we will never release the button.
527 */ 646 */
528 if (!x && !y && !key) { 647 if (!x && !y && !key) {
529 dev->idlecount++; 648 dev->idlecount++;
530 if (dev->idlecount == 10) { 649 if (dev->idlecount == 10) {
531 dev->valid = false; 650 dev->valid = false;
532 schedule_work(&dev->work); 651 schedule_work(&dev->work);
533 /* Don't resubmit urb here, wait for reinit */ 652 /* Don't resubmit urb here, wait for reinit */
534 return; 653 return;
535 } 654 }
536 } else 655 } else
537 dev->idlecount = 0; 656 dev->idlecount = 0;
538 }
539 657
540 exit: 658 exit:
541 retval = usb_submit_urb(dev->urb, GFP_ATOMIC); 659 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -632,9 +750,19 @@ static int atp_probe(struct usb_interface *iface,
632 if (!dev->data) 750 if (!dev->data)
633 goto err_free_urb; 751 goto err_free_urb;
634 752
635 usb_fill_int_urb(dev->urb, udev, 753 /* Select the USB complete (callback) function */
636 usb_rcvintpipe(udev, int_in_endpointAddr), 754 if (dev->type == ATP_FOUNTAIN ||
637 dev->data, dev->datalen, atp_complete, dev, 1); 755 dev->type == ATP_GEYSER1 ||
756 dev->type == ATP_GEYSER2)
757 usb_fill_int_urb(dev->urb, udev,
758 usb_rcvintpipe(udev, int_in_endpointAddr),
759 dev->data, dev->datalen,
760 atp_complete_geyser_1_2, dev, 1);
761 else
762 usb_fill_int_urb(dev->urb, udev,
763 usb_rcvintpipe(udev, int_in_endpointAddr),
764 dev->data, dev->datalen,
765 atp_complete_geyser_3_4, dev, 1);
638 766
639 error = atp_handle_geyser(dev); 767 error = atp_handle_geyser(dev);
640 if (error) 768 if (error)