*/
static int i8042_command(unsigned char *param, int command)
-{
+{
unsigned long flags;
int retval = 0, i = 0;
dbg("%02x -> i8042 (command)", command & 0xff);
i8042_write_command(command & 0xff);
}
-
+
if (!retval)
for (i = 0; i < ((command >> 12) & 0xf); i++) {
if ((retval = i8042_wait_write())) break;
if (!retval)
for (i = 0; i < ((command >> 8) & 0xf); i++) {
if ((retval = i8042_wait_read())) break;
- if (i8042_read_status() & I8042_STR_AUXDATA)
+ if (i8042_read_status() & I8042_STR_AUXDATA)
param[i] = ~i8042_read_data();
else
param[i] = i8042_read_data();
} else dfl = 0;
dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
- data, (str >> 6), irq,
+ data, (str >> 6), irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
-
+
goto irq_ret;
}
dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
- data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
+ data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa9)
return -1;
param = 0xa4;
- if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == 0x5b)
+ if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == 0x5b) {
+
+/*
+ * Do another loop test with the 0x5a value. Doing anything else upsets
+ * Profusion/ServerWorks OSB4 chipsets.
+ */
+
+ param = 0x5a;
+ i8042_command(¶m, I8042_CMD_AUX_LOOP);
return -1;
+ }
if (mux_version)
*mux_version = ~param;
if (i8042_enable_mux_mode(values, &mux_version))
return -1;
-
+
/* Workaround for broken chips which seem to support MUX, but in reality don't. */
- /* They all report version 12.10 */
- if (mux_version == 0xCA)
+ /* They all report version 10.12 */
+ if (mux_version == 0xAC)
return -1;
printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
/*
* Bit assignment test - filters out PS/2 i8042's in AT mode
*/
-
+
if (i8042_command(¶m, I8042_CMD_AUX_DISABLE))
return -1;
if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
if (i8042_command(¶m, I8042_CMD_AUX_ENABLE))
return -1;
if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
- return -1;
+ return -1;
/*
* Disable the interface.
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
values->exists = 0;
- return -1;
+ return -1;
}
printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
- if (code==SYS_DOWN || code==SYS_HALT)
+ if (code == SYS_DOWN || code == SYS_HALT)
i8042_controller_cleanup();
return NOTIFY_DONE;
}
sysdev_class_unregister(&kbc_sysclass);
}
- del_timer_sync(&i8042_timer);
-
i8042_controller_cleanup();
-
+
if (i8042_kbd_values.exists)
serio_unregister_port(&i8042_kbd_port);
if (i8042_aux_values.exists)
serio_unregister_port(&i8042_aux_port);
-
+
for (i = 0; i < 4; i++)
if (i8042_mux_values[i].exists)
serio_unregister_port(i8042_mux_port + i);
+ del_timer_sync(&i8042_timer);
i8042_platform_exit();
}