Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: appletouch - driver refactoring

The appletouch driver has grown up from supporting only a couple of
touchpads into supporting many touchpads, which can have different
number of sensors, different aspect ratios etc.

This patch cleans up the current driver code and makes it easy to
support the features of each different touchpad.

As a side effect, this patch also modifies the 'Y' multiplication factor
of the 'geyser3' and 'geyser4' touchpads (found on Core Duo and Core2
Duo MacBook and MacBook Pro laptops) in order to make the touchpad
output match the aspect ratio of the touchpad (Y factor changed from 43
to 64).

[dtor@mail.ru: make atp_info constant]
Signed-off-by: Stelian Pop <stelian@popies.net>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Stelian Pop and committed by
Dmitry Torokhov
09779678 b67b4b11

+136 -138
+136 -138
drivers/input/mouse/appletouch.c
··· 3 3 * 4 4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 5 5 * Copyright (C) 2005-2008 Johannes Berg (johannes@sipsolutions.net) 6 - * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 6 + * Copyright (C) 2005-2008 Stelian Pop (stelian@popies.net) 7 7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 8 8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 9 9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) ··· 35 35 #include <linux/module.h> 36 36 #include <linux/usb/input.h> 37 37 38 - /* Type of touchpad */ 39 - enum atp_touchpad_type { 40 - ATP_FOUNTAIN, 41 - ATP_GEYSER1, 42 - ATP_GEYSER2, 43 - ATP_GEYSER3, 44 - ATP_GEYSER4 38 + /* 39 + * Note: We try to keep the touchpad aspect ratio while still doing only 40 + * simple arithmetics: 41 + * 0 <= x <= (xsensors - 1) * xfact 42 + * 0 <= y <= (ysensors - 1) * yfact 43 + */ 44 + struct atp_info { 45 + int xsensors; /* number of X sensors */ 46 + int xsensors_17; /* 17" models have more sensors */ 47 + int ysensors; /* number of Y sensors */ 48 + int xfact; /* X multiplication factor */ 49 + int yfact; /* Y multiplication factor */ 50 + int datalen; /* size of USB transfers */ 51 + void (*callback)(struct urb *); /* callback function */ 45 52 }; 46 53 47 - #define ATP_DEVICE(prod, type) \ 54 + static void atp_complete_geyser_1_2(struct urb *urb); 55 + static void atp_complete_geyser_3_4(struct urb *urb); 56 + 57 + static const struct atp_info fountain_info = { 58 + .xsensors = 16, 59 + .xsensors_17 = 26, 60 + .ysensors = 16, 61 + .xfact = 64, 62 + .yfact = 43, 63 + .datalen = 81, 64 + .callback = atp_complete_geyser_1_2, 65 + }; 66 + 67 + static const struct atp_info geyser1_info = { 68 + .xsensors = 16, 69 + .xsensors_17 = 26, 70 + .ysensors = 16, 71 + .xfact = 64, 72 + .yfact = 43, 73 + .datalen = 81, 74 + .callback = atp_complete_geyser_1_2, 75 + }; 76 + 77 + static const struct atp_info geyser2_info = { 78 + .xsensors = 15, 79 + .xsensors_17 = 20, 80 + .ysensors = 9, 81 + .xfact = 64, 82 + .yfact = 43, 83 + .datalen = 64, 84 + .callback = atp_complete_geyser_1_2, 85 + }; 86 + 87 + static const struct atp_info geyser3_info = { 88 + .xsensors = 20, 89 + .ysensors = 10, 90 + .xfact = 64, 91 + .yfact = 64, 92 + .datalen = 64, 93 + .callback = atp_complete_geyser_3_4, 94 + }; 95 + 96 + static const struct atp_info geyser4_info = { 97 + .xsensors = 20, 98 + .ysensors = 10, 99 + .xfact = 64, 100 + .yfact = 64, 101 + .datalen = 64, 102 + .callback = atp_complete_geyser_3_4, 103 + }; 104 + 105 + #define ATP_DEVICE(prod, info) \ 48 106 { \ 49 107 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 50 108 USB_DEVICE_ID_MATCH_INT_CLASS | \ ··· 111 53 .idProduct = (prod), \ 112 54 .bInterfaceClass = 0x03, \ 113 55 .bInterfaceProtocol = 0x02, \ 114 - .driver_info = ATP_ ## type, \ 56 + .driver_info = (unsigned long) &info, \ 115 57 } 116 58 117 59 /* ··· 120 62 * According to Info.plist Geyser IV is the same as Geyser III.) 121 63 */ 122 64 123 - static struct usb_device_id atp_table [] = { 65 + static struct usb_device_id atp_table[] = { 124 66 /* PowerBooks Feb 2005, iBooks G4 */ 125 - ATP_DEVICE(0x020e, FOUNTAIN), /* FOUNTAIN ANSI */ 126 - ATP_DEVICE(0x020f, FOUNTAIN), /* FOUNTAIN ISO */ 127 - ATP_DEVICE(0x030a, FOUNTAIN), /* FOUNTAIN TP ONLY */ 128 - ATP_DEVICE(0x030b, GEYSER1), /* GEYSER 1 TP ONLY */ 67 + ATP_DEVICE(0x020e, fountain_info), /* FOUNTAIN ANSI */ 68 + ATP_DEVICE(0x020f, fountain_info), /* FOUNTAIN ISO */ 69 + ATP_DEVICE(0x030a, fountain_info), /* FOUNTAIN TP ONLY */ 70 + ATP_DEVICE(0x030b, geyser1_info), /* GEYSER 1 TP ONLY */ 129 71 130 72 /* PowerBooks Oct 2005 */ 131 - ATP_DEVICE(0x0214, GEYSER2), /* GEYSER 2 ANSI */ 132 - ATP_DEVICE(0x0215, GEYSER2), /* GEYSER 2 ISO */ 133 - ATP_DEVICE(0x0216, GEYSER2), /* GEYSER 2 JIS */ 73 + ATP_DEVICE(0x0214, geyser2_info), /* GEYSER 2 ANSI */ 74 + ATP_DEVICE(0x0215, geyser2_info), /* GEYSER 2 ISO */ 75 + ATP_DEVICE(0x0216, geyser2_info), /* GEYSER 2 JIS */ 134 76 135 77 /* Core Duo MacBook & MacBook Pro */ 136 - ATP_DEVICE(0x0217, GEYSER3), /* GEYSER 3 ANSI */ 137 - ATP_DEVICE(0x0218, GEYSER3), /* GEYSER 3 ISO */ 138 - ATP_DEVICE(0x0219, GEYSER3), /* GEYSER 3 JIS */ 78 + ATP_DEVICE(0x0217, geyser3_info), /* GEYSER 3 ANSI */ 79 + ATP_DEVICE(0x0218, geyser3_info), /* GEYSER 3 ISO */ 80 + ATP_DEVICE(0x0219, geyser3_info), /* GEYSER 3 JIS */ 139 81 140 82 /* Core2 Duo MacBook & MacBook Pro */ 141 - ATP_DEVICE(0x021a, GEYSER4), /* GEYSER 4 ANSI */ 142 - ATP_DEVICE(0x021b, GEYSER4), /* GEYSER 4 ISO */ 143 - ATP_DEVICE(0x021c, GEYSER4), /* GEYSER 4 JIS */ 83 + ATP_DEVICE(0x021a, geyser4_info), /* GEYSER 4 ANSI */ 84 + ATP_DEVICE(0x021b, geyser4_info), /* GEYSER 4 ISO */ 85 + ATP_DEVICE(0x021c, geyser4_info), /* GEYSER 4 JIS */ 144 86 145 87 /* Core2 Duo MacBook3,1 */ 146 - ATP_DEVICE(0x0229, GEYSER4), /* GEYSER 4 HF ANSI */ 147 - ATP_DEVICE(0x022a, GEYSER4), /* GEYSER 4 HF ISO */ 148 - ATP_DEVICE(0x022b, GEYSER4), /* GEYSER 4 HF JIS */ 88 + ATP_DEVICE(0x0229, geyser4_info), /* GEYSER 4 HF ANSI */ 89 + ATP_DEVICE(0x022a, geyser4_info), /* GEYSER 4 HF ISO */ 90 + ATP_DEVICE(0x022b, geyser4_info), /* GEYSER 4 HF JIS */ 149 91 150 92 /* Terminating entry */ 151 93 { } 152 94 }; 153 95 MODULE_DEVICE_TABLE(usb, atp_table); 154 96 155 - /* 156 - * number of sensors. Note that only 16 instead of 26 X (horizontal) 157 - * sensors exist on 12" and 15" PowerBooks. All models have 16 Y 158 - * (vertical) sensors. 159 - */ 97 + /* maximum number of sensors */ 160 98 #define ATP_XSENSORS 26 161 99 #define ATP_YSENSORS 16 162 100 ··· 161 107 162 108 /* maximum pressure this driver will report */ 163 109 #define ATP_PRESSURE 300 164 - /* 165 - * multiplication factor for the X and Y coordinates. 166 - * We try to keep the touchpad aspect ratio while still doing only simple 167 - * arithmetics. 168 - * The factors below give coordinates like: 169 - * 170 - * 0 <= x < 960 on 12" and 15" Powerbooks 171 - * 0 <= x < 1600 on 17" Powerbooks and 17" MacBook Pro 172 - * 0 <= x < 1216 on MacBooks and 15" MacBook Pro 173 - * 174 - * 0 <= y < 646 on all Powerbooks 175 - * 0 <= y < 774 on all MacBooks 176 - */ 177 - #define ATP_XFACT 64 178 - #define ATP_YFACT 43 179 110 180 111 /* 181 112 * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is ··· 198 159 struct urb *urb; /* usb request block */ 199 160 u8 *data; /* transferred data */ 200 161 struct input_dev *input; /* input dev */ 201 - enum atp_touchpad_type type; /* type of touchpad */ 162 + const struct atp_info *info; /* touchpad model */ 202 163 bool open; 203 164 bool valid; /* are the samples valid? */ 204 165 bool size_detect_done; ··· 208 169 signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; 209 170 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; 210 171 int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; 211 - int datalen; /* size of USB transfer */ 212 172 int idlecount; /* number of empty packets */ 213 173 struct work_struct work; 214 174 }; ··· 397 359 if (!dev->overflow_warned) { 398 360 printk(KERN_WARNING "appletouch: OVERFLOW with data " 399 361 "length %d, actual length is %d\n", 400 - dev->datalen, dev->urb->actual_length); 362 + dev->info->datalen, dev->urb->actual_length); 401 363 dev->overflow_warned = true; 402 364 } 403 365 case -ECONNRESET: ··· 415 377 } 416 378 417 379 /* drop incomplete datasets */ 418 - if (dev->urb->actual_length != dev->datalen) { 380 + if (dev->urb->actual_length != dev->info->datalen) { 419 381 dprintk("appletouch: incomplete data package" 420 382 " (first byte: %d, length: %d).\n", 421 383 dev->data[0], dev->urb->actual_length); ··· 423 385 } 424 386 425 387 return ATP_URB_STATUS_SUCCESS; 388 + } 389 + 390 + static void atp_detect_size(struct atp *dev) 391 + { 392 + int i; 393 + 394 + /* 17" Powerbooks have extra X sensors */ 395 + for (i = dev->info->xsensors; i < ATP_XSENSORS; i++) { 396 + if (dev->xy_cur[i]) { 397 + 398 + printk(KERN_INFO "appletouch: 17\" model detected.\n"); 399 + 400 + input_set_abs_params(dev->input, ABS_X, 0, 401 + (dev->info->xsensors_17 - 1) * 402 + dev->info->xfact - 1, 403 + ATP_FUZZ, 0); 404 + break; 405 + } 406 + } 426 407 } 427 408 428 409 /* ··· 464 407 goto exit; 465 408 466 409 /* reorder the sensors values */ 467 - if (dev->type == ATP_GEYSER2) { 410 + if (dev->info == &geyser2_info) { 468 411 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 469 412 470 413 /* ··· 494 437 dev->xy_cur[i + 24] = dev->data[5 * i + 44]; 495 438 496 439 /* Y values */ 497 - dev->xy_cur[i + 26] = dev->data[5 * i + 1]; 498 - dev->xy_cur[i + 34] = dev->data[5 * i + 3]; 440 + dev->xy_cur[ATP_XSENSORS + i] = dev->data[5 * i + 1]; 441 + dev->xy_cur[ATP_XSENSORS + i + 8] = dev->data[5 * i + 3]; 499 442 } 500 443 } 501 444 ··· 510 453 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 511 454 512 455 /* Perform size detection, if not done already */ 513 - if (!dev->size_detect_done) { 514 - 515 - /* 17" Powerbooks have extra X sensors */ 516 - for (i = (dev->type == ATP_GEYSER2 ? 15 : 16); 517 - i < ATP_XSENSORS; i++) { 518 - if (!dev->xy_cur[i]) 519 - continue; 520 - 521 - printk(KERN_INFO 522 - "appletouch: 17\" model detected.\n"); 523 - 524 - if (dev->type == ATP_GEYSER2) 525 - input_set_abs_params(dev->input, ABS_X, 526 - 0, 527 - (20 - 1) * 528 - ATP_XFACT - 1, 529 - ATP_FUZZ, 0); 530 - else 531 - input_set_abs_params(dev->input, ABS_X, 532 - 0, 533 - (26 - 1) * 534 - ATP_XFACT - 1, 535 - ATP_FUZZ, 0); 536 - break; 537 - } 538 - 456 + if (unlikely(!dev->size_detect_done)) { 457 + atp_detect_size(dev); 539 458 dev->size_detect_done = 1; 540 459 goto exit; 541 460 } ··· 532 499 dbg_dump("accumulator", dev->xy_acc); 533 500 534 501 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 535 - ATP_XFACT, &x_z, &x_f); 502 + dev->info->xfact, &x_z, &x_f); 536 503 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 537 - ATP_YFACT, &y_z, &y_f); 538 - key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON; 504 + dev->info->yfact, &y_z, &y_f); 505 + key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON; 539 506 540 507 if (x && y) { 541 508 if (dev->x_old != -1) { ··· 616 583 dbg_dump("sample", dev->xy_cur); 617 584 618 585 /* Just update the base values (i.e. touchpad in untouched state) */ 619 - if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) { 586 + if (dev->data[dev->info->datalen - 1] & ATP_STATUS_BASE_UPDATE) { 620 587 621 588 dprintk(KERN_DEBUG "appletouch: updated base values\n"); 622 589 ··· 643 610 dbg_dump("accumulator", dev->xy_acc); 644 611 645 612 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 646 - ATP_XFACT, &x_z, &x_f); 613 + dev->info->xfact, &x_z, &x_f); 647 614 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 648 - ATP_YFACT, &y_z, &y_f); 649 - key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON; 615 + dev->info->yfact, &y_z, &y_f); 616 + key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON; 650 617 651 618 if (x && y) { 652 619 if (dev->x_old != -1) { ··· 738 705 { 739 706 struct usb_device *udev = dev->udev; 740 707 741 - if (dev->type != ATP_FOUNTAIN) { 708 + if (dev->info != &fountain_info) { 742 709 /* switch to raw sensor mode */ 743 710 if (atp_geyser_init(udev)) 744 711 return -EIO; ··· 759 726 struct usb_endpoint_descriptor *endpoint; 760 727 int int_in_endpointAddr = 0; 761 728 int i, error = -ENOMEM; 729 + const struct atp_info *info = (const struct atp_info *)id->driver_info; 762 730 763 731 /* set up the endpoint information */ 764 732 /* use only the first interrupt-in endpoint */ ··· 787 753 788 754 dev->udev = udev; 789 755 dev->input = input_dev; 790 - dev->type = id->driver_info; 756 + dev->info = info; 791 757 dev->overflow_warned = false; 792 - if (dev->type == ATP_FOUNTAIN || dev->type == ATP_GEYSER1) 793 - dev->datalen = 81; 794 - else 795 - dev->datalen = 64; 796 758 797 759 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 798 760 if (!dev->urb) 799 761 goto err_free_devs; 800 762 801 - dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL, 763 + dev->data = usb_buffer_alloc(dev->udev, dev->info->datalen, GFP_KERNEL, 802 764 &dev->urb->transfer_dma); 803 765 if (!dev->data) 804 766 goto err_free_urb; 805 767 806 - /* Select the USB complete (callback) function */ 807 - if (dev->type == ATP_FOUNTAIN || 808 - dev->type == ATP_GEYSER1 || 809 - dev->type == ATP_GEYSER2) 810 - usb_fill_int_urb(dev->urb, udev, 811 - usb_rcvintpipe(udev, int_in_endpointAddr), 812 - dev->data, dev->datalen, 813 - atp_complete_geyser_1_2, dev, 1); 814 - else 815 - usb_fill_int_urb(dev->urb, udev, 816 - usb_rcvintpipe(udev, int_in_endpointAddr), 817 - dev->data, dev->datalen, 818 - atp_complete_geyser_3_4, dev, 1); 768 + usb_fill_int_urb(dev->urb, udev, 769 + usb_rcvintpipe(udev, int_in_endpointAddr), 770 + dev->data, dev->info->datalen, 771 + dev->info->callback, dev, 1); 819 772 820 773 error = atp_handle_geyser(dev); 821 774 if (error) ··· 823 802 824 803 set_bit(EV_ABS, input_dev->evbit); 825 804 826 - if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) { 827 - /* 828 - * MacBook have 20 X sensors, 10 Y sensors 829 - */ 830 - input_set_abs_params(input_dev, ABS_X, 0, 831 - ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); 832 - input_set_abs_params(input_dev, ABS_Y, 0, 833 - ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0); 834 - } else if (dev->type == ATP_GEYSER2) { 835 - /* 836 - * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected 837 - * later. 838 - */ 839 - input_set_abs_params(input_dev, ABS_X, 0, 840 - ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0); 841 - input_set_abs_params(input_dev, ABS_Y, 0, 842 - ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0); 843 - } else { 844 - /* 845 - * 12" and 15" Powerbooks only have 16 x sensors, 846 - * 17" models are detected later. 847 - */ 848 - input_set_abs_params(input_dev, ABS_X, 0, 849 - (16 - 1) * ATP_XFACT - 1, 850 - ATP_FUZZ, 0); 851 - input_set_abs_params(input_dev, ABS_Y, 0, 852 - (ATP_YSENSORS - 1) * ATP_YFACT - 1, 853 - ATP_FUZZ, 0); 854 - } 805 + input_set_abs_params(input_dev, ABS_X, 0, 806 + (dev->info->xsensors - 1) * dev->info->xfact - 1, 807 + ATP_FUZZ, 0); 808 + input_set_abs_params(input_dev, ABS_Y, 0, 809 + (dev->info->ysensors - 1) * dev->info->yfact - 1, 810 + ATP_FUZZ, 0); 855 811 input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); 856 812 857 813 set_bit(EV_KEY, input_dev->evbit); ··· 850 852 return 0; 851 853 852 854 err_free_buffer: 853 - usb_buffer_free(dev->udev, dev->datalen, 855 + usb_buffer_free(dev->udev, dev->info->datalen, 854 856 dev->data, dev->urb->transfer_dma); 855 857 err_free_urb: 856 858 usb_free_urb(dev->urb); ··· 869 871 if (dev) { 870 872 usb_kill_urb(dev->urb); 871 873 input_unregister_device(dev->input); 872 - usb_buffer_free(dev->udev, dev->datalen, 874 + usb_buffer_free(dev->udev, dev->info->datalen, 873 875 dev->data, dev->urb->transfer_dma); 874 876 usb_free_urb(dev->urb); 875 877 kfree(dev);