in panel.c [1109:1164]
static void phys_scan_contacts(void)
{
int bit, bitval;
char oldval;
char bitmask;
char gndmask;
phys_prev = phys_curr;
phys_read_prev = phys_read;
phys_read = 0; /* flush all signals */
/* keep track of old value, with all outputs disabled */
oldval = r_dtr(pprt) | scan_mask_o;
/* activate all keyboard outputs (active low) */
w_dtr(pprt, oldval & ~scan_mask_o);
/* will have a 1 for each bit set to gnd */
bitmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
/* disable all matrix signals */
w_dtr(pprt, oldval);
/* now that all outputs are cleared, the only active input bits are
* directly connected to the ground
*/
/* 1 for each grounded input */
gndmask = PNL_PINPUT(r_str(pprt)) & scan_mask_i;
/* grounded inputs are signals 40-44 */
phys_read |= (__u64)gndmask << 40;
if (bitmask != gndmask) {
/*
* since clearing the outputs changed some inputs, we know
* that some input signals are currently tied to some outputs.
* So we'll scan them.
*/
for (bit = 0; bit < 8; bit++) {
bitval = BIT(bit);
if (!(scan_mask_o & bitval)) /* skip unused bits */
continue;
w_dtr(pprt, oldval & ~bitval); /* enable this output */
bitmask = PNL_PINPUT(r_str(pprt)) & ~gndmask;
phys_read |= (__u64)bitmask << (5 * bit);
}
w_dtr(pprt, oldval); /* disable all outputs */
}
/*
* this is easy: use old bits when they are flapping,
* use new ones when stable
*/
phys_curr = (phys_prev & (phys_read ^ phys_read_prev)) |
(phys_read & ~(phys_read ^ phys_read_prev));
}