summaryrefslogtreecommitdiff
path: root/bcm5974.c
diff options
context:
space:
mode:
Diffstat (limited to 'bcm5974.c')
-rw-r--r--bcm5974.c75
1 files changed, 12 insertions, 63 deletions
diff --git a/bcm5974.c b/bcm5974.c
index 2b94835..67cbab3 100644
--- a/bcm5974.c
+++ b/bcm5974.c
@@ -157,7 +157,6 @@ struct atp {
157 struct bt_data *bt_data; /* button transferred data */ 157 struct bt_data *bt_data; /* button transferred data */
158 struct urb *tp_urb; /* trackpad usb request block */ 158 struct urb *tp_urb; /* trackpad usb request block */
159 struct tp_data *tp_data; /* trackpad transferred data */ 159 struct tp_data *tp_data; /* trackpad transferred data */
160 unsigned tp_valid; /* trackpad sensors valid */
161}; 160};
162 161
163/* logical dimensions */ 162/* logical dimensions */
@@ -283,10 +282,9 @@ static int report_tp_state(struct atp *dev, int size)
283#define ATP_WELLSPRING_MODE_WRITE_REQUEST_ID 9 282#define ATP_WELLSPRING_MODE_WRITE_REQUEST_ID 9
284#define ATP_WELLSPRING_MODE_REQUEST_VALUE 0x300 283#define ATP_WELLSPRING_MODE_REQUEST_VALUE 0x300
285#define ATP_WELLSPRING_MODE_REQUEST_INDEX 0 284#define ATP_WELLSPRING_MODE_REQUEST_INDEX 0
286#define ATP_WELLSPRING_MODE_VENDOR_VALUE_1 0x01 285#define ATP_WELLSPRING_MODE_VENDOR_VALUE 0x01
287#define ATP_WELLSPRING_MODE_VENDOR_VALUE_2 0x05
288 286
289static int atp_wellspring_init(struct atp *dev) 287static int atp_wellspring_mode(struct atp *dev)
290{ 288{
291 char *data = kmalloc(8, GFP_KERNEL); 289 char *data = kmalloc(8, GFP_KERNEL);
292 int error = 0, size; 290 int error = 0, size;
@@ -297,24 +295,6 @@ static int atp_wellspring_init(struct atp *dev)
297 goto error; 295 goto error;
298 } 296 }
299 297
300 /* reset button endpoint */
301 if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
302 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
303 0, dev->cfg.bt_ep, NULL, 0, 5000)) {
304 err("bcm5974: could not reset button endpoint");
305 error = -EIO;
306 goto error;
307 }
308
309 /* reset trackpad endpoint */
310 if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
311 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
312 0, dev->cfg.tp_ep, NULL, 0, 5000)) {
313 err("bcm5974: could not reset trackpad endpoint");
314 error = -EIO;
315 goto error;
316 }
317
318 /* read configuration */ 298 /* read configuration */
319 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), 299 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
320 ATP_WELLSPRING_MODE_READ_REQUEST_ID, 300 ATP_WELLSPRING_MODE_READ_REQUEST_ID,
@@ -329,8 +309,7 @@ static int atp_wellspring_init(struct atp *dev)
329 } 309 }
330 310
331 /* apply the mode switch */ 311 /* apply the mode switch */
332 data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE_1; 312 data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE;
333 data[1] = ATP_WELLSPRING_MODE_VENDOR_VALUE_2;
334 313
335 /* write configuration */ 314 /* write configuration */
336 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), 315 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
@@ -345,9 +324,7 @@ static int atp_wellspring_init(struct atp *dev)
345 goto error; 324 goto error;
346 } 325 }
347 326
348 dev->tp_valid = 0; 327 dprintk(2, "bcm5974: switched to wellspring mode.\n");
349
350 printk(KERN_INFO "bcm5974: Wellspring mode initialized.\n");
351 328
352 kfree(data); 329 kfree(data);
353 return 0; 330 return 0;
@@ -409,11 +386,9 @@ static void irq_trackpad(struct urb *urb)
409 goto exit; 386 goto exit;
410 } 387 }
411 388
412 /* first sample data ignored */ 389 /* control response ignored */
413 if (!dev->tp_valid) { 390 if (dev->tp_urb->actual_length == 2)
414 dev->tp_valid = 1;
415 goto exit; 391 goto exit;
416 }
417 392
418 if (report_tp_state(dev, dev->tp_urb->actual_length)) { 393 if (report_tp_state(dev, dev->tp_urb->actual_length)) {
419 dprintk(1, "bcm5974: bad trackpad package, length: %d\n", 394 dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
@@ -434,18 +409,21 @@ static int atp_open(struct input_dev *input)
434 struct atp *dev = input_get_drvdata(input); 409 struct atp *dev = input_get_drvdata(input);
435 410
436 if (!dev->open) { 411 if (!dev->open) {
412 if (atp_wellspring_mode(dev))
413 printk(KERN_INFO "bcm5974: mode switch failed\n");
414
437 if (usb_submit_urb(dev->bt_urb, GFP_KERNEL)) 415 if (usb_submit_urb(dev->bt_urb, GFP_KERNEL))
438 goto error; 416 goto error;
439 if (usb_submit_urb(dev->tp_urb, GFP_KERNEL)) 417 if (usb_submit_urb(dev->tp_urb, GFP_KERNEL))
440 goto err_free_bt_urb; 418 goto err_kill_bt;
441 } 419 }
442 420
443 dev->open = 1; 421 dev->open = 1;
444 dev->suspended = 0; 422 dev->suspended = 0;
445 return 0; 423 return 0;
446 424
447err_free_bt_urb: 425err_kill_bt:
448 usb_free_urb(dev->bt_urb); 426 usb_kill_urb(dev->bt_urb);
449error: 427error:
450 return -EIO; 428 return -EIO;
451} 429}
@@ -486,12 +464,6 @@ static int atp_probe(struct usb_interface *iface,
486 dev->input = input_dev; 464 dev->input = input_dev;
487 dev->cfg = *cfg; 465 dev->cfg = *cfg;
488 466
489 /* switch to raw sensor mode */
490 if (atp_wellspring_init(dev)) {
491 error = -EIO;
492 goto err_free_devs;
493 }
494
495 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); 467 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
496 if (!dev->bt_urb) { 468 if (!dev->bt_urb) {
497 error = -ENOMEM; 469 error = -ENOMEM;
@@ -631,35 +603,12 @@ static int atp_resume(struct usb_interface *iface)
631 return error; 603 return error;
632} 604}
633 605
634static int atp_reset_resume(struct usb_interface *iface)
635{
636 struct atp *dev = usb_get_intfdata(iface);
637
638 if (dev && atp_wellspring_init(dev))
639 printk(KERN_INFO "bcm5974: warning: reset failed\n");
640
641 return atp_resume(iface);
642}
643
644static int atp_pre_reset(struct usb_interface *iface)
645{
646 return atp_suspend(iface, PMSG_ON);
647}
648
649static int atp_post_reset(struct usb_interface *iface)
650{
651 return atp_reset_resume(iface);
652}
653
654static struct usb_driver atp_driver = { 606static struct usb_driver atp_driver = {
655 .name = "bcm5974", 607 .name = "bcm5974",
656 .probe = atp_probe, 608 .probe = atp_probe,
657 .disconnect = atp_disconnect, 609 .disconnect = atp_disconnect,
658 .suspend = atp_suspend, 610 .suspend = atp_suspend,
659 .resume = atp_resume, 611 .resume = atp_resume,
660 .reset_resume = atp_reset_resume,
661 .pre_reset = atp_pre_reset,
662 .post_reset = atp_post_reset,
663 .id_table = atp_table, 612 .id_table = atp_table,
664}; 613};
665 614