Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.16 547 lines 15 kB view raw
1/* 2 * Apple USB Touchpad (for post-February 2005 PowerBooks) driver 3 * 4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 5 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) 6 * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) 10 * 11 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, write to the Free Software 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 27 */ 28 29#include <linux/config.h> 30#include <linux/kernel.h> 31#include <linux/errno.h> 32#include <linux/init.h> 33#include <linux/slab.h> 34#include <linux/module.h> 35#include <linux/usb.h> 36#include <linux/input.h> 37#include <linux/usb_input.h> 38 39/* Apple has powerbooks which have the keyboard with different Product IDs */ 40#define APPLE_VENDOR_ID 0x05AC 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 47#define ATP_DEVICE(prod) \ 48 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 49 USB_DEVICE_ID_MATCH_INT_CLASS | \ 50 USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ 51 .idVendor = APPLE_VENDOR_ID, \ 52 .idProduct = (prod), \ 53 .bInterfaceClass = 0x03, \ 54 .bInterfaceProtocol = 0x02 55 56/* table of devices that work with this driver */ 57static struct usb_device_id atp_table [] = { 58 { ATP_DEVICE(0x020E) }, 59 { ATP_DEVICE(0x020F) }, 60 { ATP_DEVICE(0x030A) }, 61 { ATP_DEVICE(0x030B) }, 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 { } 70}; 71MODULE_DEVICE_TABLE (usb, atp_table); 72 73/* 74 * number of sensors. Note that only 16 instead of 26 X (horizontal) 75 * sensors exist on 12" and 15" PowerBooks. All models have 16 Y 76 * (vertical) sensors. 77 */ 78#define ATP_XSENSORS 26 79#define ATP_YSENSORS 16 80 81/* amount of fuzz this touchpad generates */ 82#define ATP_FUZZ 16 83 84/* maximum pressure this driver will report */ 85#define ATP_PRESSURE 300 86/* 87 * multiplication factor for the X and Y coordinates. 88 * We try to keep the touchpad aspect ratio while still doing only simple 89 * arithmetics. 90 * The factors below give coordinates like: 91 * 0 <= x < 960 on 12" and 15" Powerbooks 92 * 0 <= x < 1600 on 17" Powerbooks 93 * 0 <= y < 646 94 */ 95#define ATP_XFACT 64 96#define ATP_YFACT 43 97 98/* 99 * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is 100 * ignored. 101 */ 102#define ATP_THRESHOLD 5 103 104/* Structure to hold all of our device specific stuff */ 105struct atp { 106 char phys[64]; 107 struct usb_device * udev; /* usb device */ 108 struct urb * urb; /* usb request block */ 109 signed char * data; /* transferred data */ 110 int open; /* non-zero if opened */ 111 struct input_dev *input; /* input dev */ 112 int valid; /* are the sensors valid ? */ 113 int x_old; /* last reported x/y, */ 114 int y_old; /* used for smoothing */ 115 /* current value of the sensors */ 116 signed char xy_cur[ATP_XSENSORS + ATP_YSENSORS]; 117 /* last value of the sensors */ 118 signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; 119 /* accumulated sensors */ 120 int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; 121 int overflowwarn; /* overflow warning printed? */ 122 int datalen; /* size of an USB urb transfer */ 123}; 124 125#define dbg_dump(msg, tab) \ 126 if (debug > 1) { \ 127 int i; \ 128 printk("appletouch: %s %lld", msg, (long long)jiffies); \ 129 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) \ 130 printk(" %02x", tab[i]); \ 131 printk("\n"); \ 132 } 133 134#define dprintk(format, a...) \ 135 do { \ 136 if (debug) printk(format, ##a); \ 137 } while (0) 138 139MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); 140MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver"); 141MODULE_LICENSE("GPL"); 142 143static int debug = 1; 144module_param(debug, int, 0644); 145MODULE_PARM_DESC(debug, "Activate debugging output"); 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 157static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, 158 int *z, int *fingers) 159{ 160 int i; 161 /* values to calculate mean */ 162 int pcum = 0, psum = 0; 163 164 *fingers = 0; 165 166 for (i = 0; i < nb_sensors; i++) { 167 if (xy_sensors[i] < ATP_THRESHOLD) 168 continue; 169 if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD)) 170 (*fingers)++; 171 pcum += xy_sensors[i] * i; 172 psum += xy_sensors[i]; 173 } 174 175 if (psum > 0) { 176 *z = psum; 177 return pcum * fact / psum; 178 } 179 180 return 0; 181} 182 183static inline void atp_report_fingers(struct input_dev *input, int fingers) 184{ 185 input_report_key(input, BTN_TOOL_FINGER, fingers == 1); 186 input_report_key(input, BTN_TOOL_DOUBLETAP, fingers == 2); 187 input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2); 188} 189 190static void atp_complete(struct urb* urb, struct pt_regs* regs) 191{ 192 int x, y, x_z, y_z, x_f, y_f; 193 int retval, i, j; 194 struct atp *dev = urb->context; 195 196 switch (urb->status) { 197 case 0: 198 /* success */ 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 } 207 case -ECONNRESET: 208 case -ENOENT: 209 case -ESHUTDOWN: 210 /* This urb is terminated, clean up */ 211 dbg("%s - urb shutting down with status: %d", 212 __FUNCTION__, urb->status); 213 return; 214 default: 215 dbg("%s - nonzero urb status received: %d", 216 __FUNCTION__, urb->status); 217 goto exit; 218 } 219 220 /* drop incomplete datasets */ 221 if (dev->urb->actual_length != dev->datalen) { 222 dprintk("appletouch: incomplete data package.\n"); 223 goto exit; 224 } 225 226 /* reorder the sensors values */ 227 if (atp_is_geyser_2(dev)) { 228 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 229 230 /* 231 * The values are laid out like this: 232 * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ... 233 * '-' is an unused value. 234 */ 235 236 /* read X values */ 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 } 260 } 261 262 dbg_dump("sample", dev->xy_cur); 263 264 if (!dev->valid) { 265 /* first sample */ 266 dev->valid = 1; 267 dev->x_old = dev->y_old = -1; 268 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 269 270 /* 17" Powerbooks have extra X sensors */ 271 for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { 272 if (!dev->xy_cur[i]) continue; 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 281 input_set_abs_params(dev->input, ABS_X, 0, 282 (ATP_XSENSORS - 1) * 283 ATP_XFACT - 1, 284 ATP_FUZZ, 0); 285 286 break; 287 } 288 289 goto exit; 290 } 291 292 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { 293 /* accumulate the change */ 294 signed char change = dev->xy_old[i] - dev->xy_cur[i]; 295 dev->xy_acc[i] -= change; 296 297 /* prevent down drifting */ 298 if (dev->xy_acc[i] < 0) 299 dev->xy_acc[i] = 0; 300 } 301 302 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 303 304 dbg_dump("accumulator", dev->xy_acc); 305 306 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 307 ATP_XFACT, &x_z, &x_f); 308 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 309 ATP_YFACT, &y_z, &y_f); 310 311 if (x && y) { 312 if (dev->x_old != -1) { 313 x = (dev->x_old * 3 + x) >> 2; 314 y = (dev->y_old * 3 + y) >> 2; 315 dev->x_old = x; 316 dev->y_old = y; 317 318 if (debug > 1) 319 printk("appletouch: X: %3d Y: %3d " 320 "Xz: %3d Yz: %3d\n", 321 x, y, x_z, y_z); 322 323 input_report_key(dev->input, BTN_TOUCH, 1); 324 input_report_abs(dev->input, ABS_X, x); 325 input_report_abs(dev->input, ABS_Y, y); 326 input_report_abs(dev->input, ABS_PRESSURE, 327 min(ATP_PRESSURE, x_z + y_z)); 328 atp_report_fingers(dev->input, max(x_f, y_f)); 329 } 330 dev->x_old = x; 331 dev->y_old = y; 332 } 333 else if (!x && !y) { 334 335 dev->x_old = dev->y_old = -1; 336 input_report_key(dev->input, BTN_TOUCH, 0); 337 input_report_abs(dev->input, ABS_PRESSURE, 0); 338 atp_report_fingers(dev->input, 0); 339 340 /* reset the accumulator on release */ 341 memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); 342 } 343 344 input_report_key(dev->input, BTN_LEFT, 345 !!dev->data[dev->datalen - 1]); 346 347 input_sync(dev->input); 348 349exit: 350 retval = usb_submit_urb(dev->urb, GFP_ATOMIC); 351 if (retval) { 352 err("%s - usb_submit_urb failed with result %d", 353 __FUNCTION__, retval); 354 } 355} 356 357static int atp_open(struct input_dev *input) 358{ 359 struct atp *dev = input->private; 360 361 if (usb_submit_urb(dev->urb, GFP_ATOMIC)) 362 return -EIO; 363 364 dev->open = 1; 365 return 0; 366} 367 368static void atp_close(struct input_dev *input) 369{ 370 struct atp *dev = input->private; 371 372 usb_kill_urb(dev->urb); 373 dev->open = 0; 374} 375 376static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id) 377{ 378 struct atp *dev; 379 struct input_dev *input_dev; 380 struct usb_device *udev = interface_to_usbdev(iface); 381 struct usb_host_interface *iface_desc; 382 struct usb_endpoint_descriptor *endpoint; 383 int int_in_endpointAddr = 0; 384 int i, retval = -ENOMEM; 385 386 387 /* set up the endpoint information */ 388 /* use only the first interrupt-in endpoint */ 389 iface_desc = iface->cur_altsetting; 390 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { 391 endpoint = &iface_desc->endpoint[i].desc; 392 if (!int_in_endpointAddr && 393 (endpoint->bEndpointAddress & USB_DIR_IN) && 394 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 395 == USB_ENDPOINT_XFER_INT)) { 396 /* we found an interrupt in endpoint */ 397 int_in_endpointAddr = endpoint->bEndpointAddress; 398 break; 399 } 400 } 401 if (!int_in_endpointAddr) { 402 err("Could not find int-in endpoint"); 403 return -EIO; 404 } 405 406 /* allocate memory for our device state and initialize it */ 407 dev = kzalloc(sizeof(struct atp), GFP_KERNEL); 408 input_dev = input_allocate_device(); 409 if (!dev || !input_dev) { 410 err("Out of memory"); 411 goto err_free_devs; 412 } 413 414 dev->udev = udev; 415 dev->input = input_dev; 416 dev->overflowwarn = 0; 417 dev->datalen = (atp_is_geyser_2(dev)?64:81); 418 419 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 420 if (!dev->urb) { 421 retval = -ENOMEM; 422 goto err_free_devs; 423 } 424 425 dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL, 426 &dev->urb->transfer_dma); 427 if (!dev->data) { 428 retval = -ENOMEM; 429 goto err_free_urb; 430 } 431 432 usb_fill_int_urb(dev->urb, udev, 433 usb_rcvintpipe(udev, int_in_endpointAddr), 434 dev->data, dev->datalen, atp_complete, dev, 1); 435 436 usb_make_path(udev, dev->phys, sizeof(dev->phys)); 437 strlcat(dev->phys, "/input0", sizeof(dev->phys)); 438 439 input_dev->name = "appletouch"; 440 input_dev->phys = dev->phys; 441 usb_to_input_id(dev->udev, &input_dev->id); 442 input_dev->cdev.dev = &iface->dev; 443 444 input_dev->private = dev; 445 input_dev->open = atp_open; 446 input_dev->close = atp_close; 447 448 set_bit(EV_ABS, input_dev->evbit); 449 450 if (atp_is_geyser_2(dev)) { 451 /* 452 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected 453 * later. 454 */ 455 input_set_abs_params(input_dev, ABS_X, 0, 456 ((15 - 1) * ATP_XFACT) - 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 } 469 input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0); 470 471 set_bit(EV_KEY, input_dev->evbit); 472 set_bit(BTN_TOUCH, input_dev->keybit); 473 set_bit(BTN_TOOL_FINGER, input_dev->keybit); 474 set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); 475 set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); 476 set_bit(BTN_LEFT, input_dev->keybit); 477 478 input_register_device(dev->input); 479 480 /* save our data pointer in this interface device */ 481 usb_set_intfdata(iface, dev); 482 483 return 0; 484 485 err_free_urb: 486 usb_free_urb(dev->urb); 487 err_free_devs: 488 usb_set_intfdata(iface, NULL); 489 kfree(dev); 490 input_free_device(input_dev); 491 return retval; 492} 493 494static void atp_disconnect(struct usb_interface *iface) 495{ 496 struct atp *dev = usb_get_intfdata(iface); 497 498 usb_set_intfdata(iface, NULL); 499 if (dev) { 500 usb_kill_urb(dev->urb); 501 input_unregister_device(dev->input); 502 usb_free_urb(dev->urb); 503 usb_buffer_free(dev->udev, dev->datalen, 504 dev->data, dev->urb->transfer_dma); 505 kfree(dev); 506 } 507 printk(KERN_INFO "input: appletouch disconnected\n"); 508} 509 510static int atp_suspend(struct usb_interface *iface, pm_message_t message) 511{ 512 struct atp *dev = usb_get_intfdata(iface); 513 usb_kill_urb(dev->urb); 514 dev->valid = 0; 515 return 0; 516} 517 518static int atp_resume(struct usb_interface *iface) 519{ 520 struct atp *dev = usb_get_intfdata(iface); 521 if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC)) 522 return -EIO; 523 524 return 0; 525} 526 527static struct usb_driver atp_driver = { 528 .name = "appletouch", 529 .probe = atp_probe, 530 .disconnect = atp_disconnect, 531 .suspend = atp_suspend, 532 .resume = atp_resume, 533 .id_table = atp_table, 534}; 535 536static int __init atp_init(void) 537{ 538 return usb_register(&atp_driver); 539} 540 541static void __exit atp_exit(void) 542{ 543 usb_deregister(&atp_driver); 544} 545 546module_init(atp_init); 547module_exit(atp_exit);