diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/input/mouse/appletouch.c | 125 |
1 files changed, 77 insertions, 48 deletions
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index f132702d137d..b4423a471f02 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
| @@ -129,12 +129,12 @@ MODULE_DEVICE_TABLE (usb, atp_table); | |||
| 129 | */ | 129 | */ |
| 130 | #define ATP_THRESHOLD 5 | 130 | #define ATP_THRESHOLD 5 |
| 131 | 131 | ||
| 132 | /* MacBook Pro (Geyser 3 & 4) initialization constants */ | 132 | /* Geyser initialization constants */ |
| 133 | #define ATP_GEYSER3_MODE_READ_REQUEST_ID 1 | 133 | #define ATP_GEYSER_MODE_READ_REQUEST_ID 1 |
| 134 | #define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9 | 134 | #define ATP_GEYSER_MODE_WRITE_REQUEST_ID 9 |
| 135 | #define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300 | 135 | #define ATP_GEYSER_MODE_REQUEST_VALUE 0x300 |
| 136 | #define ATP_GEYSER3_MODE_REQUEST_INDEX 0 | 136 | #define ATP_GEYSER_MODE_REQUEST_INDEX 0 |
| 137 | #define ATP_GEYSER3_MODE_VENDOR_VALUE 0x04 | 137 | #define ATP_GEYSER_MODE_VENDOR_VALUE 0x04 |
| 138 | 138 | ||
| 139 | /* Structure to hold all of our device specific stuff */ | 139 | /* Structure to hold all of our device specific stuff */ |
| 140 | struct atp { | 140 | struct atp { |
| @@ -142,9 +142,11 @@ struct atp { | |||
| 142 | struct usb_device * udev; /* usb device */ | 142 | struct usb_device * udev; /* usb device */ |
| 143 | struct urb * urb; /* usb request block */ | 143 | struct urb * urb; /* usb request block */ |
| 144 | signed char * data; /* transferred data */ | 144 | signed char * data; /* transferred data */ |
| 145 | int open; /* non-zero if opened */ | 145 | struct input_dev * input; /* input dev */ |
| 146 | struct input_dev *input; /* input dev */ | 146 | unsigned char open; /* non-zero if opened */ |
| 147 | int valid; /* are the sensors valid ? */ | 147 | unsigned char valid; /* are the sensors valid ? */ |
| 148 | unsigned char size_detect_done; | ||
| 149 | unsigned char overflowwarn; /* overflow warning printed? */ | ||
| 148 | int x_old; /* last reported x/y, */ | 150 | int x_old; /* last reported x/y, */ |
| 149 | int y_old; /* used for smoothing */ | 151 | int y_old; /* used for smoothing */ |
| 150 | /* current value of the sensors */ | 152 | /* current value of the sensors */ |
| @@ -153,7 +155,6 @@ struct atp { | |||
| 153 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; | 155 | signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; |
| 154 | /* accumulated sensors */ | 156 | /* accumulated sensors */ |
| 155 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; | 157 | int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; |
| 156 | int overflowwarn; /* overflow warning printed? */ | ||
| 157 | int datalen; /* size of an USB urb transfer */ | 158 | int datalen; /* size of an USB urb transfer */ |
| 158 | int idlecount; /* number of empty packets */ | 159 | int idlecount; /* number of empty packets */ |
| 159 | struct work_struct work; | 160 | struct work_struct work; |
| @@ -170,7 +171,7 @@ struct atp { | |||
| 170 | 171 | ||
| 171 | #define dprintk(format, a...) \ | 172 | #define dprintk(format, a...) \ |
| 172 | do { \ | 173 | do { \ |
| 173 | if (debug) printk(format, ##a); \ | 174 | if (debug) printk(KERN_DEBUG format, ##a); \ |
| 174 | } while (0) | 175 | } while (0) |
| 175 | 176 | ||
| 176 | MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); | 177 | MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann"); |
| @@ -188,6 +189,15 @@ static int debug = 1; | |||
| 188 | module_param(debug, int, 0644); | 189 | module_param(debug, int, 0644); |
| 189 | MODULE_PARM_DESC(debug, "Activate debugging output"); | 190 | MODULE_PARM_DESC(debug, "Activate debugging output"); |
| 190 | 191 | ||
| 192 | static inline int atp_is_fountain(struct atp *dev) | ||
| 193 | { | ||
| 194 | u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
| 195 | |||
| 196 | return productId == FOUNTAIN_ANSI_PRODUCT_ID || | ||
| 197 | productId == FOUNTAIN_ISO_PRODUCT_ID || | ||
| 198 | productId == FOUNTAIN_TP_ONLY_PRODUCT_ID; | ||
| 199 | } | ||
| 200 | |||
| 191 | /* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ | 201 | /* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ |
| 192 | static inline int atp_is_geyser_2(struct atp *dev) | 202 | static inline int atp_is_geyser_2(struct atp *dev) |
| 193 | { | 203 | { |
| @@ -211,52 +221,63 @@ static inline int atp_is_geyser_3(struct atp *dev) | |||
| 211 | } | 221 | } |
| 212 | 222 | ||
| 213 | /* | 223 | /* |
| 214 | * By default Geyser 3 device sends standard USB HID mouse | 224 | * By default newer Geyser devices send standard USB HID mouse |
| 215 | * packets (Report ID 2). This code changes device mode, so it | 225 | * packets (Report ID 2). This code changes device mode, so it |
| 216 | * sends raw sensor reports (Report ID 5). | 226 | * sends raw sensor reports (Report ID 5). |
| 217 | */ | 227 | */ |
| 218 | static int atp_geyser3_init(struct usb_device *udev) | 228 | static int atp_geyser_init(struct usb_device *udev) |
| 219 | { | 229 | { |
| 220 | char data[8]; | 230 | char data[8]; |
| 221 | int size; | 231 | int size; |
| 222 | 232 | ||
| 223 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 233 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
| 224 | ATP_GEYSER3_MODE_READ_REQUEST_ID, | 234 | ATP_GEYSER_MODE_READ_REQUEST_ID, |
| 225 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 235 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| 226 | ATP_GEYSER3_MODE_REQUEST_VALUE, | 236 | ATP_GEYSER_MODE_REQUEST_VALUE, |
| 227 | ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); | 237 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); |
| 228 | 238 | ||
| 229 | if (size != 8) { | 239 | if (size != 8) { |
| 230 | err("Could not do mode read request from device" | 240 | err("Could not do mode read request from device" |
| 231 | " (Geyser 3 mode)"); | 241 | " (Geyser Raw mode)"); |
| 232 | return -EIO; | 242 | return -EIO; |
| 233 | } | 243 | } |
| 234 | 244 | ||
| 235 | /* Apply the mode switch */ | 245 | /* Apply the mode switch */ |
| 236 | data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE; | 246 | data[0] = ATP_GEYSER_MODE_VENDOR_VALUE; |
| 237 | 247 | ||
| 238 | size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 248 | size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
| 239 | ATP_GEYSER3_MODE_WRITE_REQUEST_ID, | 249 | ATP_GEYSER_MODE_WRITE_REQUEST_ID, |
| 240 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 250 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| 241 | ATP_GEYSER3_MODE_REQUEST_VALUE, | 251 | ATP_GEYSER_MODE_REQUEST_VALUE, |
| 242 | ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000); | 252 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); |
| 243 | 253 | ||
| 244 | if (size != 8) { | 254 | if (size != 8) { |
| 245 | err("Could not do mode write request to device" | 255 | err("Could not do mode write request to device" |
| 246 | " (Geyser 3 mode)"); | 256 | " (Geyser Raw mode)"); |
| 247 | return -EIO; | 257 | return -EIO; |
| 248 | } | 258 | } |
| 249 | return 0; | 259 | return 0; |
| 250 | } | 260 | } |
| 251 | 261 | ||
| 252 | /* Reinitialise the device if it's a geyser 3 */ | 262 | /* |
| 263 | * Reinitialise the device. This usually stops stream of empty packets | ||
| 264 | * coming from it. | ||
| 265 | */ | ||
| 253 | static void atp_reinit(struct work_struct *work) | 266 | static void atp_reinit(struct work_struct *work) |
| 254 | { | 267 | { |
| 255 | struct atp *dev = container_of(work, struct atp, work); | 268 | struct atp *dev = container_of(work, struct atp, work); |
| 256 | struct usb_device *udev = dev->udev; | 269 | struct usb_device *udev = dev->udev; |
| 270 | int retval; | ||
| 257 | 271 | ||
| 258 | dev->idlecount = 0; | 272 | dev->idlecount = 0; |
| 259 | atp_geyser3_init(udev); | 273 | |
| 274 | atp_geyser_init(udev); | ||
| 275 | |||
| 276 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | ||
| 277 | if (retval) { | ||
| 278 | err("%s - usb_submit_urb failed with result %d", | ||
| 279 | __FUNCTION__, retval); | ||
| 280 | } | ||
| 260 | } | 281 | } |
| 261 | 282 | ||
| 262 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | 283 | static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, |
| @@ -337,7 +358,7 @@ static void atp_complete(struct urb* urb) | |||
| 337 | break; | 358 | break; |
| 338 | case -EOVERFLOW: | 359 | case -EOVERFLOW: |
| 339 | if(!dev->overflowwarn) { | 360 | if(!dev->overflowwarn) { |
| 340 | printk("appletouch: OVERFLOW with data " | 361 | printk(KERN_WARNING "appletouch: OVERFLOW with data " |
| 341 | "length %d, actual length is %d\n", | 362 | "length %d, actual length is %d\n", |
| 342 | dev->datalen, dev->urb->actual_length); | 363 | dev->datalen, dev->urb->actual_length); |
| 343 | dev->overflowwarn = 1; | 364 | dev->overflowwarn = 1; |
| @@ -426,15 +447,17 @@ static void atp_complete(struct urb* urb) | |||
| 426 | dev->x_old = dev->y_old = -1; | 447 | dev->x_old = dev->y_old = -1; |
| 427 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); | 448 | memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); |
| 428 | 449 | ||
| 429 | if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */ | 450 | if (dev->size_detect_done || |
| 451 | atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */ | ||
| 430 | goto exit; | 452 | goto exit; |
| 431 | 453 | ||
| 432 | /* 17" Powerbooks have extra X sensors */ | 454 | /* 17" Powerbooks have extra X sensors */ |
| 433 | for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { | 455 | for (i = (atp_is_geyser_2(dev) ? 15 : 16); i < ATP_XSENSORS; i++) { |
| 434 | if (!dev->xy_cur[i]) continue; | 456 | if (!dev->xy_cur[i]) |
| 457 | continue; | ||
| 435 | 458 | ||
| 436 | printk("appletouch: 17\" model detected.\n"); | 459 | printk(KERN_INFO "appletouch: 17\" model detected.\n"); |
| 437 | if(atp_is_geyser_2(dev)) | 460 | if (atp_is_geyser_2(dev)) |
| 438 | input_set_abs_params(dev->input, ABS_X, 0, | 461 | input_set_abs_params(dev->input, ABS_X, 0, |
| 439 | (20 - 1) * | 462 | (20 - 1) * |
| 440 | ATP_XFACT - 1, | 463 | ATP_XFACT - 1, |
| @@ -444,10 +467,10 @@ static void atp_complete(struct urb* urb) | |||
| 444 | (ATP_XSENSORS - 1) * | 467 | (ATP_XSENSORS - 1) * |
| 445 | ATP_XFACT - 1, | 468 | ATP_XFACT - 1, |
| 446 | ATP_FUZZ, 0); | 469 | ATP_FUZZ, 0); |
| 447 | |||
| 448 | break; | 470 | break; |
| 449 | } | 471 | } |
| 450 | 472 | ||
| 473 | dev->size_detect_done = 1; | ||
| 451 | goto exit; | 474 | goto exit; |
| 452 | } | 475 | } |
| 453 | 476 | ||
| @@ -479,7 +502,7 @@ static void atp_complete(struct urb* urb) | |||
| 479 | dev->y_old = y; | 502 | dev->y_old = y; |
| 480 | 503 | ||
| 481 | if (debug > 1) | 504 | if (debug > 1) |
| 482 | printk("appletouch: X: %3d Y: %3d " | 505 | printk(KERN_DEBUG "appletouch: X: %3d Y: %3d " |
| 483 | "Xz: %3d Yz: %3d\n", | 506 | "Xz: %3d Yz: %3d\n", |
| 484 | x, y, x_z, y_z); | 507 | x, y, x_z, y_z); |
| 485 | 508 | ||
| @@ -507,19 +530,25 @@ static void atp_complete(struct urb* urb) | |||
| 507 | input_report_key(dev->input, BTN_LEFT, key); | 530 | input_report_key(dev->input, BTN_LEFT, key); |
| 508 | input_sync(dev->input); | 531 | input_sync(dev->input); |
| 509 | 532 | ||
| 510 | /* Many Geysers will continue to send packets continually after | 533 | /* |
| 511 | the first touch unless reinitialised. Do so if it's been | 534 | * Many Geysers will continue to send packets continually after |
| 512 | idle for a while in order to avoid waking the kernel up | 535 | * the first touch unless reinitialised. Do so if it's been |
| 513 | several hundred times a second */ | 536 | * idle for a while in order to avoid waking the kernel up |
| 514 | 537 | * several hundred times a second. Re-initialization does not | |
| 515 | if (!x && !y && !key) { | 538 | * work on Fountain touchpads. |
| 516 | dev->idlecount++; | 539 | */ |
| 517 | if (dev->idlecount == 10) { | 540 | if (!atp_is_fountain(dev)) { |
| 518 | dev->valid = 0; | 541 | if (!x && !y && !key) { |
| 519 | schedule_work(&dev->work); | 542 | dev->idlecount++; |
| 520 | } | 543 | if (dev->idlecount == 10) { |
| 521 | } else | 544 | dev->valid = 0; |
| 522 | dev->idlecount = 0; | 545 | schedule_work(&dev->work); |
| 546 | /* Don't resubmit urb here, wait for reinit */ | ||
| 547 | return; | ||
| 548 | } | ||
| 549 | } else | ||
| 550 | dev->idlecount = 0; | ||
| 551 | } | ||
| 523 | 552 | ||
| 524 | exit: | 553 | exit: |
| 525 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); | 554 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
| @@ -593,12 +622,12 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id | |||
| 593 | else | 622 | else |
| 594 | dev->datalen = 81; | 623 | dev->datalen = 81; |
| 595 | 624 | ||
| 596 | if (atp_is_geyser_3(dev)) { | 625 | if (!atp_is_fountain(dev)) { |
| 597 | /* switch to raw sensor mode */ | 626 | /* switch to raw sensor mode */ |
| 598 | if (atp_geyser3_init(udev)) | 627 | if (atp_geyser_init(udev)) |
| 599 | goto err_free_devs; | 628 | goto err_free_devs; |
| 600 | 629 | ||
| 601 | printk("appletouch Geyser 3 inited.\n"); | 630 | printk(KERN_INFO "appletouch: Geyser mode initialized.\n"); |
| 602 | } | 631 | } |
| 603 | 632 | ||
| 604 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); | 633 | dev->urb = usb_alloc_urb(0, GFP_KERNEL); |
