diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-11-01 22:13:32 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2007-11-01 22:13:32 -0400 |
commit | 2a3e480d4b3392ce8907089094bd074575f9bb2a (patch) | |
tree | 617c06b1b19090a1b08178b5b56c0fc8fe687a13 /drivers/input | |
parent | 167ebf760fcecf72824756c8235e2d30f050bedd (diff) |
Input: appletouch - idle reset logic broke older Fountains
Fountains do not support change mode request and therefore
should be excluded from idle reset attempts.
Also:
- do not re-submit URB when we decide that touchpad needs to be
reinicialized
- do not repeat size detection when reinitializing the touchpad
- Add missing KERN_* prefixes to messages
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Diffstat (limited to 'drivers/input')
-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); |