aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@tungstengraphics.com>2007-05-08 01:31:40 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-05-08 01:31:40 -0400
commitd2ada5597d33a9108acb2caf912f85cbc9caab1e (patch)
treec8fe7ebaf381f6874e768b21f978bff887137852 /drivers/input
parent334d0dd8b660557608142f0f77abc6812b48f08b (diff)
Input: i8042 - fix AUX port detection with some chips
The i8042 driver fails detection of the AUX port with some chips, because they apparently do not change the I8042_CTR_AUXDIS bit immediately. This is known to affect at least HP500/HP510 notebooks, consequently the built-in touchpad will not work. The patch will simply reread the value until it gets the expected value or a retry limit is hit, without touching other workaround code in the same area. Signed-off-by: Roland Scheidegger <sroland@tungstengraphics.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/serio/i8042.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 7c17377a65b9..3888dc307e0c 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -526,6 +526,33 @@ static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id)
526 return IRQ_HANDLED; 526 return IRQ_HANDLED;
527} 527}
528 528
529/*
530 * i8042_toggle_aux - enables or disables AUX port on i8042 via command and
531 * verifies success by readinng CTR. Used when testing for presence of AUX
532 * port.
533 */
534static int __devinit i8042_toggle_aux(int on)
535{
536 unsigned char param;
537 int i;
538
539 if (i8042_command(&param,
540 on ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE))
541 return -1;
542
543 /* some chips need some time to set the I8042_CTR_AUXDIS bit */
544 for (i = 0; i < 100; i++) {
545 udelay(50);
546
547 if (i8042_command(&param, I8042_CMD_CTL_RCTR))
548 return -1;
549
550 if (!(param & I8042_CTR_AUXDIS) == on)
551 return 0;
552 }
553
554 return -1;
555}
529 556
530/* 557/*
531 * i8042_check_aux() applies as much paranoia as it can at detecting 558 * i8042_check_aux() applies as much paranoia as it can at detecting
@@ -580,16 +607,12 @@ static int __devinit i8042_check_aux(void)
580 * Bit assignment test - filters out PS/2 i8042's in AT mode 607 * Bit assignment test - filters out PS/2 i8042's in AT mode
581 */ 608 */
582 609
583 if (i8042_command(&param, I8042_CMD_AUX_DISABLE)) 610 if (i8042_toggle_aux(0)) {
584 return -1;
585 if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
586 printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); 611 printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
587 printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n"); 612 printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
588 } 613 }
589 614
590 if (i8042_command(&param, I8042_CMD_AUX_ENABLE)) 615 if (i8042_toggle_aux(1))
591 return -1;
592 if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
593 return -1; 616 return -1;
594 617
595/* 618/*