Hi,
My current PS/2 controller initialization sequence goes like this:
Code:
a) Do a couple dummy reads from the data port.
b) Get the current controller configuration byte (controller command 0x20).
c) Do another dummy read from the data port.
d) Set a new configuration byte (controller command 0x60).
Note: This step disbles IRQs, enables clock signals to any devices
and disables the scan code translation for the first PS/2 port
e) Do another dummy read from the data port.
f) Send "disable device B" command to the controller (controller command 0xA7).
g) Get the current controller configuration (controller command 0x20).
h) If clock signal to device B is still enabled, then assume the PS/2
controller is an older "single device" controller rather than
a "dual device" controller, and mark device B as unusable.
i) If it is a "dual device" controller, send the controller configuration
byte again to re-enable device B (controller command 0x60).
j) Create a new node for the PS/2 controller in my "device tree" (mark the
IO ports and IRQ/s as used, etc).
k) Disable scanning for device A by sending command 0xF5 to it.
l) If device B is still usable, disable scanning for device B by
sending command 0xF5 to it.
m) Perform device A interface test (send command 0xAB to device).
n) If device B is still usable, perform device B interface test (send
command 0xAB to device).
o) Reset device A (device command 0xFF) - if it doesn't return 0xFA then
0xAA (ACK then BAT test passed) mark device A as unusable, otherwise
disable device A scanning again (device command 0xF5).
p) If device A is still usable, send the "identify" device command to
it and store anything returned for later.
q) If device B is still usable, reset device B (device command 0xFF) - if
it doesn't return 0xFA then 0xAA mark device B as unusable, otherwise
disable device A scanning again (device command 0xF5).
r) If device B is still usable, send the "identify" device command to
it and store anything returned for later.
s) Add any usable devices to the the "device tree" ready to load device drivers
There's a few notes that go with all this..
It's designed to support any combination of devices (a mouse where the keyboard normally goes, a pair of keyboards and no mouse, etc).
I deliberately try to disable the default scan code translation (which is meant to convert "scancode set 2" sent by the keyboard into "scancode set 1"). This translation is only possible for device A, and messes up mouse data when a mouse is plugged in as device A. Unfortunately, for some older PS/2 controllers it can't be disabled (~80486 and Bochs), and for some new computers if the BIOS has the "emulate PS/2 for USB keyboard/mouse for crappy OSs" option enabled. In this case it's difficult to have a mouse as PS/2 device A (I still need to do some research on how hard it is to reverse this translation if it can't be disabled).
All of the steps above rely on little helper routines to get data, send commands, etc. These helpers can all return a time-out error. During the early parts of initialization any time-out results in a "controller not found" condition. Later stages may result in device A or device B being marked unusable or a "controller not found" condition (if the time-out shouldn't be possible when a device isn't present).
Possible "device types" returned from step P and step R are:
Code:
0xFA AT keyboard with translation (not possible for device B)
0xFA, 0xAB, 0x41 MF2 keyboard with translation (not possible for device B)
0xFA, 0xAB, 0xC1 MF2 keyboard with translation (not possible for device B)
0xFA, 0xAB, 0x83 MF2 keyboard without translation
0xFA, 0x00 Standard mouse
0xFA, 0x03 Mouse with a scroll wheel
0xFA, 0x04 5 button mouse with a scroll wheel
There's probably device types that I haven't seen yet, but the list covers everything I've been able to test so far.
After initialization, the IRQs for any usable devices are left disabled and so is device scanning. These are enabled when a PS/2 keyboard or mouse driver does it's initialization. Leaving "device scanning" disabled prevents the device from sending any data to the controller unless they've been asked to.
Device specific configuration is left to an appropriate device driver (there's no setting the LED's, typematic rate, mouse scaling, etc). The idea is to configure the PS/2 controller only - it could be a bar code scanner or something attached for all I know.
The method above works on everything I've tested it on, but I haven't tested it on everything in the world so there's no guarantees
.
Cheers,
Brendan